summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/haleagle/ppc/pxmemctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/haleagle/ppc/pxmemctl.c')
-rw-r--r--private/ntos/nthals/haleagle/ppc/pxmemctl.c1643
1 files changed, 1643 insertions, 0 deletions
diff --git a/private/ntos/nthals/haleagle/ppc/pxmemctl.c b/private/ntos/nthals/haleagle/ppc/pxmemctl.c
new file mode 100644
index 000000000..9a844710b
--- /dev/null
+++ b/private/ntos/nthals/haleagle/ppc/pxmemctl.c
@@ -0,0 +1,1643 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Copyright (c) 1994 MOTOROLA, INC. All Rights Reserved. This file
+contains copyrighted material. Use of this file is restricted
+by the provisions of a Motorola Software License Agreement.
+
+Module Name:
+
+ pxmemctl.c
+
+Abstract:
+
+ The module initializes any planar registers.
+ This module also implements machince check parity error handling.
+
+Author:
+
+ Jim Wooldridge (jimw@austin.vnet.ibm.com)
+ Steve Johns (sjohns@pets.sps.mot.com)
+
+Revision History:
+
+--*/
+
+
+
+#include "halp.h"
+#include "pxmemctl.h"
+#include "pxpcisup.h"
+#include "pci.h"
+#include "pcip.h"
+#include "arccodes.h"
+#include "pxsystyp.h"
+#include <string.h>
+
+
+ULONG PciInterruptRoutingOther = 15;
+
+VOID HalDisplayString(PUCHAR String);
+ULONG HalpGetHID0(VOID);
+VOID HalpSetHID0(ULONG Value);
+BOOLEAN HalpStrCmp();
+VOID HalpEnableL2Cache(VOID);
+ULONG HalpSizeL2Cache(VOID);
+extern ULONG HalpSizeL2(VOID);
+extern ULONG L2_Cache_Size;
+extern VOID HalpFlushAndDisableL2(VOID);
+extern HalpPciConfigSize;
+BOOLEAN HalpInitPlanar(VOID);
+BOOLEAN HalpMapPlanarSpace(VOID);
+VOID HalpEnableEagleSettings(VOID);
+VOID HalpEnable_HID0_Settings(ULONG);
+VOID HalpCheckHardwareRevisionLevels(VOID);
+VOID HalpDumpHardwareState(VOID);
+
+#define EAGLECHIPID 0x0001
+
+#define BUF_LEN 120
+#define NEGATECHAR '~'
+
+#define EagleIndexRegister ((PULONG) (((PUCHAR) HalpIoControlBase) + 0xcf8))
+#define EagleDataRegister ((((PUCHAR) HalpIoControlBase) + 0xcfc))
+
+#define HalpReadEagleUlong(Port) \
+ (*EagleIndexRegister = (Port), __builtin_eieio(), *((PULONG) EagleDataRegister))
+
+#define HalpWriteEagleUlong(Port, Value) \
+ (*EagleIndexRegister = (Port), *((PULONG) EagleDataRegister) = (Value), __builtin_sync())
+
+#define HalpReadEagleUshort(Port) \
+ (*EagleIndexRegister = (Port&~3), __builtin_eieio(), *((PUSHORT)(EagleDataRegister+(Port&0x2))))
+
+#define HalpWriteEagleUshort(Port, Value) \
+ (*EagleIndexRegister = (Port&~3), *((PUSHORT)(EagleDataRegister+(Port&0x2))) = (Value), __builtin_sync())
+
+#define HalpWriteEagleUchar(Port, Value) \
+ (*EagleIndexRegister = (Port&~3), *((PUCHAR)(EagleDataRegister+(Port&0x3))) = (Value), __builtin_sync())
+
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT,HalpStrCmp)
+#pragma alloc_text(INIT,HalpEnableL2Cache)
+#pragma alloc_text(INIT,HalpInitPlanar)
+#pragma alloc_text(INIT,HalpMapPlanarSpace)
+#pragma alloc_text(INIT,HalpEnableEagleSettings)
+#pragma alloc_text(INIT,HalpEnable_HID0_Settings)
+#pragma alloc_text(INIT,HalpCheckHardwareRevisionLevels)
+#pragma alloc_text(INIT,HalpSizeL2Cache)
+#endif
+
+
+UCHAR HalpReadEagleUchar(ULONG Port)
+{ UCHAR c;
+ *EagleIndexRegister = Port & ~3;
+ __builtin_eieio();
+ c = *((PUCHAR)(EagleDataRegister+(Port&0x3)));
+ return (c);
+}
+
+
+// Eagle rev 2.1 reads Config register 0xC0 bit 4 into bit 3 instead.
+// Writes to bit 4 are OK.
+UCHAR HalpReadEagleC0(ULONG Port)
+{ UCHAR c;
+
+ c = HalpReadEagleUchar(0x800000C0);
+ c |= ((c & 0x08) << 1);
+ return (c);
+}
+
+
+
+typedef UCHAR (*PHALP_READ_EAGLE) (ULONG Port);
+PHALP_READ_EAGLE HalpReadEagleRegC0;
+
+
+#define HalpDisplayHex32(Num, Buf) HalpDisplayHex( 32, Num, Buf)
+#define HalpDisplayHex16(Num, Buf) HalpDisplayHex( 16, Num, Buf)
+#define HalpDisplayHex8(Num, Buf) HalpDisplayHex( 8, Num, Buf)
+
+VOID HalpDisplayHex(
+ ULONG NoBits,
+ ULONG Number,
+ IN PUCHAR Buffer
+)
+{ int Bits;
+
+ for (Bits=NoBits-4; Bits >= 0; Bits -=4) {
+ *Buffer++ = (UCHAR) ((((Number >> Bits) & 0xF) > 9) ?
+ ((Number >> Bits) & 0xF) - 10 + 'A' :
+ ((Number >> Bits) & 0xF) + '0');
+ }
+ *Buffer++ = '.';
+ *Buffer++ = '\n';
+ *Buffer++ = '\0';
+
+}
+
+
+UCHAR HalpUpperCase(UCHAR c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 'a'-'A';
+ return c;
+}
+
+
+//
+// Routine Description:
+//
+// This routine is a helper routine for parameter parsing. It compares
+// String1 to String2.
+//
+// Return Value
+//
+// TRUE if strings match; otherwise FALSE
+// MatchLen - the number of characters correctly matched.
+//
+
+// #define HalpStrCmp(String1, String2) ( strcmp(String1, String2) == 0)
+BOOLEAN HalpStrCmp( char *String0, char *String1 )
+{
+char *tmp0, *tmp1;
+
+ tmp0 = String0;
+ tmp1 = String1;
+ while( (*tmp0 = toupper( *tmp0 )) && (*tmp1 = toupper( *tmp1 )) )
+ {
+ tmp0++; tmp1++;
+ }
+ return( strcmp(String0, String1) == 0 );
+}
+
+typedef struct tagEAGLEA8 {
+ union {
+ struct {
+ ULONG CF_L2_MP : 2;
+ ULONG SPECULATIVE_PCI : 1;
+ ULONG CF_APARK : 1;
+ ULONG CF_LOOP_SNOOP : 1;
+ ULONG LITTLE_ENDIAN : 1;
+ ULONG STORE_GATHERING : 1;
+ ULONG NO_PORTS_REG : 1;
+ ULONG Reserved1 : 1;
+ ULONG CF_DPARK : 1;
+ ULONG TEA_EN : 1;
+ ULONG MCP_EN : 1;
+ ULONG FLASH_WR_EN : 1;
+ ULONG CF_LBA_EN : 1;
+ ULONG Reserved2 : 1;
+ ULONG CF_MP_ID : 1;
+ ULONG ADDRESS_MAP : 1;
+ ULONG PROC_TYPE : 2;
+ ULONG DISCONTIGOUS_IO : 1;
+ ULONG ROM_CS : 1;
+ ULONG CF_CACHE_1G : 1;
+ ULONG CF_BREAD_WS : 2;
+ ULONG CF_CBA_MASK : 8;
+ } EagleA8;
+
+ ULONG AsUlong;
+ } u;
+} EAGLEA8;
+
+typedef struct tagEAGLEAC {
+ union {
+ struct {
+ ULONG CF_WDATA : 1;
+ ULONG CF_DOE : 1;
+ ULONG CF_APHASE : 2;
+ ULONG CF_L2_SIZE : 2;
+ ULONG CF_TOE_WIDTH : 1;
+ ULONG CF_FAST_CASTOUT : 1;
+ ULONG CF_BURST_RATE : 1;
+ ULONG CF_L2_HIT_DELAY : 2;
+ ULONG reserved1 : 1;
+ ULONG CF_INV_MODE : 1;
+ ULONG CF_HOLD : 1;
+ ULONG CF_ADDR_ONLY : 1;
+ ULONG reserved2 : 1;
+ ULONG CF_HIT_HIGH : 1;
+ ULONG CF_MOD_HIGH : 1;
+ ULONG CF_SNOOP_WS : 2;
+ ULONG CF_WMODE : 2;
+ ULONG CF_DATA_RAM_TYP : 2;
+ ULONG CF_FAST_L2_MODE : 1;
+ ULONG CF_BYTE_DECODE : 1;
+ ULONG reserved3 : 2;
+ ULONG CF_FLUSH_L2 : 1;
+ ULONG reserved4 : 1;
+ ULONG L2_ENABLE : 1;
+ ULONG L2_UPDATE_EN : 1;
+ } EagleAC;
+
+ ULONG AsUlong;
+ } u;
+} EAGLEAC;
+
+
+
+typedef struct tagEAGLEC0 {
+ union {
+ struct {
+ UCHAR LOCAL_BUS : 1;
+ UCHAR PCI_MASTER_ABORT : 1;
+ UCHAR MEM_READ_PARITY : 1;
+ UCHAR Reserved : 1;
+ UCHAR MASTER_PERR : 1;
+ UCHAR MEM_SELECT_ERROR : 1;
+ UCHAR SLAVE_PERR : 1;
+ UCHAR PCI_TARGET_ABORT : 1;
+ } EagleC0;
+
+ UCHAR AsUchar;
+ } u;
+} EAGLEC0;
+
+
+typedef enum {
+ MPC601 = 1,
+ MPC603 = 3,
+ MPC603e = 6,
+ MPC604 = 4,
+ MPC604e = 9
+} CPU_TYPE;
+
+
+// Parity Enable for memory interface
+#define PCKEN 0x10000
+// Machine Check Enable
+#define MCP_EN 0x800
+// Memory Read Parity Enable
+#define MRPE 0x04
+
+typedef enum {
+ WriteThrough,
+ WriteBack
+} L2MODE;
+
+// Oem Output Display function filter noise if OEM or quite
+
+VOID OemDisplayString(PUCHAR String)
+{
+UCHAR CharBuffer[BUF_LEN];
+
+ if(HalGetEnvironmentVariable("HALREPORT",sizeof(CharBuffer),&CharBuffer[0]) == ESUCCESS) {
+ if(HalpStrCmp("YES", CharBuffer)) {
+ HalDisplayString(String);
+ }
+ } else {
+ if(HalGetEnvironmentVariable("MOT-OEM-ID",sizeof(CharBuffer),&CharBuffer[0]) != ESUCCESS) {
+ HalDisplayString(String);
+ }
+ }
+}
+
+char *
+MyStrtok (
+ char * string,
+ const char * control
+ )
+{
+ unsigned char *str;
+ const unsigned char *ctrl = control;
+
+ unsigned char map[32];
+ int count;
+
+ static char *nextoken;
+
+ /* Clear control map */
+ for (count = 0; count < 32; count++)
+ map[count] = 0;
+
+ /* Set bits in delimiter table */
+ do {
+ map[*ctrl >> 3] |= (1 << (*ctrl & 7));
+ } while (*ctrl++);
+
+ /* Initialize str. If string is NULL, set str to the saved
+ * pointer (i.e., continue breaking tokens out of the string
+ * from the last strtok call) */
+ if (string)
+ str = string;
+ else
+ str = nextoken;
+
+ /* Find beginning of token (skip over leading delimiters). Note that
+ * there is no token iff this loop sets str to point to the terminal
+ * null (*str == '\0') */
+ while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
+ str++;
+
+ string = str;
+
+ /* Find the end of the token. If it is not the end of the string,
+ * put a null there. */
+ for ( ; *str ; str++ )
+ if ( map[*str >> 3] & (1 << (*str & 7)) ) {
+ *str++ = '\0';
+ break;
+ }
+
+ /* Update nextoken (or the corresponding field in the per-thread data
+ * structure */
+ nextoken = str;
+
+ /* Determine if a token has been found. */
+ if ( string == str )
+ return NULL;
+ else
+ return string;
+}
+
+
+VOID HalpEnableL2Cache()
+{ EAGLEAC EagleRegAC;
+ EAGLEA8 EagleRegA8;
+ USHORT CpuRevision;
+ CPU_TYPE CpuType;
+ BOOLEAN SynchronousSRAMs, Negate;
+ UCHAR EagleRevision;
+ L2MODE Mode;
+ int i;
+ UCHAR CharBuffer[BUF_LEN], *Value, c1, c2;
+ UCHAR L2_Parameter[BUF_LEN];
+
+ long BridgeChipId;
+
+ BridgeChipId = HalpReadEagleUshort(0x80000002);
+
+ //
+ // For non-EAGLE chips, firmware has already enabled the L2 cache.
+ // No further action is necessary, return.
+ //
+ if (BridgeChipId != EAGLECHIPID)
+ return;
+
+ EagleRevision = HalpReadEagleUchar(0x80000008);
+
+ //
+ // Set some fields in Eagle Register 0xA8
+ //
+ EagleRegA8.u.AsUlong = HalpReadEagleUlong(0x800000A8);
+ EagleRegA8.u.EagleA8.TEA_EN = 1; // Enable TEA
+
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+ CpuType = (CPU_TYPE)(HalpGetProcessorVersion() >> 16);
+
+ EagleRegA8.u.EagleA8.CF_BREAD_WS = 0; // works for 601 & 604
+ switch (CpuType) {
+ case MPC601:
+ EagleRegA8.u.EagleA8.PROC_TYPE = 0;
+ break;
+
+ case MPC603:
+ case MPC603e:
+ EagleRegA8.u.EagleA8.PROC_TYPE = 2;
+ EagleRegA8.u.EagleA8.CF_BREAD_WS = 1; // assumes DRTRY mode !!!
+ break;
+
+ case MPC604:
+ case MPC604e:
+ EagleRegA8.u.EagleA8.PROC_TYPE = 3;
+ break;
+ }
+
+ //
+ // Set the default L2 cache timing.
+ // The timing will be platform dependent.
+ // If the L2 is already on (via firmware), just return.
+ //
+
+ EagleRegAC.u.AsUlong = HalpReadEagleUlong(0x800000AC);
+ if (EagleRegAC.u.EagleAC.L2_ENABLE)
+ return;
+
+ EagleRegAC.u.EagleAC.CF_WMODE = 3;
+ EagleRegAC.u.EagleAC.CF_MOD_HIGH = 1;
+ EagleRegAC.u.EagleAC.CF_ADDR_ONLY = 1;
+ EagleRegAC.u.EagleAC.CF_APHASE = 1;
+ EagleRegAC.u.EagleAC.CF_DOE = 1;
+ EagleRegAC.u.EagleAC.CF_WDATA = 1;
+ EagleRegAC.u.EagleAC.L2_UPDATE_EN = 1;
+ EagleRegAC.u.EagleAC.L2_ENABLE = 1;
+
+
+ switch (HalpSystemType) {
+ case MOTOROLA_BIG_BEND:
+ case MOTOROLA_POWERSTACK:
+ default:
+ SynchronousSRAMs = TRUE;
+ break;
+ }
+
+ if (SynchronousSRAMs) {
+ EagleRegAC.u.EagleAC.CF_DATA_RAM_TYP = 0;
+ EagleRegAC.u.EagleAC.CF_HOLD = 0;
+ EagleRegAC.u.EagleAC.CF_BURST_RATE = 0;
+ } else {
+ EagleRegAC.u.EagleAC.CF_HOLD = 1;
+ EagleRegAC.u.EagleAC.CF_BURST_RATE = 1;
+ if (EagleRevision == 0x21)
+ EagleRegAC.u.EagleAC.CF_DOE = 0;
+ }
+
+ //
+ // Set up the default L2 cache mode.
+ // Default to WRITE-THROUGH prior to Eagle 2.4, else WRITE-BACK
+ //
+ Mode = WriteThrough;
+ if (EagleRevision >= 0x24) {
+ Mode = WriteBack;
+ EagleRegA8.u.EagleA8.CF_LOOP_SNOOP = 1;
+ EagleRegA8.u.EagleA8.CF_CBA_MASK = 0x3f;
+ }
+
+ if (HalpSystemType == MOTOROLA_BIG_BEND) {
+ EagleRegAC.u.EagleAC.CF_SNOOP_WS = 3;
+ EagleRegAC.u.EagleAC.CF_L2_HIT_DELAY = 1;
+ EagleRegAC.u.EagleAC.CF_TOE_WIDTH = 1;
+
+ } else {
+ EagleRegAC.u.EagleAC.CF_SNOOP_WS = 2;
+ EagleRegAC.u.EagleAC.CF_FAST_CASTOUT = 1;
+ EagleRegAC.u.EagleAC.CF_L2_HIT_DELAY = 2;
+ }
+
+ //
+ // There are IBM 604 parts (Revision 3.3 and earlier) that cannot burst
+ // at the fastest rate in WRITE-BACK mode.
+ //
+ if ((Mode == WriteBack) && (CpuType == MPC604) && (CpuRevision < 0x0304))
+ EagleRegAC.u.EagleAC.CF_BURST_RATE = 1; // -2-2-2
+
+
+ //
+ // Parse the environment variable "L2"
+ //
+
+ if (HalGetEnvironmentVariable("L2", BUF_LEN, &CharBuffer[0]) == ESUCCESS) {
+
+ // Copy L2 environment variable
+ i = 0;
+ while (L2_Parameter[i] = CharBuffer[i]) {
+ i++;
+ }
+
+ for( Value = MyStrtok(CharBuffer, " :;,"); Value; Value = MyStrtok(NULL, " :;,") )
+ {
+ if (*Value == NEGATECHAR) {
+ Value++;
+ Negate = TRUE;
+ } else
+ Negate = FALSE;
+
+ // Check for L2 = "OFF"
+ if (HalpStrCmp( "OFF", Value ))
+ {
+ OemDisplayString("HAL: L2 cache is disabled via environment variable L2\n");
+ HalpFlushAndDisableL2();
+ PCR->SecondLevelDcacheSize = PCR->SecondLevelIcacheSize = 0;
+ return;
+ }
+ // Check for WriteBack
+ else if ( HalpStrCmp( "WB", Value ) )
+ {
+ if (Negate) {
+ Value--;
+ goto ParseError;
+ }
+ Mode = WriteBack;
+ EagleRegA8.u.EagleA8.CF_LOOP_SNOOP = 1;
+ EagleRegA8.u.EagleA8.CF_CBA_MASK = 0x3f;
+ }
+ // Check for WriteThrough
+ else if ( HalpStrCmp( "WT", Value ) )
+ {
+ if (Negate) {
+ Value--;
+ goto ParseError;
+ }
+ Mode = WriteThrough;
+ EagleRegA8.u.EagleA8.CF_LOOP_SNOOP = 0;
+ EagleRegA8.u.EagleA8.CF_CBA_MASK = 0x00;
+ }
+ else if (SynchronousSRAMs && HalpStrCmp("FAST_CASTOUT", Value)) {
+ if (Negate) {
+ EagleRegAC.u.EagleAC.CF_FAST_CASTOUT = 0;
+ } else
+ EagleRegAC.u.EagleAC.CF_FAST_CASTOUT = 1;
+ }
+ else if ( HalpStrCmp( "FAST_MODE", Value ) ) {
+ if (Negate) {
+ EagleRegAC.u.EagleAC.CF_FAST_L2_MODE = 0;
+ } else
+ EagleRegAC.u.EagleAC.CF_FAST_L2_MODE = 1;
+ }
+ // Check for cache timings
+ else if ( ( HalpStrCmp( "3-1-1-1", Value ) ) ||
+ ( HalpStrCmp( "4-1-1-1", Value ) ) ||
+ ( HalpStrCmp( "5-1-1-1", Value ) ) )
+ {
+ if (Negate) {
+ Value--;
+ goto ParseError;
+ }
+
+ EagleRegAC.u.EagleAC.CF_L2_HIT_DELAY = *Value - '2';
+// HIT_DELAY is where it samples HIT if =1, then 3-1-1-1 is fastest.
+// CF_DOE_DELAY adds 1 more delay to # cycles, but doesn't change where
+// HIT is sampled. If 66MHz or greater, then DOE_DELAY should be set.
+// same thing with WRITE_DELAY.
+
+ EagleRegAC.u.EagleAC.CF_SNOOP_WS = *Value - '2';
+ if( SynchronousSRAMs ) // Asynchronous SRAMs can't do -1-1-1
+ EagleRegAC.u.EagleAC.CF_BURST_RATE = 0;
+ }
+ else if ( ( HalpStrCmp( "3-2-2-2", Value ) ) ||
+ ( HalpStrCmp( "4-2-2-2", Value ) ) ||
+ ( HalpStrCmp( "5-2-2-2", Value ) ) )
+ {
+ if (Negate) {
+ Value--;
+ goto ParseError;
+ }
+
+ EagleRegAC.u.EagleAC.CF_L2_HIT_DELAY = *Value - '2';
+ EagleRegAC.u.EagleAC.CF_SNOOP_WS = *Value - '2';
+ EagleRegAC.u.EagleAC.CF_BURST_RATE = 1;
+ } else {
+
+ParseError: HalDisplayString("HAL: Error in L2 environment variable: ");
+ HalDisplayString(L2_Parameter);
+ HalDisplayString("\n illegal parameter begins here ");
+ for (i = 0; i < Value - CharBuffer; i++)
+ HalDisplayString("\304");
+ HalDisplayString("^\n");
+ break;
+ }
+
+ } // End for
+ } // End If
+
+
+ //
+ // Enable L2 cache
+ //
+ OemDisplayString("HAL: L2 cache is ");
+
+ if (L2_Cache_Size == 0) {
+ OemDisplayString("not installed.\n");
+ return;
+ }
+
+ if (Mode == WriteThrough)
+ EagleRegA8.u.EagleA8.CF_L2_MP = 1;
+ else
+ EagleRegA8.u.EagleA8.CF_L2_MP = 2;
+
+ HalpWriteEagleUlong(0x800000A8, EagleRegA8.u.AsUlong);
+ HalpWriteEagleUlong(0x800000AC, EagleRegAC.u.AsUlong);
+
+ switch (L2_Cache_Size) {
+
+ case 256:
+ OemDisplayString("256 KB");
+ break;
+
+ case 512:
+ OemDisplayString("512 KB");
+ break;
+
+ case 1024:
+ OemDisplayString("1 MB");
+ break;
+
+ default:
+ OemDisplayString("an invalid configuration. Pattern = ");
+ HalpDisplayHex32(L2_Cache_Size, CharBuffer);
+ OemDisplayString(CharBuffer);
+ PCR->SecondLevelDcacheSize = PCR->SecondLevelDcacheSize = 0;
+ return;
+ }
+
+ //
+ // Display cache mode and timing
+ //
+ if (Mode == WriteBack)
+ OemDisplayString(" (write-back ");
+ else
+ OemDisplayString(" (write-through ");
+
+ CharBuffer[0] = (UCHAR) EagleRegAC.u.EagleAC.CF_L2_HIT_DELAY + '2';
+ CharBuffer[1] = '\0';
+ OemDisplayString(CharBuffer);
+ if (EagleRegAC.u.EagleAC.CF_BURST_RATE)
+ OemDisplayString("-2-2-2)\n");
+ else
+ OemDisplayString("-1-1-1)\n");
+
+ return;
+}
+
+
+
+ULONG HalpSizeL2Cache()
+{ EAGLEAC EagleRegAC;
+ EAGLEA8 EagleRegA8;
+ CPU_TYPE CpuType;
+
+ long BridgeChipId;
+
+ BridgeChipId = HalpReadEagleUshort(0x80000002);
+
+ //
+ // For non-EAGLE chips, firmware has set up the L2 cache size in
+ // the config block and NT Kernel has copied this info into PCR
+ // structure. So, no work needs to be done, retrieve the size from PCR
+ //
+ if (BridgeChipId != EAGLECHIPID)
+ return( (PCR->SecondLevelIcacheSize >> 10) );
+
+ //
+ // Set some fields in Eagle Register 0xA8
+ //
+ EagleRegA8.u.AsUlong = HalpReadEagleUlong(0x800000A8);
+
+ CpuType = (CPU_TYPE)(HalpGetProcessorVersion() >> 16);
+ switch (CpuType) {
+
+ case MPC603:
+ case MPC603e:
+ EagleRegA8.u.EagleA8.PROC_TYPE = 2;
+ EagleRegA8.u.EagleA8.CF_BREAD_WS = 1;
+ break;
+
+ case MPC604:
+ case MPC604e:
+ EagleRegA8.u.EagleA8.PROC_TYPE = 3;
+ EagleRegA8.u.EagleA8.CF_BREAD_WS = 0;
+ break;
+
+ default:
+ return 0; // This HAL doesn't work with this processor
+ }
+
+ HalpWriteEagleUlong(0x800000A8, EagleRegA8.u.AsUlong);
+
+ EagleRegAC.u.AsUlong = HalpReadEagleUlong(0x800000AC);
+ EagleRegAC.u.EagleAC.CF_MOD_HIGH = 1;
+ HalpWriteEagleUlong(0x800000AC, EagleRegAC.u.AsUlong);
+
+ return ( HalpSizeL2());
+}
+
+
+
+
+BOOLEAN
+HalpInitPlanar (
+ VOID
+ )
+
+{ ULONG j;
+ USHORT CpuRevision;
+ CPU_TYPE CpuType;
+ UCHAR EagleRevision, c;
+ UCHAR CharBuffer[20], i;
+
+ long BridgeChipId;
+
+ switch (HalpSystemType) {
+
+ case MOTOROLA_BIG_BEND:
+ HalDisplayString("\nHAL: Motorola Big Bend System");
+ break;
+
+ case MOTOROLA_POWERSTACK:
+// HalDisplayString("\nHAL: Motorola PowerStack System");
+ break;
+
+ case SYSTEM_UNKNOWN:
+ default:
+ HalDisplayString("\nHAL: WARNING : UNKNOWN SYSTEM TYPE\n");
+ break;
+
+ }
+
+ OemDisplayString("\nHAL: Version 2.37 5/24/96.");
+
+ CpuType = (CPU_TYPE)(HalpGetProcessorVersion() >> 16);
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+
+ OemDisplayString("\nHAL: Processor is a 60");
+ i = 0;
+ switch (CpuType) {
+ case MPC601:
+ case MPC603:
+ case MPC604:
+ CharBuffer[i++] = (UCHAR)(CpuType) + '0';
+ break;
+
+ case MPC603e:
+ CharBuffer[i++] = '3';
+ CharBuffer[i++] = 'e';
+ break;
+
+ case MPC604e:
+ CharBuffer[i++] = '4';
+ CharBuffer[i++] = 'e';
+ break;
+
+ default:
+ CharBuffer[i++] = '?';
+ break;
+ }
+ CharBuffer[i] = '\0';
+ OemDisplayString(CharBuffer);
+
+ OemDisplayString(" revision ");
+ i = 0;
+ c = (UCHAR)((CpuRevision >> 8) & 0xf);
+ CharBuffer[i++] = c + '0';
+ CharBuffer[i++] = '.';
+ if (c = (UCHAR)((CpuRevision >> 4) & 0xf))
+ CharBuffer[i++] = c + '0';
+ c = (UCHAR)(CpuRevision & 0xf);
+ if (CpuType == MPC604 && c == 0) { // 604 v3.01
+ CharBuffer[i++] = '0';
+ CharBuffer[i++] = '1';
+ } else {
+ CharBuffer[i++] = c + '0';
+ }
+ CharBuffer[i] = '\0';
+ OemDisplayString(CharBuffer);
+
+
+ BridgeChipId = HalpReadEagleUshort(0x80000002);
+
+ if (BridgeChipId == EAGLECHIPID)
+ OemDisplayString("\nHAL: Eagle Revision");
+ else
+ OemDisplayString("\nHAL: Bridge Chip Revision");
+
+ i = 0;
+ EagleRevision = HalpReadEagleUchar(0x80000008);
+ CharBuffer[i++] = ' ';
+ CharBuffer[i++] = (UCHAR) (EagleRevision >> 4) + '0';
+ CharBuffer[i++] = '.';
+ CharBuffer[i++] = (UCHAR) (EagleRevision & 0x0F) + '0';
+ CharBuffer[i++] = '\n';
+ CharBuffer[i] = '\0';
+ OemDisplayString(CharBuffer);
+
+ return TRUE;
+}
+
+
+
+BOOLEAN
+HalpMapPlanarSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the interrupt acknowledge and error address
+ spaces for a PowerPC system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, then a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+ PHYSICAL_ADDRESS physicalAddress;
+
+ //
+ // Map interrupt control space.
+ //
+
+ physicalAddress.HighPart = 0;
+ physicalAddress.LowPart = INTERRUPT_PHYSICAL_BASE;
+ HalpInterruptBase = MmMapIoSpace(physicalAddress,
+ PAGE_SIZE,
+ FALSE);
+
+ if (HalpInterruptBase == NULL)
+ return FALSE;
+ else
+ return TRUE;
+
+
+
+}
+BOOLEAN
+HalpMapBusConfigSpace (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine maps the HAL PCI config
+ spaces for a PowerPC system.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ If the initialization is successfully completed, then a value of TRUE
+ is returned. Otherwise, a value of FALSE is returned.
+
+--*/
+
+{
+
+
+ PHYSICAL_ADDRESS physicalAddress;
+
+
+ //
+ // Map the PCI config space.
+ //
+
+ physicalAddress.LowPart = PCI_CONFIG_PHYSICAL_BASE;
+ HalpPciConfigBase = MmMapIoSpace(physicalAddress, HalpPciConfigSize, FALSE);
+ if (HalpPciConfigBase == NULL)
+ return FALSE;
+ else
+ return TRUE;
+
+}
+
+VOID
+HalpHandleMemoryError(
+ VOID
+ )
+
+{
+
+ UCHAR StatusByte;
+ ULONG ErrorAddress;
+ UCHAR TextAddress[11];
+ USHORT EagleRegister, Byte;
+
+ EagleRegister = HalpReadEagleUshort(0x80000006);
+ if (EagleRegister & 0x8100)
+ HalDisplayString("\nEAGLE Status Register: PARITY Error Detected.");
+ if (EagleRegister & 0x4000)
+ HalDisplayString("\nEAGLE Status Register: SERR asserted.");
+
+// MOTKJR 08/22/95 - Don't check for the following bit.
+// It is always set when NT scans the slots on the PCI bus.
+// if (EagleRegister & 0x2000)
+// HalDisplayString("\nEAGLE Status Register: Transaction terminated with master-abort.");
+
+ if (EagleRegister & 0x1000)
+ HalDisplayString("\nEAGLE Status Register: Transaction terminated by target-abort while master.");
+ if (EagleRegister & 0x0800)
+ HalDisplayString("\nEAGLE Status Register: Transaction terminated by target-abort while slave.");
+
+ //
+ // Check Memory Error Detection Register 2
+ //
+ StatusByte = HalpReadEagleUchar(0x800000C5);
+
+ if (StatusByte & 0x10) {
+ HalDisplayString ("\nEAGLE Error Detection Register 2: L2 Parity Error Detected");
+ }
+
+ if (StatusByte & 0x80) {
+ // HalDisplayString ("\nEAGLE Error Detection Register 2: Invalid Error Address");
+#if DBG
+ //
+ // We have had a catastrophic hardware malfunction.
+ // Dump the state of the Eagle and HID 0 registers.
+ //
+ HalDisplayString("\n");
+ HalpDumpHardwareState();
+#endif
+ return;
+ }
+
+ //
+ // Read the error address register first
+ //
+ ErrorAddress = HalpReadEagleUlong(0x800000C8);
+ //
+ // Convert error address to HEX characters
+ //
+ HalpDisplayHex32(ErrorAddress, TextAddress);
+ TextAddress[ 8] = '.';
+ TextAddress[ 9] = '\0';
+ TextAddress[10] = '\0';
+
+
+ //
+ // Check Memory Error Detection Register 1
+ //
+
+ StatusByte = HalpReadEagleUchar(0x800000C1);
+
+ if (StatusByte & 0x08) {
+ HalDisplayString("\nEAGLE: PCI initiated Cycle.");
+ } else {
+ HalDisplayString("\nEAGLE: CPU initiated Cycle.");
+ }
+
+ if (StatusByte & 0xC0) {
+ HalDisplayString ("\nEAGLE: PCI ");
+ if (StatusByte & 0x80)
+ HalDisplayString ("SERR");
+ else
+ HalDisplayString ("target PERR");
+ HalDisplayString (" signaled at address ");
+ HalDisplayString (TextAddress);
+ }
+
+ if (StatusByte & 0x24) {
+ HalDisplayString ("\nEAGLE: Memory ");
+ if (StatusByte & 0x20)
+ HalDisplayString ("Select");
+ else
+ HalDisplayString ("Read Parity");
+ HalDisplayString (" error at address ");
+ HalDisplayString (TextAddress);
+ }
+
+#if DBG
+ //
+ // We have had a catastrophic hardware malfunction.
+ // Dump the state of the Eagle and HID 0 registers.
+ //
+ HalDisplayString("\n");
+ HalpDumpHardwareState();
+#endif
+}
+
+
+VOID HalpEnableEagleSettings(VOID)
+{
+ ULONG EagleRegister, UseFirmwareSettings;
+ volatile ULONG FakeVectorFetch;
+ USHORT CpuRevision;
+ EAGLEC0 ErrorEnable1;
+ CPU_TYPE CpuType;
+ UCHAR EagleRevision;
+ UCHAR CharBuffer[BUF_LEN], *Value;
+ BOOLEAN Negate;
+
+ long BridgeChipId;
+
+#define SetEagleUcharC0( Clear, Val ) \
+ SetEagleReg(Clear, 0x800000C0, Val, HalpReadEagleRegC0, HalpWriteEagleUchar);
+
+#define SetEagleUchar( Clear, Offset, Val ) \
+ SetEagleReg(Clear, Offset, Val, HalpReadEagleUchar, HalpWriteEagleUchar);
+
+#define SetEagleUshort( Clear, Offset, Val ) \
+ SetEagleReg(Clear, Offset, Val, HalpReadEagleUshort, HalpWriteEagleUshort);
+
+#define SetEagleUlong( Clear, Offset, Val ) \
+ SetEagleReg(Clear, Offset, Val, HalpReadEagleUlong, HalpWriteEagleUlong);
+
+#define SetEagleReg( Clear, Offset, Val, GetReg, SetReg) \
+{ \
+ if (Clear) { \
+ SetReg(Offset, GetReg(Offset) & ~Val); \
+ } else { \
+ SetReg(Offset, GetReg(Offset) | Val); \
+ } \
+}
+
+ CpuType = (CPU_TYPE)(HalpGetProcessorVersion() >> 16);
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+ EagleRevision = HalpReadEagleUchar(0x80000008);
+ UseFirmwareSettings = FALSE;
+
+ //
+ // Adjust default settings for any known chip bugs or anomalies here.
+ // Eagle revision 2.1 has funny bits in Register C0.
+ //
+
+ //
+ // If the bridge chip is not Eagle then set the revision number to 0x24
+ // Currently the sister chip grackle is the only one supported by this
+ // code and it is equivalent to Eagle revision 0x24
+ //
+ BridgeChipId = HalpReadEagleUshort(0x80000002);
+ if (BridgeChipId != EAGLECHIPID)
+ EagleRevision = 0x24;
+
+
+ if (EagleRevision == 0x21)
+ HalpReadEagleRegC0 = HalpReadEagleC0;
+ else
+ HalpReadEagleRegC0 = HalpReadEagleUchar;
+
+
+ //
+ // Set Address and Data Park bits in Eagle.
+ // These particular bits are not "parity" related.
+ //
+ HalpWriteEagleUlong(0x800000A8, HalpReadEagleUlong(0x800000A8) | 0x208);
+
+ //
+ // Setup and initialize the default EAGLE Parity Checking.
+ // This default is platform dependent.
+ //
+
+ switch (HalpSystemType) {
+ case MOTOROLA_POWERSTACK:
+ //
+ // PowerStack Systems will initialize EAGLE Parity Checking
+ // settings at the Boot ROM or ARC Firmware level. Use these
+ // EAGLE settings if they are present, otherwise use defaults.
+ //
+ UseFirmwareSettings = ((HalpReadEagleUlong(0x800000F0) & PCKEN) &&
+ (HalpReadEagleRegC0(0x800000C0) & MRPE));
+ if (UseFirmwareSettings)
+ break;
+
+ HalpWriteEagleUchar(0x800000C4, 0x10); // Enable L2 Parity Checking.
+ // fall-through to default
+
+ default:
+
+ //
+ // Enable parity checking in Eagle chip
+ //
+ ErrorEnable1.u.AsUchar = 0;
+ ErrorEnable1.u.EagleC0.PCI_TARGET_ABORT = 1;
+ ErrorEnable1.u.EagleC0.MEM_SELECT_ERROR = 1;
+ ErrorEnable1.u.EagleC0.MEM_READ_PARITY = 1;
+ HalpWriteEagleUchar(0x800000C0, ErrorEnable1.u.AsUchar);
+
+ if (EagleRevision >= 0x22) {
+ //
+ // NT must be loaded with the PCKEN bit enabled. Check PCKEN to make
+ // sure it is enabled. If it is not enabled, then don't enable parity
+ // checking since parity errors will be found all over memory.
+ //
+ EagleRegister = HalpReadEagleUlong(0x800000F0);
+ if (EagleRegister & PCKEN) {
+
+ //
+ // Enable parity checking in Eagle chip
+ //
+ ErrorEnable1.u.EagleC0.LOCAL_BUS = 1;
+ HalpWriteEagleUchar(0x800000C0, ErrorEnable1.u.AsUchar);
+
+ //
+ // Enable SERR checking in the Command register.
+ //
+ EagleRegister = HalpReadEagleUshort(0x80000004);
+ HalpWriteEagleUshort(0x80000004, (USHORT)(EagleRegister | 0x100)); // SERR only.
+
+ //
+ // Conditionally enable Machine Check in the Eagle.
+ // Systems with IBM 604 revision 3.2 & 3.3 parts have problems
+ // with parity. Motorola parts are OK. It would be great if we
+ // could tell them apart (one from the other), but we can't. So,
+ // don't enable internal Cache parity on this (or earlier) parts.
+ //
+ if ((CpuType != MPC604) || (CpuRevision >= 0x0304)) {
+ EagleRegister = HalpReadEagleUlong(0x800000A8);
+ HalpWriteEagleUlong(0x800000A8, EagleRegister | MCP_EN);
+ }
+ }
+ }
+ }
+
+
+ //
+ // The environment variable "EAGLESETTINGS" is defined as:
+ // Matching a string serves to enable that feature while a tilde (~)
+ // immediately before the parameter string indicates that it is to be disabled.
+ //
+
+ if ( HalGetEnvironmentVariable("EAGLESETTINGS", BUF_LEN, &CharBuffer[0]) == ESUCCESS ) {
+
+ for( Value = MyStrtok(CharBuffer, " :;,"); Value; Value = MyStrtok(NULL, ":;,") ) {
+
+ Negate = FALSE;
+
+ if (*Value == NEGATECHAR) {
+ Value++;
+ Negate = TRUE;
+ }
+
+ if (HalpStrCmp("MCP_EN", Value) || HalpStrCmp("MCP", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, MCP_EN );
+
+ } else if (HalpStrCmp("TEA_EN", Value) || HalpStrCmp("TEA", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, 0x400 );
+
+ } else if (HalpStrCmp("DPARK", Value) || HalpStrCmp("CF_DPARK", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, 0x200 );
+
+ } else if (HalpStrCmp("GATHERING", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, 0x040 );
+
+ } else if (HalpStrCmp("CF_LOOP_SNOOP", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, 0x010 );
+
+ } else if (HalpStrCmp("APARK", Value) || HalpStrCmp("CF_APARK", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, 0x008 );
+
+ } else if (HalpStrCmp("SPECULATIVE", Value)) {
+ SetEagleUlong( Negate, 0x800000A8, 0x004 );
+
+ } else if (HalpStrCmp("L2_PARITY", Value) || HalpStrCmp("L2", Value)) {
+ SetEagleUchar( Negate, 0x800000C4, 0x10 );
+
+ } else if (HalpStrCmp("PCKEN", Value)) {
+ SetEagleUlong( Negate, 0x800000F0, PCKEN );
+
+ } else if (HalpStrCmp("SERR", Value)) {
+ SetEagleUshort( Negate, 0x80000004, 0x100 );
+
+ } else if (HalpStrCmp("RX_SERR_EN", Value) || HalpStrCmp("RX_SERR", Value)) {
+ SetEagleUchar( Negate, 0x800000BA, 0x20 );
+
+ } else if (HalpStrCmp("TARGET_ABORT", Value)) {
+ SetEagleUcharC0( Negate, 0x80 );
+
+ } else if (HalpStrCmp("SLAVE_PERR", Value)) {
+ SetEagleUcharC0( Negate, 0x40 );
+ SetEagleUshort( Negate, 0x80000004, 0x040 );
+
+ } else if (HalpStrCmp("SELECT_ERROR", Value) || HalpStrCmp("SELECT", Value)) {
+ SetEagleUcharC0( Negate, 0x20 );
+
+ } else if (HalpStrCmp("MASTER_PERR", Value)) {
+ SetEagleUcharC0( Negate, 0x10 );
+ SetEagleUshort( Negate, 0x80000004, 0x040 );
+
+ } else if (HalpStrCmp("DRAM", Value) || HalpStrCmp("READ", Value) || HalpStrCmp("MEMORY", Value)) {
+ SetEagleUcharC0( Negate, MRPE );
+
+ } else if (HalpStrCmp("MASTER_ABORT", Value)) {
+ SetEagleUcharC0( Negate, 0x02 );
+
+ } else if (HalpStrCmp("LOCAL_ERROR", Value) || HalpStrCmp("LOCAL", Value)) {
+ SetEagleUcharC0( Negate, 0x01 );
+
+ //
+ // Enabling (or disabling) EAGLE parity by listing
+ // all of the individual bits was too complicated.
+ // For simplicity, we will define one pseudo-bit
+ // called "PARITY". This will set (or clear) all
+ // of the individual parity bits for EAGLE platforms.
+ //
+ } else if (HalpStrCmp("PARITY", Value)) {
+ // Conditionally turn on L2 checking.
+ if (HalpSystemType == MOTOROLA_POWERSTACK) {
+ SetEagleReg( Negate, 0x800000C4, 0x10, HalpReadEagleUchar, HalpWriteEagleUchar );
+ }
+
+ // Set or Clear the PCKEN bit.
+ SetEagleReg( Negate, 0x800000F0, PCKEN, HalpReadEagleUlong, HalpWriteEagleUlong );
+
+ // Set or Clear parity checking in Eagle chip
+ SetEagleUcharC0( Negate, 0xA5 );
+
+ // Set or Clear the SERR bit in the Command register.
+ SetEagleReg( Negate, 0x80000004, 0x100, HalpReadEagleUshort, HalpWriteEagleUshort );
+
+ // Set or Clear the MCP_EN last.
+ SetEagleReg( Negate, 0x800000A8, MCP_EN, HalpReadEagleUlong, HalpWriteEagleUlong );
+
+ } else if (HalpStrCmp("CF_ADDR_ONLY_DISABLE", Value)) {
+ SetEagleUlong( Negate, 0x800000AC, 0x4000);
+ } else if (HalpStrCmp("CF_BURST_RATE", Value)) {
+ SetEagleUlong( Negate, 0x800000AC, 0x0100);
+ } else if (HalpStrCmp("CF_FAST_CASTOUT", Value)) {
+ SetEagleUlong( Negate, 0x800000AC, 0x0080);
+ } else if (HalpStrCmp("CF_TOE_WIDTH", Value)) {
+ SetEagleUlong( Negate, 0x800000AC, 0x0040);
+ } else if (HalpStrCmp("CF_DOE", Value)) {
+ SetEagleUlong( Negate, 0x800000AC, 0x0002);
+ } else if (HalpStrCmp("CF_WDATA", Value)) {
+ SetEagleUlong( Negate, 0x800000AC, 0x0001);
+
+ } else {
+ HalDisplayString( "HAL: Error in EAGLESETTINGS environment variable: ");
+ HalDisplayString(CharBuffer);
+ HalDisplayString("^\n");
+ }
+ } // End for
+ } // End If
+
+ //
+ // Initialize the PowerPC HID0 register here,
+ // before we clear the detection bits in the EAGLE.
+ // Otherwise we can miss the MCP pin signal transition.
+ //
+ HalpEnable_HID0_Settings(UseFirmwareSettings);
+
+ //
+ // Clear any detection bits that may have been set while enabling L2 cache.
+ // The Eagle does not clear the MCP_ signal until it sees a fetch from
+ // the Machine Check vector. So, we must simulate a vector fetch.
+ //
+ FakeVectorFetch = *((volatile PULONG)(0x80000200)); // Clear the EAGLE MCP_ signal if it is set.
+ HalpWriteEagleUchar(0x800000C1, 0xFF); // Clear Error Detection Register 1.
+ HalpWriteEagleUchar(0x800000C5, 0xFF); // Clear Error Detection Register 2.
+ EagleRegister = HalpReadEagleUshort(0x80000006); // Get any Un-documented Status bits.
+ HalpWriteEagleUshort(0x80000006, 0xF900 | (USHORT)(EagleRegister)); // Clear Status Register Bits.
+ FakeVectorFetch = *((volatile PULONG)(0x80000200)); // Clear the EAGLE MCP_ signal if it is set.
+
+ //
+ // Print this message last to confirm everything is working.
+ //
+
+}
+
+VOID HalpEnable_HID0_Settings(ULONG UseDefaultsHidSettings)
+{
+ ULONG EagleRegister;
+ USHORT CpuRevision;
+ CPU_TYPE CpuType;
+ UCHAR EagleRevision;
+ UCHAR CharBuffer[BUF_LEN], *Value;
+ ULONG HidEnable, HidDisable, CurrentHID0;
+ BOOLEAN Negate;
+
+ long BridgeChipId;
+
+#define HID0_MCP (0x80000000)
+#define HID0_CACHE (0x40000000)
+#define HID0_ADDRESS (0x20000000)
+#define HID0_DATA (0x10000000)
+#define HID0_PAR (0x01000000)
+#define HID0_DPM (0x00100000)
+#define HID0_ILOCK (0x00002000)
+#define HID0_DLOCK (0x00001000)
+#define HID0_FBIOB (0x00000010)
+#define HID0_BHT (0x00000004)
+
+#define SetCPUMask( Disable, Val ) \
+{ \
+ if (Disable) \
+ HidDisable |= Val; \
+ else \
+ HidEnable |= Val; \
+}
+
+ CpuType = (CPU_TYPE)(HalpGetProcessorVersion() >> 16);
+ CpuRevision = (USHORT)(HalpGetProcessorVersion() & 0xFFFF);
+
+ EagleRevision = HalpReadEagleUchar(0x80000008);
+
+ //
+ // If the bridge chip is not Eagle then set the revision number to 0x24
+ // Currently the sister chip grackle is the only one supported by this
+ // code and it is equivalent to Eagle revision 0x24
+ //
+ BridgeChipId = HalpReadEagleUshort(0x80000002);
+ if (BridgeChipId != EAGLECHIPID)
+ EagleRevision = 0x24;
+
+
+ HidEnable = 0;
+ HidDisable = 0;
+ CurrentHID0 = HalpGetHID0();
+
+ switch (CpuType) {
+ case MPC603e:
+ if (CpuRevision <= 0x102) {
+ //
+ // Disable Dynamic Power Management on 603e revisions 1.1 & 1.2
+ // 603e revisions 1.1 and 1.2 have errata w.r.t DPM.
+ //
+ CurrentHID0 &= ~HID0_DPM;
+ break;
+ }
+ // else fall through to 603
+
+ case MPC603:
+ //
+ // Enable Dynamic Power Management
+ //
+ CurrentHID0 |= HID0_DPM;
+ }
+
+ //
+ // Set the default CPU Parity Checking.
+ // This default is platform dependent.
+ //
+
+ switch (HalpSystemType) {
+ case MOTOROLA_POWERSTACK:
+ //
+ // PowerStack Systems will initialize HID0 Parity Checking
+ // settings at the Boot ROM or ARC Firmware level. Use these
+ // HID0 settings if they are present, otherwise use defaults.
+ //
+ if (UseDefaultsHidSettings) {
+ // Just enable the Machine Check Pin.
+ // Hopefully, everything else has been setup.
+ CurrentHID0 |= (HID0_MCP);
+ break;
+ }
+ // fall-through to default
+
+ default:
+ CurrentHID0 &= ~(HID0_MCP | HID0_DATA | HID0_CACHE | HID0_ADDRESS);
+
+ //
+ // Systems with IBM 604 revision 3.3 & 3.2 parts have problems with
+ // L1 parity checking. Motorola parts are OK, but we can't tell
+ // Motorola parts from IBM. So, don't enable L1 cache parity checking
+ // on 604 v3.3 or v3.2 parts.
+ switch (CpuType) {
+ case MPC604:
+ if (CpuRevision == 0x303 || CpuRevision == 0x302)
+ break;
+ // else fall through and enable Cache Parity
+ case MPC604e:
+ CurrentHID0 |= (HID0_CACHE);
+ // fall through
+ default:
+ break;
+ }
+
+ //
+ // Set up the default Parity Checking. No checking prior to Eagle 2.2.
+ // NT must be loaded with the PCKEN bit enabled. Check PCKEN to make
+ // sure it is enabled. If it is not enabled, then don't enable parity
+ // checking since parity errors will be found all over memory.
+ //
+
+ EagleRegister = HalpReadEagleUlong(0x800000F0);
+ if ((EagleRevision >= 0x22) && (EagleRegister & PCKEN)) {
+ //
+ // Systems with IBM 604 revision 3.3 parts have problems with
+ // parity generation. Motorola parts are OK. It would be great
+ // if we could tell them apart (one from the other), but we can't.
+ // So don't enable data parity checking on this (or earlier) parts.
+ //
+ if ((CpuType != MPC604) || (CpuRevision >= 0x0304))
+ CurrentHID0 |= (HID0_MCP | HID0_DATA);
+ }
+ break;
+ }
+
+ //
+ // The environment variable "HID0SETTINGS" is defined either as:
+ // "CACHE", "ADDRESS", "DATA", "MCP", "DPM" with either blank or semi-colon
+ // characters used as separators. Matching a string serves to enable
+ // that feature while a tilde (~) immediately before the parameter
+ // string indicates that it is to be disabled.
+ //
+
+ if (HalGetEnvironmentVariable("HID0SETTINGS", BUF_LEN, &CharBuffer[0]) == ESUCCESS) {
+ for( Value = MyStrtok(CharBuffer, " :;,"); Value; Value = MyStrtok(NULL, ":;,") ) {
+
+ Negate = FALSE;
+
+ if (*Value == NEGATECHAR) {
+ Value++;
+ Negate = TRUE;
+ }
+
+ if (HalpStrCmp("MCP", Value)) {
+ SetCPUMask(Negate, HID0_MCP);
+ } else if (HalpStrCmp("ADDRESS", Value)) {
+ SetCPUMask(Negate, HID0_ADDRESS);
+ } else if (HalpStrCmp("DATA", Value)) {
+ SetCPUMask(Negate, HID0_DATA);
+ } else if (HalpStrCmp("PAR", Value)) {
+ SetCPUMask(Negate, HID0_PAR);
+ } else if (HalpStrCmp("ILOCK", Value)) {
+ SetCPUMask(Negate, HID0_ILOCK);
+ } else if (HalpStrCmp("DLOCK", Value)) {
+ SetCPUMask(Negate, HID0_DLOCK);
+ } else {
+ switch (CpuType) {
+ case MPC604:
+ case MPC604e:
+ if (HalpStrCmp("BHT", Value)) {
+ SetCPUMask(Negate, HID0_BHT);
+ continue;
+ }
+ if (HalpStrCmp("CACHE", Value)) {
+ SetCPUMask(Negate, HID0_CACHE);
+ continue;
+ }
+ break;
+
+ case MPC603:
+ case MPC603e:
+ if (HalpStrCmp("DPM", Value)) {
+ SetCPUMask(Negate, HID0_DPM);
+ continue;
+ }
+ if (HalpStrCmp("FBIOB", Value)) {
+ SetCPUMask(Negate, HID0_FBIOB);
+ continue;
+ }
+ break;
+
+
+ } // End switch
+
+ HalDisplayString("HAL: Error in HID0SETTINGS environment variable: ");
+ HalDisplayString(CharBuffer);
+ HalDisplayString("\n");
+ } // End else
+
+ } // End for
+ } // End if
+
+ //
+ // Check for inconsistencies in HID0SETTINGS
+ //
+ if (HidEnable & HidDisable) {
+ HalDisplayString("HAL: Inconsistent settings in HID0SETTINGS environment variable.\n");
+ HalDisplayString(" Disable setting will override enable setting.\n");
+ //
+ // Enforce DISABLE override ENABLE
+ //
+ HidEnable &= ~HidDisable;
+ }
+
+ //
+ // Disable and Enable the bits in the HID0 register.
+ //
+ CurrentHID0 &= ~HidDisable; // Disable bits first.
+ HalpSetHID0(CurrentHID0);
+
+ CurrentHID0 |= HidEnable; // Enable Bits last.
+ HalpSetHID0(CurrentHID0);
+
+ //
+ // Print this message last to confirm everything is working.
+ //
+
+}
+
+
+VOID HalpCheckHardwareRevisionLevels(VOID)
+{
+ ULONG EagleRegister, i;
+ USHORT CpuRevision;
+ CPU_TYPE CpuType;
+ UCHAR EagleRevision;
+ ARC_STATUS Status;
+ UCHAR Buffer[10];
+
+ long BridgeChipId;
+
+ i = HalpGetProcessorVersion();
+ CpuType = (CPU_TYPE)(i >> 16);
+ CpuRevision = (USHORT)(i & 0xFFFF);
+
+ EagleRevision = HalpReadEagleUchar(0x80000008);
+ //
+ // Minimum hardware requirements:
+ // Eagle: v2.1 or greater
+ // 603 or 604: v3.2 or greater
+ // 603e or 604e: any CPU revision
+ //
+
+ //
+ // If the bridge chip is not Eagle then set the revision number to 0x24
+ // Currently the sister chip grackle is the only one supported by this
+ // code and it is equivalent to Eagle revision 0x24
+ //
+ BridgeChipId = HalpReadEagleUshort(0x80000002);
+ if (BridgeChipId != EAGLECHIPID)
+ EagleRevision = 0x24;
+
+
+ if (EagleRevision >= 0x21) {
+ switch (CpuType) {
+ case MPC603:
+ case MPC604:
+ if (CpuRevision >= 0x0302)
+ return;
+ else
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ // If the environment variable BOOTOLDHARDWARE exists (value is
+ // a don't care), then try to boot anyway.
+ Status = HalGetEnvironmentVariable("BOOTOLDHARDWARE", 5, Buffer);
+ if (Status == ESUCCESS || Status == ENOMEM)
+ return;
+
+ HalDisplayString("\nHAL: Unsupported CPU and/or EAGLE revision level. Set the\n");
+ HalDisplayString(" environment variable BOOTOLDHARDWARE to any value to boot anyway.");
+
+ //
+ // Bug check - after stalling to allow
+ // any information printed on the screen
+ // to be read and seen by the user.
+ //
+ HalDisplayString("\n");
+ for (i=0; i<12; i++) {
+ HalDisplayString(".");
+ KeStallExecutionProcessor(1000000);
+ }
+
+ KeBugCheck(HAL_INITIALIZATION_FAILED);
+ return;
+}
+
+
+
+VOID HalpDumpHardwareState(VOID)
+{ ULONG EagleRegister, HID0;
+ UCHAR CharBuffer[12];
+
+#if DBG
+
+ if ( HalGetEnvironmentVariable("DBG_HAL", BUF_LEN, &CharBuffer[0]) == ESUCCESS ) {
+
+ EagleRegister = HalpReadEagleUshort(0x80000004);
+ HalDisplayString("HAL: Eagle register 04 = 0x");
+ HalpDisplayHex16(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUshort(0x80000006);
+ HalDisplayString("HAL: Eagle register 06 = 0x");
+ HalpDisplayHex16(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUlong(0x800000A8);
+ HalDisplayString("HAL: Eagle register A8 = 0x");
+ HalpDisplayHex32(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUlong(0x800000AC);
+ HalDisplayString("HAL: Eagle register AC = 0x");
+ HalpDisplayHex32(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUchar(0x800000C0);
+ HalDisplayString("HAL: Eagle register C0 = 0x");
+ HalpDisplayHex8(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUchar(0x800000C1);
+ HalDisplayString("HAL: Eagle register C1 = 0x");
+ HalpDisplayHex8(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUchar(0x800000C3);
+ HalDisplayString("HAL: Eagle register C3 = 0x");
+ HalpDisplayHex8(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUchar(0x800000C4);
+ HalDisplayString("HAL: Eagle register C4 = 0x");
+ HalpDisplayHex8(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUchar(0x800000C5);
+ HalDisplayString("HAL: Eagle register C5 = 0x");
+ HalpDisplayHex8(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUchar(0x800000C7);
+ HalDisplayString("HAL: Eagle register C7 = 0x");
+ HalpDisplayHex8(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ EagleRegister = HalpReadEagleUlong(0x800000C8);
+ HalDisplayString("HAL: Eagle register C8 = 0x");
+ HalpDisplayHex32(EagleRegister, CharBuffer );
+ HalDisplayString(CharBuffer);
+
+ HID0 = HalpGetHID0();
+ HalDisplayString("HAL: PowerPC Register HID0 = 0x");
+ HalpDisplayHex32(HID0, CharBuffer );
+ HalDisplayString(CharBuffer);
+ }
+
+#endif
+
+}