895 lines
22 KiB
C
895 lines
22 KiB
C
/*++
|
|
|
|
Copyright (c) 1991-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
xxinithl.c
|
|
|
|
Abstract:
|
|
|
|
|
|
This module implements the initialization of the system dependent
|
|
functions that define the Hardware Architecture Layer (HAL) for a
|
|
MIPS R98B system.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
// For CPU
|
|
#define CPU_PHY_INF_OFFSET 0x1d68
|
|
#define CPU_RED_INF_OFFSET 0x1d60
|
|
//For Memory
|
|
#define SIMM_PHY_INF_OFFSET 0x1d10
|
|
#define SIMM_RED_INF_OFFSET 0x1d00
|
|
#define SIMM_PHY_CAP_OFFSET 0x1d20
|
|
#define FW_NOT_DETECT 0x0000
|
|
#define FW_16_DETECT 0x0001
|
|
#define FW_32_DETECT 0x0002
|
|
#define FW_64_DETECT 0x0004
|
|
#define FW_128_DETECT 0x0008
|
|
|
|
|
|
ULONG HalpMachineCpu;
|
|
ULONG HalpNumberOfPonce;
|
|
ULONG HalpPhysicalNode;
|
|
|
|
|
|
//For CPU
|
|
ULONG HalpLogicalCPU2PhysicalCPU[R98B_MAX_CPU];
|
|
ULONG HalpPhysicalAffinity=0;
|
|
ULONG HalpFwAffinity=0;
|
|
ULONG HalpFwDetectErrorCpu=0;
|
|
// For Memory
|
|
ULONG HalpFwDetectMemory=0;
|
|
ULONG HalpPhysicalMemory=0;
|
|
ULONG HalpFwDetectErrorMemory=0;
|
|
UCHAR HalpPhysicalSimmSize[64];
|
|
// For INTERRUPT
|
|
// v-masank@microsoft.com
|
|
//
|
|
extern PINT_ENTRY HalpIntEntryPointer;
|
|
//
|
|
// Define forward referenced prototypes.
|
|
//
|
|
|
|
VOID
|
|
HalpBugCheckCallback (
|
|
IN PVOID Buffer,
|
|
IN ULONG Length
|
|
);
|
|
|
|
BOOLEAN
|
|
HalpBusError (
|
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
IN PKTRAP_FRAME TrapFrame,
|
|
IN PVOID VirtualAddress,
|
|
IN PHYSICAL_ADDRESS PhysicalAddress
|
|
);
|
|
|
|
VOID
|
|
HalpCopyROMs(
|
|
VOID
|
|
);
|
|
|
|
extern PVOID HalpIoControlBase;
|
|
extern PVOID HalpIoMemoryBase;
|
|
extern UCHAR HalpSzPciLock[];
|
|
extern UCHAR HalpSzBreak[];
|
|
extern BOOLEAN HalpPciLockSettings;
|
|
|
|
VOID
|
|
HalpGetParameters (
|
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
|
);
|
|
|
|
//
|
|
// Put all code for HAL initialization in the INIT section. It will be
|
|
// deallocated by memory management when phase 1 initialization is
|
|
// completed.
|
|
//
|
|
|
|
#if defined(ALLOC_PRAGMA)
|
|
|
|
#pragma alloc_text(INIT, HalInitSystem)
|
|
#pragma alloc_text(INIT, HalpGetParameters)
|
|
#pragma alloc_text(INIT, HalInitializeProcessor)
|
|
#pragma alloc_text(INIT, HalStartNextProcessor)
|
|
#pragma alloc_text(INIT, HalpCpuCheck)
|
|
|
|
#endif
|
|
|
|
//
|
|
// Define global spin locks used to synchronize various HAL operations.
|
|
//
|
|
|
|
KSPIN_LOCK HalpBeepLock;
|
|
KSPIN_LOCK HalpDisplayAdapterLock;
|
|
KSPIN_LOCK HalpSystemInterruptLock;
|
|
KSPIN_LOCK HalpIprInterruptLock;
|
|
KSPIN_LOCK HalpDieLock;
|
|
KSPIN_LOCK HalpLogLock;
|
|
//
|
|
// Define bug check information buffer and callback record.
|
|
//
|
|
|
|
typedef struct _HALP_BUGCHECK_BUFFER {
|
|
ULONG FailedAddress;
|
|
ULONG DiagnosticLow;
|
|
ULONG DiagnosticHigh;
|
|
} HALP_BUGCHECK_BUFFER, *PHALP_BUGCHECK_BUFFER;
|
|
|
|
HALP_BUGCHECK_BUFFER HalpBugCheckBuffer;
|
|
|
|
extern ULONG HalpX86BiosInitialized;
|
|
extern ULONG X86BoardOnPonce;
|
|
|
|
KBUGCHECK_CALLBACK_RECORD HalpCallbackRecord;
|
|
|
|
UCHAR HalpComponentId[] = "hal.dll";
|
|
|
|
|
|
VOID
|
|
HalpGetParameters (
|
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This gets any parameters from the boot.ini invocation line.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
PCHAR Options;
|
|
|
|
if (LoaderBlock != NULL && LoaderBlock->LoadOptions != NULL) {
|
|
Options = LoaderBlock->LoadOptions;
|
|
|
|
//
|
|
// Check if PCI settings are locked down
|
|
//
|
|
|
|
if (strstr(Options, HalpSzPciLock)) {
|
|
HalpPciLockSettings = TRUE;
|
|
}
|
|
|
|
//
|
|
// Has the user asked for an initial BreakPoint?
|
|
//
|
|
|
|
if (strstr(Options, HalpSzBreak)) {
|
|
DbgBreakPoint();
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalInitSystem (
|
|
IN ULONG Phase,
|
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function initializes the Hardware Architecture Layer (HAL) for a
|
|
MIPS R3000 or R4000 system.
|
|
|
|
Arguments:
|
|
|
|
Phase - Supplies the initialization phase (zero or one).
|
|
|
|
LoaderBlock - Supplies a pointer to a loader parameter block.
|
|
|
|
Return Value:
|
|
|
|
A value of TRUE is returned is the initialization was successfully
|
|
complete. Otherwise a value of FALSE is returend.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PKPRCB Prcb;
|
|
PHYSICAL_ADDRESS PhysicalAddress;
|
|
PHYSICAL_ADDRESS ZeroAddress;
|
|
ULONG AddressSpace;
|
|
|
|
ULONG Revr;
|
|
ULONG PhysicalNumber;
|
|
|
|
ULONG Cnfg;
|
|
ULONG TmpAffinity;
|
|
PUCHAR FwNvram;
|
|
PULONG FwNvram2;
|
|
UCHAR FwCpu;
|
|
ULONG i,j;
|
|
ULONG FwMemory;
|
|
ULONG FwNoMemory;
|
|
//
|
|
// Initialize the HAL components based on the phase of initialization
|
|
// and the processor number.
|
|
//
|
|
|
|
Prcb = PCR->Prcb;
|
|
//
|
|
// DataBuserr handling
|
|
//
|
|
PCR->DataBusError = HalpBusError;
|
|
//
|
|
// Instruction BusError handling
|
|
//
|
|
PCR->InstructionBusError = HalpBusError;
|
|
|
|
if ((Phase == 0) || (Prcb->Number != 0)) {
|
|
|
|
//
|
|
// Phase 0 initialization.
|
|
//
|
|
// N.B. Phase 0 initialization is executed on all processors.
|
|
//
|
|
// Verify that the processor block major version number conform
|
|
// to the system that is being loaded.
|
|
//
|
|
|
|
if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) {
|
|
KeBugCheck(MISMATCHED_HAL);
|
|
}
|
|
|
|
//
|
|
// Map the fixed TB entries.
|
|
//
|
|
|
|
HalpMapFixedTbEntries();
|
|
HalpGetParameters (LoaderBlock);
|
|
|
|
Revr=READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->REVR ) ;
|
|
PhysicalNumber=((Revr&0x0f000000)>>24)-4;
|
|
HalpLogicalCPU2PhysicalCPU[Prcb->Number]=PhysicalNumber;
|
|
|
|
//
|
|
// If processor 0 is being initialized, then initialize various
|
|
// variables, spin locks, and the display adapter.
|
|
//
|
|
|
|
if (Prcb->Number == 0) {
|
|
|
|
//
|
|
// Fill in handlers for APIs which this hal supports
|
|
//
|
|
|
|
HalQuerySystemInformation = HaliQuerySystemInformation;
|
|
HalSetSystemInformation = HaliSetSystemInformation;
|
|
#if !defined(NT_40)
|
|
HalRegisterBusHandler = HaliRegisterBusHandler;
|
|
HalHandlerForBus = HaliHandlerForBus;
|
|
HalHandlerForConfigSpace = HaliHandlerForConfigSpace;
|
|
HalQueryBusSlots = HaliQueryBusSlots;
|
|
HalSlotControl = HaliSlotControl;
|
|
HalCompleteSlotControl = HaliCompleteSlotControl;
|
|
#endif
|
|
|
|
//
|
|
// Set NMI interrupt service routine on NVRAM
|
|
//
|
|
|
|
HalpSetupNmiHandler(); // DUMP by kita
|
|
|
|
//
|
|
// Set the number of process id's and TB entries.
|
|
//
|
|
|
|
**((PULONG *)(&KeNumberProcessIds)) = 256;
|
|
|
|
//
|
|
// Cpu Type
|
|
//
|
|
|
|
HalpCpuCheck();
|
|
|
|
//
|
|
// Set the interval clock increment value.
|
|
//
|
|
|
|
HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
|
|
HalpNextTimeIncrement = MAXIMUM_INCREMENT;
|
|
HalpNextIntervalCount = 0;
|
|
KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);
|
|
|
|
//
|
|
// Set DMA I/O coherency attributes.
|
|
//
|
|
|
|
KeSetDmaIoCoherency(DMA_READ_DCACHE_INVALIDATE | DMA_READ_ICACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP);
|
|
|
|
//
|
|
// Initialize all spin locks.
|
|
//
|
|
|
|
KeInitializeSpinLock(&HalpBeepLock);
|
|
KeInitializeSpinLock(&HalpDisplayAdapterLock);
|
|
KeInitializeSpinLock(&HalpSystemInterruptLock);
|
|
KeInitializeSpinLock(&HalpIprInterruptLock);
|
|
KeInitializeSpinLock(&HalpDieLock);
|
|
KeInitializeSpinLock(&HalpLogLock);
|
|
|
|
//
|
|
// Set address of cache error routine.
|
|
//
|
|
|
|
KeSetCacheErrorRoutine(HalpCacheErrorRoutine);
|
|
|
|
//
|
|
// Initialize the display adapter.
|
|
//
|
|
|
|
HalpInitializeDisplay0(LoaderBlock);
|
|
|
|
//
|
|
// Allocate map register memory.
|
|
//
|
|
|
|
HalpAllocateMapRegisters(LoaderBlock);
|
|
|
|
//
|
|
// Initialize and register a bug check callback record.
|
|
//
|
|
|
|
KeInitializeCallbackRecord(&HalpCallbackRecord);
|
|
KeRegisterBugCheckCallback(&HalpCallbackRecord,
|
|
HalpBugCheckCallback,
|
|
&HalpBugCheckBuffer,
|
|
sizeof(HALP_BUGCHECK_BUFFER),
|
|
&HalpComponentId[0]);
|
|
|
|
// For CPU log(FW Nvram -> OS Nvram)
|
|
Cnfg=READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->CNFG ) ;
|
|
TmpAffinity=((~((Cnfg&0x0f000000)>>24))&0x0000000f);
|
|
|
|
for(i=0;i<4;i++){
|
|
HalpPhysicalAffinity = HalpPhysicalAffinity | ((TmpAffinity>>i)&0x1);
|
|
if(i==3){
|
|
break;
|
|
}
|
|
HalpPhysicalAffinity=(HalpPhysicalAffinity)<<1;
|
|
}
|
|
|
|
(ULONG)FwNvram=0xbf080000;
|
|
FwCpu=(*FwNvram);
|
|
HalpFwAffinity=(ULONG)FwCpu;
|
|
HalpFwDetectErrorCpu=((HalpPhysicalAffinity)&(~HalpFwAffinity));
|
|
HalNvramWrite(CPU_RED_INF_OFFSET,4,&HalpFwDetectErrorCpu);
|
|
HalNvramWrite(CPU_PHY_INF_OFFSET,4,&HalpPhysicalAffinity);
|
|
|
|
//For memory Log(FW Nvram -> OS NVram)
|
|
(ULONG)FwNvram2=0xbf080050;
|
|
HalpFwDetectMemory=(*FwNvram2);
|
|
FwMemory=0;
|
|
FwNoMemory=0;
|
|
for(i=0;i<4;i++){
|
|
FwMemory=((FwMemory)|((HalpFwDetectMemory <<(i*8))& 0xff000000)) ;
|
|
if(i==3){
|
|
break;
|
|
}
|
|
FwMemory=((FwMemory)>>8);
|
|
}
|
|
for(i=0;i<8;i++){
|
|
switch(FwMemory&0xf){
|
|
case FW_NOT_DETECT:
|
|
FwNoMemory=(FwNoMemory|(0xf<<(i*4)));
|
|
break;
|
|
case FW_16_DETECT:
|
|
for(j=0;j<4;j++){
|
|
HalpPhysicalSimmSize[i*4+j]=0x04;
|
|
}
|
|
break;
|
|
case FW_32_DETECT:
|
|
for(j=0;j<4;j++){
|
|
HalpPhysicalSimmSize[i*4+j]=0x08;
|
|
}
|
|
break;
|
|
case FW_64_DETECT:
|
|
for(j=0;j<4;j++){
|
|
HalpPhysicalSimmSize[i*4+j]=0x16;
|
|
}
|
|
break;
|
|
case FW_128_DETECT:
|
|
for(j=0;j<4;j++){
|
|
HalpPhysicalSimmSize[i*4+j]=0x32;
|
|
}
|
|
break;
|
|
default:
|
|
HalpFwDetectErrorMemory=(HalpFwDetectErrorMemory|(0xf<<(i*4) ));
|
|
}
|
|
FwMemory=((FwMemory)>>4);
|
|
}
|
|
HalpPhysicalMemory=~(FwNoMemory);
|
|
|
|
HalNvramWrite(SIMM_RED_INF_OFFSET,4,&HalpFwDetectErrorMemory);
|
|
HalNvramWrite(SIMM_PHY_INF_OFFSET,4,&HalpPhysicalMemory);
|
|
HalNvramWrite(SIMM_PHY_CAP_OFFSET,64,HalpPhysicalSimmSize);
|
|
}
|
|
|
|
//
|
|
// Initialize I/O address
|
|
//
|
|
|
|
HalpMapIoSpace();
|
|
|
|
#if DBG
|
|
DbgPrint("Errnod addr is 0x%x\n",(PULONG)&(COLUMNBS_LCNTL)->ERRNOD );
|
|
#endif
|
|
//
|
|
// Initialize interrupts
|
|
//
|
|
|
|
HalpInitializeInterrupts();
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Phase 1 initialization.
|
|
//
|
|
// N.B. Phase 1 initialization is only executed on processor 0.
|
|
//
|
|
// Complete initialization of the display adapter.
|
|
//
|
|
HalpRegisterInternalBusHandlers ();
|
|
|
|
if (HalpInitializeDisplay1(LoaderBlock) == FALSE) {
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Map I/O space, calibrate the stall execution scale factor,
|
|
// and create DMA data structures.
|
|
//
|
|
|
|
HalpCalibrateStall();
|
|
|
|
HalpCreateDmaStructures();
|
|
|
|
//
|
|
// for x86bios emulator. bios copy
|
|
//
|
|
|
|
HalpCopyROMs();
|
|
|
|
//
|
|
// Map EISA memory space so the x86 bios emulator emulator can
|
|
// initialze a video adapter in an EISA slot.
|
|
//
|
|
|
|
ZeroAddress.QuadPart = 0;
|
|
AddressSpace = 0;
|
|
HalTranslateBusAddress(Isa,
|
|
0,
|
|
ZeroAddress,
|
|
&AddressSpace,
|
|
&PhysicalAddress);
|
|
|
|
HalpEisaMemoryBase = MmMapIoSpace(PhysicalAddress,
|
|
PAGE_SIZE * 256,
|
|
FALSE);
|
|
|
|
//
|
|
// reset EISA io/memory base for HalCallBios() use.
|
|
//
|
|
if( HalpX86BiosInitialized ){
|
|
if(X86BoardOnPonce == 0){
|
|
HalpIoControlBase = HalpEisaControlBase;
|
|
HalpIoMemoryBase = HalpEisaMemoryBase;
|
|
} else {
|
|
HalpIoControlBase = (PVOID)(
|
|
KSEG1_BASE +
|
|
PCI_CNTL_PHYSICAL_BASE +
|
|
(0x40000 * X86BoardOnPonce )
|
|
);
|
|
PhysicalAddress.HighPart = 1;
|
|
PhysicalAddress.LowPart = 0x40000000 * (X86BoardOnPonce+1);
|
|
HalpIoMemoryBase = MmMapIoSpace(PhysicalAddress,
|
|
PAGE_SIZE * 256,
|
|
FALSE
|
|
);
|
|
}
|
|
DbgPrint("HAL: X86 Bus=%d, HalpIoControlBase = 0x%x, HalpIoMemoryBase = 0x%x%x\n",
|
|
X86BoardOnPonce, HalpIoControlBase, HalpIoMemoryBase);
|
|
}
|
|
|
|
#if DBG
|
|
DbgPrint("HAL: EisaMemoryBase = 0x%x\n", HalpEisaMemoryBase);
|
|
#endif
|
|
// HalpInitializeX86DisplayAdapter();
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check MPU is R4400 or R10000
|
|
//
|
|
VOID
|
|
HalpCpuCheck(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// For Driver. NVRAM Erea Write Enable Any Time.
|
|
//
|
|
WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR ,STSR_WNVWINH);
|
|
//
|
|
// Default setup. future implement is daynamic diagnotics.
|
|
//
|
|
HalpNumberOfPonce = 2;
|
|
|
|
//
|
|
// Set DUMP Key Only NMI.
|
|
// PUSH Power SW coused Interrupt. Not NMI!!
|
|
//
|
|
HalpMrcModeChange((UCHAR)MRC_OP_DUMP_AND_POWERSW_NMI);
|
|
|
|
HalpPhysicalNode = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->CNFG );
|
|
|
|
if( READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->STSR) & STSR_MPU){
|
|
HalpMachineCpu = R98_CPU_R4400;
|
|
**((PULONG *)(&KeNumberTbEntries)) = 48;
|
|
|
|
}else{
|
|
HalpMachineCpu = R98_CPU_R10000;
|
|
**((PULONG *)(&KeNumberTbEntries)) = 64;
|
|
|
|
#if defined(NT_40)
|
|
//
|
|
// Set SyncIrql
|
|
//
|
|
// Hal must not set SyncIrql
|
|
// v-masank@microsoft.com 5/10/96
|
|
// KeSetSynchIrql(5);
|
|
#endif
|
|
}
|
|
//v-masank@microsoft.com for interrupt
|
|
//
|
|
HalpIntEntryPointer= (&HalpIntEntry[HalpMachineCpu][0][0]);
|
|
}
|
|
|
|
|
|
|
|
#include "rxnvr.h"
|
|
|
|
VOID
|
|
HalpSetupNmiHandler(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine set NMI handler to nvRAM.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
|
|
#if 1 //NMI Vector not imprement yet -> modify by kita
|
|
ULONG funcAddr;
|
|
KIRQL OldIrql;
|
|
ENTRYLO SavedPte[2];
|
|
PNVRAM_NMIVECTER NvramNmiVecter;
|
|
|
|
//
|
|
// Get address of HalpNmiHandler
|
|
//
|
|
|
|
funcAddr = (ULONG)HalpNmiHandler;
|
|
|
|
|
|
ASSERT( ((ULONG)&HalpNmiHandler >= KSEG0_BASE) &&
|
|
((ULONG)&HalpNmiHandler < KSEG2_BASE) );
|
|
|
|
//
|
|
// Map the NVRAM into the address space of the current process.
|
|
//
|
|
|
|
OldIrql = HalpMapNvram(&SavedPte[0]);
|
|
|
|
NvramNmiVecter = (PNVRAM_NMIVECTER)NMIVECTER_BASE;
|
|
|
|
WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[0],
|
|
(UCHAR)(funcAddr >> 24));
|
|
|
|
WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[1],
|
|
(UCHAR)((funcAddr >> 16) & 0xFF));
|
|
|
|
WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[2],
|
|
(UCHAR)((funcAddr >> 8) & 0xFF));
|
|
|
|
WRITE_REGISTER_UCHAR(&NvramNmiVecter->NmiVector[3],
|
|
(UCHAR)(funcAddr & 0xFF));
|
|
|
|
//
|
|
// Unmap the NVRAM from the address space of the current process.
|
|
//
|
|
|
|
HalpUnmapNvram(&SavedPte[0], OldIrql);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// no change
|
|
VOID
|
|
HalpBugCheckCallback (
|
|
IN PVOID Buffer,
|
|
IN ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called when a bug check occurs. Its function is
|
|
to dump the state of the memory error registers into a bug check
|
|
buffer.
|
|
|
|
Arguments:
|
|
|
|
Buffer - Supplies a pointer to the bug check buffer.
|
|
|
|
Length - Supplies the length of the bug check buffer in bytes.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// N.B This version Not Implement.
|
|
// Future support!!
|
|
//
|
|
return;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpBusError (
|
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
IN PKTRAP_FRAME TrapFrame,
|
|
IN PVOID VirtualAddress,
|
|
IN PHYSICAL_ADDRESS PhysicalAddress
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function provides the default bus error handling routine for NT.
|
|
|
|
N.B. There is no return from this routine.
|
|
|
|
Arguments:
|
|
|
|
ExceptionRecord - Supplies a pointer to an exception record.
|
|
|
|
ExceptionFrame - Supplies a pointer to an exception frame.
|
|
|
|
TrapFrame - Supplies a pointer to a trap frame.
|
|
|
|
VirtualAddress - Supplies the virtual address of the bus error.
|
|
|
|
PhysicalAddress - Supplies the physical address of the bus error.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG MagellanAllError0 =0;
|
|
ULONG MagellanAllError1 =0;
|
|
ULONG ColumbsAllError;
|
|
|
|
//
|
|
// Only one Eif or Buserr trap
|
|
//
|
|
|
|
WRITE_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->MKSR,
|
|
63-(EIF_VECTOR-DEVICE_VECTORS ));
|
|
|
|
KiAcquireSpinLock(&HalpDieLock);
|
|
HalpBusErrorLog();
|
|
|
|
// KiReleaseSpinLock(&HalpDieLock);
|
|
//
|
|
// Bus Error case (Instruction Fetch and Data Load or Store)
|
|
// -At Memory Read Multi Bit Error.
|
|
// -Read to Memory Hole Area
|
|
// -Read to reserved area or protection area
|
|
//
|
|
if(!(HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN0 ))
|
|
MagellanAllError0 = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(0)->AERR );
|
|
if(!(HalpPhysicalNode & CNFG_CONNECT4_MAGELLAN1 ))
|
|
MagellanAllError1 = READ_REGISTER_ULONG( (PULONG)&MAGELLAN_X_CNTL(1)->AERR );
|
|
|
|
ColumbsAllError = READ_REGISTER_ULONG( (PULONG)&(COLUMNBS_LCNTL)->AERR);
|
|
|
|
|
|
KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
|
|
(ULONG)VirtualAddress,
|
|
ColumbsAllError,
|
|
MagellanAllError0,
|
|
MagellanAllError1
|
|
);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
HalInitializeProcessor (
|
|
IN ULONG Number
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called early in the initialization of the kernel
|
|
to perform platform dependent initialization for each processor
|
|
before the HAL Is fully functional.
|
|
|
|
N.B. When this routine is called, the PCR is present but is not
|
|
fully initialized.
|
|
|
|
Arguments:
|
|
|
|
Number - Supplies the number of the processor to initialize.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
return;
|
|
}
|
|
|
|
BOOLEAN
|
|
HalStartNextProcessor (
|
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|
IN PKPROCESSOR_STATE ProcessorState
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is called to start the next processor.
|
|
|
|
Arguments:
|
|
|
|
LoaderBlock - Supplies a pointer to the loader parameter block.
|
|
|
|
ProcessorState - Supplies a pointer to the processor state to be
|
|
used to start the processor.
|
|
|
|
Return Value:
|
|
|
|
If a processor is successfully started, then a value of TRUE is
|
|
returned. Otherwise a value of FALSE is returned. If a value of
|
|
TRUE is returned, then the logical processor number is stored
|
|
in the processor control block specified by the loader block.
|
|
|
|
--*/
|
|
|
|
{
|
|
PRESTART_BLOCK NextRestartBlock;
|
|
ULONG Number;
|
|
PKPRCB Prcb;
|
|
|
|
//
|
|
// If the address of the first restart parameter block is NULL, then
|
|
// the host system is a uniprocessor system running with old firmware.
|
|
// Otherwise, the host system may be a multiprocessor system if more
|
|
// than one restart block is present.
|
|
//
|
|
// N.B. The first restart parameter block must be for the boot master
|
|
// and must represent logical processor 0.
|
|
//
|
|
|
|
NextRestartBlock = SYSTEM_BLOCK->RestartBlock;
|
|
if (NextRestartBlock == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Scan the restart parameter blocks for a processor that is ready,
|
|
// but not running. If a processor is found, then fill in the restart
|
|
// processor state, set the logical processor number, and set start
|
|
// in the boot status.
|
|
//
|
|
|
|
Number = 0;
|
|
do {
|
|
if ((NextRestartBlock->BootStatus.ProcessorReady != FALSE) &&
|
|
(NextRestartBlock->BootStatus.ProcessorStart == FALSE)) {
|
|
RtlZeroMemory(&NextRestartBlock->u.Mips, sizeof(MIPS_RESTART_STATE));
|
|
NextRestartBlock->u.Mips.IntA0 = ProcessorState->ContextFrame.IntA0;
|
|
NextRestartBlock->u.Mips.Fir = ProcessorState->ContextFrame.Fir;
|
|
Prcb = (PKPRCB)(LoaderBlock->Prcb);
|
|
Prcb->Number = (CCHAR)Number;
|
|
Prcb->RestartBlock = NextRestartBlock;
|
|
NextRestartBlock->BootStatus.ProcessorStart = 1;
|
|
return TRUE;
|
|
}
|
|
|
|
if (NextRestartBlock->BootStatus.ProcessorReady != FALSE){
|
|
Number += 1;
|
|
}
|
|
NextRestartBlock = NextRestartBlock->NextRestartBlock;
|
|
} while (NextRestartBlock != NULL);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
VOID
|
|
HalpVerifyPrcbVersion(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function ?
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return;
|
|
}
|