/*++ Copyright (c) 1993 Digital Equipment Corporation Module Name: alpha.h Abstract: The Alpha hardware specific header file. Author: Joe Notarangelo 31-Mar-1992 (based on mips.h by Dave Cutler) Revision History: Jeff McLeman (mcleman) 21-Jul-1992 Add bus types for ISA and EISA Thomas Van Baak (tvb) 9-Jul-1992 Created proper Alpha Exception and Trap structure definitions. */ #ifndef _ALPHAH_ #define _ALPHAH_ // begin_ntddk begin_wdm begin_nthal begin_ntndis #if defined(_ALPHA_) #ifdef __cplusplus extern "C" { #endif // Types to use to contain PFNs and their counts. typedef ULONG PFN_COUNT; typedef LONG_PTR SPFN_NUMBER, *PSPFN_NUMBER; typedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER; // Define maximum size of flush multiple TB request. #define FLUSH_MULTIPLE_MAXIMUM 16 // Indicate that the Alpha compiler supports the pragma textout construct. #define ALLOC_PRAGMA 1 // end_ntndis // Include the Alpha instruction definitions #include "alphaops.h" // Include reference machine definitions. #include "alpharef.h" // end_ntddk end_wdm // Define intrinsic PAL calls and their prototypes void __di(void); void __MB(void); void __dtbis(void *); void __ei(void); void *__rdpcr(void); void *__rdthread(void); void __ssir(unsigned long); unsigned char __swpirql(unsigned char); void __tbia(void); void __tbis(void *); void __tbisasn(void *, unsigned long); #if defined(_M_ALPHA) || defined(_M_AXP64) #pragma intrinsic(__di) #pragma intrinsic(__MB) #pragma intrinsic(__dtbis) #pragma intrinsic(__ei) #pragma intrinsic(__rdpcr) #pragma intrinsic(__rdthread) #pragma intrinsic(__ssir) #pragma intrinsic(__swpirql) #pragma intrinsic(__tbia) #pragma intrinsic(__tbis) #pragma intrinsic(__tbisasn) #endif // Define Alpha Axp Processor Ids. #if !defined(PROCESSOR_ALPHA_21064) #define PROCESSOR_ALPHA_21064 (21064) #endif // !PROCESSOR_ALPHA_21064 #if !defined(PROCESSOR_ALPHA_21164) #define PROCESSOR_ALPHA_21164 (21164) #endif // !PROCESSOR_ALPHA_21164 #if !defined(PROCESSOR_ALPHA_21066) #define PROCESSOR_ALPHA_21066 (21066) #endif // !PROCESSOR_ALPHA_21066 #if !defined(PROCESSOR_ALPHA_21068) #define PROCESSOR_ALPHA_21068 (21068) #endif // !PROCESSOR_ALPHA_21068 #if !defined(PROCESSOR_ALPHA_21164PC) #define PROCESSOR_ALPHA_21164PC (21165) #endif // !PROCESSOR_ALPHA_21164PC #if !defined(PROCESSOR_ALPHA_21264) #define PROCESSOR_ALPHA_21264 (21264) #endif // !PROCESSOR_ALPHA_21264 // end_nthal // Define Processor Control Region Structure. typedef VOID (*PKTRAP_ROUTINE)(VOID); // begin_ntddk begin_nthal // Define macro to generate import names. #define IMPORT_NAME(name) __imp_##name // Define length of interrupt vector table. #define MAXIMUM_VECTOR 256 // Define bus error routine type. struct _EXCEPTION_RECORD; struct _KEXCEPTION_FRAME; struct _KTRAP_FRAME; typedef BOOLEAN (*PKBUS_ERROR_ROUTINE) ( IN struct _EXCEPTION_RECORD *ExceptionRecord, IN struct _KEXCEPTION_FRAME *ExceptionFrame, IN struct _KTRAP_FRAME *TrapFrame ); #define PCR_MINOR_VERSION 1 #define PCR_MAJOR_VERSION 1 typedef struct _KPCR { // Major and minor version numbers of the PCR. ULONG MinorVersion; ULONG MajorVersion; // Start of the architecturally defined section of the PCR. This section // may be directly addressed by vendor/platform specific PAL/HAL code and will // not change from version to version of NT. // PALcode information. ULONGLONG PalBaseAddress; ULONG PalMajorVersion; ULONG PalMinorVersion; ULONG PalSequenceVersion; ULONG PalMajorSpecification; ULONG PalMinorSpecification; // Firmware restart information. ULONGLONG FirmwareRestartAddress; PVOID RestartBlock; // Reserved per-processor region for the PAL (3K-8 bytes). ULONGLONG PalReserved[383]; // Alignment fixup count updated by PAL and read by kernel. ULONGLONG PalAlignmentFixupCount; // Panic Stack Address. PVOID PanicStack; // Processor parameters. ULONG ProcessorType; ULONG ProcessorRevision; ULONG PhysicalAddressBits; ULONG MaximumAddressSpaceNumber; ULONG PageSize; ULONG FirstLevelDcacheSize; ULONG FirstLevelDcacheFillSize; ULONG FirstLevelIcacheSize; ULONG FirstLevelIcacheFillSize; // System Parameters. ULONG FirmwareRevisionId; UCHAR SystemType[8]; ULONG SystemVariant; ULONG SystemRevision; UCHAR SystemSerialNumber[16]; ULONG CycleClockPeriod; ULONG SecondLevelCacheSize; ULONG SecondLevelCacheFillSize; ULONG ThirdLevelCacheSize; ULONG ThirdLevelCacheFillSize; ULONG FourthLevelCacheSize; ULONG FourthLevelCacheFillSize; // Pointer to processor control block. struct _KPRCB *Prcb; // Processor identification. CCHAR Number; KAFFINITY SetMember; // Reserved per-processor region for the HAL (.5K bytes). ULONGLONG HalReserved[64]; // IRQL mapping tables. ULONG IrqlTable[8]; #define SFW_IMT_ENTRIES 4 #define HDW_IMT_ENTRIES 128 struct _IRQLMASK { USHORT IrqlTableIndex; // synchronization irql level USHORT IDTIndex; // vector in IDT } IrqlMask[SFW_IMT_ENTRIES + HDW_IMT_ENTRIES]; // Interrupt Dispatch Table (IDT). PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR]; // Reserved vectors mask, these vectors cannot be attached to via // standard interrupt objects. ULONG ReservedVectors; // Complement of processor affinity mask. KAFFINITY NotMember; ULONG InterruptInProgress; ULONG DpcRequested; // Pointer to machine check handler PKBUS_ERROR_ROUTINE MachineCheckError; // DPC Stack. PVOID DpcStack; // End of the architecturally defined section of the PCR. This section // may be directly addressed by vendor/platform specific HAL code and will // not change from version to version of NT. Some of these values are // reserved for chip-specific palcode. // end_ntddk end_nthal // Start of the operating system release dependent section of the PCR. // This section may change from release to release and should not be // addressed by vendor/platform specific HAL code. ULONG Spare1; // Current process id. ULONG CurrentPid; // Spare field. ULONG Spare2; // System service dispatch start and end address used by get/set context. ULONG_PTR SystemServiceDispatchStart; ULONG_PTR SystemServiceDispatchEnd; // Pointer to Idle thread. struct _KTHREAD *IdleThread; } KPCR, *PKPCR; // ntddk nthal // Define Processor Status Register structure typedef struct _PSR { ULONG MODE: 1; ULONG INTERRUPT_ENABLE: 1; ULONG IRQL: 3; } PSR, *PPSR; // Define Interrupt Enable Register structure typedef struct _IE { ULONG SoftwareInterruptEnables: 2; ULONG HardwareInterruptEnables: 6; } IE, *PIE; #define HARDWARE_PTE_DIRTY_MASK 0x4 #if defined(_AXP64_) #define _HARDWARE_PTE_WORKING_SET_BITS 14 typedef struct _HARDWARE_PTE { ULONGLONG Valid : 1; ULONGLONG Reserved1 : 1; ULONGLONG FaultOnWrite : 1; ULONGLONG Reserved2 : 1; ULONGLONG Global : 1; ULONGLONG GranularityHint : 2; ULONGLONG Reserved3 : 1; ULONGLONG KernelReadAccess : 1; ULONGLONG UserReadAccess : 1; ULONGLONG Reserved4 : 2; ULONGLONG KernelWriteAccess : 1; ULONGLONG UserWriteAccess : 1; ULONGLONG Reserved5 : 2; ULONGLONG Write : 1; ULONGLONG CopyOnWrite: 1; ULONGLONG SoftwareWsIndex : _HARDWARE_PTE_WORKING_SET_BITS; ULONGLONG PageFrameNumber : 32; } HARDWARE_PTE, *PHARDWARE_PTE; // Define initialize page directory base #define INITIALIZE_DIRECTORY_TABLE_BASE(dirbase, pfn) \ *((PULONGLONG)(dirbase)) = 0; \ ((PHARDWARE_PTE)(dirbase))->PageFrameNumber = pfn; \ ((PHARDWARE_PTE)(dirbase))->Write = 1; \ ((PHARDWARE_PTE)(dirbase))->KernelReadAccess = 1; \ ((PHARDWARE_PTE)(dirbase))->KernelWriteAccess = 1; \ ((PHARDWARE_PTE)(dirbase))->Global = 0; \ ((PHARDWARE_PTE)(dirbase))->FaultOnWrite = 0; \ ((PHARDWARE_PTE)(dirbase))->Valid = 1; #else typedef struct _HARDWARE_PTE { ULONG Valid: 1; ULONG Owner: 1; ULONG Dirty: 1; ULONG reserved: 1; ULONG Global: 1; ULONG GranularityHint: 2; ULONG Write: 1; ULONG CopyOnWrite: 1; ULONG PageFrameNumber: 23; } HARDWARE_PTE, *PHARDWARE_PTE; // Define initialize page directory base #define INITIALIZE_DIRECTORY_TABLE_BASE(dirbase, pfn) \ ((PHARDWARE_PTE)(dirbase))->PageFrameNumber = pfn; \ ((PHARDWARE_PTE)(dirbase))->Global = 0; \ ((PHARDWARE_PTE)(dirbase))->Dirty = 1; \ ((PHARDWARE_PTE)(dirbase))->Valid = 1; #endif // begin_nthal // Define some constants for bus type #define MACHINE_TYPE_ISA 0 #define MACHINE_TYPE_EISA 2 // Define pointer to Processor Control Registers #define PCR ((PKPCR)__rdpcr()) // begin_ntddk #if defined(_AXP64_) #define KI_USER_SHARED_DATA 0xffffffffff000000UI64 #else #define KI_USER_SHARED_DATA 0xff000000UL #endif #define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA) // begin_wdm // length of dispatch code in interrupt template #define DISPATCH_LENGTH 4 // Define IRQL levels across the architecture. #define PASSIVE_LEVEL 0 #define LOW_LEVEL 0 #define APC_LEVEL 1 #define DISPATCH_LEVEL 2 #define HIGH_LEVEL 7 #define SYNCH_LEVEL (IPI_LEVEL-1) // end_ntddk end_wdm end_nthal #define KiProfileIrql PROFILE_LEVEL // enable portable code // Define interrupt levels that cannot be connected #define ILLEGAL_LEVEL ( (1<<0) | (1<PreviousMode) #define KeGetDcacheFillSize() PCR->FirstLevelDcacheFillSize // Test if executing DPC. BOOLEAN KeIsExecutingDpc (VOID); // Return interrupt trap frame PKTRAP_FRAME KeGetInterruptTrapFrame(VOID); // begin_ntddk // Get address of current PRCB. #define KeGetCurrentPrcb() (PCR->Prcb) // Get current processor number. #define KeGetCurrentProcessorNumber() KeGetCurrentPrcb()->Number // end_ntddk // Define interface to get pcr address PKPCR KeGetPcr(VOID); // end_nthal // Data cache, instruction cache, I/O buffer, and write buffer flush routine prototypes. VOID KeSweepDcache (IN BOOLEAN AllProcessors); #define KeSweepCurrentDcache() HalSweepDcache(); VOID KeSweepIcache (IN BOOLEAN AllProcessors); VOID KeSweepIcacheRange (IN BOOLEAN AllProcessors, IN PVOID BaseAddress, IN ULONG_PTR Length); #define KeSweepCurrentIcache() HalSweepIcache(); VOID KeFlushIcacheRange (IN BOOLEAN AllProcessors, IN PVOID BaseAddress, IN ULONG_PTR Length); // begin_ntddk begin_wdm begin_ntndis begin_nthal // Cache and write buffer flush functions. VOID KeFlushIoBuffers (IN PMDL Mdl, IN BOOLEAN ReadOperation, IN BOOLEAN DmaOperation); // end_ntddk end_wdm end_ntndis // Clock, profile, and interprocessor interrupt functions. struct _KEXCEPTION_FRAME; struct _KTRAP_FRAME; NTKERNELAPI VOID KeIpiInterrupt (IN struct _KTRAP_FRAME *TrapFrame); #define KeYieldProcessor() NTKERNELAPI VOID KeProfileInterrupt (VOID); NTKERNELAPI VOID KeProfileInterruptWithSource (IN KPROFILE_SOURCE ProfileSource); NTKERNELAPI VOID KeUpdateRunTime (VOID); NTKERNELAPI VOID KeUpdateSystemTime (IN ULONG TimeIncrement); // The following function prototypes are exported for use in MP HALs. #if defined(NT_UP) #define KiAcquireSpinLock(SpinLock) #else VOID KiAcquireSpinLock (IN PKSPIN_LOCK SpinLock); #endif #if defined(NT_UP) #define KiReleaseSpinLock(SpinLock) #else VOID KiReleaseSpinLock (IN PKSPIN_LOCK SpinLock); #endif // end_nthal // KeTestSpinLock may be used to spin at low IRQL until the lock is available. // The IRQL must then be raised and the lock acquired with KeTryToAcquireSpinLock. // If that fails, lower the IRQL and start again. #if defined(NT_UP) #define KeTestSpinLock(SpinLock) (TRUE) #else BOOLEAN KeTestSpinLock (IN PKSPIN_LOCK SpinLock); #endif // Fill TB entry. #define KeFillEntryTb(Pte, Virtual, Invalid) \ if (Invalid != FALSE) { \ KeFlushSingleTb(Virtual, FALSE, FALSE, Pte, *Pte); \ } // Define machine-specific external references. extern ULONG KiInterruptTemplate[]; // Define machine-dependent function prototypes. VOID KeFlushDcache (IN BOOLEAN AllProcessors, IN PVOID BaseAddress OPTIONAL, IN ULONG Length); ULONG KiCopyInformation (IN OUT PEXCEPTION_RECORD ExceptionRecord1, IN PEXCEPTION_RECORD ExceptionRecord2); BOOLEAN KiEmulateByteWord(IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT struct _KEXCEPTION_FRAME *ExceptionFrame, IN OUT struct _KTRAP_FRAME *TrapFrame); BOOLEAN KiEmulateFloating (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT struct _KEXCEPTION_FRAME *ExceptionFrame, IN OUT struct _KTRAP_FRAME *TrapFrame, IN OUT PSW_FPCR SoftwareFpcr); BOOLEAN KiEmulateReference (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT struct _KEXCEPTION_FRAME *ExceptionFrame, IN OUT struct _KTRAP_FRAME *TrapFrame, IN BOOLEAN QuadwordOnly); BOOLEAN KiFloatingException (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT struct _KEXCEPTION_FRAME *ExceptionFrame, IN OUT struct _KTRAP_FRAME *TrapFrame, IN BOOLEAN ImpreciseTrap, OUT PULONG SoftFpcrCopy); ULONGLONG KiGetRegisterValue (IN ULONG Register, IN struct _KEXCEPTION_FRAME *ExceptionFrame, IN struct _KTRAP_FRAME *TrapFrame); VOID KiSetFloatingStatus (IN OUT PEXCEPTION_RECORD ExceptionRecord); VOID KiSetRegisterValue (IN ULONG Register, IN ULONGLONG Value, OUT struct _KEXCEPTION_FRAME *ExceptionFrame, OUT struct _KTRAP_FRAME *TrapFrame); VOID KiRequestSoftwareInterrupt (KIRQL RequestIrql); // Define query system time macro. #if _AXP64_ #define KiQuerySystemTime(CurrentTime) \ while (TRUE) { \ (CurrentTime)->HighPart = SharedUserData->SystemHigh1Time; \ (CurrentTime)->LowPart = SharedUserData->SystemLowTime; \ if ((CurrentTime)->HighPart == SharedUserData->SystemHigh2Time) break; \ } #else #define KiQuerySystemTime(CurrentTime) *(PULONGLONG)(CurrentTime) = SharedUserData->SystemTime #endif // Define query tick count macro. #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) // begin_wdm begin_ntddk #define KeQueryTickCount(CurrentCount ) *(PULONGLONG)(CurrentCount) = **((volatile ULONGLONG **)(&KeTickCount)); // end_wdm end_ntddk #else // begin_nthal #define KiQueryTickCount(CurrentCount) *(PULONGLONG)(CurrentCount) = KeTickCount; VOID KeQueryTickCount (OUT PLARGE_INTEGER CurrentCount); // end_nthal #endif #define KiQueryLowTickCount() (ULONG)KeTickCount #define KiQueryInterruptTime(CurrentTime) *(PULONGLONG)(CurrentTime) = SharedUserData->InterruptTime // Define executive macros for acquiring and releasing executive spinlocks. // These macros can ONLY be used by executive components and NOT by drivers. // Drivers MUST use the kernel interfaces since they must be MP enabled on all systems. // KeRaiseIrql is one instruction shorter than KeAcquireSpinLock on Alpha UP. // KeLowerIrql is one instruction shorter than KeReleaseSpinLock. #if defined(NT_UP) && !defined(_NTDDK_) && !defined(_NTIFS_) #define ExAcquireSpinLock(Lock, OldIrql) KeRaiseIrql(DISPATCH_LEVEL, (OldIrql)) #define ExReleaseSpinLock(Lock, OldIrql) KeLowerIrql((OldIrql)) #define ExAcquireSpinLockAtDpcLevel(Lock) #define ExReleaseSpinLockFromDpcLevel(Lock) #else // begin_wdm begin_ntddk #define ExAcquireSpinLock(Lock, OldIrql) KeAcquireSpinLock((Lock), (OldIrql)) #define ExReleaseSpinLock(Lock, OldIrql) KeReleaseSpinLock((Lock), (OldIrql)) #define ExAcquireSpinLockAtDpcLevel(Lock) KeAcquireSpinLockAtDpcLevel(Lock) #define ExReleaseSpinLockFromDpcLevel(Lock) KeReleaseSpinLockFromDpcLevel(Lock) // end_wdm end_ntddk #endif // The acquire and release fast lock macros disable and enable interrupts on UP nondebug systems. On MP or debug systems, the spinlock routines are used. // N.B. Extreme caution should be observed when using these routines. #if defined(_M_ALPHA) #define _disable() __di() #define _enable() __ei() #endif #if defined(NT_UP) && !DBG #define ExAcquireFastLock(Lock, OldIrql) ExAcquireSpinLock(Lock, OldIrql) #else #define ExAcquireFastLock(Lock, OldIrql) ExAcquireSpinLock(Lock, OldIrql) #endif #if defined(NT_UP) && !DBG #define ExReleaseFastLock(Lock, OldIrql) ExReleaseSpinLock(Lock, OldIrql) #else #define ExReleaseFastLock(Lock, OldIrql) ExReleaseSpinLock(Lock, OldIrql) #endif // Alpha function definitions // BOOLEAN KiIsThreadNumericStateSaved(IN PKTHREAD Address) // This call is used on a not running thread to see if it's numeric state has been saved in its context information. // On Alpha the numeric state is always saved. #define KiIsThreadNumericStateSaved(a) TRUE // VOID KiRundownThread(IN PKTHREAD Address) #define KiRundownThread(a) // Alpha Feature bit definitions #define KF_BYTE 0x00000001 // Define macro to test if x86 feature is present. // N.B. All x86 features test TRUE on Alpha systems. #define Isx86FeaturePresent(_f_) TRUE // begin_ntddk begin_wdm begin_nthal begin_ntndis #ifdef __cplusplus } // extern "C" #endif #endif // _ALPHA_ // end_ntddk end_wdm end_nthal end_ntndis #endif // _ALPHAH_