diff options
Diffstat (limited to 'private/ntos/nthals/halxlt/alpha/alinitnt.c')
-rw-r--r-- | private/ntos/nthals/halxlt/alpha/alinitnt.c | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/private/ntos/nthals/halxlt/alpha/alinitnt.c b/private/ntos/nthals/halxlt/alpha/alinitnt.c new file mode 100644 index 000000000..04cf746b1 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/alinitnt.c @@ -0,0 +1,750 @@ +/*++ + +Copyright (c) 1993 Digital Equipment Corporation + +Module Name: + + alinitnt.c + +Abstract: + + + This module implements the platform-specific initialization for + an Alcor system. + +Author: + + Joe Notarangelo 19-Jul-1994 + +Environment: + + Kernel mode only. + +Revision History: + + +--*/ + +#include "halp.h" +#include "pcrtc.h" +#include "alcor.h" +#include "iousage.h" +#include "stdio.h" + +#include "fwcallbk.h" + +#include <ntverp.h> // to get the product build number. + + +// +// Define extern global buffer for the Uncorrectable Error Frame. +// declared in halalpha\inithal.c +// + +extern PERROR_FRAME PUncorrectableError; + +// +// Define the Product Naming data. +// + +PCHAR HalpFamilyName = "Alpha XL"; + +#define MAX_INIT_MSG (80) + + + +// +// 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 global data used to communicate new clock rates to the clock +// interrupt service routine. +// + +ULONG HalpCurrentTimeIncrement; +ULONG HalpNextRateSelect; +ULONG HalpNextTimeIncrement; +ULONG HalpNewTimeIncrement; + +// +// Define external references. +// + +extern ULONG HalDisablePCIParityChecking; + +// +// Function prototypes. +// + +BOOLEAN +HalpInitializeAlcorInterrupts ( + VOID + ); + +VOID +HalpParseLoaderBlock( + PLOADER_PARAMETER_BLOCK LoaderBlock + ); + +VOID +HalpAlcorErrorInterrupt( + VOID + ); + +VOID +HalpRegisterPlatformResources( + PUCHAR HalName + ); + + +// +// 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 Alcor +// +// IRQ0 = CIA_INT +// IRQ1 = SYS_INT (PCI and ESC interrupts) +// IRQ2 = Interval Clock +// IRQ3 = Reserved +// + + +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 ULONG HalpCiaErrorInterrupt(); + extern ULONG HalpDeviceInterrupt(); + extern ULONG HalpHaltInterrupt(); + ULONG Vector; + + // + // 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. + // + + HalpInitializeProcessorParameters(); + + // + // Start the periodic interrupt from the RTC + // + + HalpProgramIntervalTimer(MAXIMUM_RATE_SELECT); + + // + // Initialize Alcor interrupts. + // + + HalpInitializeAlcorInterrupts(); + + // + // Initialize the EV5 (21164) interrupts. + // + + HalpInitialize21164Interrupts(); + + PCR->InterruptRoutine[EV5_IRQ0_VECTOR] = + (PKINTERRUPT_ROUTINE)HalpCiaErrorInterrupt; + + PCR->InterruptRoutine[EV5_IRQ1_VECTOR] = + (PKINTERRUPT_ROUTINE)HalpDeviceInterrupt; + + PCR->InterruptRoutine[EV5_IRQ2_VECTOR] = + (PKINTERRUPT_ROUTINE)HalpClockInterrupt; + + PCR->InterruptRoutine[EV5_HALT_VECTOR] = + (PKINTERRUPT_ROUTINE)HalpHaltInterrupt; + + PCR->InterruptRoutine[EV5_MCHK_VECTOR] = + (PKINTERRUPT_ROUTINE)HalpAlcorErrorInterrupt; + + PCR->InterruptRoutine[EV5_CRD_VECTOR] = + (PKINTERRUPT_ROUTINE)Halp21164CorrectedErrorInterrupt; + + HalpStart21164Interrupts(); + + + return TRUE; + +} + + +VOID +HalpSetTimeIncrement( + VOID + ) +/*++ + +Routine Description: + + This routine is responsible for setting the time increment for an EV5 + based machine via a call into the kernel. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + // + // Set the time increment value. + // + + HalpCurrentTimeIncrement = MAXIMUM_INCREMENT; + HalpNextTimeIncrement = MAXIMUM_INCREMENT; + HalpNextRateSelect = 0; + KeSetTimeIncrement( MAXIMUM_INCREMENT, MINIMUM_INCREMENT ); + +} + + + +VOID +HalpInitializeClockInterrupts( + VOID + ) + +/*++ + +Routine Description: + + This function is a NOOP for Alcor. + +Arguments: + + None. + +Return Value: + + None. + +--*/ + +{ + 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; + + HalpInitializeCiaMachineChecks( ReportCorrectables = FALSE, + PciParityChecking = FALSE ); + + 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; + + if( Phase == 0 ){ + + // + // Phase 0 Initialization. + // + + // + // Parse the Loader Parameter block looking for PCI entry to determine + // if PCI parity should be disabled + // + + HalpParseLoaderBlock( LoaderBlock ); + + // + // Establish the error handler, to reflect the PCI parity checking. + // + + if( HalDisablePCIParityChecking != 0 ){ + PciParityChecking = FALSE; + } else { + PciParityChecking = TRUE; + } + + HalpInitializeCiaMachineChecks( ReportCorrectables = TRUE, + PciParityChecking ); + + } else { + + // + // Phase 1 Initialization. + // + + // + // Initialize the existing bus handlers. + // + + HalpRegisterInternalBusHandlers(); + + // + // Initialize PCI Bus. + // + + HalpInitializePCIBus(LoaderBlock); + + // + // Initialize profiler. + // + + HalpInitializeProfiler(); + + sprintf(MsgBuffer, + "Digital Equipment Corporation %s %d", + HalpFamilyName, + HalpClockMegaHertz ); + + HalDisplayString( MsgBuffer ); + HalDisplayString( "\n" ); + + // + // Build the string to register the HAL. + // + + strcat(MsgBuffer, " PCI/ISA HAL"); + + HalpRegisterPlatformResources( MsgBuffer ); + + } + + return; + +} + + +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; + Resource.u.Start = I2C_INTERFACE_DATA_PORT; + Resource.u.Length = I2C_INTERFACE_LENGTH; + HalpRegisterResourceUsage(&Resource); + + 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); +} + + +ULONG +HalSetTimeIncrement ( + IN ULONG DesiredIncrement + ) + +/*++ + +Routine Description: + + This function is called to set the clock interrupt rate to the frequency + required by the specified time increment value. + +Arguments: + + DesiredIncrement - Supplies desired number of 100ns units between clock + interrupts. + +Return Value: + + The actual time increment in 100ns units. + +--*/ + +{ + ULONG NewTimeIncrement; + ULONG NextRateSelect; + KIRQL OldIrql; + + // + // Raise IRQL to the highest level, set the new clock interrupt + // parameters, lower IRQl, and return the new time increment value. + // + + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + if (DesiredIncrement < MINIMUM_INCREMENT) { + DesiredIncrement = MINIMUM_INCREMENT; + } + if (DesiredIncrement > MAXIMUM_INCREMENT) { + DesiredIncrement = MAXIMUM_INCREMENT; + } + + // + // Find the allowed increment that is less than or equal to + // the desired increment. + // + + if (DesiredIncrement >= RTC_PERIOD_IN_CLUNKS4) { + NewTimeIncrement = RTC_PERIOD_IN_CLUNKS4; + NextRateSelect = RTC_RATE_SELECT4; + } else if (DesiredIncrement >= RTC_PERIOD_IN_CLUNKS3) { + NewTimeIncrement = RTC_PERIOD_IN_CLUNKS3; + NextRateSelect = RTC_RATE_SELECT3; + } else if (DesiredIncrement >= RTC_PERIOD_IN_CLUNKS2) { + NewTimeIncrement = RTC_PERIOD_IN_CLUNKS2; + NextRateSelect = RTC_RATE_SELECT2; + } else { + NewTimeIncrement = RTC_PERIOD_IN_CLUNKS1; + NextRateSelect = RTC_RATE_SELECT1; + } + + HalpNextRateSelect = NextRateSelect; + HalpNewTimeIncrement = NewTimeIncrement; + + KeLowerIrql(OldIrql); + + return NewTimeIncrement; +} + + +VOID +HalpGetMachineDependentErrorFrameSizes( + PULONG RawProcessorSize, + PULONG RawSystemInfoSize + ) +/*++ + +Routine Description: + + This function is called from HalpAllocateUncorrectableErrorFrame. + This function retuns the size of the system specific error frame + sizes. + +Arguments: + + RawProcessorSize - Processor-specific uncorrectable frame size. + + RawSystemInfoSize - system-specific uncorrectable frame size. + +Return Value: + + None. + +--*/ +{ + *RawProcessorSize = sizeof(PROCESSOR_EV5_UNCORRECTABLE); + *RawSystemInfoSize = sizeof(CIA_UNCORRECTABLE_FRAME); + return; +} + +VOID +HalpGetSystemInfo(SYSTEM_INFORMATION *SystemInfo) +/*++ + +Routine Description: + + Fills in the system information structure. + NOTE: Must later investigate the Fw call to get the firmware revision + ID. Must also figure out a way to get the OS version (preferebly the + build number). + +Arguments: + + SystemInfo - Pointer to the SYSTEM_INFORMATION structure. + +Return Value: + + None + +--*/ +{ + char systemtype[] = "XLT"; + 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 + +--*/ +{ + // + // 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; + + + return; +} + + +// +//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; +} + +// +//jnfix - this variable is needed because the clock interrupt handler +// - in intsup.s was made to be familiar with ev4prof.c, unfortunate +// - since we don't use ev4prof.c, so for now this is a hack, later +// - we will either fix intsup.s or create a new intsup.s that does +// - not have this hack +// + +ULONG HalpNumberOfTicksReload; |