diff options
Diffstat (limited to '')
52 files changed, 4740 insertions, 0 deletions
diff --git a/private/ntos/nthals/halxlt/alpha/adjust.c b/private/ntos/nthals/halxlt/alpha/adjust.c new file mode 100644 index 000000000..47c267fb8 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/adjust.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\adjust.c" + diff --git a/private/ntos/nthals/halxlt/alpha/alcor.h b/private/ntos/nthals/halxlt/alpha/alcor.h new file mode 100644 index 000000000..90931ecfa --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/alcor.h @@ -0,0 +1,100 @@ +/*++ + +Copyright (c) 1994 Digital Equipment Corporation + +Module Name: + + alcor.h + +Abstract: + + This file contains definitions specific to the Alcor platform + +Author: + + Steve Brooks 11-Jul-1994 + +Environment: + + Kernel mode + +Revision History: + + +--*/ + +#ifndef _ALCORH_ +#define _ALCORH_ + +// +// Include definitions for the components that make up Alcor. +// + +#include "axp21164.h" // 21164 (EV5) microprocessor definitions +#include "cia.h" // CIA controller definitions +#include "gru.h" // GRU controller definitions + +// +// Define number of PCI, EISA, and combo slots +// + +#define NUMBER_EISA_SLOTS 4 +#define NUMBER_PCI_SLOTS 5 +#define NUMBER_COMBO_SLOTS 1 + +// +// Define the data and csr ports for the I2C bus and OCP. +// + +#define I2C_INTERFACE_DATA_PORT 0x550 +#define I2C_INTERFACE_CSR_PORT 0x551 +#define I2C_INTERFACE_LENGTH 0x2 +#define I2C_INTERFACE_MASK 0x1 + +// +// Define the index and data ports for the NS Super IO chip. +// + +#define SUPERIO_INDEX_PORT 0x398 +#define SUPERIO_DATA_PORT 0x399 +#define SUPERIO_PORT_LENGTH 0x2 + +// +// PCI bus address values: +// + +#define PCI_MAX_LOCAL_DEVICE 12 +#define PCI_MAX_INTERRUPT_VECTOR (MAXIMUM_PCI_VECTOR - PCI_VECTORS) + +// +// Define numbers and names of cpus. +// + +#define HAL_PRIMARY_PROCESSOR ((ULONG)0) +#define HAL_MAXIMUM_PROCESSOR ((ULONG)0) + +// +// Define default processor frequency. +// + +#define DEFAULT_PROCESSOR_FREQUENCY_MHZ (250) + +// +// Define Alcor-specific routines that are really macros for performance. +// + +#define HalpAcknowledgeEisaInterrupt(x) (UCHAR)(INTERRUPT_ACKNOWLEDGE(x)) + +// +// Define the per-processor data structures allocated in the PCR. +// + +typedef struct _ALCOR_PCR{ + ULONGLONG HalpCycleCount; // 64-bit per-processor cycle count + ULONG Reserved[3]; // Pad ProfileCount to offset 20 + EV5ProfileCount ProfileCount; // Profile counter state + } ALCOR_PCR, *PALCOR_PCR; + +#define HAL_PCR ( (PALCOR_PCR)(&(PCR->HalReserved)) ) + +#endif //_ALCORH_ diff --git a/private/ntos/nthals/halxlt/alpha/alcorerr.c b/private/ntos/nthals/halxlt/alpha/alcorerr.c new file mode 100644 index 000000000..dfd3bc8cf --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/alcorerr.c @@ -0,0 +1,154 @@ +/*++ + +Copyright (c) 1994 Digital Equipment Corporation + +Module Name: + + alcorerr.c + +Abstract: + + This module implements error handling (machine checks and error + interrupts) for the Alcor platform. + +Author: + + Joe Notarangelo 27-Jul-1994 + +Environment: + + Kernel mode only. + +Revision History: + +--*/ + +#include "halp.h" +#include "alcor.h" + +// +// Declare the extern variable UncorrectableError declared in +// inithal.c. +// +extern PERROR_FRAME PUncorrectableError; + + +// +// Function prototypes. +// + +VOID +HalpSetMachineCheckEnables( + IN BOOLEAN DisableMachineChecks, + IN BOOLEAN DisableProcessorCorrectables, + IN BOOLEAN DisableSystemCorrectables + ); + +BOOLEAN +HalHandleNMI( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext + ); + + +VOID +HalpAlcorErrorInterrupt( + VOID + ) +/*++ + +Routine Description: + + This routine is the interrupt handler for an ALCOR machine check interrupt + The function calls HalpCiaReportFatalError() + +Arguments: + + None. + +Return Value: + + None. If a Fatal Error is detected the system is crashed. + +--*/ +{ + + HalAcquireDisplayOwnership(NULL); + + // + // Display the dreaded banner. + // + + HalDisplayString( "\nFatal system hardware error.\n\n" ); + + // + // If this is a CIA uncorrectable error then report the error and + // crash the system. + // + + if( HalpCiaUncorrectableError() == TRUE ){ + + HalpCiaReportFatalError(); + + KeBugCheckEx( DATA_BUS_ERROR, + 0xfacefeed, //jnfix - quick error interrupt id + 0, + 0, + (ULONG)PUncorrectableError ); + + } + + // + // It was not a CIA uncorrectable error, therefore this must be an + // NMI interrupt. + // + + HalHandleNMI( NULL, NULL ); + + return; // never + +} + + +BOOLEAN +HalpPlatformMachineCheck( + IN PEXCEPTION_RECORD ExceptionRecord, + IN PKEXCEPTION_FRAME ExceptionFrame, + IN PKTRAP_FRAME TrapFrame + ) +/*++ + +Routine Description: + + This routine is given control when an hard error is acknowledged + by the CIA chipset. The routine is given the chance to + correct and dismiss the error. + +Arguments: + + ExceptionRecord - Supplies a pointer to the exception record generated + at the point of the exception. + + ExceptionFrame - Supplies a pointer to the exception frame generated + at the point of the exception. + + TrapFrame - Supplies a pointer to the trap frame generated + at the point of the exception. + +Return Value: + + TRUE is returned if the machine check has been handled and dismissed - + indicating that execution can continue. FALSE is return otherwise. + +--*/ +{ + + // + // All machine check handling on Alcor is determined by the CIA. + // + + return( HalpCiaMachineCheck( ExceptionRecord, + ExceptionFrame, + TrapFrame ) ); + +} 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; diff --git a/private/ntos/nthals/halxlt/alpha/alintsup.c b/private/ntos/nthals/halxlt/alpha/alintsup.c new file mode 100644 index 000000000..ddb18d70f --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/alintsup.c @@ -0,0 +1,599 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation +Copyright (c) 1992, 1993 Digital Equipment Corporation + +Module Name: + + alintsup.c + +Abstract: + + The module provides the interrupt support for Alcor systems. + +Author: + + Eric Rehm (DEC) 29-December-1993 + +Revision History: + + Chao Chen (DEC) 26-July-1994 + Adapted from Avanti module for Alcor. + +--*/ + + +#include "halp.h" +#include "eisa.h" +#include "ebsgdma.h" +#include "alcor.h" +#include "pcrtc.h" +#include "pintolin.h" + + +// +// Declare the interrupt structures and spinlocks for the intermediate +// interrupt dispatchers. +// + +KINTERRUPT HalpPciInterrupt; +KINTERRUPT HalpEisaInterrupt; + +// +// Define the context structure for use by interrupt service routines. +// + +typedef BOOLEAN (*PSECOND_LEVEL_DISPATCH)( + PKINTERRUPT InterruptObject, + PVOID ServiceContext, + PKTRAP_FRAME TrapFrame + ); + +// +// Declare the interrupt handler for the EISA bus. The interrupt dispatch +// routine, HalpEisaDispatch, is called from this handler. +// + +BOOLEAN +HalpEisaInterruptHandler( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext + ); + +// +// The following is the interrupt object used for DMA controller interrupts. +// DMA controller interrupts occur when a memory parity error occurs or a +// programming error occurs to the DMA controller. +// + +KINTERRUPT HalpEisaNmiInterrupt; + +// +// The following function initializes NMI handling. +// + +VOID +HalpInitializeNMI( + VOID + ); + +// +// The following function is called when an EISA NMI occurs. +// + +BOOLEAN +HalHandleNMI( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext + ); + +// +// The following functions handle the PCI interrupts. +// + +VOID +HalpInitializePciInterrupts ( + VOID + ); + +VOID +HalpDisablePciInterrupt( + IN ULONG Vector + ); + +VOID +HalpEnablePciInterrupt( + IN ULONG Vector, + IN KINTERRUPT_MODE InterruptMode + ); + +BOOLEAN +HalpDeviceDispatch( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext, + IN PKTRAP_FRAME TrapFrame + ); + + +BOOLEAN +HalpInitializeAlcorInterrupts ( + VOID + ) +/*++ + +Routine Description: + + This routine initializes the structures necessary for EISA & PCI operations + and connects the intermediate interrupt dispatchers. It also initializes + the EISA interrupt controller; the Alcor ESC's interrupt controller is + compatible with the EISA interrupt contoller used on Jensen. + +Arguments: + + None. + +Return Value: + + If the second level interrupt dispatchers are connected, then a value of + TRUE is returned. Otherwise, a value of FALSE is returned. + +--*/ + +{ + KIRQL oldIrql; + + // + // Initialize the EISA NMI interrupt. + // + + HalpInitializeNMI(); + + (PVOID) HalpPCIPinToLineTable = (PVOID) AlcorPCIPinToLineTable; + + // + // Intitialize interrupt controller + // + + KeRaiseIrql(DEVICE_HIGH_LEVEL, &oldIrql); + + // + // Initialize the PCI interrupts. + // + + HalpInitializePciInterrupts(); + + // + // Initialize the ESC's PICs for EISA interrupts. + // + + HalpInitializeEisaInterrupts(); + + // + // Restore the IRQL. + // + + KeLowerIrql(oldIrql); + + // + // Initialize the EISA DMA mode registers to a default value. + // Disable all of the DMA channels except channel 4 which is the + // cascade of channels 0-3. + // + + WRITE_PORT_UCHAR( + &((PEISA_CONTROL) HalpEisaControlBase)->Dma1BasePort.AllMask, + 0x0F + ); + + WRITE_PORT_UCHAR( + &((PEISA_CONTROL) HalpEisaControlBase)->Dma2BasePort.AllMask, + 0x0E + ); + + return(TRUE); +} + + +VOID +HalpInitializeNMI( + VOID + ) +/*++ + +Routine Description: + + This function is called to intialize ESC NMI interrupts. + +Arguments: + + None. + +Return Value: + + None. +--*/ +{ + UCHAR DataByte; + + // + // Initialize the ESC NMI interrupt. + // + + KeInitializeInterrupt( &HalpEisaNmiInterrupt, + HalHandleNMI, + NULL, + NULL, + EISA_NMI_VECTOR, + EISA_NMI_LEVEL, + EISA_NMI_LEVEL, + LevelSensitive, + FALSE, + 0, + FALSE + ); + + // + // Don't fail if the interrupt cannot be connected. + // + + KeConnectInterrupt( &HalpEisaNmiInterrupt ); + + // + // Clear the Eisa NMI disable bit. This bit is the high order of the + // NMI enable register. + // + + DataByte = 0; + + WRITE_PORT_UCHAR( + &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, + DataByte + ); + +} + + +BOOLEAN +HalHandleNMI( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext + ) +/*++ + +Routine Description: + + This function is called when an EISA NMI occurs. It prints the + appropriate status information and bugchecks. + +Arguments: + + Interrupt - Supplies a pointer to the interrupt object + + ServiceContext - Bug number to call bugcheck with. + +Return Value: + + Returns TRUE. + +--*/ +{ + UCHAR StatusByte; + + StatusByte = + READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus); + + if (StatusByte & 0x80) { + HalDisplayString ("NMI: Parity Check / Parity Error\n"); + } + + if (StatusByte & 0x40) { + HalDisplayString ("NMI: Channel Check / IOCHK\n"); + } + + KeBugCheck(NMI_HARDWARE_FAILURE); + return(TRUE); +} + + +VOID +HalpAcknowledgeClockInterrupt( + VOID + ) +/*++ + +Routine Description: + + Acknowledge the clock interrupt from the interval timer. The interval + timer for Alcor comes from a Dallas real-time clock. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + + // + // Acknowledge the clock interrupt by reading the control register C of + // the Real Time Clock. + // + + HalpReadClockRegister( RTC_CONTROL_REGISTERC ); + + return; +} + + +// +// The enable mask for all interrupts sourced from the GRU (all device +// interrupts, and all from PCI). A "1" indicates the interrupt is enabled. +// + +ULONG HalpPciInterruptMask; + + +VOID +HalpInitializePciInterrupts ( + VOID + ) + +/*++ + +Routine Description: + + This routine initializes the Alcor PCI interrupts. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + // + // Disable interrupts except EISA. + // + + HalpPciInterruptMask = GRU_ENABLE_EISA_INT; + + WRITE_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntMask, + HalpPciInterruptMask); + + // + // Set all interrupts to level. + // + + WRITE_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntEdge, + GRU_SET_LEVEL_INT); + + // + // Set all interrupts to active low except EISA. + // + + WRITE_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntHiLo, + GRU_SET_LOW_INT); + + // + // Clear the interrupt clear register. + // + + WRITE_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntClear, 0); + + +} + + + +VOID +HalpDisablePciInterrupt( + IN ULONG Vector + ) + +/*++ + +Routine Description: + + This function disables the PCI interrupt specified by Vector. + +Arguments: + + Vector - Supplies the vector of the PCI interrupt that is disabled. + +Return Value: + + None. + +--*/ + +{ + // + // Calculate the PCI interrupt vector, relative to 0. + // + + Vector -= PCI_VECTORS; + + // + // Get the current state of the interrupt mask register, then set + // the bit corresponding to the adjusted value of Vector to zero, + // to disable that PCI interrupt. + // + + HalpPciInterruptMask &= (ULONG) ~(1 << Vector); + WRITE_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntMask, + HalpPciInterruptMask); +} + + +VOID +HalpEnablePciInterrupt( + IN ULONG Vector, + IN KINTERRUPT_MODE InterruptMode + ) + +/*++ + +Routine Description: + + This function enables the PCI interrupt specified by Vector. +Arguments: + + Vector - Supplies the vector of the PCI interrupt that is enabled. + + InterruptMode - Supplies the mode of the interrupt; LevelSensitive or + Latched (ignored for Alcor PCI interrupts; they're always levels). + +Return Value: + + None. + +--*/ + +{ + // + // Calculate the PCI interrupt vector, relative to 0. + // + + Vector -= PCI_VECTORS; + + // + // Get the current state of the interrupt mask register, then set + // the bit corresponding to the adjusted value of Vector to one, + // to ensable that PCI interrupt. + // + + HalpPciInterruptMask |= (ULONG) 1 << Vector; + WRITE_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntMask, + HalpPciInterruptMask); + +} + + +BOOLEAN +HalpDeviceDispatch( + IN PKINTERRUPT Interrupt, + IN PVOID ServiceContext, + IN PKTRAP_FRAME TrapFrame + ) +/*++ + +Routine Description: + + This routine is entered as the result of an interrupt being generated + via the vector that is connected to an interrupt object associated with + the PCI device interrupts. Its function is to call the second-level + interrupt dispatch routine. + +Arguments: + + Interrupt - Supplies a pointer to the interrupt object. + + ServiceContext - Supplies a pointer to the PCI interrupt register. + + TrapFrame - Supplies a pointer to the trap frame for this interrupt. + +Return Value: + + Returns the value returned from the second level routine. + +--*/ +{ + PULONG DispatchCode; + ULONG IdtIndex; + ULONG IntNumber; + PKINTERRUPT InterruptObject; + ULONG PCIVector; + ULONG Slot; + + // + // Read in the interrupt register. + // + + PCIVector=READ_GRU_REGISTER(&((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntReq); + + // + // Consider only those interrupts which are currently enabled. + // + + PCIVector &= HalpPciInterruptMask; + + // + // Continue processing interrupts while any are requested. + // + + while( (PCIVector & (GRU_EISA_MASK_INT | GRU_PCI_MASK_INT)) != 0 ){ + + // + // Did PCI or EISA interrupt occur? + // + + if (PCIVector & GRU_EISA_MASK_INT) { + + // + // EISA interrupt. Call HalpEisaDispatch. + // + + HalpEisaDispatch( Interrupt, (PVOID)CIA_PCI_INTACK_QVA, TrapFrame); + + } else { + + // + // PCI interrupt. Find out which slot. + // + + for (Slot = 0; Slot < NUMBER_PCI_SLOTS; Slot++) { + + if (PCIVector & 0xf) + break; + else + PCIVector = PCIVector >> 4; + } + + // + // Find out which of the IntA, IntB, IntC, or IntD occurred. + // + + for (IntNumber = 0; IntNumber < 4; IntNumber++) { + + if (PCIVector & 0x1) + break; + else + PCIVector = PCIVector >> 1; + } + + // + // Dispatch to the secondary interrupt service routine. + // + + IdtIndex = (Slot * (NUMBER_PCI_SLOTS - 1) + IntNumber) + + PCI_VECTORS; + DispatchCode = (PULONG)PCR->InterruptRoutine[IdtIndex]; + InterruptObject = CONTAINING_RECORD( DispatchCode, + KINTERRUPT, + DispatchCode ); + + ((PSECOND_LEVEL_DISPATCH)InterruptObject->DispatchAddress)( + InterruptObject, + InterruptObject->ServiceContext, + TrapFrame ); + } + + // + // Check for more interrupts. + // + + PCIVector = READ_GRU_REGISTER( + &((PGRU_INTERRUPT_CSRS)GRU_CSRS_QVA)->IntReq); + PCIVector &= HalpPciInterruptMask; + + } //end while( (PCIVector & (GRU_EISA_MASK_INT | GRU_PCI_MASK_INT)) != 0 ) + + return TRUE; + +} diff --git a/private/ntos/nthals/halxlt/alpha/allstart.c b/private/ntos/nthals/halxlt/alpha/allstart.c new file mode 100644 index 000000000..42f70b7ca --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/allstart.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\allstart.c" + diff --git a/private/ntos/nthals/halxlt/alpha/alsysint.c b/private/ntos/nthals/halxlt/alpha/alsysint.c new file mode 100644 index 000000000..384133a2e --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/alsysint.c @@ -0,0 +1,497 @@ +/*++ + +Copyright (c) 1994 Digital Equipment Corporation + +Module Name: + + alsysint.c + +Abstract: + + This module implements the HAL enable/disable system interrupt, and + request interprocessor interrupt routines for the Alcor system. + +Author: + + Joe Notarangelo 20-Jul-1994 + +Environment: + + Kernel mode + +Revision History: + +--*/ + +#include "halp.h" +#include "alcor.h" + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE,HalpGetSystemInterruptVector) +#endif + + +// +// Function prototype +// + +VOID +HalpDisablePciInterrupt( + IN ULONG Vector + ); + +VOID +HalpEnablePciInterrupt( + IN ULONG Vector, + IN KINTERRUPT_MODE InterruptMode + ); + +VOID +HalpSetMachineCheckEnables( + IN BOOLEAN DisableMachineChecks, + IN BOOLEAN DisableProcessorCorrectables, + IN BOOLEAN DisableSystemCorrectables + ); + + +VOID +HalDisableSystemInterrupt ( + IN ULONG Vector, + IN KIRQL Irql + ) + +/*++ + +Routine Description: + + This routine disables the specified system interrupt. + +Arguments: + + Vector - Supplies the vector of the system interrupt that is disabled. + + Irql - Supplies the IRQL of the interrupting source. + +Return Value: + + None. + +--*/ + +{ + + KIRQL OldIrql; + + // + // Raise IRQL to the highest level. + // + + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + // + // If the vector number is within the range of the EISA interrupts, then + // disable the EISA interrrupt. + // + + if (Vector >= EISA_VECTORS && + Vector < MAXIMUM_EISA_VECTOR && + Irql == DEVICE_HIGH_LEVEL) { + HalpDisableEisaInterrupt(Vector); + } + + // + // If the vector number is within the range of the PCI interrupts, then + // disable the PCI interrrupt. + // + + if (Vector >= PCI_VECTORS && + Vector < MAXIMUM_PCI_VECTOR && + Irql == DEVICE_HIGH_LEVEL) { + HalpDisablePciInterrupt(Vector); + } + + // + // If the vector is a performance counter vector we will ignore + // the enable - the performance counters are enabled directly by + // the wrperfmon callpal. Wrperfmon must be controlled directly + // by the driver. + // + + switch (Vector) { + + case PC0_VECTOR: + case PC1_VECTOR: + case PC2_VECTOR: + + break; + + case CORRECTABLE_VECTOR: + + // + // Disable the correctable error interrupt. + // + + { + CIA_ERR_MASK CiaErrMask; + + CiaErrMask.all = READ_CIA_REGISTER( + &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->ErrMask); + + CiaErrMask.CorErr = 0x0; + + WRITE_CIA_REGISTER(&((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->ErrMask, + CiaErrMask.all + ); + + HalpSetMachineCheckEnables( FALSE, TRUE, TRUE ); + } + + break; + + } //end switch Vector + + // + // Lower IRQL to the previous level. + // + + KeLowerIrql(OldIrql); + return; +} + + +BOOLEAN +HalEnableSystemInterrupt ( + IN ULONG Vector, + IN KIRQL Irql, + IN KINTERRUPT_MODE InterruptMode + ) + +/*++ + +Routine Description: + + This routine enables the specified system interrupt. + +Arguments: + + Vector - Supplies the vector of the system interrupt that is enabled. + + Irql - Supplies the IRQL of the interrupting source. + + InterruptMode - Supplies the mode of the interrupt; LevelSensitive or + Latched. + +Return Value: + + TRUE if the system interrupt was enabled + +--*/ + +{ + BOOLEAN Enabled = FALSE; + KIRQL OldIrql; + + // + // Raise IRQL to the highest level. + // + + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + // + // If the vector number is within the range of the EISA interrupts, then + // enable the EISA interrrupt and set the Level/Edge register. + // + + if (Vector >= EISA_VECTORS && + Vector < MAXIMUM_EISA_VECTOR && + Irql == DEVICE_HIGH_LEVEL) { + HalpEnableEisaInterrupt( Vector, InterruptMode ); + Enabled = TRUE; + } + + // + // If the vector number is within the range of the PCI interrupts, then + // enable the PCI interrrupt. + // + + if (Vector >= PCI_VECTORS && + Vector < MAXIMUM_PCI_VECTOR && + Irql == DEVICE_HIGH_LEVEL) { + HalpEnablePciInterrupt( Vector, InterruptMode ); + Enabled = TRUE; + } + + // + // If the vector is a performance counter vector we will ignore + // the enable - the performance counters are enabled directly by + // the wrperfmon callpal. Wrperfmon must be controlled directly + // by the driver. + // + + switch (Vector) { + + case PC0_VECTOR: + case PC1_VECTOR: + case PC2_VECTOR: + + Enabled = TRUE; + break; + + + case CORRECTABLE_VECTOR: + + // + // Enable the correctable error interrupt. + // + + { + CIA_ERR_MASK CiaErrMask; + + CiaErrMask.all = READ_CIA_REGISTER( + &((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->ErrMask); + + CiaErrMask.CorErr = 0x1; + + WRITE_CIA_REGISTER(&((PCIA_ERROR_CSRS)(CIA_ERROR_CSRS_QVA))->ErrMask, + CiaErrMask.all + ); + + HalpSetMachineCheckEnables( FALSE, FALSE, FALSE ); + } + + Enabled = TRUE; + break; + + + } //end switch Vector + + // + // Lower IRQL to the previous level. + // + + KeLowerIrql(OldIrql); + return Enabled; + +} + + +ULONG +HalpGetSystemInterruptVector( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity + ) + +/*++ + +Routine Description: + + This function returns the system interrupt vector and IRQL level + corresponding to the specified bus interrupt level and/or vector. The + system interrupt vector and IRQL are suitable for use in a subsequent + call to KeInitializeInterrupt. + + We only use InterfaceType and BusInterruptLevel. BusInterruptVector + for EISA and ISA are the same as the InterruptLevel, so ignore. + +Arguments: + + BusHandler - Supplies a pointer to the bus handler of the bus that + needs a system interrupt vector. + + RootHandler - Supplies a pointer to the bus handler of the root + bus for the bus represented by BusHandler. + + BusInterruptLevel - Supplies the bus-specific interrupt level. + + BusInterruptVector - Supplies the bus-specific interrupt vector. + + Irql - Returns the system request priority. + + Affinity - Returns the affinity for the requested vector + +Return Value: + + Returns the system interrupt vector corresponding to the specified device. + +--*/ + +{ + ULONG BusNumber = BusHandler->BusNumber; + INTERFACE_TYPE InterfaceType = BusHandler->InterfaceType; + ULONG Vector; + + *Affinity = 1; + + switch (InterfaceType) { + + case ProcessorInternal: + + // + // Handle the internal defined for the processor itself + // and used to control the performance counters in the 21064. + // + + if( (Vector = HalpGet21164PerformanceVector( BusInterruptLevel, + Irql)) != 0 ){ + + // + // Performance counter was successfully recognized. + // + + *Affinity = HalpActiveProcessors; + return Vector; + + } else if ((Vector = HalpGet21164CorrectableVector( BusInterruptLevel, + Irql)) != 0 ){ + + // + // Correctable error interrupt was sucessfully recognized. + // + + *Affinity = 1; + return Vector; + + } else { + + // + // Unrecognized processor interrupt. + // + + *Irql = 0; + *Affinity = 0; + return 0; + + } //end if Vector + + break; + + case Internal: + + // + // This bus type is for things connected to the processor + // in some way other than a standard bus, e.g., (E)ISA, PCI. + // Since devices on this "bus," apart from the special case of + // the processor, above, interrupt via the 82c59 cascade in the + // ESC, we assign vectors based on (E)ISA_VECTORS - see below. + // Firmware must agree on these vectors, as it puts them in + // the CDS. + // + + *Irql = DEVICE_HIGH_LEVEL; + + return(BusInterruptLevel + ISA_VECTORS); + break; + + case Isa: + + // + // Assumes all ISA devices coming in on same processor pin + // + + *Irql = DEVICE_HIGH_LEVEL; + + // + // The vector is equal to the specified bus level plus ISA_VECTORS. + // N.B.: this encoding technique uses the notion of defining a + // base interrupt vector in the space defined by the constant, + // ISA_VECTORS, which may or may not differ from EISA_VECTORS or + // PCI_VECTORS. + // + + return(BusInterruptLevel + ISA_VECTORS); + break; + + + case Eisa: + + // + // Assumes all EISA devices coming in on same processor pin + // + + *Irql = DEVICE_HIGH_LEVEL; + + // + // The vector is equal to the specified bus level plus the EISA_VECTOR. + // + + return(BusInterruptLevel + EISA_VECTORS); + break; + + case PCIBus: + + // + // Assumes all PCI devices coming in on same processor pin + // + + *Irql = DEVICE_HIGH_LEVEL; + + // + // The vector is equal to the specified bus level plus the PCI_VECTOR + // + // N.B. The BusInterruptLevel is one-based while the vectors + // themselves are zero-based. The BusInterruptLevel must be + // one-based because if scsiport sees a zero vector then it + // will believe the interrupt is not connected. So in PCI + // configuration we have made the interrupt vector correspond + // to the slot and interrupt pin. + // + // N.B - bias for disjoint bus levels + // + + return( (BusInterruptLevel - 0x11) + PCI_VECTORS); + + break; + + default: + + // + // Not an interface supported on Alcor systems. + // + +#if defined(HALDBG) + + DbgPrint("ALSYSINT: InterfaceType (%x) not supported on Alcor\n", + InterfaceType); + +#endif + + *Irql = 0; + *Affinity = 0; + return(0); + break; + + } //end switch(InterfaceType) + +} + + +VOID +HalRequestIpi ( + IN ULONG Mask + ) +/*++ + +Routine Description: + + This routine requests an interprocessor interrupt on a set of processors. + This routine performs no function on an Alcor because it is a + uni-processor system. + +Arguments: + + Mask - Supplies the set of processors that are sent an interprocessor + interrupt. + +Return Value: + + None. + +--*/ + +{ + return; +} diff --git a/private/ntos/nthals/halxlt/alpha/apecs.c b/private/ntos/nthals/halxlt/alpha/apecs.c new file mode 100644 index 000000000..06eb91348 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/apecs.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\apecs.c" + diff --git a/private/ntos/nthals/halxlt/alpha/apecserr.c b/private/ntos/nthals/halxlt/alpha/apecserr.c new file mode 100644 index 000000000..441154cc9 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/apecserr.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\apecserr.c" + diff --git a/private/ntos/nthals/halxlt/alpha/apecsio.s b/private/ntos/nthals/halxlt/alpha/apecsio.s new file mode 100644 index 000000000..27bb7caa7 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/apecsio.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\apecsio.s" + diff --git a/private/ntos/nthals/halxlt/alpha/bios.c b/private/ntos/nthals/halxlt/alpha/bios.c new file mode 100644 index 000000000..3a9d3aa50 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/bios.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\bios.c" + diff --git a/private/ntos/nthals/halxlt/alpha/busdata.c b/private/ntos/nthals/halxlt/alpha/busdata.c new file mode 100644 index 000000000..f3c197f82 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/busdata.c @@ -0,0 +1,137 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation +Copyright (c) 1994 Digital Equipment Corporation + +Module Name: + + busdata.c + +Abstract: + + This module contains get/set bus data routines. + +Author: + + Darryl E. Havens (darrylh) 11-Apr-1990 + Steve Brooks 30-Jun-1994 + Joe Notarangelo 30-Jun-1994 + +Environment: + + Kernel mode + +Revision History: + +--*/ + +#include "halp.h" + +// +// External Function Prototypes +// + +ULONG +HalpNoBusData ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length + ); + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT,HalpRegisterInternalBusHandlers) +#endif + + +VOID +HalpRegisterInternalBusHandlers ( + VOID + ) +/*++ + +Routine Description: + + This function registers the bushandlers for buses on the system + that will always be present on the system. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + PBUS_HANDLER Bus; + + // + // Initalize BusHandler data before registering any handlers + // + + HalpInitBusHandler (); + + // + // Build the processor internal bus 0 + // + + HaliRegisterBusHandler (ProcessorInternal, // Bus Type + -1, // No config space + 0, // Bus Number + -1, // No parent bus type + 0, // No parent bus number + 0, // No extension data + NULL, // No install handler + &Bus); // Bushandler return + + Bus->GetInterruptVector = HalpGetSystemInterruptVector; + + // + // Build internal-bus 0, or system level bus + // + + HaliRegisterBusHandler (Internal, // Bus Type + -1, // No config space + 0, // Bus Number + -1, // No parent bus type + 0, // No parent bus number + 0, // No extension data + NULL, // No install handler + &Bus); // Bushandler return + + Bus->GetInterruptVector = HalpGetSystemInterruptVector; + Bus->TranslateBusAddress = HalpTranslateSystemBusAddress; + + // + // Build Isa/Eisa bus #0 + // + + HaliRegisterBusHandler (Eisa, // Bus Type + EisaConfiguration, // Config space type + 0, // Internal bus #0 + Internal, // Parent bus type + 0, // Parent bus number + 0, // No extension data + NULL, // No install handler + &Bus); // Bushandler return + + Bus->GetBusData = HalpGetEisaData; + Bus->AdjustResourceList = HalpAdjustEisaResourceList; + + HaliRegisterBusHandler (Isa, // Bus Type + -1, // No config space + 0, // Internal bus #0 + Eisa, // Parent bus type + 0, // Parent bus number + 0, // No extension data + NULL, // No install handler + &Bus); // Bushandler returne + + Bus->GetBusData = HalpNoBusData; + Bus->AdjustResourceList = HalpAdjustIsaResourceList; + +} diff --git a/private/ntos/nthals/halxlt/alpha/cache.c b/private/ntos/nthals/halxlt/alpha/cache.c new file mode 100644 index 000000000..561528477 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/cache.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\cache.c" + diff --git a/private/ntos/nthals/halxlt/alpha/cia.c b/private/ntos/nthals/halxlt/alpha/cia.c new file mode 100644 index 000000000..7948bfe16 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/cia.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\cia.c" + diff --git a/private/ntos/nthals/halxlt/alpha/ciaaddr.c b/private/ntos/nthals/halxlt/alpha/ciaaddr.c new file mode 100644 index 000000000..b85818ac0 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ciaaddr.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ciaaddr.c" + diff --git a/private/ntos/nthals/halxlt/alpha/ciaerr.c b/private/ntos/nthals/halxlt/alpha/ciaerr.c new file mode 100644 index 000000000..bfb9efc93 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ciaerr.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ciaerr.c" + diff --git a/private/ntos/nthals/halxlt/alpha/ciaio.s b/private/ntos/nthals/halxlt/alpha/ciaio.s new file mode 100644 index 000000000..16202a7e1 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ciaio.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ciaio.s" + diff --git a/private/ntos/nthals/halxlt/alpha/ciamapio.c b/private/ntos/nthals/halxlt/alpha/ciamapio.c new file mode 100644 index 000000000..3e9f7a9c1 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ciamapio.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ciamapio.c" + diff --git a/private/ntos/nthals/halxlt/alpha/cmos8k.c b/private/ntos/nthals/halxlt/alpha/cmos8k.c new file mode 100644 index 000000000..091dfa410 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/cmos8k.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\cmos8k.c" + diff --git a/private/ntos/nthals/halxlt/alpha/devintr.s b/private/ntos/nthals/halxlt/alpha/devintr.s new file mode 100644 index 000000000..d861febd2 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/devintr.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\devintr.s" + diff --git a/private/ntos/nthals/halxlt/alpha/ebsgdma.c b/private/ntos/nthals/halxlt/alpha/ebsgdma.c new file mode 100644 index 000000000..e2d35353d --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ebsgdma.c @@ -0,0 +1,6 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ebsgdma.c" diff --git a/private/ntos/nthals/halxlt/alpha/eisasup.c b/private/ntos/nthals/halxlt/alpha/eisasup.c new file mode 100644 index 000000000..1b52e85e7 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/eisasup.c @@ -0,0 +1,6 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\eisasup.c" diff --git a/private/ntos/nthals/halxlt/alpha/ev5cache.c b/private/ntos/nthals/halxlt/alpha/ev5cache.c new file mode 100644 index 000000000..cd83f7451 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ev5cache.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ev5cache.c" + diff --git a/private/ntos/nthals/halxlt/alpha/ev5int.c b/private/ntos/nthals/halxlt/alpha/ev5int.c new file mode 100644 index 000000000..23727330f --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ev5int.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ev5int.c" + diff --git a/private/ntos/nthals/halxlt/alpha/ev5ints.s b/private/ntos/nthals/halxlt/alpha/ev5ints.s new file mode 100644 index 000000000..66852f382 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ev5ints.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ev5ints.s" + diff --git a/private/ntos/nthals/halxlt/alpha/ev5mchk.c b/private/ntos/nthals/halxlt/alpha/ev5mchk.c new file mode 100644 index 000000000..0bedd3dfc --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ev5mchk.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ev5mchk.c" + diff --git a/private/ntos/nthals/halxlt/alpha/ev5mem.s b/private/ntos/nthals/halxlt/alpha/ev5mem.s new file mode 100644 index 000000000..dcad6563c --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ev5mem.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ev5mem.s" + diff --git a/private/ntos/nthals/halxlt/alpha/ev5prof.c b/private/ntos/nthals/halxlt/alpha/ev5prof.c new file mode 100644 index 000000000..839438fd9 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ev5prof.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\ev5prof.c" + diff --git a/private/ntos/nthals/halxlt/alpha/fwreturn.c b/private/ntos/nthals/halxlt/alpha/fwreturn.c new file mode 100644 index 000000000..65ae88cb8 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/fwreturn.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\fwreturn.c" + diff --git a/private/ntos/nthals/halxlt/alpha/haldebug.c b/private/ntos/nthals/halxlt/alpha/haldebug.c new file mode 100644 index 000000000..ce91863ec --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/haldebug.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\haldebug.c" + diff --git a/private/ntos/nthals/halxlt/alpha/halpal.s b/private/ntos/nthals/halxlt/alpha/halpal.s new file mode 100644 index 000000000..fc89f8370 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/halpal.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\halpal.s" + diff --git a/private/ntos/nthals/halxlt/alpha/haltsup.s b/private/ntos/nthals/halxlt/alpha/haltsup.s new file mode 100644 index 000000000..b8a697144 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/haltsup.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\haltsup.s" + diff --git a/private/ntos/nthals/halxlt/alpha/idle.s b/private/ntos/nthals/halxlt/alpha/idle.s new file mode 100644 index 000000000..f517bab2f --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/idle.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\idle.s" + diff --git a/private/ntos/nthals/halxlt/alpha/info.c b/private/ntos/nthals/halxlt/alpha/info.c new file mode 100644 index 000000000..22aef63a3 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/info.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\info.c" + diff --git a/private/ntos/nthals/halxlt/alpha/inithal.c b/private/ntos/nthals/halxlt/alpha/inithal.c new file mode 100644 index 000000000..d0b4b3539 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/inithal.c @@ -0,0 +1,1063 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation +Copyright (c) 1992, 1993 Digital Equipment Corporation + +Module Name: + + inithal.c + +Abstract: + + + This module implements the initialization of the system dependent + functions that define the Hardware Architecture Layer (HAL) for an + Alpha machine + +Author: + + David N. Cutler (davec) 25-Apr-1991 + Miche Baker-Harvey (miche) 18-May-1992 + +Environment: + + Kernel mode only. + +Revision History: + + 28-Jul-1992 Jeff McLeman (mcleman) + Add code to allocate a mapping buffer for buffered DMA + + 14-Jul-1992 Jeff McLeman (mcleman) + Add call to HalpCachePcrValues, which will call the PALcode to + cache values of the PCR that need fast access. + + 10-Jul-1992 Jeff McLeman (mcleman) + Remove reference to initializing the fixed TB entries, since Alpha + does not have fixed TB entries. + + 24-Sep-1993 Joe Notarangelo + Restructured to make this module platform-independent. + +--*/ + +#include "halp.h" +#include "eisa.h" + +// +// Declare the extern variable UncorrectableError declared in +// inithal.c. +// +PERROR_FRAME PUncorrectableError; + +// +// external +// + +ULONG HalDisablePCIParityChecking = 0xffffffff; + +// +// Define HAL spinlocks. +// + +KSPIN_LOCK HalpBeepLock; +KSPIN_LOCK HalpDisplayAdapterLock; +KSPIN_LOCK HalpSystemInterruptLock; + +// +// Mask of all of the processors that are currently active. +// + +KAFFINITY HalpActiveProcessors; + +// +// Mapping of the logical processor numbers to the physical processors. +// + +ULONG HalpLogicalToPhysicalProcessor[HAL_MAXIMUM_PROCESSOR+1]; + +ULONG AlreadySet = 0; + +// +// HalpClockFrequency is the processor cycle counter frequency in units +// of cycles per second (Hertz). It is a large number (e.g., 125,000,000) +// but will still fit in a ULONG. +// +// HalpClockMegaHertz is the processor cycle counter frequency in units +// of megahertz. It is a small number (e.g., 125) and is also the number +// of cycles per microsecond. The assumption here is that clock rates will +// always be an integral number of megahertz. +// +// Having the frequency available in both units avoids multiplications, or +// especially divisions in time critical code. +// + +ULONG HalpClockFrequency; +ULONG HalpClockMegaHertz = DEFAULT_PROCESSOR_FREQUENCY_MHZ; + +ULONGLONG HalpContiguousPhysicalMemorySize; +// +// Use the square wave mode of the PIT to measure the processor +// speed. The timer has a frequency of 1.193MHz. We want a +// square wave with a period of 50ms so we must initialize the +// pit with a count of: +// 50ms*1.193MHz = 59650 cycles +// + +#define TIMER_REF_VALUE 59650 + +VOID +HalpVerifyPrcbVersion( + VOID + ); + +VOID +HalpRecurseLoaderBlock( + IN PCONFIGURATION_COMPONENT_DATA CurrentEntry + ); + +ULONG +HalpQuerySystemFrequency( + ULONG SampleTime + ); + +VOID +HalpAllocateUncorrectableFrame( + VOID + ); + + +BOOLEAN +HalInitSystem ( + IN ULONG Phase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock + ) + +/*++ + +Routine Description: + + This function initializes the Hardware Architecture Layer (HAL) for an + Alpha 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; + ULONG BuildType = 0; + + Prcb = PCR->Prcb; + + // + // Perform initialization for the primary processor. + // + + if( Prcb->Number == HAL_PRIMARY_PROCESSOR ){ + + if (Phase == 0) { + +#if HALDBG + + DbgPrint( "HAL/HalInitSystem: Phase = %d\n", Phase ); + DbgBreakPoint(); + HalpDumpMemoryDescriptors( LoaderBlock ); + +#endif //HALDBG + // + // Get the memory Size. + // + HalpContiguousPhysicalMemorySize = HalpGetContiguousMemorySize( + LoaderBlock ); + + + // + // Set second level cache size + // NOTE: Although we set the PCR with the right cache size this + // could be overridden by setting the Registry key + // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet + // \Control\Session Manager + // \Memory Management\SecondLevelDataCache. + // + // + // + // If the secondlevel cache size is 0 or 512KB then it is + // possible that the firmware is an old one. In which case + // we determine the cache size here. If the value is anything + // other than these then it is a new firmware and probably + // reporting the correct cache size hence use this value. + // + + if(LoaderBlock->u.Alpha.SecondLevelDcacheSize == 0 || + LoaderBlock->u.Alpha.SecondLevelDcacheSize == 512*__1K){ + PCR->SecondLevelCacheSize = HalpGetBCacheSize( + HalpContiguousPhysicalMemorySize + ); + } else { + PCR->SecondLevelCacheSize = + LoaderBlock->u.Alpha.SecondLevelDcacheSize; + } + + + // + // Initialize HAL spinlocks. + // + + KeInitializeSpinLock(&HalpBeepLock); + KeInitializeSpinLock(&HalpDisplayAdapterLock); + KeInitializeSpinLock(&HalpSystemInterruptLock); + + // + // Fill in handlers for APIs which this HAL supports + // + + HalQuerySystemInformation = HaliQuerySystemInformation; + HalSetSystemInformation = HaliSetSystemInformation; + + // + // Phase 0 initialization. + // + + HalpInitializeCia( LoaderBlock ); + + HalpSetTimeIncrement(); + HalpMapIoSpace(); + HalpCreateDmaStructures(LoaderBlock); + HalpEstablishErrorHandler(); + HalpInitializeDisplay(LoaderBlock); + HalpInitializeMachineDependent( Phase, LoaderBlock ); + HalpInitializeInterrupts(); + HalpVerifyPrcbVersion(); + + // + // Set the processor active in the HAL active processor mask. + // + + HalpActiveProcessors = 1 << Prcb->Number; + + // + // Initialize the logical to physical processor mapping + // for the primary processor. + // + + HalpLogicalToPhysicalProcessor[0] = HAL_PRIMARY_PROCESSOR; + + return TRUE; + + } else { + +#if HALDBG + + DbgPrint( "HAL/HalInitSystem: Phase = %d\n", Phase ); + DbgBreakPoint(); + +#endif //HALDBG + + // + // Phase 1 initialization. + // + + HalpInitializeClockInterrupts(); + HalpInitializeMachineDependent( Phase, LoaderBlock ); + + // + // Allocate memory for the uncorrectable frame + // + + HalpAllocateUncorrectableFrame(); + + // + // Initialize the Buffer for Uncorrectable Error. + // + + HalpInitializeUncorrectableErrorFrame(); + + return TRUE; + + } + } + + // + // Perform necessary processor-specific initialization for + // secondary processors. Phase is ignored as this will be called + // only once on each secondary processor. + // + + HalpMapIoSpace(); + HalpInitializeInterrupts(); + HalpInitializeMachineDependent( Phase, LoaderBlock ); + + // + // Set the processor active in the HAL active processor mask. + // + + HalpActiveProcessors |= 1 << Prcb->Number; + +#if HALDBG + + DbgPrint( "Secondary %d is alive\n", Prcb->Number ); + +#endif //HALDBG + + return TRUE; +} + + + +VOID +HalpAllocateUncorrectableFrame( + VOID + ) +/*++ + +Routine Description: + + This function is called after the Phase1 Machine Dependent initialization. + It must be called only after Phase1 machine dependent initialization. + This function allocates the necessary amountof memory for storing the + uncorrectable error frame. This function makes a call to a machine + dependent function 'HalpGetMachineDependentErrorFrameSizes' for + getting the size of the Processor Specific and System Specific error + frame size. The machine dependent code will + know the size of these frames after the machine depedant Phase1 + initialization. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + ULONG RawProcessorFrameSize; + ULONG RawSystemFrameSize; + ULONG EntireErrorFrameSize; + + // + // First get the machine dependent error frame sizes. + // + HalpGetMachineDependentErrorFrameSizes( + &RawProcessorFrameSize, + &RawSystemFrameSize); + + // + // Compute the total size of the error frame + // + EntireErrorFrameSize = sizeof(ERROR_FRAME) + RawProcessorFrameSize + + RawSystemFrameSize; + + // + // Allocate space to store the error frame. + // Not sure if it is OK to use ExAllocatePool at this instant. + // We will give this a try if it doesn't work What do we do??!! + // + + PUncorrectableError = ExAllocatePool(NonPagedPool, + EntireErrorFrameSize); + if(PUncorrectableError == NULL) { + return; + } + + PUncorrectableError->LengthOfEntireErrorFrame = EntireErrorFrameSize; + + // + // if the size is not equal to zero then set the RawInformation pointers + // to point to the right place. If not set the pointer to NULL and set + // size to 0. + // + + // + // make Raw processor info to point right after the error frame. + // + if(RawProcessorFrameSize) { + PUncorrectableError->UncorrectableFrame.RawProcessorInformation = + (PVOID)((PUCHAR)PUncorrectableError + sizeof(ERROR_FRAME) ); + PUncorrectableError->UncorrectableFrame.RawProcessorInformationLength = + RawProcessorFrameSize; + } + else{ + PUncorrectableError->UncorrectableFrame.RawProcessorInformation = + NULL; + PUncorrectableError->UncorrectableFrame.RawProcessorInformationLength = + 0; + } + if(RawSystemFrameSize){ + PUncorrectableError->UncorrectableFrame.RawSystemInformation = + (PVOID)((PUCHAR)PUncorrectableError->UncorrectableFrame. + RawProcessorInformation + RawProcessorFrameSize); + PUncorrectableError->UncorrectableFrame.RawSystemInformationLength = + RawSystemFrameSize; + } + else{ + PUncorrectableError->UncorrectableFrame.RawSystemInformation = + NULL; + PUncorrectableError->UncorrectableFrame.RawSystemInformationLength = + 0; + } +} + + + +VOID +HalpGetProcessorInfo( + PPROCESSOR_INFO pProcessorInfo +) +/*++ + +Routine Description: + + Collects the Processor Information and fills in the buffer. + +Arguments: + + pProcessorInfo - Pointer to the PROCESSOR_INFO structure into which + the processor information will be filled in. + +Return Value: + + None. + +--*/ +{ + PKPRCB Prcb; + + pProcessorInfo->ProcessorType = PCR->ProcessorType; + pProcessorInfo->ProcessorRevision = PCR->ProcessorRevision; + + Prcb = PCR->Prcb; + pProcessorInfo->LogicalProcessorNumber = Prcb->Number; + pProcessorInfo->PhysicalProcessorNumber = + HalpLogicalToPhysicalProcessor[Prcb->Number]; + return; +} + + + +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. + +--*/ + +{ + ULONG LogicalNumber; + PRESTART_BLOCK NextRestartBlock; + ULONG PhysicalNumber; + PKPRCB Prcb; + +#if !defined(NT_UP) + + // + // 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. + // + + LogicalNumber = 0; + PhysicalNumber = 0; + do { + + // + // 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. + // + + if( NextRestartBlock->BootStatus.ProcessorReady == FALSE ){ + + PhysicalNumber += 1; + + } else { + + // + // Check if this processor has already been started. + // If it has not then start it now. + // + + if( NextRestartBlock->BootStatus.ProcessorStart == FALSE ){ + + RtlZeroMemory( &NextRestartBlock->u.Alpha, + sizeof(ALPHA_RESTART_STATE)); + NextRestartBlock->u.Alpha.IntA0 = + ProcessorState->ContextFrame.IntA0; + NextRestartBlock->u.Alpha.IntSp = + ProcessorState->ContextFrame.IntSp; + NextRestartBlock->u.Alpha.ReiRestartAddress = + (ULONG)ProcessorState->ContextFrame.Fir; + Prcb = (PKPRCB)(LoaderBlock->Prcb); + Prcb->Number = (CCHAR)LogicalNumber; + Prcb->RestartBlock = NextRestartBlock; + NextRestartBlock->BootStatus.ProcessorStart = 1; + + HalpLogicalToPhysicalProcessor[LogicalNumber] = PhysicalNumber; + + return TRUE; + + } else { + + // + // Ensure that the logical to physical mapping has been + // established for this processor. + // + + HalpLogicalToPhysicalProcessor[LogicalNumber] = PhysicalNumber; + + } + + LogicalNumber += 1; + PhysicalNumber += 1; + } + + NextRestartBlock = NextRestartBlock->NextRestartBlock; + + } while (NextRestartBlock != NULL); + +#endif // !defined(NT_UP) + + return FALSE; +} + +VOID +HalpVerifyPrcbVersion( + VOID + ) +/*++ + +Routine Description: + + This function verifies that the HAL matches the kernel. If there + is a mismatch the HAL bugchecks the system. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + + PKPRCB Prcb; + + // + // Verify Prcb major version number, and build options are + // all conforming to this binary image + // + + Prcb = KeGetCurrentPrcb(); + +#if DBG + if (!(Prcb->BuildType & PRCB_BUILD_DEBUG)) { + // This checked hal requires a checked kernel + KeBugCheckEx (MISMATCHED_HAL, 2, Prcb->BuildType, PRCB_BUILD_DEBUG, 0); + } +#else + if (Prcb->BuildType & PRCB_BUILD_DEBUG) { + // This free hal requires a free kernel + KeBugCheckEx (MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0); + } +#endif +#ifndef NT_UP + if (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR) { + // This MP hal requires an MP kernel + KeBugCheckEx (MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0); + } +#endif + if (Prcb->MajorVersion != PRCB_MAJOR_VERSION) { + KeBugCheckEx (MISMATCHED_HAL, + 1, Prcb->MajorVersion, PRCB_MAJOR_VERSION, 0); + } + + +} + + +VOID +HalpParseLoaderBlock( + IN PLOADER_PARAMETER_BLOCK LoaderBlock + ) +{ + + if (LoaderBlock == NULL) { + return; + } + + HalpRecurseLoaderBlock( (PCONFIGURATION_COMPONENT_DATA) + LoaderBlock->ConfigurationRoot); +} + + + +VOID +HalpRecurseLoaderBlock( + IN PCONFIGURATION_COMPONENT_DATA CurrentEntry + ) +/*++ + +Routine Description: + + This routine parses the loader parameter block looking for the PCI + node. Once found, used to determine if PCI parity checking should be + enabled or disabled. Set the default to not disable checking. + +Arguments: + + CurrentEntry - Supplies a pointer to a loader configuration + tree or subtree. + +Return Value: + + None. + +--*/ +{ + + PCONFIGURATION_COMPONENT Component; + PWSTR NameString; + + // + // Quick out + // + + if (AlreadySet) { + return; + } + + if (CurrentEntry) { + Component = &CurrentEntry->ComponentEntry; + + if (Component->Class == AdapterClass && + Component->Type == MultiFunctionAdapter) { + + if (strcmp(Component->Identifier, "PCI") == 0) { + HalDisablePCIParityChecking = Component->Flags.ConsoleOut; + AlreadySet = TRUE; +#if HALDBG + DbgPrint("ARC tree sets PCI parity checking to %s\n", + HalDisablePCIParityChecking ? "OFF" : "ON"); +#endif + return; + } + } + + // + // Process all the Siblings of current entry + // + + HalpRecurseLoaderBlock(CurrentEntry->Sibling); + + // + // Process all the Childeren of current entry + // + + HalpRecurseLoaderBlock(CurrentEntry->Child); + + } +} + + +ULONG +HalpQuerySystemFrequency( + ULONG SampleTime + ) +/*++ + +Routine Description: + + This routine returns the speed at which the system is running in hertz. + The system frequency is calculated by counting the number of processor + cycles that occur during 500ms, using the Programmable Interval Timer + (PIT) as the reference time. The PIT is used to generate a square + wave with a 50ms Period. We use the Speaker counter since we can + enable and disable the count from software. The output of the + speaker is obtained from the SIO NmiStatus register. + +Arguments: + + None. + +Return Value: + + The system frequency in Hertz. + +--*/ +{ + TIMER_CONTROL TimerControlSetup; + TIMER_CONTROL TimerControlReadStatus; + TIMER_STATUS TimerStatus; + NMI_STATUS NmiStatus; + PEISA_CONTROL controlBase; + ULONGLONG Count1; + ULONGLONG Count2; + ULONG NumberOfIntervals; + ULONG SquareWaveState = 0; + +// mdbfix - move this into eisa.h one day +#define SB_READ_STATUS_ONLY 2 + + controlBase = HalpEisaControlBase; + + // + // Disable the speaker counter. + // + + *((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus); + + NmiStatus.SpeakerGate = 0; + NmiStatus.SpeakerData = 0; + + // these are MBZ when writing to NMIMISC + NmiStatus.RefreshToggle = 0; + NmiStatus.SpeakerTimer = 0; + NmiStatus.IochkNmi = 0; + + WRITE_PORT_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus)); + + // + // Number of Square Wave transitions to count. + // at 50ms period, count the number of 25ms + // square wave transitions for a sample reference + // time to against which we measure processor cycle count. + // + + NumberOfIntervals = (SampleTime/50) * 2; + + // + // Set the timer for counter 0 in binary mode, square wave output + // + + TimerControlSetup.BcdMode = 0; + TimerControlSetup.Mode = TM_SQUARE_WAVE; + TimerControlSetup.SelectByte = SB_LSB_THEN_MSB; + TimerControlSetup.SelectCounter = SELECT_COUNTER_2; + + // + // Set the counter for a latched read of the status. + // We will poll the PIT for the state of the square + // wave output. + // + + TimerControlReadStatus.BcdMode = 0; + TimerControlReadStatus.Mode = (1 << SELECT_COUNTER_2); + TimerControlReadStatus.SelectByte = SB_READ_STATUS_ONLY; + TimerControlReadStatus.SelectCounter = SELECT_READ_BACK; + + + // + // Write the count value LSB and MSB for a 50ms clock period + // + + WRITE_PORT_UCHAR( &controlBase->CommandMode1, + *(PUCHAR)&TimerControlSetup ); + + WRITE_PORT_UCHAR( &controlBase->SpeakerTone, + TIMER_REF_VALUE & 0xff ); + + WRITE_PORT_UCHAR( &controlBase->SpeakerTone, + (TIMER_REF_VALUE >> 8) & 0xff ); + + // + // Enable the speaker counter but disable the SPKR output signal. + // + + *((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus); + + NmiStatus.SpeakerGate = 1; + NmiStatus.SpeakerData = 0; + + // these are MBZ when writing to NMIMISC + NmiStatus.RefreshToggle = 0; + NmiStatus.SpeakerTimer = 0; + NmiStatus.IochkNmi = 0; + + WRITE_PORT_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus)); + + // + // Synchronize with the counter before taking the first + // sample of the Processor Cycle Count (PCC). Since we + // are using the Square Wave Mode, wait until the next + // state change and then observe half a cycle before + // sampling. + // + + // + // observe the low transition of the square wave output. + // + do { + + *((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus); + + } while (NmiStatus.SpeakerTimer != SquareWaveState); + + SquareWaveState ^= 1; + + // + // observe the next transition of the square wave output and then + // take the first cycle counter sample. + // + do { + + *((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus); + + } while (NmiStatus.SpeakerTimer != SquareWaveState); + + Count1 = __RCC(); + + // + // Wait for the 500ms time period to pass and then take the + // second sample of the PCC. For a 50ms period, we have to + // observe eight wave transitions (25ms each). + // + + do { + + SquareWaveState ^= 1; + + // + // wait for wave transition + // + do { + + *((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus); + + } while (NmiStatus.SpeakerTimer != SquareWaveState); + + } while (--NumberOfIntervals); + + Count2 = __RCC(); + + // + // Disable the speaker counter. + // + + *((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus); + + NmiStatus.SpeakerGate = 0; + NmiStatus.SpeakerData = 0; + + WRITE_PORT_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus)); + + // + // Calculate the Hz by the number of processor cycles + // elapsed during 1s. + // + // Hz = PCC/SampleTime * 1000ms/s + // = PCC * (1000/SampleTime) + // + + // did the counter wrap? if so add 2^32 + if (Count1 > Count2) { + + Count2 += (ULONGLONG)(1 << 32); + + } + + return (ULONG) ((Count2 - Count1)*(((ULONG)1000)/SampleTime)); +} + + +VOID +HalpInitializeProcessorParameters( + VOID + ) +/*++ + +Routine Description: + + This routine initalize the processor counter parameters + HalpClockFrequency and HalpClockMegaHertz based on the + estimated CPU speed. A 1s reference time is used for + the estimation. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + ULONG MHz; + + HalpClockFrequency = HalpQuerySystemFrequency(1000); + HalpClockMegaHertz = MHz = HalpClockFrequency / 1000000; + + // + // Hotwire HalpClockMegaHertz to match product name! + // + if (MHz > 490) HalpClockMegaHertz = 500; + else if (MHz > 456) HalpClockMegaHertz = 466; + else if (MHz > 423) HalpClockMegaHertz = 433; + else if (MHz > 390) HalpClockMegaHertz = 400; + else if (MHz > 356) HalpClockMegaHertz = 366; + else if (MHz > 323) HalpClockMegaHertz = 333; + else if (MHz > 290) HalpClockMegaHertz = 300; + else; // there must be some mistake... +} + + + + +#if 0 +VOID +HalpGatherPerformanceParameterStats( + VOID + ) + +/*++ + +Routine Description: + + This routine gathers statistics on the method for + estimating the system frequency. + +Arguments: + + None. + +Return Value: + + None. + +--*/ + +{ + ULONG Index; + ULONG Hertz[32]; + ULONGLONG Mean = 0; + ULONGLONG Variance = 0; + ULONGLONG TempHertz; + + // + // take 32 samples of estimated CPU speed, + // calculating the mean in the process. + // + DbgPrint("Sample\tFrequency\tMegaHertz\n\n"); + + for (Index = 0; Index < 32; Index++) { + Hertz[Index] = HalpQuerySystemFrequency(500); + Mean += Hertz[Index]; + + DbgPrint( + "%d\t%d\t%d\n", + Index, + Hertz[Index], + (ULONG)((Hertz[Index] + 500000)/1000000) + ); + + } + + // + // calculate the mean + // + + Mean /= 32; + + // + // calculate the variance + // + for (Index = 0; Index < 32; Index++) { + TempHertz = (Mean > Hertz[Index])? + (Mean - Hertz[Index]) : (Hertz[Index] - Mean); + TempHertz = TempHertz*TempHertz; + Variance += TempHertz; + } + + Variance /= 32; + + DbgPrint("\nResults\n\n"); + DbgPrint( + "Mean = %d\nVariance = %d\nMegaHertz (derived) = %d\n", + Mean, + Variance, + (Mean + 500000)/ 1000000 + ); + +} +#endif + diff --git a/private/ntos/nthals/halxlt/alpha/intsup.s b/private/ntos/nthals/halxlt/alpha/intsup.s new file mode 100644 index 000000000..a7d9f8f4f --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/intsup.s @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// +#include "pcrtc.h" +#include "..\halalpha\intsup.s" + diff --git a/private/ntos/nthals/halxlt/alpha/ioproc.c b/private/ntos/nthals/halxlt/alpha/ioproc.c new file mode 100644 index 000000000..36d338384 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/ioproc.c @@ -0,0 +1,91 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + ioproc.c + +Abstract: + + Stub functions for UP hals. + +Author: + + Ken Reneris (kenr) 22-Jan-1991 + +Environment: + + Kernel mode only. + +Revision History: + + Added to Avanti Hals (Sameer Dekate) 04-May-1994 + +--*/ + +#include "halp.h" +#include "iousage.h" + +UCHAR HalName[] = "Alpha Compatible PCI/Eisa/Isa HAL"; + +VOID +HalpInitializePCIBus ( + VOID + ); + +BOOLEAN +HalpInitMP ( + IN ULONG Phase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock + ); + +VOID HalpInitializePciBuses (VOID); +VOID HalpInitOtherBuses (VOID); + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT,HalpInitMP) +#pragma alloc_text(INIT,HalStartNextProcessor) +#pragma alloc_text(INIT,HalpInitOtherBuses) +#endif + + + +BOOLEAN +HalpInitMP ( + IN ULONG Phase, + IN PLOADER_PARAMETER_BLOCK LoaderBlock + ) +{ + return TRUE; + // do nothing +} + + +VOID +HalpResetAllProcessors ( + VOID + ) +{ + // Just return, that will invoke the standard PC reboot code +} + + +BOOLEAN +HalStartNextProcessor ( + IN PLOADER_PARAMETER_BLOCK pLoaderBlock, + IN PKPROCESSOR_STATE pProcessorState + ) +{ + // no other processors + return FALSE; +} + + +VOID +HalpInitOtherBuses ( + VOID + ) +{ + // no other internal buses supported +} diff --git a/private/ntos/nthals/halxlt/alpha/iousage.c b/private/ntos/nthals/halxlt/alpha/iousage.c new file mode 100644 index 000000000..6ac8f6f4e --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/iousage.c @@ -0,0 +1,647 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + iousage.c + +Abstract: + +Author: + + Ken Reneris (kenr) + +Environment: + + Kernel mode only. + +Revision History: + + Chao Chen 1-25-1995 + +--*/ + +#include "halp.h" +#include "iousage.h" + +// +// Externals. +// + +extern KAFFINITY HalpActiveProcessors; + +// +// Private resource list. +// + +static PBUS_USAGE HalpBusUsageList = NULL; +static PRESOURCE_USAGE HalpResourceUsageList = NULL; + +// +// Default HAL name. +// + +#define MAX_NAME_LENGTH 256 +UCHAR HalRegisteredName[MAX_NAME_LENGTH] = "Alpha Compatible PCI/EISA/ISA HAL"; + +// +// Function prototype. +// + +VOID +HalpReportResourceUsage ( + IN PUNICODE_STRING HalName + ); + +VOID +HalpGetResourceSortValue ( + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, + OUT PULONG sortscale, + OUT PLARGE_INTEGER sortvalue + ); + +// +// Pragma stuff. +// + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT,HalpRegisterHalName) +#pragma alloc_text(INIT,HalpRegisterBusUsage) +#pragma alloc_text(INIT,HalpRegisterResourceUsage) +#pragma alloc_text(INIT,HalReportResourceUsage) +#pragma alloc_text(INIT,HalpReportResourceUsage) +#pragma alloc_text(INIT,HalpGetResourceSortValue) +#endif + +// +// Function definitions. +// + + +VOID +HalpRegisterHalName( + IN PUCHAR NewHalName + ) +/*++ + +Routine Description: + + Allow the HAL to register a name string. + +Arguments: + + HalName - Supplies a pointer to the HAL name to register. + +Return Value: + + None. + +--*/ +{ + + strncpy( HalRegisteredName, NewHalName, MAX_NAME_LENGTH ); + return; +} + + + +VOID +HalpRegisterBusUsage ( + IN INTERFACE_TYPE BusType + ) +/*++ + +Routine Description: + + Register the different bus types in the system. + +Arguments: + + BusType - bus type that requires registering. + +Return Value: + + None. + +--*/ +{ + PBUS_USAGE Temp; + + // + // Allocate the buffer to store the bus information. + // + + Temp = (PBUS_USAGE)ExAllocatePool(NonPagedPool, sizeof(BUS_USAGE)); + + // + // Save the bus type. + // + + Temp->BusType = BusType; + + // + // Add the bus type to the head of the list. + // + + Temp->Next = HalpBusUsageList; + HalpBusUsageList = Temp; +} + + + +VOID +HalpRegisterResourceUsage ( + IN PRESOURCE_USAGE Resource + ) +/*++ + +Routine Description: + + Register the resources used internally by the HAL to the I/O system. + +Arguments: + + Resource - resource that requires registering. + +Return Value: + + None. + +--*/ +{ + PRESOURCE_USAGE Temp; + + // + // Allocate the buffer to store the resource information. + // + + Temp = (PRESOURCE_USAGE)ExAllocatePool(NonPagedPool, sizeof(RESOURCE_USAGE)); + + // + // Copy the resource to the buffer we allocated. + // + + RtlCopyMemory(Temp, Resource, sizeof(RESOURCE_USAGE)); + + // + // Add the resource to the head of the resource list. + // + + Temp->Next = HalpResourceUsageList; + HalpResourceUsageList = Temp; +} + + + +VOID +HalReportResourceUsage ( + VOID + ) +/*++ + +Routine Description: + + Report the resources used internally by the HAL to the I/O system. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + ANSI_STRING AHalName; + UNICODE_STRING UHalName; + + // + // Convert the string. + // + + RtlInitAnsiString (&AHalName, HalRegisteredName); + RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE); + + // + // Report the resources registered as in use by the HAL. + // + + HalpReportResourceUsage(&UHalName); + + RtlFreeUnicodeString(&UHalName); +} + + + +VOID +HalpGetResourceSortValue ( + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, + OUT PULONG sortscale, + OUT PLARGE_INTEGER sortvalue + ) +/*++ + +Routine Description: + + Used by HalpReportResourceUsage in order to properly sort + partial_resource_descriptors. + +Arguments: + + pRCurLoc - resource descriptor + +Return Value: + + sortscale - scaling of resource descriptor for sorting + sortvalue - value to sort on + + +--*/ +{ + + switch (pRCurLoc->Type) { + case CmResourceTypeInterrupt: + *sortscale = 0; + sortvalue->QuadPart = pRCurLoc->u.Interrupt.Level; + break; + + case CmResourceTypePort: + *sortscale = 1; + *sortvalue = pRCurLoc->u.Port.Start; + break; + + case CmResourceTypeMemory: + *sortscale = 2; + *sortvalue = pRCurLoc->u.Memory.Start; + break; + + case CmResourceTypeDma: + *sortscale = 3; + sortvalue->QuadPart = pRCurLoc->u.Dma.Channel; + break; + + default: + *sortscale = 4; + sortvalue->QuadPart = 0; + break; + } +} + + + +VOID +HalpReportResourceUsage ( + IN PUNICODE_STRING HalName + ) +/*++ + +Routine Description: + + This routine registers the resources for the hal. + +Arguments: + + HalName - the name of the hal to be registered. + +Return Value: + + None. + +--*/ +{ + PCM_RESOURCE_LIST RawResourceList, TranslatedResourceList; + PCM_FULL_RESOURCE_DESCRIPTOR pRFullDesc, pTFullDesc; + PCM_PARTIAL_RESOURCE_LIST pRPartList, pTPartList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, pTCurLoc; + PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc, pTSortLoc; + CM_PARTIAL_RESOURCE_DESCRIPTOR RPartialDesc, TPartialDesc; + ULONG i, j, k, ListSize, Count; + ULONG curscale, sortscale; + LARGE_INTEGER curvalue, sortvalue; + PHYSICAL_ADDRESS PhyAddress; + PBUS_USAGE CurrentBus; + PRESOURCE_USAGE CurrentResource; + + // + // Allocate some space to build the resource structure. + // + + RawResourceList= + (PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2); + TranslatedResourceList= + (PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2); + + // + // This functions assumes unset fields are zero. + // + + RtlZeroMemory (RawResourceList, PAGE_SIZE*2); + RtlZeroMemory (TranslatedResourceList, PAGE_SIZE*2); + + // + // Initialize the lists + // + + RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1; + pRFullDesc = RawResourceList->List; + pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List; + pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List; + + // + // Report all the HAL resources. + // + + CurrentBus = HalpBusUsageList; + + while (CurrentBus) { + + // + // Start at the head of the resource list for each bus type. + // + + CurrentResource = HalpResourceUsageList; + + while (CurrentResource) { + + // + // Register the resources for a particular bus. + // + + if (CurrentBus->BusType == CurrentResource->BusType) { + + switch (CurrentResource->ResourceType) { + + case CmResourceTypeInterrupt: + + // + // Process interrupt resources. + // + + RPartialDesc.Type = CmResourceTypeInterrupt; + RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; + + if (CurrentResource->u.InterruptMode == Latched) + RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LATCHED; + else + RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + + RPartialDesc.u.Interrupt.Vector = + CurrentResource->u.BusInterruptVector; + RPartialDesc.u.Interrupt.Level = + CurrentResource->u.BusInterruptVector; + RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors; + + RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc)); + TPartialDesc.u.Interrupt.Vector = + CurrentResource->u.SystemInterruptVector; + TPartialDesc.u.Interrupt.Level = + CurrentResource->u.SystemIrql; + + break; + + case CmResourceTypePort: + case CmResourceTypeMemory: + + // + // Process port and memory resources. + // + + RPartialDesc.Type = CurrentResource->ResourceType; + RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; + + if (RPartialDesc.Type == CmResourceTypePort) { + + // + // In IO space. + // + + i = 1; + RPartialDesc.Flags = CM_RESOURCE_PORT_IO; + + } else { + + // + // In memory space. + // + + i = 0; + RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE; + } + + // + // Notice: assume u.Memory and u.Port have the same layout. + // + + RPartialDesc.u.Memory.Start.HighPart = 0; + RPartialDesc.u.Memory.Start.LowPart = CurrentResource->u.Start; + RPartialDesc.u.Memory.Length = CurrentResource->u.Length; + + RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc)); + + // + // Translate the address. + // + + HalTranslateBusAddress(CurrentResource->BusType, + CurrentResource->BusNumber, + RPartialDesc.u.Memory.Start, + &i, + &PhyAddress ); + + TPartialDesc.u.Memory.Start = PhyAddress; + + if ((RPartialDesc.Type == CmResourceTypePort) && (i == 0)) + TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY; + + break; + + case CmResourceTypeDma: + + // + // Process dma resources. + // + + RPartialDesc.Type = CmResourceTypeDma; + RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; + + RPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel; + RPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort; + + RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc)); + TPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel; + TPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort; + + break; + + default: + + // + // Got a resource we don't know. Bail out! + // + + goto NextResource; + } + + // + // Include the current resource in the HAL list. + // + + if (pRFullDesc->InterfaceType != CurrentBus->BusType) { + + // + // Interface type changed, add another full section + // + + RawResourceList->Count++; + TranslatedResourceList->Count++; + + pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pRCurLoc; + pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pTCurLoc; + + pRFullDesc->InterfaceType = CurrentBus->BusType; + pTFullDesc->InterfaceType = CurrentBus->BusType; + + pRPartList = &pRFullDesc->PartialResourceList; + pTPartList = &pTFullDesc->PartialResourceList; + + // + // Bump current location pointers up + // + + pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors; + pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors; + } + + // + // Add current resource in. + // + + pRPartList->Count++; + pTPartList->Count++; + RtlCopyMemory(pRCurLoc, &RPartialDesc, sizeof(RPartialDesc)); + RtlCopyMemory(pTCurLoc, &TPartialDesc, sizeof(TPartialDesc)); + + pRCurLoc++; + pTCurLoc++; + } + + // + // Finished with this resource, move to the next one. + // + + NextResource: + CurrentResource = CurrentResource->Next; + } + + // + // Finished with this bus, move to the next one. + // + + CurrentBus = CurrentBus->Next; + } + + // + // Do the actual reporting. + // + + ListSize = (ULONG)(((PUCHAR)pRCurLoc) - ((PUCHAR)RawResourceList)); + + // + // The HAL's resource usage structures have been built + // Sort the partial lists based on the Raw resource values. + // + + pRFullDesc = RawResourceList->List; + pTFullDesc = TranslatedResourceList->List; + + for (i=0; i < RawResourceList->Count; i++) { + + pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors; + pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors; + Count = pRFullDesc->PartialResourceList.Count; + + for (j=0; j < Count; j++) { + HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue); + + pRSortLoc = pRCurLoc; + pTSortLoc = pTCurLoc; + + for (k=j; k < Count; k++) { + HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue); + + if (sortscale < curscale || + (sortscale == curscale && + (sortvalue.QuadPart < curvalue.QuadPart)) ){ + + // + // Swap the elements. + // + + RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc); + RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc); + RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc); + + // + // Swap translated descriptor as well. + // + + RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc); + RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc); + RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc); + + // + // Get new curscale & curvalue. + // + + HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue); + } + + pRSortLoc++; + pTSortLoc++; + } + + pRCurLoc++; + pTCurLoc++; + } + + pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc; + pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc; + } + + // + // Inform the IO system of our resources. + // + + IoReportHalResourceUsage(HalName, + RawResourceList, + TranslatedResourceList, + ListSize); + + ExFreePool (RawResourceList); + ExFreePool (TranslatedResourceList); + + // + // Free all registered buses. + // + + while (HalpBusUsageList) { + + CurrentBus = HalpBusUsageList; + HalpBusUsageList = HalpBusUsageList->Next; + ExFreePool(CurrentBus); + } + + // + // Free all registered resources. + // + + while (HalpResourceUsageList) { + + CurrentResource = HalpResourceUsageList; + HalpResourceUsageList = HalpResourceUsageList->Next; + ExFreePool(CurrentResource); + } +} + diff --git a/private/ntos/nthals/halxlt/alpha/iousage.h b/private/ntos/nthals/halxlt/alpha/iousage.h new file mode 100644 index 000000000..b54cd179a --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/iousage.h @@ -0,0 +1,107 @@ +/*++ + +Copyright (c) 1993-1995 Microsoft Corporation +Copyright (c) 1993-1995 Digital Equipment Corporation + +Module Name: + + iousage.h + +Abstract: + + This header file defines the iousage definitions + +Author: + + Sameer Dekate 5-3-1994 + + +Revision History: + + Chao Chen 1-25-1995 + +--*/ + +// +// Resource usage information +// + +// +// Bus usage information. +// + +typedef struct _HalBusUsage{ + INTERFACE_TYPE BusType; + struct _HalBusUsage *Next; +} BUS_USAGE, *PBUS_USAGE; + +// +// Address usage information. +// + +typedef struct _HalResourceUsage { + + // + // Common elements. + // + + INTERFACE_TYPE BusType; + ULONG BusNumber; + CM_RESOURCE_TYPE ResourceType; + struct _HalResourceUsage *Next; + + // + // Resource type specific. + // + + union { + + // + // Address usage. + // + + struct { + ULONG Start; + ULONG Length; + }; + + // + // Vector type specific. + // + + struct { + KINTERRUPT_MODE InterruptMode; + ULONG BusInterruptVector; + ULONG SystemInterruptVector; + KIRQL SystemIrql; + }; + + // + // Dma type specific. + // + + struct { + ULONG DmaChannel; + ULONG DmaPort; + }; + } u; +} RESOURCE_USAGE, *PRESOURCE_USAGE; + +// +// Functions to report HAL's resource usage. +// + +VOID +HalpRegisterHalName( + IN PUCHAR HalName + ); + +VOID +HalpRegisterBusUsage ( + IN INTERFACE_TYPE BusType + ); + +VOID +HalpRegisterResourceUsage ( + IN PRESOURCE_USAGE Resource + ); diff --git a/private/ntos/nthals/halxlt/alpha/machdep.h b/private/ntos/nthals/halxlt/alpha/machdep.h new file mode 100644 index 000000000..21a40d2f0 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/machdep.h @@ -0,0 +1,42 @@ +/*++ + +Copyright (c) 1993 Digital Equipment Corporation + +Module Name: + + machdep.h + +Abstract: + + This file includes the platform-dependent include files used to + build the HAL. + +Author: + + Joe Notarangelo 01-Dec-1993 + +Environment: + + Kernel mode + +Revision History: + + +--*/ + +#ifndef _MACHDEP_ +#define _MACHDEP_ + +// +// Include Alcor platform-specific definitions. +// + +#include "alcor.h" + +// +// Include scatter/gather definitions. +// + +#include "ebsgdma.h" + +#endif //_MACHDEP_ diff --git a/private/ntos/nthals/halxlt/alpha/memory.c b/private/ntos/nthals/halxlt/alpha/memory.c new file mode 100644 index 000000000..76b1eb7df --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/memory.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\memory.c" + diff --git a/private/ntos/nthals/halxlt/alpha/nvenv.c b/private/ntos/nthals/halxlt/alpha/nvenv.c new file mode 100644 index 000000000..ba5a5c8f7 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/nvenv.c @@ -0,0 +1 @@ +#include "..\halalpha\nvenv.c" diff --git a/private/ntos/nthals/halxlt/alpha/nvram.c b/private/ntos/nthals/halxlt/alpha/nvram.c new file mode 100644 index 000000000..879c41c68 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/nvram.c @@ -0,0 +1 @@ +#include "..\halalpha\nvram.c" diff --git a/private/ntos/nthals/halxlt/alpha/pcibus.c b/private/ntos/nthals/halxlt/alpha/pcibus.c new file mode 100644 index 000000000..3ce95ed54 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pcibus.c @@ -0,0 +1,124 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation, Digital Equipment Corporation + + +Module Name: + + pcibus.c + +Abstract: + + Platform-specific PCI bus routines + +Author: + + Steve Brooks 30-Jun-1994 + Joe Notarangelo 30-Jun-1994 + +Environment: + + Kernel mode + +Revision History: + +--*/ + +#include "halp.h" +#include "pci.h" +#include "pcip.h" +#include "machdep.h" + + +extern ULONG PCIMaxBus; + + +PCI_CONFIGURATION_TYPES +HalpPCIConfigCycleType ( + IN PBUS_HANDLER BusHandler + ) +{ + if (BusHandler->BusNumber == 0) { + return PciConfigType0; + } else { + return PciConfigType1; + } +} + + +VOID +HalpPCIConfigAddr ( + IN PBUS_HANDLER BusHandler, + IN PCI_SLOT_NUMBER Slot, + PPCI_CFG_CYCLE_BITS pPciAddr + ) +{ + PCI_CONFIGURATION_TYPES ConfigType; + + ConfigType = HalpPCIConfigCycleType(BusHandler); + +#if HALDBG + + DbgPrint( "PCI Config Access: Bus = %d, Device = %d, Type = %d\n", + BusNumber, Slot.u.bits.DeviceNumber, ConfigType ); + +#endif //HALDBG + + if (ConfigType == PciConfigType0) { + + // + // Initialize PciAddr for a type 0 configuration cycle + // + // Note that HalpValidPCISlot has already done bounds checking + // on DeviceNumber. + // + // PciAddr can be intialized for different bus numbers + // with distinct configuration spaces here. + // + + pPciAddr->u.AsULONG = (ULONG) CIA_PCI_CONFIG_BASE_QVA; + + // + // Encoding of the configuration addresses differs between + // passes of the CIA. Use the pre-determined global HalpCiaRevision + // to decide which encoding to use. + // + + if( HalpCiaRevision == CIA_REVISION_1 ){ + + // + // CIA Pass 1 + // + + pPciAddr->u.AsULONG += ( 1 << (Slot.u.bits.DeviceNumber + 11) ); + + } else { + + // + // CIA Pass 2 or later. + // + + pPciAddr->u.AsULONG += ( (Slot.u.bits.DeviceNumber) << 11 ); + + } + + pPciAddr->u.bits0.FunctionNumber = Slot.u.bits.FunctionNumber; + pPciAddr->u.bits0.Reserved1 = PciConfigType0; + + } else { + + // + // Initialize PciAddr for a type 1 configuration cycle + // + // + + pPciAddr->u.AsULONG = (ULONG) CIA_PCI_CONFIG_BASE_QVA; + pPciAddr->u.bits1.BusNumber = BusHandler->BusNumber; + pPciAddr->u.bits1.FunctionNumber = Slot.u.bits.FunctionNumber; + pPciAddr->u.bits1.DeviceNumber = Slot.u.bits.DeviceNumber; + pPciAddr->u.bits1.Reserved1 = PciConfigType1; + + } + + return; +} diff --git a/private/ntos/nthals/halxlt/alpha/pciesc.c b/private/ntos/nthals/halxlt/alpha/pciesc.c new file mode 100644 index 000000000..49142ea83 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pciesc.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\pciesc.c" + diff --git a/private/ntos/nthals/halxlt/alpha/pcisup.c b/private/ntos/nthals/halxlt/alpha/pcisup.c new file mode 100644 index 000000000..360919f42 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pcisup.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\pcisup.c" + diff --git a/private/ntos/nthals/halxlt/alpha/pcrtc.c b/private/ntos/nthals/halxlt/alpha/pcrtc.c new file mode 100644 index 000000000..2e57b87d6 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pcrtc.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\pcrtc.c" + diff --git a/private/ntos/nthals/halxlt/alpha/pcserial.c b/private/ntos/nthals/halxlt/alpha/pcserial.c new file mode 100644 index 000000000..a2f159c48 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pcserial.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\pcserial.c" + diff --git a/private/ntos/nthals/halxlt/alpha/pcspeakr.c b/private/ntos/nthals/halxlt/alpha/pcspeakr.c new file mode 100644 index 000000000..807b6f324 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pcspeakr.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\pcspeakr.c" + diff --git a/private/ntos/nthals/halxlt/alpha/perfcntr.c b/private/ntos/nthals/halxlt/alpha/perfcntr.c new file mode 100644 index 000000000..6c0a8f892 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/perfcntr.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\perfcntr.c" + diff --git a/private/ntos/nthals/halxlt/alpha/pintolin.h b/private/ntos/nthals/halxlt/alpha/pintolin.h new file mode 100644 index 000000000..5595b6c19 --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/pintolin.h @@ -0,0 +1,170 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation +Copyright (c) 1994 Digital Equipment Corporation + +Module Name: + + pintolin.h + +Abstract: + + This file includes the platform-dependent Pin To Line Tables + +Author: + + Steve Brooks 6-July 1994 + +Environment: + + Kernel mode + +Revision History: + + +--*/ + +// +// These tables represent the mapping from slot number and interrupt pin +// into a PCI Interrupt Vector. +// +// Formally, these mappings can be expressed as: +// +// PCIPinToLine: +// SlotNumber.DeviceNumber x InterruptPin -> InterruptLine +// +// LineToVector: +// InterruptLine -> InterruptVector +// +// VectorToIRRBit: +// InterruptVector -> InterruptRequestRegisterBit +// +// VectorToIMRBit: +// InterruptVector -> InterruptMaskRegisterBit +// +// SlotNumberToIDSEL: +// SlotNumber.DeviceNumber -> IDSEL +// +// subject to following invariants (predicates must always be true): +// +// Slot.DeviceNumber in {0,...,15} +// +// InterruptPin in {1, 2, 3, 4} +// +// InterruptRequestRegisterBit in {0,...,15} +// +// InterruptMaskRegisterBit in {0,...,15} +// +// PCIPinToLine(SlotNumber.DeviceNumber, InterruptPin) = +// PCIPinToLineTable[SlotNumber.DeviceNumber, InterruptPin] +// (Table-lookup function initialized below) +// +// LineToVector(InterruptLine) = PCI_VECTORS + InterruptLine +// +// VectorToIRRBit(InterruptVector) = InterruptVector - 1 +// +// VectorToIMRBit(InterruptVector) [see below] +// +// SlotNumberToIDSEL(SlotNumber.DeviceNumber) = (1 << (Slot.DeviceNumber+11)) +// +// where: +// +// SlotNumber.DeviceNumber: +// Alpha AXP Platforms receive interrupts on local PCI buses only, which +// are limited to 16 devices (PCI AD[11]-AD[26]). (We loose AD[27]-AD[31] +// since PCI Config space is a sparse space, requiring a five-bit shift.) +// +// InterruptPin: +// Each virtual slot has up to four interrupt pins INTA#, INTB#, INTC#, INTD#, +// as per the PCI Spec. V2.0, Section 2.2.6. (FYI, only multifunction devices +// use INTB#, INTC#, INTD#.) +// +// PCI configuration space indicates which interrupt pin a device will use +// in the InterruptPin register, which has the values: +// +// INTA# = 1, INTB#=2, INTC#=3, INTD# = 4 +// +// Note that there may be up to 8 functions/device on a PCI multifunction +// device plugged into the option slots, e.g., Slot #0. +// Each function has it's own PCI configuration space, addressed +// by the SlotNumber.FunctionNumber field, and will identify which +// interrput pin of the four it will use in it's own InterruptPin register. +// +// If the option is a PCI-PCI bridge, interrupts across the bridge will +// somehow be combined to appear on some combination of the four +// interrupt pins that the bridge plugs into. +// +// InterruptLine: +// This PCI Configuration register, unlike x86 PC's, is maintained by +// software and represents offset into PCI interrupt vectors. +// Whenever HalGetBusData or HalGetBusDataByOffset is called, +// HalpPCIPinToLine() computes the correct InterruptLine register value +// by using the HalpPCIPinToLineTable mapping. +// +// InterruptRequestRegisterBit: +// 0xff is used to mark an invalid IRR bit, hence an invalid request +// for a vector. Also, note that the 16 bits of the EB66 IRR must +// be access as two 8-bit reads. +// +// InterruptMaskRegisterBit: +// On EB66, the PinToLine table may also be find the to write the +// InterruptMaskRegister. Formally, we can express this invariant as +// +// VectorToIMRBit(InterrruptVector) = InterruptVector - 1 +// +// +// IDSEL: +// For accessing PCI configuration space on a local PCI bus (as opposed +// to over a PCI-PCI bridge), type 0 configuration cycles must be generated. +// In this case, the IDSEL pin of the device to be accessed is tied to one +// of the PCI Address lines AD[11] - AD[26]. (The function field in the +// PCI address is used should we be accessing a multifunction device.) +// Anyway, virtual slot 0 represents the device with IDSEL = AD[11], and +// so on. +// + +// +// Interrupt Vector Table Mapping for Alcor. +// +// Alcor PCI interrupts are mapped to arbitrary interrupt numbers +// in the table below. The values are a 1-1 map of the bit numbers +// in the Alcor PCI interrupt register that are connected to PCI +// devices. N.B.: there are two other interrupts in this register, +// but they are not connected to I/O devices, so they're not +// represented in the table. +// +// Limit init table to 14 entries, which is the +// MAX_PCI_LOCAL_DEVICES_MIKASA. +// +// We won't ever try to set an InterruptLine register of a slot +// greater than Virtual slot 13 = PCI_AD[24]. +// +// +// N.B. - Have biased the bus interrupt vectors/levels for PCI to start +// at 0x11 so they are disjoint from EISA levels +// + +ULONG *HalpPCIPinToLineTable; + +ULONG AlcorPCIPinToLineTable[][4]= +{ + +// +// Pin 1 Pin 2 Pin 3 Pin 4 +// ----- ----- ----- ----- +// + + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 0 = PCI_AD[11] + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 1 = PCI_AD[12] + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 2 = PCI_AD[13] + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 3 = PCI_AD[14] + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 4 = PCI_AD[15] + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 5 = PCI_AD[16] + { 0x1e, 0xff, 0xff, 0xff }, // Virtual Slot 6 = PCI_AD[17] Maverick Ethernet Controller + { 0x19, 0x1a, 0x1b, 0x1c }, // Virtual Slot 7 = PCI_AD[18] 64 bit Slot #0 + { 0x21, 0x22, 0x23, 0x24 }, // Virtual Slot 8 = PCI_AD[19] 32 bit Slot #0 + { 0x1d, 0x1e, 0x1f, 0x20 }, // Virtual Slot 9 = PCI_AD[20] 32 bit Slot #1 + { 0xff, 0xff, 0xff, 0xff }, // Virtual Slot 10 = PCI_AD[21] Eisa Bridge + { 0x11, 0x12, 0x13, 0x14 }, // Virtual Slot 11 = PCI_AD[22] 64 bit Slot #2 + { 0x15, 0x16, 0x17, 0x18 }, // Virtual Slot 12 = PCI_AD[23] 64 bit Slot #1 +}; diff --git a/private/ntos/nthals/halxlt/alpha/vga.c b/private/ntos/nthals/halxlt/alpha/vga.c new file mode 100644 index 000000000..764c585af --- /dev/null +++ b/private/ntos/nthals/halxlt/alpha/vga.c @@ -0,0 +1,7 @@ +// +// This file simply includes the source file from the common Alpha +// HAL directory. +// + +#include "..\halalpha\vga.c" + |