From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/nthals/haleb164/alpha/ebinitnt.c | 677 ++++++++++++++++++++++++++ 1 file changed, 677 insertions(+) create mode 100644 private/ntos/nthals/haleb164/alpha/ebinitnt.c (limited to 'private/ntos/nthals/haleb164/alpha/ebinitnt.c') diff --git a/private/ntos/nthals/haleb164/alpha/ebinitnt.c b/private/ntos/nthals/haleb164/alpha/ebinitnt.c new file mode 100644 index 000000000..c7ba7e0fc --- /dev/null +++ b/private/ntos/nthals/haleb164/alpha/ebinitnt.c @@ -0,0 +1,677 @@ +/*++ + +Copyright (c) 1994 Digital Equipment Corporation + +Module Name: + + ebinitnt.c + +Abstract: + + + This module implements the platform-specific initialization for + an EB164 system. + +Author: + + Joe Notarangelo 06-Sep-1994 + +Environment: + + Kernel mode only. + +Revision History: + + +--*/ + +#include "halp.h" +#include "pcrtc.h" +#include "eb164.h" +#include "iousage.h" + +#include "fwcallbk.h" + +#include // to get the product build number. +// +// Define extern global buffer for the Uncorrectable Error Frame. +// declared in halalpha\inithal.c +// + +extern PERROR_FRAME PUncorrectableError; + +// +// PLATFORM_TYPE enumeration so that the HAL can be used on +// similar systems with run-time differences +// +PLATFORM_TYPES PlatformType = UnknownPlatform; + + +// +// 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 EB164 +// +// IRQ0 = CIA_INT +// IRQ1 = SYS_INT (PCI and ESC interrupts) +// IRQ2 = Interval Clock +// IRQ3 = Error Interrupts + +// +// 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_ISA; + +// +// Define global data used to communicate new clock rates to the clock +// interrupt service routine. +// + +ULONG HalpCurrentTimeIncrement; +ULONG HalpNextRateSelect; +ULONG HalpNextTimeIncrement; +ULONG HalpNewTimeIncrement; + +// +// External references. +// + +extern ULONG HalDisablePCIParityChecking; + +// +// Function prototypes. +// + +BOOLEAN +HalpInitializeEB164Interrupts ( + VOID + ); + +VOID +HalpParseLoaderBlock( + PLOADER_PARAMETER_BLOCK LoaderBlock + ); + +VOID +HalpErrorInterrupt( + VOID + ); + +BOOLEAN +HalpInitializeInterrupts ( + VOID + ) + +/*++ + +Routine Description: + + This function initializes interrupts for an EB164 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 EB164 interrupts. + // + + HalpInitializeEB164Interrupts(); + + // + // 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)HalpErrorInterrupt; + + 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 EV4 + 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 ); + +} + + + +// +// Define global data used to calibrate and stall processor execution. +// + +ULONG HalpProfileCountRate; + +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. + +--*/ + +{ + + // + // Compute the profile interrupt rate. + // + + HalpProfileCountRate = ((1000 * 1000 * 10) / KeQueryTimeIncrement()); + + 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 EV4-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; + BOOLEAN ReportCorrectables; + BOOLEAN PciParityChecking; + CIA_REVISION CiaRevision; // kmc - used to figure out if this is a PC164 + + // + // Since we have a flash device mapped in PCI memory space, but its + // HAL driver is pretending to be a cmos8k driver - override the + // HalpCMOSRamBase value set in HalpMapIoSpace (ciamapio.c) with the + // correct QVA to reach the environment block in the flash through + // the SIO. + // + HalpCMOSRamBase = (PVOID)NVRAM_ENVIRONMENT_QVA; + + if( Phase == 0 ){ + + // + // Phase 0 Initialization. + // + + // + // Determine the system type, if there's a REV 3 CIA + // then it's an AlphaPC164, otherwiser it's an EB164 + // + CiaRevision.all = + READ_CIA_REGISTER(&((PCIA_GENERAL_CSRS)(CIA_GENERAL_CSRS_QVA))->CiaRevision); + + PlatformType = EB164; + if (CiaRevision.CiaRev == CIA_REVISION_3) { + PlatformType = AlphaPC164; + } + +#ifdef HALDBG + DbgPrint("LOOK AT THIS ONE\r\n"); + DumpCia(CiaGeneralRegisters | + CiaErrorRegisters | + CiaScatterGatherRegisters); +#endif + // + // 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. + // + + PciParityChecking = (BOOLEAN)(HalDisablePCIParityChecking == 0); + + HalpInitializeCiaMachineChecks(ReportCorrectables = TRUE, + PciParityChecking); + + } else { + + // + // Phase 1 Initialization. + // + + // + // Initialize the existing bus handlers. + // + + HalpRegisterInternalBusHandlers(); + + // + // Initialize PCI Bus. + // + + HalpInitializePCIBus(LoaderBlock); + + // + // Initialize profiler. + // + + HalpInitializeProfiler(); + + } + + return; + +} + + + +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; +} + + +// +//jnfix +// +// This routine is bogus and does not apply to EB164 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(CIA_UNCORRECTABLE_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[] = "eb164"; + 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 + +--*/ +{ + PROCESSOR_EV5_UNCORRECTABLE processorFrame; + + // + // 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 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; + -- cgit v1.2.3