/*++

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 begin_ntosp

#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_wdm
#define POWER_LEVEL  7

// end_ntndis end_ntosp
// begin_wdm
//
// 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.
//
// begin_ntosp

#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

// end_ntosp
// 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
//

// begin_ntddk

#define PCR ((PKPCR)__rdpcr())

// begin_ntosp

#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 end_ntosp

#define KiProfileIrql PROFILE_LEVEL     // enable portable code

//
// Define interrupt levels that cannot be connected
//

#define ILLEGAL_LEVEL  ( (1<<0) | (1<<APC_LEVEL) | (1<<DISPATCH_LEVEL) | \
                         (1<<CLOCK_LEVEL) | (1<<IPI_LEVEL) )
//
// Sanitize FPCR and PSR based on processor mode.
//
// ## tvb&jn - need to replace these with proper macros.
//

#define SANITIZE_FPCR(fpcr, mode) (fpcr)

//
// Define SANITIZE_PSR for Alpha.
//
// If kernel mode, then caller specifies  psr
//
// If user mode, then
//      force mode bit to user (1)
//      force interrupt enable bit to true (1)
//      force irql to 0
//
// In both cases insure that extraneous bits are not set
//

#define SANITIZE_PSR(psr, mode) \
    ( ((mode) == KernelMode) ?  \
        (psr & 0x3f) :          \
        (0x3) )

// begin_nthal begin_ntosp
//
// Exception frame
//
//  This frame is established when handling an exception. It provides a place
//  to save all nonvolatile registers. The volatile registers will already
//  have been saved in a trap frame.
//
//  The layout of the record conforms to a standard call frame since it is
//  used as such. Thus it contains a place to save a return address and is
//  padded so that it is EXACTLY a multiple of 32 bytes in length.
//
//
//  N.B - the 32-byte alignment is more stringent than required by the
//  calling standard (which requires 16-byte alignment), the 32-byte alignment
//  is established for performance reasons in the interaction with the PAL.
//

typedef struct _KEXCEPTION_FRAME {

    ULONGLONG IntRa;    // return address register, ra

    ULONGLONG FltF2;    // nonvolatile floating registers, f2 - f9
    ULONGLONG FltF3;
    ULONGLONG FltF4;
    ULONGLONG FltF5;
    ULONGLONG FltF6;
    ULONGLONG FltF7;
    ULONGLONG FltF8;
    ULONGLONG FltF9;

    ULONGLONG IntS0;    //  nonvolatile integer registers, s0 - s5
    ULONGLONG IntS1;
    ULONGLONG IntS2;
    ULONGLONG IntS3;
    ULONGLONG IntS4;
    ULONGLONG IntS5;
    ULONGLONG IntFp;    // frame pointer register, fp/s6

    ULONGLONG SwapReturn;
    ULONG Psr;          // processor status
    ULONG Fill[5];      // padding for 32-byte stack frame alignment
                        // N.B. - Ulongs from the filler section are used
                        //        in ctxsw.s - do not delete

} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;

// end_ntosp

//
// Trap Frame
//
//  This frame is established when handling a trap. It provides a place to
//  save all volatile registers. The nonvolatile registers are saved in an
//  exception frame or through the normal C calling conventions for saved
//  registers.
//
//  The layout of the record conforms to a standard call frame since it is
//  used as such. Thus it contains a place to save a return address and is
//  padded so that it is EXACTLY a multiple of 32 bytes in length.
//
//
//  N.B - the 32-byte alignment is more stringent than required by the
//  calling standard (which requires 16-byte alignment), the 32-byte alignment
//  is established for performance reasons in the interaction with the PAL.
//

typedef struct _KTRAP_FRAME {

    //
    // Fields saved in the PALcode.
    //

    ULONGLONG IntSp;    // $30: stack pointer register, sp
    ULONGLONG Fir;      // (fault instruction) continuation address
    ULONG Psr;          // processor status
    ULONG Fill1[1];     // unused
    ULONGLONG IntFp;    // $15: frame pointer register, fp/s6

    ULONGLONG IntA0;    // $16: argument registers, a0 - a3
    ULONGLONG IntA1;    // $17:
    ULONGLONG IntA2;    // $18:
    ULONGLONG IntA3;    // $19:

    ULONGLONG IntRa;    // $26: return address register, ra
    ULONGLONG IntGp;    // $29: global pointer register, gp
    UCHAR ExceptionRecord[(sizeof(EXCEPTION_RECORD) + 15) & (~15)];

    //
    // Volatile integer registers, s0 - s5 are nonvolatile.
    //

    ULONGLONG IntV0;    //  $0: return value register, v0
    ULONGLONG IntT0;    //  $1: temporary registers, t0 - t7
    ULONGLONG IntT1;    //  $2:
    ULONGLONG IntT2;    //  $3:
    ULONGLONG IntT3;    //  $4:
    ULONGLONG IntT4;    //  $5:
    ULONGLONG IntT5;    //  $6:
    ULONGLONG IntT6;    //  $7:
    ULONGLONG IntT7;    //  $8:

    ULONGLONG IntT8;    // $22: temporary registers, t8 - t11
    ULONGLONG IntT9;    // $23:
    ULONGLONG IntT10;   // $24:
    ULONGLONG IntT11;   // $25:

    ULONGLONG IntT12;   // $27: temporary register, t12
    ULONGLONG IntAt;    // $28: assembler temporary register, at

    ULONGLONG IntA4;    // $20: remaining argument registers a4 - a5
    ULONGLONG IntA5;    // $21:

    //
    // Volatile floating point registers, f2 - f9 are nonvolatile.
    //

    ULONGLONG FltF0;    // $f0:
    ULONGLONG Fpcr;     // floating point control register
    ULONGLONG FltF1;    // $f1:

    ULONGLONG FltF10;   // $f10: temporary registers, $f10 - $f30
    ULONGLONG FltF11;   // $f11:
    ULONGLONG FltF12;   // $f12:
    ULONGLONG FltF13;   // $f13:
    ULONGLONG FltF14;   // $f14:
    ULONGLONG FltF15;   // $f15:
    ULONGLONG FltF16;   // $f16:
    ULONGLONG FltF17;   // $f17:
    ULONGLONG FltF18;   // $f18:
    ULONGLONG FltF19;   // $f19:
    ULONGLONG FltF20;   // $f20:
    ULONGLONG FltF21;   // $f21:
    ULONGLONG FltF22;   // $f22:
    ULONGLONG FltF23;   // $f23:
    ULONGLONG FltF24;   // $f24:
    ULONGLONG FltF25;   // $f25:
    ULONGLONG FltF26;   // $f26:
    ULONGLONG FltF27;   // $f27:
    ULONGLONG FltF28;   // $f28:
    ULONGLONG FltF29;   // $f29:
    ULONGLONG FltF30;   // $f30:

    ULONG OldIrql;      // Previous Irql.
    ULONG PreviousMode; // Previous Mode.
    ULONG_PTR TrapFrame; //
    ULONG Fill2[3];     // padding for 32-byte stack frame alignment

} KTRAP_FRAME, *PKTRAP_FRAME;

#define KTRAP_FRAME_LENGTH ((sizeof(KTRAP_FRAME) + 15) & ~15)
#define KTRAP_FRAME_ALIGN (16)
#define KTRAP_FRAME_ROUND (KTRAP_FRAME_ALIGN - 1)

//
// Firmware Frame
//
//  The firmware frame is similar to the trap frame, but is built by the PAL
//  code that is active when the OS Loader is running. It does not contain an
//  exception record or NT style exception information.
//
//  Type field defintions and parameters.
//

#define FW_EXC_MCHK 0xdec0              // p1=icPerrStat, p2=dcPerrStat
#define FW_EXC_ARITH 0xdec1             // p1=excSum, p2=excMask
#define FW_EXC_INTERRUPT 0xdec2         // p1=isr, p2=ipl, p3=intid
#define FW_EXC_DFAULT 0xdec3            // p1=sp
#define FW_EXC_ITBMISS 0xdec4           // none
#define FW_EXC_ITBACV 0xdec5            // none
#define FW_EXC_NDTBMISS 0xdec6          // p1=sp
#define FW_EXC_PDTBMISS 0xdec7          // p1=sp
#define FW_EXC_UNALIGNED 0xdec8         // p1=sp
#define FW_EXC_OPCDEC 0xdec9            // p1=sp
#define FW_EXC_FEN 0xdeca               // p1=icsr
#define FW_EXC_HALT 0xdecb              // not used
#define FW_EXC_BPT 0xdecc               // p1=0 - user, p1=1 - kernel, p1=type - call kdbg
#define FW_EXC_GENTRAP 0xdecd           // p1=gentrap code
#define FW_EXC_HALT_INTERRUPT 0xdece    // p1=isr, p2=ipl, p3=intid

typedef struct _FIRMWARE_FRAME {
    ULONGLONG Type;
    ULONGLONG Param1;
    ULONGLONG Param2;
    ULONGLONG Param3;
    ULONGLONG Param4;
    ULONGLONG Param5;
    ULONGLONG Psr;
    ULONGLONG Mmcsr;
    ULONGLONG Va;
    ULONGLONG Fir;
    ULONGLONG IntV0;
    ULONGLONG IntT0;
    ULONGLONG IntT1;
    ULONGLONG IntT2;
    ULONGLONG IntT3;
    ULONGLONG IntT4;
    ULONGLONG IntT5;
    ULONGLONG IntT6;
    ULONGLONG IntT7;
    ULONGLONG IntS0;
    ULONGLONG IntS1;
    ULONGLONG IntS2;
    ULONGLONG IntS3;
    ULONGLONG IntS4;
    ULONGLONG IntS5;
    ULONGLONG IntFp;
    ULONGLONG IntA0;
    ULONGLONG IntA1;
    ULONGLONG IntA2;
    ULONGLONG IntA3;
    ULONGLONG IntA4;
    ULONGLONG IntA5;
    ULONGLONG IntT8;
    ULONGLONG IntT9;
    ULONGLONG IntT10;
    ULONGLONG IntT11;
    ULONGLONG IntRa;
    ULONGLONG IntT12;
    ULONGLONG IntAt;
    ULONGLONG IntGp;
    ULONGLONG IntSp;
    ULONGLONG IntZero;
    ULONGLONG FltF0;
    ULONGLONG FltF1;
    ULONGLONG FltF2;
    ULONGLONG FltF3;
    ULONGLONG FltF4;
    ULONGLONG FltF5;
    ULONGLONG FltF6;
    ULONGLONG FltF7;
    ULONGLONG FltF8;
    ULONGLONG FltF9;
    ULONGLONG FltF10;
    ULONGLONG FltF11;
    ULONGLONG FltF12;
    ULONGLONG FltF13;
    ULONGLONG FltF14;
    ULONGLONG FltF15;
    ULONGLONG FltF16;
    ULONGLONG FltF17;
    ULONGLONG FltF18;
    ULONGLONG FltF19;
    ULONGLONG FltF20;
    ULONGLONG FltF21;
    ULONGLONG FltF22;
    ULONGLONG FltF23;
    ULONGLONG FltF24;
    ULONGLONG FltF25;
    ULONGLONG FltF26;
    ULONGLONG FltF27;
    ULONGLONG FltF28;
    ULONGLONG FltF29;
    ULONGLONG FltF30;
    ULONGLONG FltF31;
} FIRMWARE_FRAME, *PFIRMWARE_FRAME;

#define FIRMWARE_FRAME_LENGTH sizeof(FIRMWARE_FRAME)

//
// The frame saved by KiCallUserMode is defined here to allow
// the kernel debugger to trace the entire kernel stack
// when usermode callouts are pending.
//

typedef struct _KCALLOUT_FRAME {
    ULONGLONG   F2;   // saved floating registers f2 - f9
    ULONGLONG   F3;
    ULONGLONG   F4;
    ULONGLONG   F5;
    ULONGLONG   F6;
    ULONGLONG   F7;
    ULONGLONG   F8;
    ULONGLONG   F9;
    ULONGLONG   S0;   // saved integer registers s0 - s5
    ULONGLONG   S1;
    ULONGLONG   S2;
    ULONGLONG   S3;
    ULONGLONG   S4;
    ULONGLONG   S5;
    ULONGLONG   FP;
    ULONGLONG   CbStk;  // saved callback stack address
    ULONGLONG   InStk;  // saved initial stack address
    ULONGLONG   TrFr;   // saved callback trap frame address
    ULONGLONG   TrFir;
    ULONGLONG   Ra;     // saved return address
    ULONGLONG   A0;     // saved argument registers a0-a2
    ULONGLONG   A1;
} KCALLOUT_FRAME, *PKCALLOUT_FRAME;

typedef struct _UCALLOUT_FRAME {
    PVOID Buffer;
    ULONG Length;
    ULONG ApiNumber;
    ULONG Pad;
    ULONGLONG Sp;
    ULONGLONG Ra;
} UCALLOUT_FRAME, *PUCALLOUT_FRAME;

//
// Define Machine Check Status code that is passed in the exception
// record for a machine check exception.
//

typedef struct _MCHK_STATUS {
    ULONG Correctable: 1;
    ULONG Retryable: 1;
} MCHK_STATUS, *PMCHK_STATUS;

//
// Define the MCES register (Machine Check Error Summary).
//

typedef struct _MCES {
    ULONG MachineCheck: 1;
    ULONG SystemCorrectable: 1;
    ULONG ProcessorCorrectable: 1;
    ULONG DisableProcessorCorrectable: 1;
    ULONG DisableSystemCorrectable: 1;
    ULONG DisableMachineChecks: 1;
} MCES, *PMCES;

// end_nthal

// begin_ntddk begin_wdm begin_ntosp
//
// Non-volatile floating point state
//

typedef struct _KFLOATING_SAVE {
    ULONGLONG   Fpcr;
    ULONGLONG   SoftFpcr;
    ULONG       Reserved1;              // These reserved words are here to make it
    ULONG       Reserved2;              // the same size as i386/WDM.
    ULONG       Reserved3;
    ULONG       Reserved4;
} KFLOATING_SAVE, *PKFLOATING_SAVE;

// end_ntddk end_wdm end_ntosp
//
// Define Alpha status code aliases. These are internal to PALcode and
// kernel trap handling.
//

#define STATUS_ALPHA_FLOATING_NOT_IMPLEMENTED    STATUS_ILLEGAL_FLOAT_CONTEXT
#define STATUS_ALPHA_ARITHMETIC_EXCEPTION    STATUS_FLOAT_STACK_CHECK
#define STATUS_ALPHA_GENTRAP    STATUS_INSTRUCTION_MISALIGNMENT

//
// Define status code for bad virtual address.  This status differs from
// those above in that it will be forwarded to the offending code.  In lieu
// of defining a new status code, we wlll alias this to an access violation.
// Code can distinguish this error from an access violation by checking
// the number of parameters: a standard access violation has 2 parameters,
// while a non-canonical virtual address access violation will have 3
// parameters (the third parameter is the upper 32-bits of the non-canonical
// virtual address.
//

#define STATUS_ALPHA_BAD_VIRTUAL_ADDRESS    STATUS_ACCESS_VIOLATION

// begin_nthal begin_ntosp
//
// Define the halt reason codes.
//

#define AXP_HALT_REASON_HALT 0
#define AXP_HALT_REASON_REBOOT 1
#define AXP_HALT_REASON_RESTART 2
#define AXP_HALT_REASON_POWERFAIL 3
#define AXP_HALT_REASON_POWEROFF 4
#define AXP_HALT_REASON_PALMCHK 6
#define AXP_HALT_REASON_DBLMCHK 7

// Processor State frame: Before a processor freezes itself, it
// dumps the processor state to the processor state frame for
// debugger to examine.  This is used by KeFreezeExecution and
// KeUnfreezeExecution routines.
//

typedef struct _KPROCESSOR_STATE {
    struct _CONTEXT ContextFrame;
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;

// begin_ntddk
//
// Processor Control Block (PRCB)
//

#define PRCB_MINOR_VERSION 1
#define PRCB_MAJOR_VERSION 2
#define PRCB_BUILD_DEBUG        0x0001
#define PRCB_BUILD_UNIPROCESSOR 0x0002

typedef struct _KPRCB {

//
// Major and minor version numbers of the PCR.
//

    USHORT MinorVersion;
    USHORT MajorVersion;

//
// Start of the architecturally defined section of the PRCB. This section
// may be directly addressed by vendor/platform specific HAL code and will
// not change from version to version of NT.
//

    struct _KTHREAD *CurrentThread;
    struct _KTHREAD *NextThread;
    struct _KTHREAD *IdleThread;
    CCHAR Number;
    CCHAR Reserved;
    USHORT BuildType;
    KAFFINITY SetMember;
    struct _RESTART_BLOCK *RestartBlock;

//
// End of the architecturally defined section of the PRCB. This section
// may be directly addressed by vendor/platform specific HAL code and will
// not change from version to version of NT.
//
// end_ntddk end_nthal

    ULONG InterruptCount;
    ULONG DpcTime;
    ULONG InterruptTime;
    ULONG KernelTime;
    ULONG UserTime;
    KDPC QuantumEndDpc;

//
// Address of PCR.
//

    PKPCR Pcr;

//
// MP Information.
//

    struct _KNODE * ParentNode;         // Node this processor is a member of
    PVOID Spare3;
    volatile ULONG IpiFrozen;
    struct _KPROCESSOR_STATE ProcessorState;
    ULONG LastDpcCount;
    ULONG DpcBypassCount;
    ULONG SoftwareInterrupts;
    PKTRAP_FRAME InterruptTrapFrame;
    ULONG ApcBypassCount;
    ULONG DispatchInterruptCount;
    ULONG DebugDpcTime;
    PVOID Spares[6];

//
// Spares.
//

    PVOID MoreSpares[3];
    PKIPI_COUNTS IpiCounts;

//
// Per-processor data for various hot code which resides in the
// kernel image.  We give each processor it's own copy of the data
// to lessen the caching impact of sharing the data between multiple
// processors.
//

//
//  Spares (formerly fsrtl filelock free lists)
//

    PVOID SpareHotData[2];

//
// Cache manager performance counters.
//

    ULONG CcFastReadNoWait;
    ULONG CcFastReadWait;
    ULONG CcFastReadNotPossible;
    ULONG CcCopyReadNoWait;
    ULONG CcCopyReadWait;
    ULONG CcCopyReadNoWaitMiss;

//
// Kernel performance counters.
//

    ULONG KeAlignmentFixupCount;
    ULONG KeContextSwitches;
    ULONG KeDcacheFlushCount;
    ULONG KeExceptionDispatchCount;
    ULONG KeFirstLevelTbFills;
    ULONG KeFloatingEmulationCount;
    ULONG KeIcacheFlushCount;
    ULONG KeSecondLevelTbFills;
    ULONG KeSystemCalls;
    ULONG KeByteWordEmulationCount;

//
//  Reserved for future counters.
//

    ULONG ReservedCounter[1];

//
// I/O system per processor single entry lookaside lists.
//

    PVOID SmallIrpFreeEntry;
    PVOID LargeIrpFreeEntry;
    PVOID MdlFreeEntry;

//
// Object manager per processor single entry lookaside lists.
//

    PVOID CreateInfoFreeEntry;
    PVOID NameBufferFreeEntry;

//
// Cache manager per processor single entry lookaside lists.
//

    PVOID SharedCacheMapEntry;

//
//  Spares (formerly fsrtl filelock free lists)
//

#if defined(_AXP64_)

    PVOID MoreSpareHotData[1];

#else

    PVOID MoreSpareHotData[2];

#endif

//
// Nonpaged per processor lookaside lists.
//

    PP_LOOKASIDE_LIST PPLookasideList[16];

//
// Nonpaged per processor small pool lookaside lists.
//

    PP_LOOKASIDE_LIST PPNPagedLookasideList[POOL_SMALL_LISTS];

//
// Paged per processor small pool lookaside lists.
//

    PP_LOOKASIDE_LIST PPPagedLookasideList[POOL_SMALL_LISTS];

//
// Per processor lock queue entries.
//

    KSPIN_LOCK_QUEUE LockQueue[16];

//
// Reserved Pad.
//

#if defined(_AXP64_)

    UCHAR ReservedPad[(20 * 8) - 4];

#else

    UCHAR ReservedPad[(24 * 8) - 4];

#endif

//
// MP interprocessor request packet barrier.
//
// N.B. This is carefully allocated in a different cache line from
//      the request packet.
//

   volatile ULONG PacketBarrier;

//
// MP interprocessor request packet and summary.
//
// N.B. This is carefully aligned to be on a cache line boundary.
//

    volatile PVOID CurrentPacket[3];
    volatile KAFFINITY TargetSet;
    volatile PKIPI_WORKER WorkerRoutine;
    ULONG CachePad1[11];

//
// N.B. These two longwords must be on a quadword boundary and adjacent.
//

    volatile ULONGLONG RequestSummary;

//
// Spare counters.
//

    ULONG Spare4[14];
    ULONG DpcInterruptRequested;
    ULONG Spare5[17];
    ULONG CachePad2[1];
    ULONG PageColor;
    ULONG MaximumDpcQueueDepth;
    ULONG MinimumDpcRate;
    ULONG AdjustDpcThreshold;
    ULONG DpcRequestRate;
    LARGE_INTEGER StartCount;
//
// DPC list head, spinlock, and count.
//

    LIST_ENTRY DpcListHead;
    KSPIN_LOCK DpcLock;
    ULONG DpcCount;
    ULONG QuantumEnd;
    ULONG DpcRoutineActive;
    ULONG DpcQueueDepth;

    BOOLEAN SkipTick;

//
// Processor's power state
//
    PROCESSOR_POWER_STATE PowerState;

} KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB;      // ntddk nthal

// begin_ntddk begin_wdm begin_nthal begin_ntndis
//
// I/O space read and write macros.
//
//  These have to be actual functions on Alpha, because we need
//  to shift the VA and OR in the BYTE ENABLES.
//
//  These can become INLINEs if we require that ALL Alpha systems shift
//  the same number of bits and have the SAME byte enables.
//
//  The READ/WRITE_REGISTER_* calls manipulate I/O registers in MEMORY space?
//
//  The READ/WRITE_PORT_* calls manipulate I/O registers in PORT space?
//

NTHALAPI
UCHAR
READ_REGISTER_UCHAR(
    PUCHAR Register
    );

NTHALAPI
USHORT
READ_REGISTER_USHORT(
    PUSHORT Register
    );

NTHALAPI
ULONG
READ_REGISTER_ULONG(
    PULONG Register
    );

NTHALAPI
VOID
READ_REGISTER_BUFFER_UCHAR(
    PUCHAR  Register,
    PUCHAR  Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
READ_REGISTER_BUFFER_USHORT(
    PUSHORT Register,
    PUSHORT Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
READ_REGISTER_BUFFER_ULONG(
    PULONG  Register,
    PULONG  Buffer,
    ULONG   Count
    );


NTHALAPI
VOID
WRITE_REGISTER_UCHAR(
    PUCHAR Register,
    UCHAR   Value
    );

NTHALAPI
VOID
WRITE_REGISTER_USHORT(
    PUSHORT Register,
    USHORT  Value
    );

NTHALAPI
VOID
WRITE_REGISTER_ULONG(
    PULONG Register,
    ULONG   Value
    );

NTHALAPI
VOID
WRITE_REGISTER_BUFFER_UCHAR(
    PUCHAR  Register,
    PUCHAR  Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
WRITE_REGISTER_BUFFER_USHORT(
    PUSHORT Register,
    PUSHORT Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
WRITE_REGISTER_BUFFER_ULONG(
    PULONG  Register,
    PULONG  Buffer,
    ULONG   Count
    );

NTHALAPI
UCHAR
READ_PORT_UCHAR(
    PUCHAR Port
    );

NTHALAPI
USHORT
READ_PORT_USHORT(
    PUSHORT Port
    );

NTHALAPI
ULONG
READ_PORT_ULONG(
    PULONG  Port
    );

NTHALAPI
VOID
READ_PORT_BUFFER_UCHAR(
    PUCHAR  Port,
    PUCHAR  Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
READ_PORT_BUFFER_USHORT(
    PUSHORT Port,
    PUSHORT Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
READ_PORT_BUFFER_ULONG(
    PULONG  Port,
    PULONG  Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
WRITE_PORT_UCHAR(
    PUCHAR  Port,
    UCHAR   Value
    );

NTHALAPI
VOID
WRITE_PORT_USHORT(
    PUSHORT Port,
    USHORT  Value
    );

NTHALAPI
VOID
WRITE_PORT_ULONG(
    PULONG  Port,
    ULONG   Value
    );

NTHALAPI
VOID
WRITE_PORT_BUFFER_UCHAR(
    PUCHAR  Port,
    PUCHAR  Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
WRITE_PORT_BUFFER_USHORT(
    PUSHORT Port,
    PUSHORT Buffer,
    ULONG   Count
    );

NTHALAPI
VOID
WRITE_PORT_BUFFER_ULONG(
    PULONG  Port,
    PULONG  Buffer,
    ULONG   Count
    );

// end_ntndis end_wdm
//
// Define Interlocked operation result values.
//

#define RESULT_ZERO 0
#define RESULT_NEGATIVE 1
#define RESULT_POSITIVE 2

//
// Interlocked result type is portable, but its values are machine specific.
// Constants for value are in i386.h, mips.h, etc.
//

typedef enum _INTERLOCKED_RESULT {
    ResultNegative = RESULT_NEGATIVE,
    ResultZero     = RESULT_ZERO,
    ResultPositive = RESULT_POSITIVE
} INTERLOCKED_RESULT;

//
// Convert portable interlock interfaces to architecture specific interfaces.
//


#define ExInterlockedIncrementLong(Addend, Lock) \
    ExAlphaInterlockedIncrementLong(Addend)

#define ExInterlockedDecrementLong(Addend, Lock) \
    ExAlphaInterlockedDecrementLong(Addend)

#define ExInterlockedExchangeUlong(Target, Value, Lock) \
    ExAlphaInterlockedExchangeUlong(Target, Value)

NTKERNELAPI
INTERLOCKED_RESULT
ExAlphaInterlockedIncrementLong (
    IN PLONG Addend
    );

NTKERNELAPI
INTERLOCKED_RESULT
ExAlphaInterlockedDecrementLong (
    IN PLONG Addend
    );

NTKERNELAPI
ULONG
ExAlphaInterlockedExchangeUlong (
    IN PULONG Target,
    IN ULONG Value
    );

//  begin_wdm

#if defined(_M_ALPHA) && !defined(RC_INVOKED)

#define InterlockedIncrement _InterlockedIncrement
#define InterlockedDecrement _InterlockedDecrement
#define InterlockedExchange _InterlockedExchange
#define InterlockedExchangeAdd _InterlockedExchangeAdd

LONG
InterlockedIncrement (
    IN OUT PLONG Addend
    );

LONG
InterlockedDecrement (
    IN OUT PLONG Addend
    );

LONG
InterlockedExchange (
    IN OUT PLONG Target,
    LONG Value
    );

#if defined(_M_AXP64)

#define InterlockedCompareExchange _InterlockedCompareExchange
#define InterlockedCompareExchange64 _InterlockedCompareExchange64
#define InterlockedExchangePointer _InterlockedExchangePointer
#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer
#define InterlockedExchange64 _InterlockedExchange64

LONG
InterlockedCompareExchange (
    IN OUT PLONG Destination,
    IN LONG ExChange,
    IN LONG Comperand
    );

LONGLONG
InterlockedCompareExchange64 (
    IN OUT PLONGLONG Destination,
    IN LONGLONG ExChange,
    IN LONGLONG Comperand
    );

PVOID
InterlockedExchangePointer (
    IN OUT PVOID *Target,
    IN PVOID Value
    );

PVOID
InterlockedCompareExchangePointer (
    IN OUT PVOID *Destination,
    IN PVOID ExChange,
    IN PVOID Comperand
    );

LONGLONG
InterlockedExchange64(
    IN OUT PLONGLONG Target,
    IN LONGLONG Value
    );

#pragma intrinsic(_InterlockedCompareExchange64)
#pragma intrinsic(_InterlockedExchangePointer)
#pragma intrinsic(_InterlockedCompareExchangePointer)
#pragma intrinsic(_InterlockedExchange64)

#else

#define InterlockedExchangePointer(Target, Value) \
    (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))

#define InterlockedCompareExchange(Destination, ExChange, Comperand) \
    (LONG)_InterlockedCompareExchange((PVOID *)(Destination), (PVOID)(ExChange), (PVOID)(Comperand))

#define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
    _InterlockedCompareExchange(Destination, ExChange, Comperand)

PVOID
_InterlockedCompareExchange (
    IN OUT PVOID *Destination,
    IN PVOID ExChange,
    IN PVOID Comperand
    );

NTKERNELAPI
LONGLONG
InterlockedCompareExchange64 (
    IN OUT PLONGLONG Destination,
    IN LONGLONG Exchange,
    IN LONGLONG Comperand
    );

NTKERNELAPI
LONGLONG
ExpInterlockedCompareExchange64 (
    IN OUT PLONGLONG Destination,
    IN PLONGLONG Exchange,
    IN PLONGLONG Comperand
    );

#endif

LONG
InterlockedExchangeAdd(
    IN OUT PLONG Addend,
    IN LONG Value
    );

#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)
#pragma intrinsic(_InterlockedExchange)
#pragma intrinsic(_InterlockedExchangeAdd)
#pragma intrinsic(_InterlockedCompareExchange)

#endif

// there is a lot of other stuff that could go in here
//   probe macros
//   others
// end_ntddk end_wdm end_nthal end_ntosp
//
// Intrinsic interlocked functions.
//


// begin_ntddk begin_wdm begin_nthal begin_ntndis begin_ntosp

//
// Define the page size for the Alpha ev4 and lca as 8k.
//

#define PAGE_SIZE 0x2000

//
// Define the number of trailing zeroes in a page aligned virtual address.
// This is used as the shift count when shifting virtual addresses to
// virtual page numbers.
//

#define PAGE_SHIFT 13L

// end_ntddk end_wdm end_nthal end_ntndis

//
// Define the number of bits to shift to right justify the Page Directory Index
// field of a PTE.
//

#if defined(_AXP64_)

#define PDI_SHIFT 23
#define PDI1_SHIFT 33
#define PDI2_SHIFT 23
#define PDI_MASK 0x3ff

#else

#define PDI_SHIFT 24

#endif

//
// Define the number of bits to shift to right justify the Page Table Index
// field of a PTE.
//

#define PTI_SHIFT 13

//
// Define the maximum address space number allowable for the architecture.
//

#define ALPHA_AXP_MAXIMUM_ASN 0xffffffff

// begin_ntddk begin_nthal

//
// The highest user address reserves 64K bytes for a guard page. This is so
// the probing of addresses from kernel mode only have to check the
// starting address for structures of 64K bytes or less.
//

#if defined(_AXP64_)

#define MM_HIGHEST_USER_ADDRESS (PVOID)0x3FFFFFEFFFF // highest user address
#define MM_USER_PROBE_ADDRESS          0x3FFFFFF0000UI64 // guard page address
#define MM_SYSTEM_RANGE_START   (PVOID)0xFFFFFC0000000000 // start of system space

#else

#define MM_HIGHEST_USER_ADDRESS (PVOID)0x7FFEFFFF // highest user address
#define MM_USER_PROBE_ADDRESS 0x7FFF0000 // starting address of guard page
#define MM_SYSTEM_RANGE_START (PVOID)KSEG0_BASE // start of system space

#endif


//
// The following definitions are required for the debugger data block.
//

extern PVOID MmHighestUserAddress;
extern PVOID MmSystemRangeStart;
extern ULONG_PTR MmUserProbeAddress;

//
// The lowest user address reserves the low 64k.
//

#define MM_LOWEST_USER_ADDRESS  (PVOID)0x00010000

// begin_wdm

#define MmGetProcedureAddress(Address) (Address)
#define MmLockPagableCodeSection(Address) MmLockPagableDataSection(Address)

// end_ntddk end_wdm end_nthal

//
// Define the page table base and the page directory base for
// the TB miss routines and memory management.
//

#if defined(_AXP64_)

#define PDE_TBASE 0xFFFFFE0180600000UI64 // first level PDR address
#define PDE_SELFMAP 0xFFFFFE0180601800UI64 // first level PDR self map address
#define PDE_UBASE 0xFFFFFE0180000000UI64 // user second level PDR address
#define PDE_KBASE 0xFFFFFE01807FE000UI64 // kernel second level PDR address
#define PDE_BASE PDE_KBASE              // kernel second level PDR address
#define PTE_BASE 0xFFFFFE0000000000UI64 // page table address
#define PDE64_BASE 0xFFFFFE0180600000UI64 // first level PDR address
#define PTE64_BASE 0xFFFFFE0000000000UI64 // page table address
#define VA_SHIFT (63 - 42)              // address sign extend shift count

#else

#define PDE_BASE (ULONG)0xC0180000      // first level PDR address
#define PDE_SELFMAP (ULONG)0xC0180300   // first level PDR self map address
#define PTE_BASE (ULONG)0xC0000000      // page table address
#define PDE64_BASE (ULONG)0xC0184000    // first level 64-bit PDR address
#define PTE64_BASE (ULONG)0xC2000000    // 64-bit page table address

#endif

// end_ntosp

//
// Generate kernel segment physical address.
//

#if defined(_AXP64_)

#define KSEG_ADDRESS(FrameNumber) \
    ((PVOID)(KSEG43_BASE | ((ULONG_PTR)(FrameNumber) << PAGE_SHIFT)))

#else

#define KSEG_ADDRESS(FrameNumber) \
    ((PVOID)(KSEG0_BASE | ((ULONG)(FrameNumber) << PAGE_SHIFT)))

#endif

// begin_ntddk begin_wdm
//
// The lowest address for system space.
//

#if defined(_AXP64_)

#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xFFFFFE0200000000

#else

#define MM_LOWEST_SYSTEM_ADDRESS (PVOID)0xC0800000

#endif

// end_ntddk end_wdm

#if defined(_AXP64_)

#define SYSTEM_BASE 0xFFFFFE0200000000  // start of system space (no typecast)

#else

#define SYSTEM_BASE 0xc0800000          // start of system space (no typecast)

#endif

// begin_nthal begin_ntddk begin_wdm begin_ntosp

//
// Define prototypes to access PCR values
//

NTKERNELAPI
KIRQL
KeGetCurrentIrql();

// end_nthal end_ntddk end_wdm

#if defined(_M_ALPHA)
#define KeGetCurrentThread() ((struct _KTHREAD *) __rdthread())
#endif

// begin_ntddk begin_wdm

NTSTATUS
KeSaveFloatingPointState (
    OUT PKFLOATING_SAVE     FloatSave
    );

NTSTATUS
KeRestoreFloatingPointState (
    IN PKFLOATING_SAVE      FloatSave
    );

// end_ntddk end_wdm
// begin_nthal

#define KeGetPreviousMode() (KeGetCurrentThread()->PreviousMode)

// end_ntosp

#define KeGetDcacheFillSize() PCR->FirstLevelDcacheFillSize

//
// Test if executing DPC.
//

BOOLEAN
KeIsExecutingDpc (
    VOID
    );

//
// Return interrupt trap frame
//
PKTRAP_FRAME
KeGetInterruptTrapFrame(
    VOID
    );

// begin_ntddk begin_ntosp
//
// Get address of current PRCB.
//

#define KeGetCurrentPrcb() (PCR->Prcb)

//
// Get current processor number.
//

#define KeGetCurrentProcessorNumber() KeGetCurrentPrcb()->Number

// end_ntddk end_ntosp

//
// 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 begin_ntosp
//
// Cache and write buffer flush functions.
//

VOID
KeFlushIoBuffers (
    IN PMDL Mdl,
    IN BOOLEAN ReadOperation,
    IN BOOLEAN DmaOperation
    );

// end_ntddk end_wdm end_ntndis end_ntosp

//
// 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
    );

// begin_ntosp

NTKERNELAPI
VOID
KeProfileInterruptWithSource (
    IN KPROFILE_SOURCE ProfileSource
    );

// end_ntosp

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); \
    }

NTKERNELAPI                                         // nthal
VOID                                                // nthal
KeFlushCurrentTb (                                  // nthal
    VOID                                            // nthal
    );                                              // nthal
                                                    // nthal
//
// 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
    );

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 tick count macro.
//
// begin_ntddk begin_nthal begin_ntosp

#if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_)

//  begin_wdm

#define KeQueryTickCount(CurrentCount ) \
    *(PULONGLONG)(CurrentCount) = **((volatile ULONGLONG **)(&KeTickCount));

//  end_wdm

#else

#define KiQueryTickCount(CurrentCount) \
    *(PULONGLONG)(CurrentCount) = KeTickCount.QuadPart;

VOID
KeQueryTickCount (
    OUT PLARGE_INTEGER CurrentCount
    );

#endif // defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_)

// end_ntddk end_nthal end_ntosp

//
// 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 begin_ntosp

#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 end_ntosp

#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 begin_ntosp
#ifdef __cplusplus
}   // extern "C"
#endif
#endif // _ALPHA_
// end_ntddk end_wdm end_nthal end_ntndis end_ntosp

#endif // _ALPHAH_
