5 #ifndef __INTERNAL_HAL_HAL_H
6 #define __INTERNAL_HAL_HAL_H
8 #define HAL_APC_REQUEST 0
9 #define HAL_DPC_REQUEST 1
11 /* CMOS Registers and Ports */
12 #define CMOS_CONTROL_PORT (PUCHAR)0x70
13 #define CMOS_DATA_PORT (PUCHAR)0x71
14 #define RTC_REGISTER_A 0x0A
15 #define RTC_REGISTER_B 0x0B
16 #define RTC_REG_A_UIP 0x80
17 #define RTC_REGISTER_CENTURY 0x32
20 #define IDT_REGISTERED 0x01
21 #define IDT_LATCHED 0x02
22 #define IDT_INTERNAL 0x11
23 #define IDT_DEVICE 0x21
25 /* Conversion functions */
26 #define BCD_INT(bcd) \
27 (((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
28 #define INT_BCD(int) \
29 (UCHAR)(((int / 10) << 4) + (int % 10))
32 // Commonly stated as being 1.19318MHz
34 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
37 // However, the true value is closer to 1.19318181[...]81MHz since this is 1/3rd
38 // of the NTSC color subcarrier frequency which runs at 3.57954545[...]45MHz.
40 // Note that Windows uses 1.193167MHz which seems to have no basis. However, if
41 // one takes the NTSC color subcarrier frequency as being 3.579545 (trimming the
42 // infinite series) and divides it by three, one obtains 1.19318167.
44 // It may be that the original NT HAL source code introduced a typo and turned
45 // 119318167 into 1193167 by ommitting the "18". This is very plausible as the
46 // number is quite long.
48 #define PIT_FREQUENCY 1193182
51 // These ports are controlled by the i8254 Programmable Interrupt Timer (PIT)
53 #define TIMER_CHANNEL0_DATA_PORT 0x40
54 #define TIMER_CHANNEL1_DATA_PORT 0x41
55 #define TIMER_CHANNEL2_DATA_PORT 0x42
56 #define TIMER_CONTROL_PORT 0x43
59 // Mode 0 - Interrupt On Terminal Count
60 // Mode 1 - Hardware Re-triggerable One-Shot
61 // Mode 2 - Rate Generator
62 // Mode 3 - Square Wave Generator
63 // Mode 4 - Software Triggered Strobe
64 // Mode 5 - Hardware Triggered Strobe
66 typedef enum _TIMER_OPERATING_MODES
74 PitOperatingMode2Reserved
,
75 PitOperatingMode5Reserved
76 } TIMER_OPERATING_MODES
;
78 typedef enum _TIMER_ACCESS_MODES
80 PitAccessModeCounterLatch
,
86 typedef enum _TIMER_CHANNELS
94 typedef union _TIMER_CONTROL_PORT_REGISTER
99 TIMER_OPERATING_MODES OperatingMode
:3;
100 TIMER_ACCESS_MODES AccessMode
:2;
101 TIMER_CHANNELS Channel
:2;
104 } TIMER_CONTROL_PORT_REGISTER
, *PTIMER_CONTROL_PORT_REGISTER
;
107 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
110 // This port is controled by the i8255 Programmable Peripheral Interface (PPI)
112 #define SYSTEM_CONTROL_PORT_A 0x92
113 #define SYSTEM_CONTROL_PORT_B 0x61
114 typedef union _SYSTEM_CONTROL_PORT_B_REGISTER
118 UCHAR Timer2GateToSpeaker
:1;
119 UCHAR SpeakerDataEnable
:1;
120 UCHAR ParityCheckEnable
:1;
121 UCHAR ChannelCheckEnable
:1;
122 UCHAR RefreshRequest
:1;
123 UCHAR Timer2Output
:1;
124 UCHAR ChannelCheck
:1;
128 } SYSTEM_CONTROL_PORT_B_REGISTER
, *PSYSTEM_CONTROL_PORT_B_REGISTER
;
131 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
134 // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
136 #define PIC1_CONTROL_PORT 0x20
137 #define PIC1_DATA_PORT 0x21
138 #define PIC2_CONTROL_PORT 0xA0
139 #define PIC2_DATA_PORT 0xA1
142 // Definitions for ICW/OCW Bits
144 typedef enum _I8259_ICW1_OPERATING_MODE
148 } I8259_ICW1_OPERATING_MODE
;
150 typedef enum _I8259_ICW1_INTERRUPT_MODE
154 } I8259_ICW1_INTERRUPT_MODE
;
156 typedef enum _I8259_ICW1_INTERVAL
160 } I8259_ICW1_INTERVAL
;
162 typedef enum _I8259_ICW4_SYSTEM_MODE
166 } I8259_ICW4_SYSTEM_MODE
;
168 typedef enum _I8259_ICW4_EOI_MODE
172 } I8259_ICW4_EOI_MODE
;
174 typedef enum _I8259_ICW4_BUFFERED_MODE
180 } I8259_ICW4_BUFFERED_MODE
;
182 typedef enum _I8259_READ_REQUEST
188 } I8259_READ_REQUEST
;
190 typedef enum _I8259_EOI_MODE
203 // Definitions for ICW Registers
205 typedef union _I8259_ICW1
210 I8259_ICW1_OPERATING_MODE OperatingMode
:1;
211 I8259_ICW1_INTERVAL Interval
:1;
212 I8259_ICW1_INTERRUPT_MODE InterruptMode
:1;
214 UCHAR InterruptVectorAddress
:3;
217 } I8259_ICW1
, *PI8259_ICW1
;
219 typedef union _I8259_ICW2
224 UCHAR InterruptVector
:5;
227 } I8259_ICW2
, *PI8259_ICW2
;
229 typedef union _I8259_ICW3
251 } I8259_ICW3
, *PI8259_ICW3
;
253 typedef union _I8259_ICW4
257 I8259_ICW4_SYSTEM_MODE SystemMode
:1;
258 I8259_ICW4_EOI_MODE EoiMode
:1;
259 I8259_ICW4_BUFFERED_MODE BufferedMode
:2;
260 UCHAR SpecialFullyNestedMode
:1;
264 } I8259_ICW4
, *PI8259_ICW4
;
266 typedef union _I8259_OCW2
272 I8259_EOI_MODE EoiMode
:3;
275 } I8259_OCW2
, *PI8259_OCW2
;
277 typedef union _I8259_OCW3
281 I8259_READ_REQUEST ReadRequest
:2;
285 UCHAR SpecialMaskMode
:2;
289 } I8259_OCW3
, *PI8259_OCW3
;
291 typedef union _I8259_ISR
308 } I8259_ISR
, *PI8259_ISR
;
310 typedef I8259_ISR I8259_IDR
, *PI8259_IDR
;
313 // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
316 // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
318 #define EISA_ELCR_MASTER 0x4D0
319 #define EISA_ELCR_SLAVE 0x4D1
321 typedef union _EISA_ELCR
349 } EISA_ELCR
, *PEISA_ELCR
;
351 typedef struct _PIC_MASK
362 } PIC_MASK
, *PPIC_MASK
;
366 (*PHAL_SW_INTERRUPT_HANDLER
)(
372 __attribute__((regparm(3)))
373 (*PHAL_DISMISS_INTERRUPT
)(
380 __attribute__((regparm(3)))
381 HalpDismissIrqGeneric(
388 __attribute__((regparm(3)))
396 __attribute__((regparm(3)))
404 __attribute__((regparm(3)))
412 // Mm PTE/PDE to Hal PTE/PDE
414 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
415 #define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
417 typedef struct _IDTUsageFlags
425 UCHAR BusReleativeVector
;
428 typedef struct _HalAddressUsage
430 struct _HalAddressUsage
*Next
;
431 CM_RESOURCE_TYPE Type
;
438 } ADDRESS_USAGE
, *PADDRESS_USAGE
;
441 PADAPTER_OBJECT NTAPI
HalpAllocateAdapterEx(ULONG NumberOfMapRegisters
,BOOLEAN IsMaster
, BOOLEAN Dma32BitAddresses
);
446 HalpRegisterVector(IN UCHAR Flags
,
448 IN ULONG SystemVector
,
453 HalpEnableInterruptHandler(IN UCHAR Flags
,
455 IN ULONG SystemVector
,
458 IN KINTERRUPT_MODE Mode
);
461 VOID NTAPI
HalpInitializePICs(IN BOOLEAN EnableInterrupts
);
462 VOID
HalpApcInterrupt(VOID
);
463 VOID
HalpDispatchInterrupt(VOID
);
466 VOID NTAPI
HalpInitializeClock(VOID
);
470 HalpCalibrateStallExecution(VOID
);
473 VOID
HalpInitPciBus (VOID
);
476 VOID
HalpInitDma (VOID
);
478 /* Non-generic initialization */
479 VOID
HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock
);
480 VOID
HalpInitPhase1(VOID
);
481 VOID NTAPI
HalpClockInterrupt(VOID
);
482 VOID NTAPI
HalpProfileInterrupt(VOID
);
493 HalpCheckPowerButton(
499 HalpRegisterKdSupportFunctions(
505 HalpSetupPciDeviceForDebugging(
506 IN PVOID LoaderBlock
,
507 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
512 HalpReleasePciDeviceForDebugging(
513 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
521 HalpMapPhysicalMemory64(
522 IN PHYSICAL_ADDRESS PhysicalAddress
,
528 HalpUnmapVirtualAddress(
529 IN PVOID VirtualAddress
,
536 HaliQuerySystemInformation(
537 IN HAL_QUERY_INFORMATION_CLASS InformationClass
,
540 OUT PULONG ReturnedLength
545 HaliSetSystemInformation(
546 IN HAL_SET_INFORMATION_CLASS InformationClass
,
556 HalpBiosDisplayReset(
579 // Processor Halt Routine
588 // CMOS initialization
597 // Spinlock for protecting CMOS access
601 HalpAcquireSystemHardwareSpinLock(
607 HalpReleaseCmosSpinLock(
612 // This is duplicated from ke_x.h
616 // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
620 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
622 /* Make sure that we don't own the lock already */
623 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) == *SpinLock
)
625 /* We do, bugcheck! */
626 KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
631 /* Try to acquire it */
632 if (InterlockedBitTestAndSet((PLONG
)SpinLock
, 0))
634 /* Value changed... wait until it's locked */
635 while (*(volatile KSPIN_LOCK
*)SpinLock
== 1)
638 /* On debug builds, we use a much slower but useful routine */
639 //Kii386SpinOnSpinLock(SpinLock, 5);
641 /* FIXME: Do normal yield for now */
644 /* Otherwise, just yield and keep looping */
652 /* On debug builds, we OR in the KTHREAD */
653 *SpinLock
= (KSPIN_LOCK
)KeGetCurrentThread() | 1;
655 /* All is well, break out */
662 // Spinlock Release at IRQL >= DISPATCH_LEVEL
666 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
669 /* Make sure that the threads match */
670 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) != *SpinLock
)
672 /* They don't, bugcheck */
673 KeBugCheckEx(SPIN_LOCK_NOT_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
677 InterlockedAnd((PLONG
)SpinLock
, 0);
683 // Spinlock Acquire at IRQL >= DISPATCH_LEVEL
687 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
689 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
690 UNREFERENCED_PARAMETER(SpinLock
);
694 // Spinlock Release at IRQL >= DISPATCH_LEVEL
698 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
700 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
701 UNREFERENCED_PARAMETER(SpinLock
);
707 #define KfLowerIrql KeLowerIrql
709 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
710 #define KiAcquireSpinLock(SpinLock)
711 #define KiReleaseSpinLock(SpinLock)
712 #define KfAcquireSpinLock(SpinLock) KfRaiseIrql(DISPATCH_LEVEL);
713 #define KfReleaseSpinLock(SpinLock, OldIrql) KeLowerIrql(OldIrql);
714 #endif // !CONFIG_SMP
717 extern BOOLEAN HalpNMIInProgress
;
719 extern PVOID HalpRealModeStart
;
720 extern PVOID HalpRealModeEnd
;
722 extern ADDRESS_USAGE HalpDefaultIoSpace
;
724 extern KSPIN_LOCK HalpSystemHardwareLock
;
726 extern PADDRESS_USAGE HalpAddressUsageList
;
728 #endif /* __INTERNAL_HAL_HAL_H */