Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2256 lines
46 KiB

/*++ BUILD Version: 0001 // Increment this if a change has global effects
Copyright (c) 1991 Microsoft Corporation
Module Name:
halp.h
Abstract:
This header file defines the private Hardware Architecture Layer (HAL)
interfaces, defines and structures.
Author:
John Vert (jvert) 11-Feb-92
Revision History:
--*/
#ifndef _HALP_H_
#define _HALP_H_
#include "nthal.h"
#include "halnls.h"
//
//Pickup the pnp guid definitions.
//
#include "wdmguid.h"
#if defined(NEC_98)
#include "nec98.h"
#else
#if MCA
#include "mca.h"
#else
#include "eisa.h"
#endif
#endif // NEC_98
#ifndef _HALI_
#include "hali.h"
#endif
#ifdef RtlMoveMemory
#undef RtlMoveMemory
// #undef RtlCopyMemory
// #undef RtlFillMemory
// #undef RtlZeroMemory
//#define RtlCopyMemory(Destination,Source,Length) RtlMoveMemory((Destination),(Source),(Length))
#if defined(_WIN64)
__inline
VOID
RtlMoveMemory (
PVOID Destination,
CONST VOID *Source,
SIZE_T Length
)
{
memmove(Destination,Source,Length);
}
#else
VOID
RtlMoveMemory (
PVOID Destination,
CONST VOID *Source,
SIZE_T Length
);
#endif
// VOID
// RtlFillMemory (
// PVOID Destination,
// ULONG Length,
// UCHAR Fill
// );
//
// VOID
// RtlZeroMemory (
// PVOID Destination,
// ULONG Length
// );
//
#endif
#if defined(_AMD64_)
//
// A temporary macro used to indicate that a particular piece of code
// has never been executed on AMD64 before, and should be examined
// carefully for correct operation.
//
#define AMD64_COVERAGE_TRAP() DbgBreakPoint()
//
// The following prototypes are not available from the standard HAL headers
// due to the fact that NO_LEGACY_DRIVERS is defined while compiling the
// HAL... however, they are used internally.
//
NTSTATUS
HalAssignSlotResources (
IN PUNICODE_STRING RegistryPath,
IN PUNICODE_STRING DriverClassName OPTIONAL,
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject,
IN INTERFACE_TYPE BusType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN OUT PCM_RESOURCE_LIST *AllocatedResources
);
ULONG
HalGetInterruptVector(
IN INTERFACE_TYPE InterfaceType,
IN ULONG BusNumber,
IN ULONG BusInterruptLevel,
IN ULONG BusInterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity
);
ULONG
HalGetBusData(
IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length
);
ULONG
HalSetBusData(
IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length
);
//
// We are sharing code that was written for the x86. There are some
// macros with identical meanings but different names in AMD64. Following
// are some definitions to abstract those differences.
//
//
// CLOCK2_LEVEL on x86 is CLOCK_LEVEL on AMD64.
//
#define CLOCK2_LEVEL CLOCK_LEVEL
//
// X86 EFLAGS_INTERRUPT_MASK == AMD64 EFLAGS_IF_MASK
//
#define EFLAGS_INTERRUPT_MASK EFLAGS_IF_MASK
//
// The PCR's pointer to the current prcb is named Prcb, while on AMD64
// it is named CurrentPrcb.
//
// The CurrentPrcb() macro is used to abstract this difference.
//
#define CurrentPrcb(x) (x)->CurrentPrcb
//
// The x86 KiReturnHandlerAddressFromIDT() is the equivalent of the AMD64's
// KeGetIdtHandlerAddress()
//
#define KiReturnHandlerAddressFromIDT(v) (ULONG_PTR)KeGetIdtHandlerAddress(v)
//
// More macro and structure name differences
//
#define RDMSR(m) ReadMSR(m)
#define WRMSR(m,d) WriteMSR(m,d)
#define KGDTENTRY KGDTENTRY64
#define PKGDTENTRY PKGDTENTRY64
#define PIOPM_SIZE (sizeof(KIO_ACCESS_MAP) + sizeof(ULONG))
//
// The AMD64 in long mode uses 8-byte PTE entries, which have the same format
// as Pentium PAE page tables.
//
#if !defined(_HALPAE_)
#define _HALPAE_ 1
#endif
#define HARDWARE_PTE_X86PAE HARDWARE_PTE
#define HARDWARE_PTE_X86 HARDWARE_PTE
#define PHARDWARE_PTE_X86PAE PHARDWARE_PTE
#define PHARDWARE_PTE_X86 PHARDWARE_PTE
#define PDE_BASE_X86PAE PDE_BASE
#define PDE_BASE_X86 PDE_BASE
#define PDI_SHIFT_X86PAE PDI_SHIFT
#define PDI_SHIFT_X86 PDI_SHIFT
//
// Fence instruction.
//
__forceinline
VOID
HalpProcessorFence (
VOID
)
{
CPU_INFO cpuInfo;
KiCpuId (0,&cpuInfo);
}
#define HalpGetProcessorFlags() __getcallerseflags()
//
// While _enable() and _disable() are intrinsics in both the AMD64 and X86
// compilers, they are disabled on X86. HalpDisableInterruptsNoFlags and
// HalpEnableInterrupts are macros used to abstract this difference.
//
#define HalpDisableInterruptsNoFlags _disable
#define HalpEnableInterrupts _enable
//
// There is no intrinsic for the hlt instruction on AMD64. HalpHalt()
// is a function call on AMD64, and inline asm on X86.
//
VOID
HalpHalt (
VOID
);
//
// On x86, the variables HalpClockSetMSRate, HalpClockMcaQueueDpc and
// HalpClockWork are defined in an .asm module such that HalpClockWork
// is defined as a DWORD that overlapps HalpClockSetMSRate and
// HalpClockMcaQueueDpc.
//
// This is not directly representable in C, so instead HALP_CLOCKWORK_UNION
// is defined and the above variable names are instead redefined to reference
// elements of this union.
//
#define HalpClockSetMSRate HalpClockWorkUnion.ClockSetMSRate
#define HalpClockMcaQueueDpc HalpClockWorkUnion.ClockMcaQueueDpc
#define HalpClockWork HalpClockWorkUnion.ClockWork
typedef union {
struct {
UCHAR ClockMcaQueueDpc;
UCHAR ClockSetMSRate;
UCHAR bReserved1;
UCHAR bReserved2;
};
ULONG ClockWork;
} HALP_CLOCKWORK_UNION;
extern HALP_CLOCKWORK_UNION HalpClockWorkUnion;
#else
//
// Following are X86 definitions that are used to help abstract differences
// between X86 and AMD64 platforms.
//
#define AMD64_COVERAGE_TRAP()
//
// We are sharing code that was written for the x86. There are some
// macros with identical meanings but different names in AMD64. Following
// are some definitions to abstract those differences.
//
//
// The following _KPCR fields have different names but identical purposes.
//
#define IdtBase IDT
#define GdtBase GDT
#define TssBase TSS
//
// The PCR's pointer to the current prcb is named Prcb, while on AMD64
// it is named CurrentPrcb.
//
// The CurrentPrcb() macro is used to abstract this difference.
//
#define CurrentPrcb(x) (x)->Prcb
//
// On X86, HalpGetProcessorFlags() can be implemented inline.
//
__forceinline
ULONG
HalpGetProcessorFlags (
VOID
)
/*++
Routine Description:
This procedure retrieves the contents of the EFLAGS register.
Arguments:
None.
Return Value:
The 32-bit contents of the EFLAGS register.
--*/
{
ULONG flags;
_asm {
pushfd
pop eax
mov flags, eax
}
return flags;
}
//
// While _enable() and _disable() are intrinsics in both the AMD64 and X86
// compilers, they are disabled in the HAL on X86.
//
// HalpDisableInterruptsNoFlags and HalpEnableInterrupts are macros used
// to abstract this difference.
//
#define HalpDisableInterruptsNoFlags() _asm cli
#define HalpEnableInterrupts() _asm sti
//
// There is no intrinsic for the hlt instruction on AMD64. HalpHalt()
// is a function call on AMD64, and inline asm on X86.
//
#define HalpHalt() _asm hlt
//
// Fence instruction
//
__forceinline
VOID
HalpProcessorFence (
VOID
)
{
_asm {
xor eax, eax
cpuid
}
}
#endif
#define PROCESSOR_FENCE HalpProcessorFence()
__forceinline
ULONG
HalpDisableInterrupts(
VOID
)
/*++
Routine Description:
This function saves the state of the processor flag register, clears the
state of the interrupt flag (disables interrupts), and returns the
previous contents of the processor flag register.
Arguments:
None.
Return Value:
The previous contents of the processor flag register.
--*/
{
ULONG flags;
flags = HalpGetProcessorFlags();
HalpDisableInterruptsNoFlags();
return flags;
}
__forceinline
VOID
HalpRestoreInterrupts(
IN ULONG Flags
)
/*++
Routine Description:
This procedure restores the state of the interrupt flag based on a
value returned by a previous call to HalpDisableInterrupts.
Arguments:
Flags - Supplies the value returned by a previous call to
HalpDisableInterrupts
Return Value:
None.
--*/
{
if ((Flags & EFLAGS_INTERRUPT_MASK) != 0) {
HalpEnableInterrupts();
}
}
#if defined(_WIN64)
//
// For AMD64 (and, ideally, all subsequent WIN64 platforms), interrupt
// service routines are C callable.
//
typedef PKSERVICE_ROUTINE PHAL_INTERRUPT_SERVICE_ROUTINE;
#define HAL_INTERRUPT_SERVICE_PROTOTYPE(RoutineName) \
BOOLEAN \
RoutineName ( \
IN PKINTERRUPT Interrupt, \
IN PVOID ServiceContext \
)
#define PROCESSOR_CURRENT ((UCHAR)-1)
VOID
HalpSetHandlerAddressToIDTIrql (
IN ULONG Vector,
IN PHAL_INTERRUPT_SERVICE_ROUTINE ServiceRoutine,
IN PVOID Context,
IN KIRQL Irql
);
#define KiSetHandlerAddressToIDT Dont_Use_KiSetHandlerAddressToIdt
//
// On AMD64, the HAL does not connect directly to the IDT, rather the
// kernel handles the interrupt and calls a C-callable interrupt routine.
//
// Therefore, HalpSetHandlerAddressToIDT() must supply a context and an
// IRQL in addition to the vector number and interrupt routine.
//
// On X86, the context and IRQL are ignored, as the vector is inserted
// directly into the IDT, such that the service routine is responsible for
// raising IRQL.
//
#define KiSetHandlerAddressToIDTIrql(v,a,c,i) \
HalpSetHandlerAddressToIDTIrql (v,a,c,i);
#else
//
// On X86, the last two parameters of KiSetHandlerAddressToIDTIrql()
// (Context and Irql) are ignored. The interrupt handlers themselves
// are responsible for raising IRQL.
//
#define KiSetHandlerAddressToIDTIrql(v,a,c,i) KiSetHandlerAddressToIDT(v,a)
//
// For X86, interrupt service routines must be written in assembler because
// they are referenced directly in the IDT and trasferred to directly by
// the processor with a convention that is not C callable.
//
// For purposes of C code that references ISRs, then, the prototype is
// very simple.
//
typedef
VOID
(*PHAL_INTERRUPT_SERVICE_ROUTINE)(
VOID
);
#define HAL_INTERRUPT_SERVICE_PROTOTYPE(RoutineName) \
VOID \
RoutineName ( \
VOID \
)
#endif
typedef
VOID
(*HALP_MOVE_MEMORY_ROUTINE)(
PVOID Destination,
CONST VOID *Source,
SIZE_T Length
);
VOID
HalpMovntiCopyBuffer(
PVOID Destination,
CONST VOID *Source,
ULONG Length
);
VOID
HalpSetInternalVector (
IN ULONG InternalVector,
IN PHAL_INTERRUPT_SERVICE_ROUTINE HalInterruptSerivceRoutine,
IN PVOID Context,
IN KIRQL Irql
);
extern HALP_MOVE_MEMORY_ROUTINE HalpMoveMemory;
#if MCA
#include "ixmca.h"
#else
#include "ixisa.h"
#endif
#include "ix8259.inc"
#if DBG
extern ULONG HalDebug;
#define HalPrint(x) \
if (HalDebug) { \
DbgPrint("HAL: "); \
DbgPrint x; \
DbgPrint("\n"); \
}
#else
#define HalPrint(x)
#endif
//
// Define map register translation entry structure.
//
typedef struct _TRANSLATION_ENTRY {
PVOID VirtualAddress;
ULONG PhysicalAddress;
ULONG Index;
} TRANSLATION_ENTRY, *PTRANSLATION_ENTRY;
//
// Some devices require a phyicially contiguous data buffers for DMA transfers.
// Map registers are used give the appearance that all data buffers are
// contiguous. In order to pool all of the map registers a master
// adapter object is used. This object is allocated and saved internal to this
// file. It contains a bit map for allocation of the registers and a queue
// for requests which are waiting for more map registers. This object is
// allocated during the first request to allocate an adapter which requires
// map registers.
//
// In this system, the map registers are translation entries which point to
// map buffers. Map buffers are physically contiguous and have physical memory
// addresses less than 0x01000000. All of the map registers are allocated
// initialially; however, the map buffers are allocated base in the number of
// adapters which are allocated.
//
// If the master adapter is NULL in the adapter object then device does not
// require any map registers.
//
extern POBJECT_TYPE *IoAdapterObjectType;
extern BOOLEAN LessThan16Mb;
extern BOOLEAN HalpEisaDma;
VOID
HalpGrowMapBufferWorker(
IN PVOID Context
);
//
// Work item to grow map buffers
//
typedef struct _BUFFER_GROW_WORK_ITEM {
WORK_QUEUE_ITEM WorkItem;
PADAPTER_OBJECT AdapterObject;
ULONG MapRegisterCount;
} BUFFER_GROW_WORK_ITEM, *PBUFFER_GROW_WORK_ITEM;
//
// Map buffer prameters. These are initialized in HalInitSystem
//
//
// PAE note:
//
// Previously, there was only one class of adapter that we had to double-buffer
// for: adapters with only 24 address lines that could access memory up to
// 16MB.
//
// The HAL tracked these map buffers with a single, global master adapter.
// Associated with this master adapter were three global variables:
//
// - MasterAdapterObject
// - HalpMapBufferSize
// - HalpMapBufferPhysicalAddress
//
// With PAE, we have another class of adapters that require double-buffering:
// specifically, adapters with only 32 address lines that can access memory
// up to 4G.
//
// This meant the introduction of another master adapter along with an
// associated set of variables. For PAE-capable hals, this data has been
// reorganized into a MASTER_ADAPTER_OBJECT (see ixisa.h).
//
// So now we have two global MASTER_ADAPTER_OBJECT structures:
//
// MasterAdapter24
// MasterAdapter32
//
// The following macros are used in code that is included in PAE-capable
// hals. It is important to note that in a non-PAE-capable HAL (i.e. one
// that does not have _HALPAE_ defined), the macros must resolve to the
// values that they replaced.
//
#if defined(_HALPAE_)
PADAPTER_OBJECT
HalpAllocateAdapterEx(
IN ULONG MapRegistersPerChannel,
IN PVOID AdapterBaseVa,
IN PVOID ChannelNumber,
IN BOOLEAN Dma32Bit
);
extern MASTER_ADAPTER_OBJECT MasterAdapter24;
extern MASTER_ADAPTER_OBJECT MasterAdapter32;
#define HalpMasterAdapterStruc( Dma32Bit ) \
((HalPaeEnabled() && (Dma32Bit)) ? &MasterAdapter32 : &MasterAdapter24)
#define HalpMaximumMapBufferRegisters( Dma32Bit ) \
(HalpMasterAdapterStruc( Dma32Bit )->MaxBufferPages)
#define HalpMaximumMapRegisters( Dma32Bit ) \
(Dma32Bit ? MAXIMUM_PCI_MAP_REGISTER : MAXIMUM_ISA_MAP_REGISTER)
#define HalpMapBufferSize( Dma32Bit ) \
(HalpMasterAdapterStruc( Dma32Bit )->MapBufferSize)
#define HalpMapBufferPhysicalAddress( Dma32Bit ) \
(HalpMasterAdapterStruc( Dma32Bit )->MapBufferPhysicalAddress)
#define HalpMasterAdapter( Dma32Bit ) \
HalpMasterAdapterStruc( Dma32Bit )->AdapterObject
#else
extern PHYSICAL_ADDRESS HalpMapBufferPhysicalAddress;
extern ULONG HalpMapBufferSize;
extern PADAPTER_OBJECT MasterAdapterObject;
#define HalpAllocateAdapterEx( _m, _a, _c, _d ) \
HalpAllocateAdapter( _m, _a, _c )
#define HalpMaximumMapBufferRegisters( Dma32Bit ) \
(MAXIMUM_MAP_BUFFER_SIZE / PAGE_SIZE)
#define HalpMaximumMapRegisters( Dma32Bit ) \
(MAXIMUM_ISA_MAP_REGISTER)
#define HalpMapBufferSize( Dma32Bit ) HalpMapBufferSize
#define HalpMapBufferPhysicalAddress( Dma32Bit ) \
(HalpMapBufferPhysicalAddress)
#define HalpMasterAdapter( Dma32Bit ) MasterAdapterObject
#endif
extern ULONG HalpBusType;
extern ULONG HalpCpuType;
extern UCHAR HalpSerialLen;
extern UCHAR HalpSerialNumber[];
#if defined(_AMD64_)
//
// Amd64 decodes 48 bits of virtual address space.
//
#define MI_DECODE_MASK (((ULONG64)1 << 48) - 1)
#define VA_TRUNC(x) ((ULONG64)(x) & MI_DECODE_MASK)
#else
#define VA_TRUNC(x) (x)
#endif
//
// The following macros are taken from mm\i386\mi386.h. We need them here
// so the HAL can map its own memory before memory-management has been
// initialized, or during a BugCheck.
//
// MiGetPdeAddress returns the address of the PDE which maps the
// given virtual address.
//
#define MiGetPdeAddressX86(va) ((PHARDWARE_PTE)(((((ULONG_PTR)(va)) >> 22) << 2) + PDE_BASE))
//
// MiGetPteAddress returns the address of the PTE which maps the
// given virtual address.
//
#define MiGetPteAddressX86(va) ((PHARDWARE_PTE)(((((ULONG_PTR)(va)) >> 12) << 2) + PTE_BASE))
//
// MiGetPteIndex returns the index within a page table of the PTE for the
// given virtual address
//
#define MiGetPteIndexX86(va) (((ULONG_PTR)(va) >> PAGE_SHIFT) & 0x3FF)
#define MiGetPteIndexPae(va) (((ULONG_PTR)(VA_TRUNC(va)) >> PAGE_SHIFT) & 0x1FF)
//
// The following macros are taken from mm\i386\mipae.h. We need them here
// so the HAL can map its own memory before memory-management has been
// initialized, or during a BugCheck.
//
// MiGetPdeAddressPae returns the address of the PDE which maps the
// given virtual address.
//
#define MiGetPdeAddressPae(va) ((PHARDWARE_PTE_X86PAE)(PDE_BASE_X86PAE + ((((ULONG_PTR)(VA_TRUNC(va))) >> 21) << 3)))
//
// MiGetPteAddressPae returns the address of the PTE which maps the
// given virtual address.
//
#define MiGetPteAddressPae(va) ((PHARDWARE_PTE_X86PAE)(PTE_BASE + ((((ULONG_PTR)(VA_TRUNC(va))) >> 12) << 3)))
//
// Resource usage information
//
#pragma pack(1)
typedef struct {
UCHAR Flags;
} IDTUsageFlags;
typedef struct {
KIRQL Irql;
UCHAR BusReleativeVector;
} IDTUsage;
typedef struct _HalAddressUsage{
struct _HalAddressUsage *Next;
CM_RESOURCE_TYPE Type; // Port or Memory
UCHAR Flags; // same as IDTUsage.Flags
struct {
ULONG Start;
ULONG Length;
} Element[];
} ADDRESS_USAGE;
#pragma pack()
#define IDTOwned 0x01 // IDT is not available for others
#define InterruptLatched 0x02 // Level or Latched
#define RomResource 0x04 // ROM
#define InternalUsage 0x11 // Report usage on internal bus
#define DeviceUsage 0x21 // Report usage on device bus
extern IDTUsageFlags HalpIDTUsageFlags[];
extern IDTUsage HalpIDTUsage[];
extern ADDRESS_USAGE *HalpAddressUsageList;
#define HalpRegisterAddressUsage(a) \
(a)->Next = HalpAddressUsageList, HalpAddressUsageList = (a);
//
// Temp definitions to thunk into supporting new bus extension format
//
VOID
HalpRegisterInternalBusHandlers (
VOID
);
PBUS_HANDLER
HalpAllocateBusHandler (
IN INTERFACE_TYPE InterfaceType,
IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN INTERFACE_TYPE ParentBusDataType,
IN ULONG ParentBusNumber,
IN ULONG BusSpecificData
);
#define HalpHandlerForBus HaliHandlerForBus
#define HalpSetBusHandlerParent(c,p) (c)->ParentHandler = p;
//
// Define function prototypes.
//
VOID
HalInitSystemPhase2(
VOID
);
KIRQL
HaliRaiseIrqlToDpcLevel (
VOID
);
BOOLEAN
HalpGrowMapBuffers(
PADAPTER_OBJECT AdapterObject,
ULONG Amount
);
PADAPTER_OBJECT
HalpAllocateAdapter(
IN ULONG MapRegistersPerChannel,
IN PVOID AdapterBaseVa,
IN PVOID MapRegisterBase
);
HAL_INTERRUPT_SERVICE_PROTOTYPE(HalpClockInterrupt);
KIRQL
HalpDisableAllInterrupts (
VOID
);
VOID
HalpReenableInterrupts (
KIRQL NewIrql
);
#if defined(_AMD64_)
VOID
HalpInitializeProfiling (
ULONG Number
);
NTSTATUS
HalpSetProfileSourceInterval(
IN KPROFILE_SOURCE ProfileSource,
IN OUT ULONG_PTR *Interval
);
NTSTATUS
HalpQueryProfileInformation(
IN HAL_QUERY_INFORMATION_CLASS InformationClass,
IN ULONG BufferSize,
OUT PVOID Buffer,
OUT PULONG ReturnedLength
);
#endif
HAL_INTERRUPT_SERVICE_PROTOTYPE(HalpProfileInterrupt);
VOID
HalpInitializeClock(
VOID
);
VOID
HalpInitializeStallExecution(
IN CCHAR ProcessorNumber
);
VOID
HalpRemoveFences (
VOID
);
VOID
HalpInitializePICs(
BOOLEAN EnableInterrupts
);
VOID
HalpIrq13Handler (
VOID
);
VOID
HalpFlushTLB (
VOID
);
VOID
HalpSerialize (
VOID
);
PVOID
HalpMapPhysicalMemory64(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberPages
);
PVOID
HalpMapPhysicalMemoryWriteThrough64(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberPages
);
ULONG
HalpAllocPhysicalMemory(
IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN ULONG MaxPhysicalAddress,
IN ULONG NoPages,
IN BOOLEAN bAlignOn64k
);
VOID
HalpUnmapVirtualAddress(
IN PVOID VirtualAddress,
IN ULONG NumberPages
);
PVOID
HalpRemapVirtualAddress64 (
IN PVOID VirtualAddress,
IN PHYSICAL_ADDRESS PhysicalAddress,
IN BOOLEAN WriteThrough
);
PHYSICAL_ADDRESS
__inline
HalpPtrToPhysicalAddress(
IN PVOID Address
)
/*++
Routine Description:
This routine converts a physical address expressed as a PVOID into
a physical address expresses as PHYSICAL_ADDRESS.
Arguments:
Address - PVOID representation of the physical address.
Return Value:
PHYSICAL_ADDRESS representation of the physical address.
--*/
{
PHYSICAL_ADDRESS physicalAddress;
physicalAddress.QuadPart = (ULONG_PTR)Address;
return physicalAddress;
}
#if defined(_HALPAE_)
//
// This hal is to be PAE compatible. Therefore, physical addresses must
// be treated as 64-bit entitites instead of PVOID.
//
#define _PHYS64_
#endif
#if defined(_PHYS64_)
//
// HALs with _PHYS64_ defined pass physical addresses as PHYSICAL_ADDRESS,
// so call the 64-bit versions of these routines directly.
//
#define HalpMapPhysicalMemory HalpMapPhysicalMemory64
#define HalpMapPhysicalMemoryWriteThrough HalpMapPhysicalMemoryWriteThrough64
#define HalpRemapVirtualAddress HalpRemapVirtualAddress64
#define HalpMapPhysicalRange(_addr_,_len_) \
HalpMapPhysicalMemory((_addr_), \
HalpRangePages((_addr_).QuadPart,(_len_)))
#define HalpUnMapPhysicalRange(_addr_,_len_) \
HalpUnmapVirtualAddress((_addr_), \
HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
#else
//
// HALs without _PHYS64_ defined pass physical addresses as PVOIDs. Convert
// such parameters to PHYSICAL_ADDRESS before passing to the 64-bit routines.
//
PVOID
__inline
HalpMapPhysicalMemory(
IN PVOID PhysicalAddress,
IN ULONG NumberPages
)
{
PHYSICAL_ADDRESS physicalAddress;
physicalAddress = HalpPtrToPhysicalAddress( PhysicalAddress );
return HalpMapPhysicalMemory64( physicalAddress, NumberPages );
}
PVOID
__inline
HalpMapPhysicalMemoryWriteThrough(
IN PVOID PhysicalAddress,
IN ULONG NumberPages
)
{
PHYSICAL_ADDRESS physicalAddress;
physicalAddress = HalpPtrToPhysicalAddress( PhysicalAddress );
return HalpMapPhysicalMemoryWriteThrough64( physicalAddress, NumberPages );
}
PVOID
__inline
HalpRemapVirtualAddress(
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN BOOLEAN WriteThrough
)
{
PHYSICAL_ADDRESS physicalAddress;
physicalAddress = HalpPtrToPhysicalAddress( PhysicalAddress );
return HalpRemapVirtualAddress64( VirtualAddress,
physicalAddress,
WriteThrough );
}
#define HalpMapPhysicalRangeWriteThrough(_addr_,_len_) \
HalpMapPhysicalMemoryWriteThrough((_addr_), \
HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
#define HalpMapPhysicalRange(_addr_,_len_) \
HalpMapPhysicalMemory((_addr_), \
HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
#define HalpUnMapPhysicalRange(_addr_,_len_) \
HalpUnmapVirtualAddress((_addr_), \
HalpRangePages((ULONG_PTR)(_addr_),(_len_)))
#endif
ULONG
__inline
HalpRangePages(
IN ULONGLONG Address,
IN ULONG Length
)
{
ULONG startPage;
ULONG endPage;
startPage = (ULONG)(Address / PAGE_SIZE);
endPage = (ULONG)((Address + Length + PAGE_SIZE - 1) / PAGE_SIZE);
return endPage - startPage;
}
BOOLEAN
HalpBiosDisplayReset(
IN VOID
);
HAL_DISPLAY_BIOS_INFORMATION
HalpGetDisplayBiosInformation (
VOID
);
VOID
HalpInitializeCmos (
VOID
);
VOID
HalpReadCmosTime (
PTIME_FIELDS TimeFields
);
VOID
HalpWriteCmosTime (
PTIME_FIELDS TimeFields
);
VOID
HalpAcquireCmosSpinLock (
VOID
);
VOID
HalpReleaseCmosSpinLock (
VOID
);
VOID
HalpResetAllProcessors (
VOID
);
VOID
HalpWriteResetCommand (
VOID
);
VOID
HalpCpuID (
ULONG InEax,
PULONG OutEax,
PULONG OutEbx,
PULONG OutEcx,
PULONG OutEdx
);
#if defined(_WIN64)
#define HalpYieldProcessor()
#else
VOID
HalpYieldProcessor (
VOID
);
#endif
ULONGLONG
FASTCALL
RDMSR (
IN ULONG MsrAddress
);
VOID
WRMSR (
IN ULONG MsrAddress,
IN ULONGLONG MsrValue
);
NTSTATUS
HalpEnableInterruptHandler (
IN UCHAR ReportFlags,
IN ULONG BusInterruptVector,
IN ULONG SystemInterruptVector,
IN KIRQL SystemIrql,
IN PHAL_INTERRUPT_SERVICE_ROUTINE HalInterruptServiceRoutine,
IN KINTERRUPT_MODE InterruptMode
);
VOID
HalpRegisterVector (
IN UCHAR ReportFlags,
IN ULONG BusInterruptVector,
IN ULONG SystemInterruptVector,
IN KIRQL SystemIrql
);
VOID
HalpReportResourceUsage (
IN PUNICODE_STRING HalName,
IN INTERFACE_TYPE DeviceInterfaceToUse
);
VOID
HalpYearIs(
IN ULONG Year
);
VOID
HalpRecordEisaInterruptVectors(
VOID
);
VOID
HalpMcaCurrentProcessorSetConfig(
VOID
);
NTSTATUS
HalpGetNextProcessorApicId(
IN ULONG ProcessorNumber,
IN OUT UCHAR *ApicId
);
VOID
FASTCALL
HalpIoDelay (
VOID
);
//
// Defines for HalpFeatureBits
//
#define HAL_PERF_EVENTS 0x00000001
#define HAL_NO_SPECULATION 0x00000002
#define HAL_MCA_PRESENT 0x00000004 // Intel MCA Available
#define HAL_MCE_PRESENT 0x00000008 // ONLY Pentium style MCE available
#define HAL_CR4_PRESENT 0x00000010
#define HAL_WNI_PRESENT 0x00000020
#define HAL_NX_PRESENT 0x00000040 // from extended processor features
extern ULONG HalpFeatureBits;
extern USHORT HalpPciIrqMask;
//
// Defines for Processor Features returned from CPUID instruction
//
#define CPUID_MCA_MASK 0x4000
#define CPUID_MCE_MASK 0x0080
#define CPUID_VME_MASK 0x0002
#define CPUID_WNI_MASK 0x04000000
#define CPUID_NX_MASK 0x00100000
NTSTATUS
HalpGetMceInformation(
IN PHAL_ERROR_INFO ErrorInfo,
OUT PULONG ErrorInfoLength
);
NTSTATUS
HalpMceRegisterKernelDriver(
IN PKERNEL_ERROR_HANDLER_INFO KernelErrorHandler,
IN ULONG InfoSize
);
//
// Token passed in by WMI to distinguish it from the MCA logging driver.
//
#define HALP_KERNEL_TOKEN 0x59364117
NTSTATUS
HalpGetMcaLog(
OUT PMCA_EXCEPTION Exception,
IN ULONG BufferSize,
OUT PULONG ReturnedLength
);
NTSTATUS
HalpMcaRegisterDriver(
IN PMCA_DRIVER_INFO pMcaDriverInfo // Info about registering driver
);
VOID
HalpMcaInit(
VOID
);
//
// Disable the Local APIC on UP (PIC 8259) PentiumPro systems to work around
// spurious interrupt errata.
//
#define APIC_BASE_MSR 0x1B
#define APIC_ENABLED 0x0000000000000800
//
// PnP stuff
//
#define HAL_BUS_INTERFACE_STD_VERSION 1
#define HAL_IRQ_TRANSLATOR_VERSION 0
#define HAL_MEMIO_TRANSLATOR_VERSION 1
VOID
HalTranslatorReference(
PVOID Context
);
VOID
HalTranslatorDereference(
PVOID Context
);
NTSTATUS
HalIrqTranslateResources(
IN PVOID Context,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
IN RESOURCE_TRANSLATION_DIRECTION Direction,
IN ULONG AlternativesCount, OPTIONAL
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
);
NTSTATUS
HalIrqTranslateResourcesRoot(
IN PVOID Context,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
IN RESOURCE_TRANSLATION_DIRECTION Direction,
IN ULONG AlternativesCount, OPTIONAL
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
);
NTSTATUS
HalIrqTranslateResourceRequirementsRoot(
IN PVOID Context,
IN PIO_RESOURCE_DESCRIPTOR Source,
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PULONG TargetCount,
OUT PIO_RESOURCE_DESCRIPTOR *Target
);
NTSTATUS
HalIrqTranslateResourceRequirementsIsa(
IN PVOID Context,
IN PIO_RESOURCE_DESCRIPTOR Source,
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PULONG TargetCount,
OUT PIO_RESOURCE_DESCRIPTOR *Target
);
NTSTATUS
HalIrqTranslateResourcesIsa(
IN PVOID Context,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
IN RESOURCE_TRANSLATION_DIRECTION Direction,
IN ULONG AlternativesCount, OPTIONAL
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
);
NTSTATUS
HalpTransMemIoResourceRequirement(
IN PVOID Context,
IN PIO_RESOURCE_DESCRIPTOR Source,
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PULONG TargetCount,
OUT PIO_RESOURCE_DESCRIPTOR *Target
);
NTSTATUS
HalpTransMemIoResource(
IN PVOID Context,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
IN RESOURCE_TRANSLATION_DIRECTION Direction,
IN ULONG AlternativesCount, OPTIONAL
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
);
NTSTATUS
HalIrqTranslateRequirementsPciBridge(
IN PVOID Context,
IN PIO_RESOURCE_DESCRIPTOR Source,
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PULONG TargetCount,
OUT PIO_RESOURCE_DESCRIPTOR *Target
);
NTSTATUS
HalIrqTranslateResourcesPciBridge(
IN PVOID Context,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
IN RESOURCE_TRANSLATION_DIRECTION Direction,
IN ULONG AlternativesCount, OPTIONAL
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
);
NTSTATUS
HalpIrqTranslateRequirementsPci(
IN PVOID Context,
IN PIO_RESOURCE_DESCRIPTOR Source,
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PULONG TargetCount,
OUT PIO_RESOURCE_DESCRIPTOR *Target
);
NTSTATUS
HalpIrqTranslateResourcesPci(
IN PVOID Context,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
IN RESOURCE_TRANSLATION_DIRECTION Direction,
IN ULONG AlternativesCount, OPTIONAL
IN IO_RESOURCE_DESCRIPTOR Alternatives[], OPTIONAL
IN PDEVICE_OBJECT PhysicalDeviceObject,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
);
BOOLEAN
HalpTranslateSystemBusAddress(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN PHYSICAL_ADDRESS BusAddress,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress
);
ULONG
HalpGetSystemInterruptVector(
IN PBUS_HANDLER BusHandler,
IN PBUS_HANDLER RootHandler,
IN ULONG InterruptLevel,
IN ULONG InterruptVector,
OUT PKIRQL Irql,
OUT PKAFFINITY Affinity
);
ULONG
HalpGetIsaIrqState(
ULONG Vector
);
extern INT_ROUTE_INTERFACE_STANDARD PciIrqRoutingInterface;
#if defined(_WIN64)
#define MM_HAL_RESERVED ((PVOID)HAL_VA_START)
#else
#define MM_HAL_RESERVED ((PVOID)0xffc00000)
#endif
#if defined(_HALPAE_)
#if defined(_AMD64_)
//
// For the purposes of the AMD64 HAL, "PAE" mode is always enabled, therefore
// no run-time PAE checks are necessary.
//
#define HalPaeEnabled() TRUE
#else // _AMD64_
//
// This hal supports PAE mode. Therefore checks need to be made at run-time
// to determine whether PAE is enabled or not.
//
BOOLEAN
__inline
HalPaeEnabled(
VOID
)
{
return SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] != FALSE;
}
#endif // _AMD64_
#else
//
// This hal does not support PAE mode. Therefore no run-time PAE checks
// are necessary.
//
#define HalPaeEnabled() FALSE
#endif
//
// The following inline functions and macros are used so that PHARDWARE_PTE
// can be used as a pointer to a four-byte legacy PTE or an eight-byte
// PAE PTE.
//
// With the exception of the PageFrameNumber field, all fields in these two
// different PTE formats are identical. Therefore access to these fields
// can be made directly.
//
// However, code in a PAE-enabled HAL may not access the PageFrameNumber
// of a PTE directly, nor may it make any assumptions about the size of a
// PTE or the number of address bits decoded by the page directory pointer
// table, the page directory or the page table. Instead, the following
// inline functions should be used.
//
ULONG
__inline
HalPteSize(
VOID
)
/*++
Routine Description:
This routine returns the size, in bytes, of a PTE.
Arguments:
None.
Return Value:
The size, in bytes, of a PTE.
--*/
{
if (HalPaeEnabled() != FALSE) {
return sizeof(HARDWARE_PTE_X86PAE);
} else {
return sizeof(HARDWARE_PTE_X86);
}
}
PHARDWARE_PTE
__inline
HalpIndexPteArray(
IN PHARDWARE_PTE BasePte,
IN ULONG Index
)
/*++
Routine Description:
This routine returns the address of a PTE within an array of PTEs.
Arguments:
BasePte - Pointer to the PTE array.
Index - Index within the PTE array.
Return Value:
Address of BasePte[ Index ]
--*/
{
PHARDWARE_PTE pointerPte;
pointerPte = (PHARDWARE_PTE)((ULONG_PTR)BasePte + Index * HalPteSize());
return pointerPte;
}
VOID
__inline
HalpAdvancePte(
IN OUT PHARDWARE_PTE *PointerPte,
IN ULONG Count
)
/*++
Routine Description:
This routine advances the value of a PTE pointer by the specified number
of PTEs.
Arguments:
PointerPte - Pointer to the PTE pointer to increment.
Count - Number of PTEs to advance the PTE pointer.
Return Value:
None.
--*/
{
*PointerPte = HalpIndexPteArray( *PointerPte, Count );
}
VOID
__inline
HalpIncrementPte(
IN PHARDWARE_PTE *PointerPte
)
/*++
Routine Description:
This routine increments the value of a PTE pointer by one PTE.
Arguments:
PointerPte - Pointer to the PTE pointer to increment.
Return Value:
None.
--*/
{
HalpAdvancePte( PointerPte, 1 );
}
VOID
__inline
HalpSetPageFrameNumber(
IN OUT PHARDWARE_PTE PointerPte,
IN ULONGLONG PageFrameNumber
)
/*++
Routine Description:
This routine sets the PageFrameNumber within a PTE.
Arguments:
PointerPte - Pointer to the PTE to modify.
Return Value:
None.
--*/
{
PHARDWARE_PTE_X86PAE pointerPtePae;
if (HalPaeEnabled() != FALSE) {
pointerPtePae = (PHARDWARE_PTE_X86PAE)PointerPte;
pointerPtePae->PageFrameNumber = PageFrameNumber;
} else {
PointerPte->PageFrameNumber = (ULONG_PTR)PageFrameNumber;
}
}
ULONGLONG
__inline
HalpGetPageFrameNumber(
IN PHARDWARE_PTE PointerPte
)
/*++
Routine Description:
This routine retrieves PageFrameNumber from within a PTE.
Arguments:
PointerPte - Pointer to the PTE to read.
Return Value:
The page frame number within the PTE.
--*/
{
PHARDWARE_PTE_X86PAE pointerPtePae;
ULONGLONG pageFrameNumber;
if (HalPaeEnabled() != FALSE) {
pointerPtePae = (PHARDWARE_PTE_X86PAE)PointerPte;
pageFrameNumber = pointerPtePae->PageFrameNumber;
} else {
pageFrameNumber = PointerPte->PageFrameNumber;
}
return pageFrameNumber;
}
VOID
__inline
HalpCopyPageFrameNumber(
OUT PHARDWARE_PTE DestinationPte,
IN PHARDWARE_PTE SourcePte
)
/*++
Routine Description:
This routine copies the page frame number from one PTE to another PTE.
Arguments:
DestinationPte - Pointer to the PTE in which the new page frame number
will be stored.
PointerPte - Pointer to the PTE from which the page frame number will be
read.
Return Value:
None.
--*/
{
ULONGLONG pageFrameNumber;
pageFrameNumber = HalpGetPageFrameNumber( SourcePte );
HalpSetPageFrameNumber( DestinationPte, pageFrameNumber );
}
BOOLEAN
__inline
HalpIsPteFree(
IN PHARDWARE_PTE PointerPte
)
/*++
Routine Description:
This routine determines whether a PTE is free or not. A free PTE is defined
here as one containing all zeros.
Arguments:
PointerPte - Pointer to the PTE for which the detmination is desired.
Return Value:
TRUE - The PTE is free.
FALSE - The PTE is not free.
--*/
{
ULONGLONG pteContents;
if (HalPaeEnabled() != FALSE) {
pteContents = *(PULONGLONG)PointerPte;
} else {
pteContents = *(PULONG)PointerPte;
}
if (pteContents == 0) {
return TRUE;
} else {
return FALSE;
}
}
VOID
__inline
HalpFreePte(
IN PHARDWARE_PTE PointerPte
)
/*++
Routine Description:
This routine sets a PTE to the free state. It does this by setting the
entire PTE to zero.
Arguments:
PointerPte - Pointer to the PTE to free.
Return Value:
None.
--*/
{
if (HalPaeEnabled() != FALSE) {
*((PULONGLONG)PointerPte) = 0;
} else {
*((PULONG)PointerPte) = 0;
}
}
PHARDWARE_PTE
__inline
MiGetPteAddress(
IN PVOID Va
)
/*++
Routine Description:
Given a virtual address, this routine returns a pointer to the mapping PTE.
Arguments:
Va - Virtual Address for which a PTE pointer is desired.
Return Value:
None.
--*/
{
PHARDWARE_PTE pointerPte;
if (HalPaeEnabled() != FALSE) {
pointerPte = (PHARDWARE_PTE)MiGetPteAddressPae( Va );
} else {
pointerPte = MiGetPteAddressX86( Va );
}
return pointerPte;
}
PHARDWARE_PTE
__inline
MiGetPdeAddress(
IN PVOID Va
)
/*++
Routine Description:
Given a virtual address, this routine returns a pointer to the mapping PDE.
Arguments:
Va - Virtual Address for which a PDE pointer is desired.
Return Value:
None.
--*/
{
PHARDWARE_PTE pointerPte;
if (HalPaeEnabled() != FALSE) {
pointerPte = (PHARDWARE_PTE)MiGetPdeAddressPae( Va );
} else {
pointerPte = MiGetPdeAddressX86( Va );
}
return pointerPte;
}
ULONG
__inline
MiGetPteIndex(
IN PVOID Va
)
/*++
Routine Description:
Given a virtual address, this routine returns the index of the mapping
PTE within its page table.
Arguments:
Va - Virtual Address for which the PTE index is desired.
Return Value:
None.
--*/
{
ULONG_PTR index;
if (HalPaeEnabled() != FALSE) {
index = MiGetPteIndexPae( Va );
} else {
index = MiGetPteIndexX86( Va );
}
return (ULONG)index;
}
ULONG
__inline
MiGetPdiShift(
VOID
)
/*++
Routine Description:
Returns the number of bits that an address should be shifted right in order
to right-justify the portion of the address mapped by a page directory
entry.
Arguments:
None.
Return Value:
The number of bits to shift right.
--*/
{
ULONG shift;
if (HalPaeEnabled() != FALSE) {
shift = PDI_SHIFT_X86PAE;
} else {
shift = PDI_SHIFT_X86;
}
return shift;
}
//
// ACPI specific stuff
//
NTSTATUS
HalpSetupAcpiPhase0(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
NTSTATUS
HalpAcpiFindRsdtPhase0(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
HaliHaltSystem(
VOID
);
VOID
HalpCheckPowerButton(
VOID
);
VOID
HalpRegisterHibernate(
VOID
);
VOID
FASTCALL
HalProcessorThrottle (
IN UCHAR Throttle
);
VOID
HalpSaveInterruptControllerState(
VOID
);
VOID
HalpSaveDmaControllerState(
VOID
);
VOID
HalpSaveTimerState(
VOID
);
VOID
HalpRestoreInterruptControllerState(
VOID
);
VOID
HalpSetInterruptControllerWakeupState(
ULONG Context
);
VOID
HalpRestorePicEdgeLevelRegister(
VOID
);
VOID
HalpSetAcpiEdgeLevelRegister(
VOID
);
VOID
HalpRestoreDmaControllerState(
VOID
);
VOID
HalpRestoreTimerState(
VOID
);
NTSTATUS
HalacpiGetInterruptTranslator(
IN INTERFACE_TYPE ParentInterfaceType,
IN ULONG ParentBusNumber,
IN INTERFACE_TYPE BridgeInterfaceType,
IN USHORT Size,
IN USHORT Version,
OUT PTRANSLATOR_INTERFACE Translator,
OUT PULONG BridgeBusNumber
);
VOID
HalpInitNonBusHandler (
VOID
);
VOID
HalpMapNvsArea(
VOID
);
VOID
HalpPreserveNvsArea(
VOID
);
VOID
HalpRestoreNvsArea(
VOID
);
VOID
HalpFreeNvsBuffers(
VOID
);
VOID
HalpPowerStateCallback(
IN PVOID CallbackContext,
IN PVOID Argument1,
IN PVOID Argument2
);
NTSTATUS
HalpBuildResumeStructures(
VOID
);
NTSTATUS
HalpFreeResumeStructures(
VOID
);
typedef struct {
UCHAR MasterMask;
UCHAR SlaveMask;
UCHAR MasterEdgeLevelControl;
UCHAR SlaveEdgeLevelControl;
} PIC_CONTEXT, *PPIC_CONTEXT;
#define EISA_DMA_CHANNELS 8
typedef struct {
UCHAR Dma1ExtendedModePort;
UCHAR Dma2ExtendedModePort;
DMA1_CONTROL Dma1Control;
DMA2_CONTROL Dma2Control;
} DMA_CONTEXT, *PDMA_CONTEXT;
typedef struct {
UCHAR nothing;
} TIMER_CONTEXT, *PTIMER_CONTEXT;
typedef struct {
PIC_CONTEXT PicState;
DMA_CONTEXT DmaState;
} MOTHERBOARD_CONTEXT, *PMOTHERBOARD_CONTEXT;
typedef struct {
UCHAR ChannelMode;
UCHAR ChannelExtendedMode;
UCHAR ChannelMask;
BOOLEAN ChannelProgrammed; // Adapter created, mode set
#if DBG
BOOLEAN ChannelBusy;
#endif
} DMA_CHANNEL_CONTEXT;
extern MOTHERBOARD_CONTEXT HalpMotherboardState;
extern PVOID HalpSleepPageLock;
extern PVOID HalpSleepPage16Lock;
extern DMA_CHANNEL_CONTEXT HalpDmaChannelState[];
ULONG
HalpcGetCmosDataByType(
IN CMOS_DEVICE_TYPE CmosType,
IN ULONG SourceAddress,
IN PUCHAR DataBuffer,
IN ULONG ByteCount
);
ULONG
HalpcSetCmosDataByType(
IN CMOS_DEVICE_TYPE CmosType,
IN ULONG SourceAddress,
IN PUCHAR DataBuffer,
IN ULONG ByteCount
);
NTSTATUS
HalpOpenRegistryKey(
OUT PHANDLE Handle,
IN HANDLE BaseHandle OPTIONAL,
IN PUNICODE_STRING KeyName,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN Create
);
#ifdef WANT_IRQ_ROUTING
NTSTATUS
HalpInitIrqArbiter (
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
HalpFillInIrqArbiter (
IN PDEVICE_OBJECT HalFdo,
IN LPCGUID InterfaceType,
IN USHORT Version,
IN PVOID InterfaceSpecificData,
IN ULONG InterfaceBufferSize,
IN OUT PINTERFACE Interface,
IN OUT PULONG Length
);
VOID
HalpIrqArbiterInterfaceReference(
IN PVOID Context
);
VOID
HalpIrqArbiterInterfaceDereference(
IN PVOID Context
);
#endif
//
// PnPBIOS specific stuff
//
VOID
HalpMarkChipsetDecode(
BOOLEAN FullDecodeChipset
);
ULONG
HalpPhase0SetPciDataByOffset (
ULONG BusNumber,
ULONG SlotNumber,
PVOID Buffer,
ULONG Offset,
ULONG Length
);
ULONG
HalpPhase0GetPciDataByOffset (
ULONG BusNumber,
ULONG SlotNumber,
PVOID Buffer,
ULONG Offset,
ULONG Length
);
NTSTATUS
HalpSetupPciDeviceForDebugging(
IN PLOADER_PARAMETER_BLOCK LoaderBlock, OPTIONAL
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
);
NTSTATUS
HalpReleasePciDeviceForDebugging(
IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
);
VOID
HalpRegisterKdSupportFunctions(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
HalpRegisterPciDebuggingDeviceInfo(
VOID
);
#endif // _HALP_H_