Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1324 lines
31 KiB

/*++
Copyright (c) 1993 Digital Equipment Corporation
Module Name:
rwinitnt.c
Abstract:
This module implements the platform-specific initialization for
a Rawhide system.
Author:
Eric Rehm 4-May-1994
Environment:
Kernel mode only.
Revision History:
--*/
#include "halp.h"
#include "rawhide.h"
#include "iousage.h"
#include "stdio.h"
// Includes for Error Logging
#include "fwcallbk.h" // To get firmware revisions
#include <ntverp.h> // To O/S build number
#include "errframe.h" // Error Frame Definitions
//
// Define extern global buffer for the Uncorrectable Error Frame.
//
extern PERROR_FRAME PUncorrectableError;
extern IOD_REGISTER_CLASS DumpIodFlag;
//
// Define the Product Naming data.
//
PCHAR HalpFamilyName = "AlphaServer";
PCHAR HalpProductName = "4000";
ULONG HalpProcessorNumber = 5;
#define MAX_INIT_MSG (80)
PRAWHIDE_SYSTEM_CLASS_DATA HalpSystemClassData;
ULONG HalpNumberOfIods;
ULONG HalpNumberOfCpus;
//
// Define the bus type, this value allows us to distinguish between
// EISA and ISA systems. We're only interested in distinguishing
// between just those two buses.
//
ULONG HalpBusType = MACHINE_TYPE_EISA;
//
// Define external references.
//
extern ULONG HalDisablePCIParityChecking;
//
// Function prototypes.
//
VOID
HalpInitializeProcessorParameters(
VOID
);
BOOLEAN
HalpInitializeRawhideInterrupts (
VOID
);
VOID
HalpParseLoaderBlock(
PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
HalpRegisterPlatformResources(
PUCHAR HalName
);
#if HALDBG
VOID
HalpDumpSystemClassData(
PRAWHIDE_SYSTEM_CLASS_DATA SystemClassData
);
#endif // HALDBG
//
// Irql mask and tables
//
// irql 0 - passive
// irql 1 - sfw apc level
// irql 2 - sfw dispatch level
// irql 3 - device low
// irql 4 - device high
// irql 5 - interval clock
// irql 6 - not used
// irql 7 - error, mchk, nmi, performance counters
//
//
//
// The hardware interrupt pins are used as follows for Rawhide
//
// IRQ0 = Reserved (unused)
// IRQ1 = IOD Interrupts (PCI, ESC, and CAP interrupts)
// IRQ2 = Interval Clock
// IRQ3 = IP Interrupt
// SYS_MCH_CHK_IRQ = Duplicate TAG parity error (cached CUD only)
// MCH_HLT_IRQ = Halt button or CPU halt
//
BOOLEAN
HalpInitializeInterrupts (
VOID
)
/*++
Routine Description:
This function initializes interrupts for an Alcor system.
Arguments:
None.
Return Value:
A value of TRUE is returned if the initialization is successfully
completed. Otherwise a value of FALSE is returned.
--*/
{
extern ULONG Halp21164CorrectedErrorInterrupt();
extern VOID HalpCacheErrorInterrupt();
extern ULONG HalpDeviceInterrupt();
#if !defined(NT_UP)
extern VOID HalpIpiInterruptHandler();
#endif //NT_UP
extern ULONG HalpHaltInterrupt();
PKPRCB Prcb;
ULONG Vector;
Prcb = PCR->Prcb;
//
// Initialize interrupt handling for the primary processor and
// any system-wide interrupt initialization.
//
if( Prcb->Number == HAL_PRIMARY_PROCESSOR ){
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Primary Processor\n");
#endif // HALDBG
//
// Initialize HAL processor parameters based on estimated CPU speed.
// This must be done before HalpStallExecution is called. Compute integral
// megahertz first to avoid rounding errors due to imprecise cycle clock
// period values.
//
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Init Processor Params\n");
#endif // HALDBG
HalpInitializeProcessorParameters();
//
// Start the periodic interrupt from the RTC
//
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Program Interval Timer\n");
#endif // HALDBG
HalpProgramIntervalTimer(MAXIMUM_CLOCK_INCREMENT);
//
// Initialize Rawhide interrupts.
//
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Init Rawhide Interrupts\n");
#endif // HALDBG
HalpInitializeRawhideInterrupts();
//
// Initialize the EV5 (21164) interrupts.
//
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Init 21164 Interrupts\n");
#endif // HALDBG
HalpInitialize21164Interrupts();
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Init IDT entries\n");
#endif // HALDBG
#if 0
PCR->InterruptRoutine[EV5_IRQ0_VECTOR] = // IRQ0 is unused on Rawhide
(PKINTERRUPT_ROUTINE) NULL;
#endif
PCR->InterruptRoutine[EV5_IRQ1_VECTOR] = // IOD Interrupt
(PKINTERRUPT_ROUTINE)HalpDeviceInterrupt;
PCR->InterruptRoutine[EV5_IRQ2_VECTOR] = // Interval Timer Interrupt
(PKINTERRUPT_ROUTINE)HalpClockInterrupt;
#if !defined(NT_UP)
PCR->InterruptRoutine[EV5_IRQ3_VECTOR] = // IP Interrupt
(PKINTERRUPT_ROUTINE)HalpIpiInterruptHandler;
#endif //NT_UP
PCR->InterruptRoutine[EV5_HALT_VECTOR] = // Halt button, CPU halt
(PKINTERRUPT_ROUTINE)HalpHaltInterrupt;
PCR->InterruptRoutine[EV5_MCHK_VECTOR] = // Duplicate TAG Parity Error
(PKINTERRUPT_ROUTINE)HalpCacheErrorInterrupt; // (cached CUD only).
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Start 21164 Interrupts\n");
#endif // HALDBG
HalpStart21164Interrupts();
#if HALDBG
DumpAllIods(DumpIodFlag & IodInterruptRegisters);
DbgPrint("HalpInitializeInterrupts: Primary Processor Complete\n");
#endif // HALDBG
} else {
#if !defined(NT_UP)
#if HALDBG
DbgPrint("HalpInitializeInterrupts: Secondary Processor\n");
#endif // HALDBG
//
//
// Initialize the EV5 (21164) interrupts.
//
HalpInitialize21164Interrupts();
#if 0
PCR->InterruptRoutine[EV5_IRQ0_VECTOR] = // IRQ0 is unused on Rawhide
(PKINTERRUPT_ROUTINE) NULL;
#endif
PCR->InterruptRoutine[EV5_IRQ1_VECTOR] = // IOD Interrupt
(PKINTERRUPT_ROUTINE)HalpDeviceInterrupt;
PCR->InterruptRoutine[EV5_IRQ2_VECTOR] = // Interval Timer Interrupt
(PKINTERRUPT_ROUTINE)HalpSecondaryClockInterrupt;
PCR->InterruptRoutine[EV5_IRQ3_VECTOR] = // IP Interrupt
(PKINTERRUPT_ROUTINE)HalpIpiInterruptHandler;
PCR->InterruptRoutine[EV5_HALT_VECTOR] = // Halt button, CPU halt
(PKINTERRUPT_ROUTINE)HalpHaltInterrupt;
PCR->InterruptRoutine[EV5_MCHK_VECTOR] = // Duplicate TAG Parity Error
(PKINTERRUPT_ROUTINE)HalpCacheErrorInterrupt; // (cached CUD only).
HalpStart21164Interrupts();
#endif //NT_UP
}
return TRUE;
}
VOID
HalpInitializeClockInterrupts(
VOID
)
/*++
Routine Description:
This function is called during phase 1 initialization to complete
the initialization of clock interrupts. For EV4, this function
connects the true clock interrupt handler and initializes the values
required to handle profile interrupts.
Arguments:
None.
Return Value:
None.
--*/
{
#if 0
// mdbfix - who references this?
//
// Compute the profile interrupt rate.
//
HalpProfileCountRate = ((1000 * 1000 * 10) / KeQueryTimeIncrement());
#endif
//
// Set the time increment value and connect the real clock interrupt
// routine.
//
PCR->InterruptRoutine[EV5_IRQ2_VECTOR] = HalpClockInterrupt;
return;
}
VOID
HalpEstablishErrorHandler(
VOID
)
/*++
Routine Description:
This routine performs the initialization necessary for the HAL to
begin servicing machine checks.
Arguments:
None.
Return Value:
None.
--*/
{
BOOLEAN PciParityChecking;
BOOLEAN ReportCorrectables;
//
// Connect the machine check handler via the PCR.
//
PCR->MachineCheckError = HalMachineCheck;
HalpInitializeIodMachineChecks( ReportCorrectables = FALSE,
PciParityChecking = FALSE );
return;
}
VOID
HalpInitializeSystemClassData(
ULONG Phase,
PLOADER_PARAMETER_BLOCK LoaderBlock
)
/*++
Routine Description:
Initialize the Rawhide configuration masks passed in the ARC tree.
For phase 0, only initialize the hardware masks. Wait until phase 1,
(after memory manager started) to allocate and save.
Arguments:
LoaderBlock - Supplies a pointer to the loader parameter block.
Return Value:
None.
--*/
{
PCONFIGURATION_COMPONENT_DATA ConfigComponent;
PRAWHIDE_SYSTEM_CLASS_DATA SystemClassData;
MC_ENUM_CONTEXT mcCtx;
ConfigComponent = KeFindConfigurationEntry(
LoaderBlock->ConfigurationRoot,
SystemClass, // Class
ArcSystem, // Type
0
);
//
// Check for errors
//
if ( (ConfigComponent == NULL) ||
(ConfigComponent->ConfigurationData == NULL) ) {
#if HALDBG
DbgPrint ("HalpInitializeSystemClassData: Configuration Data Missing\n");
DbgBreakPoint ();
#endif // HALDBG
}
SystemClassData = (PRAWHIDE_SYSTEM_CLASS_DATA)
ConfigComponent->ConfigurationData;
if (Phase == 0) {
#if HALDBG
HalpDumpSystemClassData(SystemClassData);
#endif
//
// Initialize the rawhide configuration masks
//
HalpIodMask = SystemClassData->IodMask;
HalpCpuMask = SystemClassData->CpuMask;
HalpGcdMask = SystemClassData->GcdMask;
HalpNumberOfIods = HalpMcBusEnumStart(HalpIodMask, &mcCtx);
HalpNumberOfCpus = HalpMcBusEnumStart(HalpCpuMask, &mcCtx);
} else {
//
// Allocate memory and save
//
HalpSystemClassData = (PRAWHIDE_SYSTEM_CLASS_DATA)
ExAllocatePool(NonPagedPool, SystemClassData->Length);
RtlMoveMemory(
HalpSystemClassData,
ConfigComponent->ConfigurationData,
SystemClassData->Length
);
}
}
#if HALDBG
VOID
HalpDumpSystemClassData(
PRAWHIDE_SYSTEM_CLASS_DATA SystemClassData
)
{
#define ONE_MB 1024
ULONG entry;
ULONGLONG TotalMemorySize;
ULONGLONG FreeMemorySize;
ULONGLONG BadMemorySize;
ULONGLONG EntrySizeInBytes;
//
// Print out machine dependent data for debug
//
DbgPrint("System Class Data:\r\n");
DbgPrint("Length: %x\n", SystemClassData->Length);
DbgPrint("Version: %x\n", SystemClassData->Version);
DbgPrint("Flags: %8.8x %8.8x\n", SystemClassData->Flags.all >> 32,
SystemClassData->Flags);
DbgPrint("CpuMask: %8.8x %8.8x\n", SystemClassData->CpuMask >> 32,
SystemClassData->CpuMask);
DbgPrint("GcdMask: %8.8x %8.8x\n", SystemClassData->GcdMask >> 32,
SystemClassData->GcdMask);
DbgPrint("IodMask: %8.8x %8.8x\n", SystemClassData->IodMask >> 32,
SystemClassData->IodMask);
DbgPrint("System Configuration:\n");
DbgPrint("\tValidBits: %x\n", SystemClassData->SystemConfig.ValidBits);
DbgPrint("\tSystemManufacturer: %s\r\n",
SystemClassData->SystemConfig.SystemManufacturer);
DbgPrint("\tSystemModel: %s\r\n",
SystemClassData->SystemConfig.SystemModel);
DbgPrint("\tSystemSerialNumber: %s\r\n",
SystemClassData->SystemConfig.SystemSerialNumber);
DbgPrint("\tSystemRevisionLevel: %s\r\n",
SystemClassData->SystemConfig.SystemRevisionLevel);
DbgPrint("\tSystemVariation: %s\r\n",
SystemClassData->SystemConfig.SystemVariation);
DbgPrint("\tSystemConsoleTypeRev: %s\r\n",
SystemClassData->SystemConfig.ConsoleTypeRev);
DbgPrint("MemoryDescriptor is: %s\r\n",
(SystemClassData->Flags.MemoryDescriptorValid ?
"Valid" : "Invalid"));
DbgPrint("MemoryDescriptorCount: %d\r\n",
SystemClassData->MemoryDescriptorCount);
DbgPrint("MemoryDescriptor is: %s\n",
(SystemClassData->Flags.MemoryDescriptorValid ?
"Valid" : "Invalid"));
DbgPrint("MemoryDescriptorCount: %d\n", SystemClassData->MemoryDescriptorCount);
DbgPrint("Descriptor\tMemoryType\tBasePage\tPageCount\tSize\tTested?\n");
TotalMemorySize = 0;
FreeMemorySize = 0;
BadMemorySize = 0;
for (entry = 0; entry < SystemClassData->MemoryDescriptorCount; entry++) {
EntrySizeInBytes =
(SystemClassData->MemoryDescriptor[entry].PageCount) << PAGE_SHIFT;
DbgPrint("[%d]\t\t%d\t\t%x\t\t%8x\t%4d Mb %x\n",
entry,
SystemClassData->MemoryDescriptor[entry].MemoryType,
SystemClassData->MemoryDescriptor[entry].BasePage,
SystemClassData->MemoryDescriptor[entry].PageCount,
(EntrySizeInBytes / ONE_MB),
SystemClassData->MemoryDescriptor[entry].bTested
);
//
// Total up free (good memory) entries
//
if (SystemClassData->MemoryDescriptor[entry].MemoryType
== RawhideMemoryFree) {
FreeMemorySize += EntrySizeInBytes;
}
//
// Total up hole (bad memory) entries
// Remember them so that they can be removed later.
//
if (SystemClassData->MemoryDescriptor[entry].MemoryType
== RawhideMemoryBad) {
//
// N.B. If this is the last descriptor, and it's a hole
// (bad memory), then ignore it.
//
if (entry == (SystemClassData->MemoryDescriptorCount - 1)) {
break;
}
BadMemorySize += EntrySizeInBytes;
}
//
// Total up all entries, except a trailing hole
//
TotalMemorySize += EntrySizeInBytes;
}
DbgPrint("Total Size:\t\t\t\t\t%8x\t%4d Mb\n\n",
(TotalMemorySize >> PAGE_SHIFT),
(TotalMemorySize / ONE_MB));
DbgPrint("Free Memory Size:\t\t\t\t%8x\t%4d Mb\n",
(FreeMemorySize >> PAGE_SHIFT),
(FreeMemorySize / ONE_MB));
DbgPrint("Bad Memory Size:\t\t\t\t%8x\t%4d Mb\n",
(BadMemorySize >> PAGE_SHIFT),
(BadMemorySize / ONE_MB));
}
#endif // HALDBG
VOID
HalpEarlyInitializeMachineDependent(
IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
/*++
Routine Description:
This function performs any critical Platform-specific initialization based on
the current phase on initialization.
Arguments:
Phase - Supplies an indicator for phase of initialization, phase 0 or
phase 1.
LoaderBlock - supplies a pointer to the loader block.
Return Value:
None.
--*/
{
if( Phase == 0 ){
//
// Phase 0 Initialization.
//
//
// Initialize the Rawhide hardware configuration masks from the
// SRM Machine Dependent Data passed in the Configuration Tree.
//
HalpInitializeSystemClassData(Phase, LoaderBlock);
} else {
//
// Phase 1 Initialization.
//
}
return;
}
VOID
HalpInitializeMachineDependent(
IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
/*++
Routine Description:
This function performs any Platform-specific initialization based on
the current phase on initialization.
Arguments:
Phase - Supplies an indicator for phase of initialization, phase 0 or
phase 1.
LoaderBlock - supplies a pointer to the loader block.
Return Value:
None.
--*/
{
ULONG BusIrql;
ULONG BusNumber;
UCHAR MsgBuffer[MAX_INIT_MSG];
BOOLEAN ReportCorrectables;
BOOLEAN PciParityChecking;
PKPRCB Prcb;
PRAWHIDE_PCR pRawhidePcr;
IOD_POSTED_INTERRUPT_ADDR PostingTable;
IOD_WHOAMI IodWhoAmI;
Prcb = PCR->Prcb;
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Phase = %d\n", Phase);
#endif // HALDBG
if( Prcb->Number == HAL_PRIMARY_PROCESSOR) {
if( Phase == 0 ){
//
// Phase 0 Initialization.
//
//
// Parse the Loader Parameter block looking for PCI entry to determine
// if PCI parity should be disabled
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Parse Loader Block\n");
#endif // HALDBG
HalpParseLoaderBlock( LoaderBlock );
//
// Establish the error handler, to reflect the PCI parity checking.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: \n");
#endif // HALDBG
if( HalDisablePCIParityChecking != 0 ){
PciParityChecking = FALSE;
} else {
PciParityChecking = TRUE;
}
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init Iod Machine Checks\n");
#endif // HALDBG
HalpInitializeIodMachineChecks( ReportCorrectables = TRUE,
PciParityChecking );
//
// Initialize the IOD mapping table, assigning logical
// numbers to all IOD's. This logical number cooresponds
// to the HwBusNumber found in PCIPBUSDATA.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init Iod Mapping Table\n");
#endif // HALDBG
HalpMcBusEnumAndCall(HalpIodMask, HalpInitializeIodMappingTable);
//
// Initialize the logical to physical processor mapping
// for the primary processor.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init HalpLogicalToPhysicalProcesor\n");
#endif // HALDBG
HalpInitializeProcessorMapping(
HAL_PRIMARY_PROCESSOR,
HAL_PRIMARY_PROCESSOR,
LoaderBlock
);
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Phase %d complete\n", Phase);
#endif // HALDBG
} else {
//
// Phase 1 Initialization.
//
//
// Save the Machine Dependent Data now that Memory Manager started.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init System Class Data\n");
#endif // HALDBG
HalpInitializeSystemClassData(Phase, LoaderBlock);
//
// Initialize the existing bus handlers.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Register Internal Bus Handlers\n");
#endif // HALDBG
HalpRegisterInternalBusHandlers();
//
// Initialize PCI Bus.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init PCI Bus\n");
#endif // HALDBG
HalpInitializePCIBus(LoaderBlock);
//
// Initialize the IOD vector table
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init Iod Vector Table\n");
#endif // HALDBG
HalpInitializeIodVectorTable();
//
// Initialize the IOD interrupt vector table CSR's
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init Iod Vector CSRs\n");
#endif // HALDBG
HalpMcBusEnumAndCall(HalpIodMask, HalpInitializeIodVectorCSRs);
//
// Generate pointer to the CPU's area in the IOD vector table
//
PostingTable.all = 0;
PostingTable.Base4KPage = ((ULONG)HalpIodPostedInterrupts / __4K);
PostingTable.CpuOffset =
HalpLogicalToPhysicalProcessor[PCR->Number].all;
HAL_PCR->PostedInterrupts =
(PIOD_POSTED_INTERRUPT)PostingTable.all;
//
// Initialize the IOD and CPU interrupt Vector table
//
HalpInitializeVectorBalanceData();
//
// Initialize the CPU vector entry for this processor
//
HalpInitializeCpuVectorData(PCR->Number);
//
// Assign the primary processors vectors
//
HalpAssignPrimaryProcessorVectors(&HalpIodVectorDataHead);
//
// Initialize profiler.
//
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Init Profiler\n");
#endif // HALDBG
HalpInitializeProfiler();
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Print Version Message\n");
#endif // HALDBG
//
// Print a message with version number.
//
sprintf( MsgBuffer,
"Digital Equipment Corporation %s %s %d/%d\n",
HalpFamilyName,
HalpProductName,
HalpProcessorNumber,
HalpClockMegaHertz );
HalDisplayString( MsgBuffer );
//
// Register the name of the HAL.
//
sprintf( MsgBuffer,
"%s %s %d/%d PCI/EISA HAL",
HalpFamilyName,
HalpProductName,
HalpProcessorNumber,
HalpClockMegaHertz );
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Register Platform Resources\n");
#endif // HALDBG
HalpRegisterPlatformResources( MsgBuffer );
#if HALDBG
DbgPrint("HalpInitializeMachineDependent: Phase %d Complete\n", Phase);
#endif // HALDBG
}
} else {
//
// Connect the machine check handler via the PCR. The machine check
// handler for Rawhide is the default EV4 parity-mode handler. Note
// that this was done in HalpEstablishErrorHandler() for the
// primary processor.
//
PCR->MachineCheckError = HalMachineCheck;
//
// Generate pointer to the CPU's area in the IOD vector table
//
PostingTable.all = 0;
PostingTable.Base4KPage = ((ULONG)HalpIodPostedInterrupts / __4K);
PostingTable.CpuOffset = HalpLogicalToPhysicalProcessor[PCR->Number].all;
HAL_PCR->PostedInterrupts = (PIOD_POSTED_INTERRUPT)PostingTable.all;
//
// Initialize profiler on this secondary processor.
//
HalpInitializeProfiler();
//
// Initialize the CPU vector entry for this processor
//
HalpInitializeCpuVectorData(PCR->Number);
}
return;
}
VOID
HalpInitializeProcessorMapping(
IN ULONG LogicalProcessor,
IN ULONG PhysicalProcessor,
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
/*++
Routine Description:
This function initializes the logical to physical processor mapping
entry in the processor mapping table. The physical mapping is passed
by ARC FW via the configuration tree.
Arguments:
LogicalProcessor - logical processor number.
PhysicalProcessor - restart block number.
LoaderBlock - supplies a pointer to the loader block.
Return Value:
None.
--*/
{
PCONFIGURATION_COMPONENT_DATA CpuConfigComponent;
PHALP_PROCESSOR_ID HalpProcessorId;
//
// If the processor is not ready then we assume that it is not
// present. We must increment the physical processor number but
// the logical processor number does not changed.
//
//
// Get a pointer to the configuration entry for this processor.
// The configuration data will contain the processors MC device ID.
//
CpuConfigComponent = KeFindConfigurationEntry(
LoaderBlock->ConfigurationRoot,
ProcessorClass,
CentralProcessor,
&PhysicalProcessor
);
//
// Check for errors.
//
if ( (CpuConfigComponent == NULL) ||
(CpuConfigComponent->ConfigurationData == NULL) ) {
#if 0 //HALDBG
DbgPrint ("HalStartNextProcessor: Configuration Data Missing\n");
#endif //HALDBG
// What to do now?
DbgBreakPoint ();
}
//
// Obtain a pointer to the processor Id from the configuration data.
//
HalpProcessorId =
((PHALP_PROCESSOR_ID)CpuConfigComponent->ConfigurationData);
//
// Initialize the table entry for this processor.
//
HalpLogicalToPhysicalProcessor[LogicalProcessor].all = HalpProcessorId->all;
}
VOID
HalpRegisterPlatformResources(
PUCHAR HalName
)
/*++
Routine Description:
Register I/O resources used by the HAL.
Arguments:
HalName - Supplies a pointer to the name for the HAL.
Return Value:
None.
--*/
{
RESOURCE_USAGE Resource;
//
// Register the buses.
//
HalpRegisterBusUsage(Internal);
HalpRegisterBusUsage(Eisa);
HalpRegisterBusUsage(Isa);
HalpRegisterBusUsage(PCIBus);
//
// Register the name of the HAL.
//
HalpRegisterHalName( HalName );
//
// Register the interrupt vector used for the cascaded interrupt
// on the 8254s.
//
Resource.BusType = Isa;
Resource.BusNumber = 0;
Resource.ResourceType = CmResourceTypeInterrupt;
Resource.u.InterruptMode = Latched;
Resource.u.BusInterruptVector = 2;
Resource.u.SystemInterruptVector = 2;
Resource.u.SystemIrql = 2;
HalpRegisterResourceUsage(&Resource);
//
// Register machine specific io/memory addresses.
//
Resource.BusType = Isa;
Resource.BusNumber = 0;
Resource.ResourceType = CmResourceTypePort;
#if 0
Resource.u.Start = I2C_INTERFACE_DATA_PORT;
Resource.u.Length = I2C_INTERFACE_LENGTH;
HalpRegisterResourceUsage(&Resource);
#endif
Resource.u.Start = SUPERIO_INDEX_PORT;
Resource.u.Length = SUPERIO_PORT_LENGTH;
HalpRegisterResourceUsage(&Resource);
//
// Register the DMA channel used for the cascade.
//
Resource.BusType = Isa;
Resource.BusNumber = 0;
Resource.ResourceType = CmResourceTypeDma;
Resource.u.DmaChannel = 0x4;
Resource.u.DmaPort = 0x0;
HalpRegisterResourceUsage(&Resource);
}
//
//jnfix
//
// This routine is bogus and does not apply to Alcor and the call should be
// ripped out of fwreturn (or at least changed to something that is more
// abstract).
//
VOID
HalpResetHAERegisters(
VOID
)
{
return;
}
VOID
HalpGetMachineDependentErrorFrameSizes(
PULONG RawProcessorSize,
PULONG RawSystemInfoSize
)
/*++
Routine Description:
This function returns the size of the system specific structures.
Arguments:
RawProcessorSize - Pointer to a buffer that will receive the
size of the processor specific error information buffer.
RawSystemInfoSize - Pointer to a buffer that will receive the
size of the system specific error information buffer.
Return Value:
none
--*/
{
*RawProcessorSize = sizeof(PROCESSOR_EV5_UNCORRECTABLE);
*RawSystemInfoSize = sizeof(RAWHIDE_UNCORRECTABLE_FRAME)
+ HalpNumberOfIods * sizeof(IOD_ERROR_FRAME);
//
// ecrfix - will have to figure out something else for
// PCI, ESC snapshots and System Mgmt Frame.
//
return;
}
VOID
HalpGetSystemInfo(SYSTEM_INFORMATION *SystemInfo)
/*++
Routine Description:
This function fills in the System information.
Arguments:
SystemInfo - Pointer to the SYSTEM_INFORMATION buffer that needs
to be filled in.
Return Value:
none
--*/
{
char systemtype[] = "Rawhide";
EXTENDED_SYSTEM_INFORMATION FwExtSysInfo;
VenReturnExtendedSystemInformation(&FwExtSysInfo);
RtlCopyMemory(SystemInfo->FirmwareRevisionId,
FwExtSysInfo.FirmwareVersion,
16);
RtlCopyMemory(SystemInfo->SystemType, systemtype, 8);
SystemInfo->ClockSpeed =
((1000 * 1000) + (PCR->CycleClockPeriod >> 1)) / PCR->CycleClockPeriod;
SystemInfo->SystemRevision = PCR->SystemRevision;
// RtlCopyMemory(SystemInfo->SystemSerialNumber,
// PCR->SystemSerialNumber,
// 16);
SystemInfo->SystemVariant = PCR->SystemVariant;
SystemInfo->PalMajorVersion = PCR->PalMajorVersion;
SystemInfo->PalMinorVersion = PCR->PalMinorVersion;
SystemInfo->OsRevisionId = VER_PRODUCTBUILD;
//
// For now fill in dummy values.
//
SystemInfo->ModuleVariant = 1UL;
SystemInfo->ModuleRevision = 1UL;
SystemInfo->ModuleSerialNumber = 0;
return;
}
VOID
HalpInitializeUncorrectableErrorFrame (
VOID
)
/*++
Routine Description:
This function Allocates an Uncorrectable Error frame for this
system and initializes the frame with certain constant/global
values.
This is routine called during machine dependent system
Initialization.
Arguments:
none
Return Value:
none
--*/
{
PRAWHIDE_UNCORRECTABLE_FRAME rawerr;
//
// If the Uncorrectable error buffer is not set then simply return
//
if(PUncorrectableError == NULL)
return;
PUncorrectableError->Signature = ERROR_FRAME_SIGNATURE;
PUncorrectableError->FrameType = UncorrectableFrame;
//
// ERROR_FRAME_VERSION is define in errframe.h and will
// change as and when there is a change in the errframe.h.
// This Version number helps the service, that reads this
// information from the dumpfile, to check if it knows about
// this frmae version type to decode. If it doesn't know, it
// will dump the entire frame to the EventLog with a message
// "Error Frame Version Mismatch".
//
PUncorrectableError->VersionNumber = ERROR_FRAME_VERSION;
//
// The sequence number will always be 1 for Uncorrectable errors.
//
PUncorrectableError->SequenceNumber = 1;
//
// The PerformanceCounterValue field is not used for Uncorrectable
// errors.
//
PUncorrectableError->PerformanceCounterValue = 0;
//
// We will fill in the UncorrectableFrame.SystemInfo here.
//
HalpGetSystemInfo(&PUncorrectableError->UncorrectableFrame.System);
PUncorrectableError->UncorrectableFrame.Flags.SystemInformationValid = 1;
//
// Fill in Common RCUD Header
//
rawerr = (PRAWHIDE_UNCORRECTABLE_FRAME)
PUncorrectableError->UncorrectableFrame.RawSystemInformation;
strncpy( PUncorrectableError->UncorrectableFrame.System.SystemSerialNumber,
HalpSystemClassData->SystemConfig.SystemSerialNumber, 10);
strncpy( rawerr->CudHeader.SystemSN,
HalpSystemClassData->SystemConfig.SystemSerialNumber, 10);
strncpy( rawerr->CudHeader.SystemRev,
HalpSystemClassData->SystemConfig.SystemRevisionLevel, 4);
// Jam the SRM console revision in the Module SN
strncpy( rawerr->CudHeader.ModuleSN,
HalpSystemClassData->SystemConfig.ConsoleTypeRev, 9);
rawerr->CudHeader.ModuleSN[9] = '\0';
// Jam the first 5 chars of System Model (4x00, etc.) in a reserved field
strncpy( rawerr->CudHeader.Reserved2,
HalpSystemClassData->SystemConfig.SystemModel, 5);
rawerr->CudHeader.Reserved2[5] = '\0';
//
// The following RCUD header data is not valid for Windows NT.
//
rawerr->CudHeader.HwRevision = 0;
rawerr->CudHeader.ModType = 0;
rawerr->CudHeader.DisabledResources = 0;
//
// Fill in MC Bus Snapshot header
//
rawerr->McBusSnapshot.Length = sizeof(MC_BUS_SNAPSHOT)
+ HalpNumberOfIods * sizeof(IOD_ERROR_FRAME);
rawerr->McBusSnapshot.NumberOfIods = HalpNumberOfIods;
return;
}