935 lines
22 KiB
C
935 lines
22 KiB
C
/* #pragma comment(exestr, "@(#) NEC(MIPS) xxinithl.c 1.2 95/10/17 01:19:57" ) */
|
||
/*++
|
||
|
||
Copyright (c) 1995 NEC Corporation
|
||
Copyright (c) 1991-1994 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 R4000 system.
|
||
|
||
Author:
|
||
|
||
David N. Cutler (davec) 25-Apr-1991
|
||
|
||
Environment:
|
||
|
||
Kernel mode only.
|
||
|
||
Revision History:
|
||
|
||
Modification History for NEC R94A (MIPS R4400):
|
||
|
||
H000 Wed Sep 14 19:38:36 JST 1994 kbnes!kishimoto
|
||
- HalInitSystem()
|
||
Define global spin locks used to synchronize
|
||
various LED operations, and initialize LED spin locks.
|
||
H001 Fri Oct 14 15:03:38 JST 1994 kbnes!kishimoto
|
||
- HalInitSystem(),HalpBugCheckCallback(),HalpBusError()
|
||
Modify to read the 33-bit register.
|
||
Bacause the InvalidAddress register of R94A is 33-bits long.
|
||
And original compile errors are modified.
|
||
H002 Fri Oct 21 14:25:22 JST 1994 kbnes!kishimoto
|
||
- call HalR94aDebugPrint to display debug infomation.
|
||
A001 Mon Oct 24 17:19:06 JST 1994 ataka@oa2.kb.nec.co.jp
|
||
- Call HalpInitBusHandlers
|
||
H003 Mon Nov 21 22:01:43 1994 kbnes!kishimoto
|
||
- TEMP TEMP :
|
||
comment out HalpInitializeX86DisplayAdapter() for R94A BBM
|
||
M004 Fri Jan 06 10:53:32 JST 1995 kbnes!A.kuriyama
|
||
- HalpPrintMdl() call
|
||
H005 Mon Jan 16 02:10:42 1995 kbnes!kishimoto
|
||
- initialize PCI configuration register spin lock
|
||
M006 kuriyama@oa2.kb.nec.co.jp Fri Mar 31 17:15:35 JST 1995
|
||
- add _IPI_LIMIT_ support
|
||
S007 kuriyama@oa2.kb.nec.co.jp Mon Apr 03 10:31:37 JST 1995
|
||
- delete PrintMdl ( ifdef _PRINT_MDL_ )
|
||
S008 kuriyama@oa2.kb.nec.co.jp Mon May 22 02:11:30 JST 1995
|
||
- add support for esm
|
||
M009 kuriyama@oa2.kb.nec.co.jp Mon Jun 05 02:53:50 JST 1995
|
||
- add search NMI interface aread
|
||
S010 kuriayam@oa2.kb.nec.co.jp Mon Jun 05 04:44:09 JST 1995
|
||
- NMI interface bug fix
|
||
M011 kuriyama@oa2.kb.nec.co.jp Fri Jun 16 19:13:45 JST 1995
|
||
- add support for esm Ecc 1bit/2bit error logging
|
||
M012 kuriyama@oa2.kb.nec.co.jp Thu Jun 22 10:52:21 JST 1995
|
||
- add ecc 1bit safty flag
|
||
M013 kisimoto@oa2.kb.nec.co.jp Thu Jul 20 19:21:44 JST 1995
|
||
- Merge build 1057 halx86
|
||
H014 kisimoto@oa2.kb.nec.co.jp Sat Aug 12 14:28:46 1995
|
||
- Removed IPI_LIMIT, BBMLED code, J94C definitions,
|
||
and rearrange comments.
|
||
M015 kuriyama@oa2.kb.nec.co.jp Wed Aug 23 19:32:18 JST 1995
|
||
- add for x86bios support
|
||
H016 kisimoto@oa2.kb.nec.co.jp Tue Sep 5 20:43:22 1995
|
||
- add initialization of spinlock to support
|
||
PCI Fast Back-to-back transfer.
|
||
M017 nishi@oa2.kb.nec.co.jp Tue Sep 18 20:43:22 1995
|
||
- add Software Power Off, when system panic is occured
|
||
--*/
|
||
|
||
#include "halp.h"
|
||
/* Start M017 */
|
||
#define HEADER_FILE
|
||
#include "kxmips.h"
|
||
/* End M017 */
|
||
|
||
|
||
//
|
||
// M015
|
||
// Define for x86bios emulator use.
|
||
//
|
||
|
||
// PCHAR K351UseBios=NULL;
|
||
VOID HalpCopyROMs(VOID);
|
||
extern PVOID HalpIoMemoryBase;
|
||
extern PVOID HalpIoControlBase;
|
||
|
||
typedef
|
||
VOID
|
||
(*PHALP_CONTROLLER_SETUP) (
|
||
VOID
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PHALP_DISPLAY_CHARACTER) (
|
||
UCHAR
|
||
);
|
||
|
||
VOID
|
||
HalpDisplayINT10Setup (
|
||
VOID);
|
||
|
||
VOID HalpOutputCharacterINT10 (
|
||
IN UCHAR Character );
|
||
|
||
VOID HalpScrollINT10 (
|
||
IN UCHAR line
|
||
);
|
||
|
||
VOID HalpDisplayCharacterVGA (
|
||
IN UCHAR Character );
|
||
|
||
BOOLEAN
|
||
HalpInitializeX86DisplayAdapter(
|
||
VOID
|
||
);
|
||
|
||
extern PHALP_DISPLAY_CHARACTER HalpDisplayCharacter;
|
||
extern PHALP_CONTROLLER_SETUP HalpDisplayControllerSetup;
|
||
|
||
//
|
||
// M012
|
||
// Define Ecc safety flags
|
||
//
|
||
|
||
#define CHECKED 1
|
||
#define NOT_CHECKED 0
|
||
#define RUNNING 1
|
||
#define NOT_RUNNING 0
|
||
|
||
//
|
||
// M012
|
||
// Define Ecc safety variables
|
||
//
|
||
|
||
UCHAR HalpAnotherCheckedECC = NOT_CHECKED;
|
||
UCHAR HalpAnotherRunningECC = NOT_RUNNING;
|
||
|
||
|
||
//
|
||
// Define forward referenced prototypes.
|
||
//
|
||
|
||
#if defined(_PRINT_MDL_) // M004,S007
|
||
VOID
|
||
HalpPrintMdl (
|
||
PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
);
|
||
#endif // _PRINT_MDL_
|
||
|
||
VOID
|
||
HalpSearchNMIInterface ( // M009
|
||
PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
);
|
||
|
||
ULONG HalpNMIInterfaceAddress = 0;
|
||
|
||
extern
|
||
VOID // M011
|
||
HalpSetInitDisplayTimeStamp(
|
||
VOID
|
||
);
|
||
|
||
extern
|
||
ULONG // M011
|
||
HalpEccError(
|
||
IN ULONG EccDiagnostic,
|
||
IN ULONG MemoryFailed
|
||
);
|
||
|
||
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
|
||
);
|
||
|
||
//
|
||
// 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, HalInitializeProcessor)
|
||
#pragma alloc_text(INIT, HalStartNextProcessor)
|
||
|
||
#endif
|
||
|
||
//
|
||
// Define global spin locks used to synchronize various HAL operations.
|
||
//
|
||
|
||
KSPIN_LOCK HalpBeepLock;
|
||
KSPIN_LOCK HalpDisplayAdapterLock;
|
||
KSPIN_LOCK HalpSystemInterruptLock;
|
||
KSPIN_LOCK HalpPCIConfigLock; // H005
|
||
KSPIN_LOCK Ecc1bitDisableLock; // M011
|
||
KSPIN_LOCK Ecc1bitRoutineLock; // M012
|
||
KSPIN_LOCK HalpPCIBackToBackLock; // H016
|
||
#if defined(_IPI_LIMIT_)
|
||
KSPIN_LOCK HalpIpiRequestLock;
|
||
#endif //_IPI_LIMIT_
|
||
|
||
//
|
||
// 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;
|
||
|
||
KBUGCHECK_CALLBACK_RECORD HalpCallbackRecord;
|
||
|
||
UCHAR HalpComponentId[] = "hal.dll";
|
||
|
||
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.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
ULONG FailedAddress;
|
||
PKPRCB Prcb;
|
||
PHYSICAL_ADDRESS PhysicalAddress;
|
||
PHYSICAL_ADDRESS ZeroAddress;
|
||
ULONG AddressSpace;
|
||
LARGE_INTEGER registerLarge; // H001
|
||
|
||
UCHAR ModeNow; // M017
|
||
KIRQL OldIrql; // M017
|
||
ENTRYLO Pte[2]; // M017
|
||
|
||
//
|
||
// Initialize the HAL components based on the phase of initialization
|
||
// and the processor number.
|
||
//
|
||
|
||
Prcb = PCR->Prcb;
|
||
PCR->DataBusError = HalpBusError;
|
||
PCR->InstructionBusError = HalpBusError;
|
||
if ((Phase == 0) || (Prcb->Number != 0)) {
|
||
|
||
|
||
/* Start M017 */
|
||
if (Prcb->Number == 0) {
|
||
|
||
//
|
||
// for software controlled power supply.
|
||
//
|
||
#if defined(_MRCPOWER_)
|
||
|
||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||
|
||
Pte[0].PFN = MRC_TEMP_PHYSICAL_BASE >> PAGE_SHIFT;
|
||
|
||
Pte[0].G = 1;
|
||
Pte[0].V = 1;
|
||
Pte[0].D = 1;
|
||
|
||
//
|
||
// set second page to global and not valid.
|
||
//
|
||
|
||
Pte[0].C = UNCACHED_POLICY;
|
||
Pte[1].G = 1;
|
||
Pte[1].V = 0;
|
||
|
||
//
|
||
// Map MRC using virtual address of DMA controller.
|
||
//
|
||
|
||
KeFillFixedEntryTb((PHARDWARE_PTE)&Pte[0],
|
||
(PVOID)DMA_VIRTUAL_BASE,
|
||
DMA_ENTRY);
|
||
|
||
//
|
||
// MRC Mode bit change to 0 ( Power Off interrupt is NMI )
|
||
//
|
||
ModeNow = READ_REGISTER_UCHAR(
|
||
&MRC_CONTROL->Mode,
|
||
);
|
||
|
||
WRITE_REGISTER_UCHAR(
|
||
&MRC_CONTROL->Mode,
|
||
ModeNow & 0x02,
|
||
);
|
||
|
||
KeLowerIrql(OldIrql);
|
||
|
||
#endif // _MRCPOWER_
|
||
}
|
||
/* End M017*/
|
||
|
||
//
|
||
// 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();
|
||
|
||
//
|
||
// If processor 0 is being initialized, then initialize various
|
||
// variables, spin locks, and the display adapter.
|
||
//
|
||
|
||
if (Prcb->Number == 0) {
|
||
|
||
#if 0
|
||
//
|
||
// M013
|
||
// Fill in handlers for APIs which this hal supports
|
||
//
|
||
|
||
HalQuerySystemInformation = HaliQuerySystemInformation;
|
||
HalSetSystemInformation = HaliSetSystemInformation;
|
||
HalRegisterBusHandler = HaliRegisterBusHandler;
|
||
HalHandlerForBus = HaliHandlerForBus;
|
||
HalHandlerForConfigSpace = HaliHandlerForConfigSpace;
|
||
HalQueryBusSlots = HaliQueryBusSlots;
|
||
HalSlotControl = HaliSlotControl;
|
||
HalCompleteSlotControl = HaliCompleteSlotControl;
|
||
#endif
|
||
|
||
//
|
||
// Set the number of process id's and TB entries.
|
||
//
|
||
|
||
**((PULONG *)(&KeNumberProcessIds)) = 256;
|
||
**((PULONG *)(&KeNumberTbEntries)) = 48;
|
||
|
||
//
|
||
// Set the interval clock increment value.
|
||
//
|
||
|
||
HalpCurrentTimeIncrement = MAXIMUM_INCREMENT;
|
||
HalpNextTimeIncrement = MAXIMUM_INCREMENT;
|
||
HalpNextIntervalCount = 0;
|
||
|
||
KeSetTimeIncrement(MAXIMUM_INCREMENT, MINIMUM_INCREMENT);
|
||
|
||
//
|
||
// M013
|
||
// Set DMA I/O coherency attributes.
|
||
//
|
||
|
||
KeSetDmaIoCoherency(DMA_READ_DCACHE_INVALIDATE | DMA_READ_ICACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP);
|
||
|
||
//
|
||
// Initialize all spin locks.
|
||
//
|
||
|
||
#if defined(_DUO_)
|
||
|
||
KeInitializeSpinLock(&HalpBeepLock);
|
||
KeInitializeSpinLock(&HalpDisplayAdapterLock);
|
||
KeInitializeSpinLock(&HalpSystemInterruptLock);
|
||
#if defined(_IPI_LIMIT_)
|
||
KeInitializeSpinLock(&HalpIpiRequestLock);
|
||
#endif //_IPI_LIMIT_
|
||
|
||
#endif
|
||
|
||
KeInitializeSpinLock(&Ecc1bitDisableLock); // M011
|
||
KeInitializeSpinLock(&Ecc1bitRoutineLock); // M012
|
||
KeInitializeSpinLock(&HalpPCIConfigLock); // H005
|
||
KeInitializeSpinLock(&HalpPCIBackToBackLock); // H016
|
||
|
||
//
|
||
// Set address of cache error routine.
|
||
//
|
||
|
||
KeSetCacheErrorRoutine(HalpCacheErrorRoutine);
|
||
|
||
//
|
||
// Initialize the display adapter.
|
||
//
|
||
|
||
// temp
|
||
|
||
// TmpInitNvram();
|
||
|
||
#if DBG
|
||
printNvramData();
|
||
#endif // DBG
|
||
|
||
HalpInitializeDisplay0(LoaderBlock);
|
||
|
||
//
|
||
// Allocate map register memory.
|
||
//
|
||
|
||
#if defined(_PRINT_MDL_)
|
||
HalpPrintMdl(LoaderBlock); // M004,S007
|
||
#endif //_PRINT_MDL
|
||
|
||
HalpSearchNMIInterface(LoaderBlock); // M009
|
||
|
||
HalpAllocateMapRegisters(LoaderBlock);
|
||
|
||
//
|
||
// Initialize and register a bug check callback record.
|
||
//
|
||
|
||
KeInitializeCallbackRecord(&HalpCallbackRecord);
|
||
|
||
KeRegisterBugCheckCallback(&HalpCallbackRecord,
|
||
HalpBugCheckCallback,
|
||
&HalpBugCheckBuffer,
|
||
sizeof(HALP_BUGCHECK_BUFFER),
|
||
&HalpComponentId[0]);
|
||
}
|
||
|
||
//
|
||
// H001
|
||
// Clear memory address error registers.
|
||
//
|
||
|
||
#if defined(_DUO_)
|
||
|
||
#if defined(_R94A_)
|
||
|
||
READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, ®isterLarge);
|
||
FailedAddress = registerLarge.LowPart;
|
||
|
||
#else
|
||
|
||
FailedAddress = (ULONG)((volatile DMA_REGISTERS *)DMA_VIRTUAL_BASE)->InvalidAddress.Long;
|
||
|
||
#endif
|
||
|
||
#endif
|
||
|
||
FailedAddress = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long; // H001
|
||
|
||
//
|
||
// 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 (); // M013
|
||
|
||
if (HalpInitializeDisplay1(LoaderBlock) == FALSE) {
|
||
return FALSE;
|
||
|
||
} else {
|
||
|
||
//
|
||
// Map I/O space, calibrate the stall execution scale factor,
|
||
// and create DMA data structures.
|
||
//
|
||
|
||
HalpMapIoSpace();
|
||
|
||
HalpSetInitDisplayTimeStamp(); // S008
|
||
|
||
HalpCalibrateStall();
|
||
|
||
HalpCreateDmaStructures();
|
||
|
||
//
|
||
// M015
|
||
// 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);
|
||
|
||
//
|
||
// M014
|
||
// reset EISA io/memory base for HalCallBios() use.
|
||
//
|
||
HalpIoControlBase = HalpEisaControlBase;
|
||
HalpIoMemoryBase = HalpEisaMemoryBase;
|
||
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
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.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PHALP_BUGCHECK_BUFFER DumpBuffer;
|
||
LARGE_INTEGER registerLarge; // H001
|
||
|
||
//
|
||
// Capture the failed memory address and diagnostic registers.
|
||
//
|
||
|
||
DumpBuffer = (PHALP_BUGCHECK_BUFFER)Buffer;
|
||
|
||
#if defined(_DUO_)
|
||
|
||
#if defined(_R94A_) // H001
|
||
|
||
READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, ®isterLarge);
|
||
DumpBuffer->DiagnosticLow = registerLarge.LowPart;
|
||
|
||
|
||
#else
|
||
|
||
DumpBuffer->DiagnosticLow =
|
||
(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress.Long;
|
||
|
||
#endif
|
||
|
||
DumpBuffer->DiagnosticHigh =
|
||
(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic.u.LargeInteger.HighPart;
|
||
|
||
#else
|
||
|
||
DumpBuffer->DiagnosticLow =
|
||
(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticLow.Long;
|
||
|
||
DumpBuffer->DiagnosticHigh =
|
||
(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticHigh.Long;
|
||
|
||
#endif
|
||
|
||
DumpBuffer->FailedAddress = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long;
|
||
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 DiagnosticHigh;
|
||
ULONG DiagnosticLow;
|
||
ULONG FailedAddress;
|
||
LARGE_INTEGER registerLarge; // H001
|
||
|
||
//
|
||
// Bug check specifying the exception code, the virtual address, the
|
||
// failed memory address, and either the ECC diagnostic registers or
|
||
// the parity diagnostic registers depending on the platform.
|
||
//
|
||
|
||
#if defined(_DUO_)
|
||
|
||
#if !defined(_R94A_)
|
||
|
||
DiagnosticLow =
|
||
(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress.Long;
|
||
|
||
#endif
|
||
|
||
DiagnosticHigh =
|
||
(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->EccDiagnostic.u.LargeInteger.HighPart;
|
||
|
||
#else
|
||
|
||
DiagnosticLow = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticLow.Long;
|
||
DiagnosticHigh = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->ParityDiagnosticHigh.Long;
|
||
|
||
#endif
|
||
|
||
FailedAddress = (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->MemoryFailedAddress.Long;
|
||
|
||
// start M011
|
||
{
|
||
ULONG returnValue;
|
||
KIRQL OldIrql;
|
||
|
||
//
|
||
// Call Ecc 1bit/2bit error routine.
|
||
// if 1bit error return TRUE.(OS run continue)
|
||
// Otherwise bugcheck.
|
||
//
|
||
|
||
if (DiagnosticHigh & 0x66000000) {
|
||
|
||
KeRaiseIrql(HIGH_LEVEL,&OldIrql);
|
||
returnValue = HalpEccError(DiagnosticHigh, FailedAddress);
|
||
KeLowerIrql(OldIrql);
|
||
|
||
if (returnValue == 2) {
|
||
KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
|
||
(ULONG)VirtualAddress,
|
||
FailedAddress,
|
||
DiagnosticLow,
|
||
DiagnosticHigh);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
} else { // M012
|
||
|
||
READ_REGISTER_DWORD((PVOID)&((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->InvalidAddress, ®isterLarge);
|
||
DiagnosticLow = registerLarge.LowPart;
|
||
|
||
if (DiagnosticLow & 1) {
|
||
|
||
KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
|
||
(ULONG)VirtualAddress,
|
||
FailedAddress,
|
||
DiagnosticLow,
|
||
DiagnosticHigh);
|
||
|
||
return FALSE;
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
|
||
}
|
||
|
||
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.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
#if defined(_DUO_)
|
||
|
||
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;
|
||
}
|
||
|
||
Number += 1;
|
||
NextRestartBlock = NextRestartBlock->NextRestartBlock;
|
||
} while (NextRestartBlock != NULL);
|
||
|
||
#endif
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
VOID
|
||
HalpVerifyPrcbVersion(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function ?
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HalpSearchNMIInterface (
|
||
PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
)
|
||
{
|
||
PLIST_ENTRY NextMd;
|
||
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
|
||
ULONG FirmwareParmanentCount = 0;
|
||
|
||
//
|
||
// Get the lower bound of the free physical memory and the
|
||
// number of physical pages by walking the memory descriptor lists.
|
||
//
|
||
|
||
NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
|
||
|
||
while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
|
||
|
||
MemoryDescriptor = CONTAINING_RECORD(NextMd,
|
||
MEMORY_ALLOCATION_DESCRIPTOR,
|
||
ListEntry);
|
||
|
||
if (MemoryDescriptor->MemoryType == MemoryFirmwarePermanent) {
|
||
|
||
if (++FirmwareParmanentCount == 2) { // S010
|
||
HalpNMIInterfaceAddress = MemoryDescriptor->BasePage << PAGE_SHIFT;
|
||
#if DBG
|
||
DbgPrint("NMI Interface was found!\n");
|
||
DbgPrint("MemoryType = %d ",MemoryDescriptor->MemoryType);
|
||
DbgPrint("BasePage = %010x ",MemoryDescriptor->BasePage);
|
||
DbgPrint("PageCount = %5d\n",MemoryDescriptor->PageCount);
|
||
#endif // DBG
|
||
}
|
||
#if DBG
|
||
DbgPrint("Firmware Parmanent entry was found!\n");
|
||
DbgPrint("MemoryType = %d ",MemoryDescriptor->MemoryType);
|
||
DbgPrint("BasePage = %010x ",MemoryDescriptor->BasePage);
|
||
DbgPrint("PageCount = %5d\n",MemoryDescriptor->PageCount);
|
||
#endif // DBG
|
||
}
|
||
NextMd = MemoryDescriptor->ListEntry.Flink;
|
||
}
|
||
}
|