5 #ifndef __INTERNAL_HAL_HAL_H
6 #define __INTERNAL_HAL_HAL_H
8 typedef struct _HAL_BIOS_FRAME
15 PKTRAP_FRAME TrapFrame
;
23 } HAL_BIOS_FRAME
, *PHAL_BIOS_FRAME
;
25 #define HAL_APC_REQUEST 0
26 #define HAL_DPC_REQUEST 1
28 /* CMOS Registers and Ports */
29 #define CMOS_CONTROL_PORT (PUCHAR)0x70
30 #define CMOS_DATA_PORT (PUCHAR)0x71
31 #define RTC_REGISTER_A 0x0A
32 #define RTC_REGISTER_B 0x0B
33 #define RTC_REG_A_UIP 0x80
34 #define RTC_REGISTER_CENTURY 0x32
37 #define IDT_REGISTERED 0x01
38 #define IDT_LATCHED 0x02
39 #define IDT_INTERNAL 0x11
40 #define IDT_DEVICE 0x21
42 /* Conversion functions */
43 #define BCD_INT(bcd) \
44 (((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
45 #define INT_BCD(int) \
46 (UCHAR)(((int / 10) << 4) + (int % 10))
51 #define VIDEO_SERVICES 0x10
54 // Operations for INT 10h (in AH)
56 #define SET_VIDEO_MODE 0x00
59 // Video Modes for INT10h AH=00 (in AL)
61 #define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
64 // Generates a 16-bit (real-mode or Virtual 8086) BIOS interrupt with a given AX */
68 HalpCallBiosInterrupt(IN ULONG Interrupt
,
74 "movl $%c[v], %%eax\n"
83 // Constructs a stack of the given size and alignment in the real-mode .text region */
87 HalpRealModeStack(IN ULONG Alignment
,
94 ".globl _HalpRealModeEnd\n_HalpRealModeEnd:\n"
102 // Commonly stated as being 1.19318MHz
104 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
107 // However, the true value is closer to 1.19318181[...]81MHz since this is 1/3rd
108 // of the NTSC color subcarrier frequency which runs at 3.57954545[...]45MHz.
110 // Note that Windows uses 1.193167MHz which seems to have no basis. However, if
111 // one takes the NTSC color subcarrier frequency as being 3.579545 (trimming the
112 // infinite series) and divides it by three, one obtains 1.19318167.
114 // It may be that the original NT HAL source code introduced a typo and turned
115 // 119318167 into 1193167 by ommitting the "18". This is very plausible as the
116 // number is quite long.
118 #define PIT_FREQUENCY 1193182
121 // These ports are controlled by the i8254 Programmable Interrupt Timer (PIT)
123 #define TIMER_CHANNEL0_DATA_PORT 0x40
124 #define TIMER_CHANNEL1_DATA_PORT 0x41
125 #define TIMER_CHANNEL2_DATA_PORT 0x42
126 #define TIMER_CONTROL_PORT 0x43
129 // Mode 0 - Interrupt On Terminal Count
130 // Mode 1 - Hardware Re-triggerable One-Shot
131 // Mode 2 - Rate Generator
132 // Mode 3 - Square Wave Generator
133 // Mode 4 - Software Triggered Strobe
134 // Mode 5 - Hardware Triggered Strobe
136 typedef enum _TIMER_OPERATING_MODES
144 PitOperatingMode2Reserved
,
145 PitOperatingMode5Reserved
146 } TIMER_OPERATING_MODES
;
148 typedef enum _TIMER_ACCESS_MODES
150 PitAccessModeCounterLatch
,
154 } TIMER_ACCESS_MODES
;
156 typedef enum _TIMER_CHANNELS
164 typedef union _TIMER_CONTROL_PORT_REGISTER
169 TIMER_OPERATING_MODES OperatingMode
:3;
170 TIMER_ACCESS_MODES AccessMode
:2;
171 TIMER_CHANNELS Channel
:2;
174 } TIMER_CONTROL_PORT_REGISTER
, *PTIMER_CONTROL_PORT_REGISTER
;
177 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
180 // This port is controled by the i8255 Programmable Peripheral Interface (PPI)
182 #define SYSTEM_CONTROL_PORT_A 0x92
183 #define SYSTEM_CONTROL_PORT_B 0x61
184 typedef union _SYSTEM_CONTROL_PORT_B_REGISTER
188 UCHAR Timer2GateToSpeaker
:1;
189 UCHAR SpeakerDataEnable
:1;
190 UCHAR ParityCheckEnable
:1;
191 UCHAR ChannelCheckEnable
:1;
192 UCHAR RefreshRequest
:1;
193 UCHAR Timer2Output
:1;
194 UCHAR ChannelCheck
:1;
198 } SYSTEM_CONTROL_PORT_B_REGISTER
, *PSYSTEM_CONTROL_PORT_B_REGISTER
;
201 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
204 // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
206 #define PIC1_CONTROL_PORT 0x20
207 #define PIC1_DATA_PORT 0x21
208 #define PIC2_CONTROL_PORT 0xA0
209 #define PIC2_DATA_PORT 0xA1
212 // Definitions for ICW/OCW Bits
214 typedef enum _I8259_ICW1_OPERATING_MODE
218 } I8259_ICW1_OPERATING_MODE
;
220 typedef enum _I8259_ICW1_INTERRUPT_MODE
224 } I8259_ICW1_INTERRUPT_MODE
;
226 typedef enum _I8259_ICW1_INTERVAL
230 } I8259_ICW1_INTERVAL
;
232 typedef enum _I8259_ICW4_SYSTEM_MODE
236 } I8259_ICW4_SYSTEM_MODE
;
238 typedef enum _I8259_ICW4_EOI_MODE
242 } I8259_ICW4_EOI_MODE
;
244 typedef enum _I8259_ICW4_BUFFERED_MODE
250 } I8259_ICW4_BUFFERED_MODE
;
252 typedef enum _I8259_READ_REQUEST
258 } I8259_READ_REQUEST
;
260 typedef enum _I8259_EOI_MODE
273 // Definitions for ICW Registers
275 typedef union _I8259_ICW1
280 I8259_ICW1_OPERATING_MODE OperatingMode
:1;
281 I8259_ICW1_INTERVAL Interval
:1;
282 I8259_ICW1_INTERRUPT_MODE InterruptMode
:1;
284 UCHAR InterruptVectorAddress
:3;
287 } I8259_ICW1
, *PI8259_ICW1
;
289 typedef union _I8259_ICW2
294 UCHAR InterruptVector
:5;
297 } I8259_ICW2
, *PI8259_ICW2
;
299 typedef union _I8259_ICW3
321 } I8259_ICW3
, *PI8259_ICW3
;
323 typedef union _I8259_ICW4
327 I8259_ICW4_SYSTEM_MODE SystemMode
:1;
328 I8259_ICW4_EOI_MODE EoiMode
:1;
329 I8259_ICW4_BUFFERED_MODE BufferedMode
:2;
330 UCHAR SpecialFullyNestedMode
:1;
334 } I8259_ICW4
, *PI8259_ICW4
;
336 typedef union _I8259_OCW2
342 I8259_EOI_MODE EoiMode
:3;
345 } I8259_OCW2
, *PI8259_OCW2
;
347 typedef union _I8259_OCW3
351 I8259_READ_REQUEST ReadRequest
:2;
355 UCHAR SpecialMaskMode
:2;
359 } I8259_OCW3
, *PI8259_OCW3
;
361 typedef union _I8259_ISR
378 } I8259_ISR
, *PI8259_ISR
;
380 typedef I8259_ISR I8259_IDR
, *PI8259_IDR
;
383 // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
386 // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
388 #define EISA_ELCR_MASTER 0x4D0
389 #define EISA_ELCR_SLAVE 0x4D1
391 typedef union _EISA_ELCR
419 } EISA_ELCR
, *PEISA_ELCR
;
421 typedef struct _PIC_MASK
432 } PIC_MASK
, *PPIC_MASK
;
436 (*PHAL_SW_INTERRUPT_HANDLER
)(
442 __attribute__((regparm(3)))
443 (*PHAL_DISMISS_INTERRUPT
)(
450 __attribute__((regparm(3)))
451 HalpDismissIrqGeneric(
458 __attribute__((regparm(3)))
466 __attribute__((regparm(3)))
474 __attribute__((regparm(3)))
482 // Mm PTE/PDE to Hal PTE/PDE
484 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
485 #define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
487 typedef struct _IDTUsageFlags
495 UCHAR BusReleativeVector
;
498 typedef struct _HalAddressUsage
500 struct _HalAddressUsage
*Next
;
501 CM_RESOURCE_TYPE Type
;
508 } ADDRESS_USAGE
, *PADDRESS_USAGE
;
511 PADAPTER_OBJECT NTAPI
HalpAllocateAdapterEx(ULONG NumberOfMapRegisters
,BOOLEAN IsMaster
, BOOLEAN Dma32BitAddresses
);
516 HalpRegisterVector(IN UCHAR Flags
,
518 IN ULONG SystemVector
,
523 HalpEnableInterruptHandler(IN UCHAR Flags
,
525 IN ULONG SystemVector
,
528 IN KINTERRUPT_MODE Mode
);
531 VOID NTAPI
HalpInitializePICs(IN BOOLEAN EnableInterrupts
);
532 VOID
HalpApcInterrupt(VOID
);
533 VOID
HalpDispatchInterrupt(VOID
);
536 VOID NTAPI
HalpInitializeClock(VOID
);
540 HalpCalibrateStallExecution(VOID
);
543 VOID
HalpInitPciBus (VOID
);
546 VOID
HalpInitDma (VOID
);
548 /* Non-generic initialization */
549 VOID
HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock
);
550 VOID
HalpInitPhase1(VOID
);
551 VOID NTAPI
HalpClockInterrupt(VOID
);
552 VOID NTAPI
HalpProfileInterrupt(VOID
);
563 HalpCheckPowerButton(
569 HalpRegisterKdSupportFunctions(
575 HalpSetupPciDeviceForDebugging(
576 IN PVOID LoaderBlock
,
577 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
582 HalpReleasePciDeviceForDebugging(
583 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
591 HalpMapPhysicalMemory64(
592 IN PHYSICAL_ADDRESS PhysicalAddress
,
598 HalpUnmapVirtualAddress(
599 IN PVOID VirtualAddress
,
606 HaliQuerySystemInformation(
607 IN HAL_QUERY_INFORMATION_CLASS InformationClass
,
610 OUT PULONG ReturnedLength
615 HaliSetSystemInformation(
616 IN HAL_SET_INFORMATION_CLASS InformationClass
,
626 HalpBiosDisplayReset(
631 // Processor Halt Routine
640 // CMOS initialization
649 // Spinlock for protecting CMOS access
653 HalpAcquireSystemHardwareSpinLock(
659 HalpReleaseCmosSpinLock(
664 // This is duplicated from ke_x.h
668 // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
672 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
674 /* Make sure that we don't own the lock already */
675 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) == *SpinLock
)
677 /* We do, bugcheck! */
678 KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
683 /* Try to acquire it */
684 if (InterlockedBitTestAndSet((PLONG
)SpinLock
, 0))
686 /* Value changed... wait until it's locked */
687 while (*(volatile KSPIN_LOCK
*)SpinLock
== 1)
690 /* On debug builds, we use a much slower but useful routine */
691 //Kii386SpinOnSpinLock(SpinLock, 5);
693 /* FIXME: Do normal yield for now */
696 /* Otherwise, just yield and keep looping */
704 /* On debug builds, we OR in the KTHREAD */
705 *SpinLock
= (KSPIN_LOCK
)KeGetCurrentThread() | 1;
707 /* All is well, break out */
714 // Spinlock Release at IRQL >= DISPATCH_LEVEL
718 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
721 /* Make sure that the threads match */
722 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) != *SpinLock
)
724 /* They don't, bugcheck */
725 KeBugCheckEx(SPIN_LOCK_NOT_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
729 InterlockedAnd((PLONG
)SpinLock
, 0);
735 // Spinlock Acquire at IRQL >= DISPATCH_LEVEL
739 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
741 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
742 UNREFERENCED_PARAMETER(SpinLock
);
746 // Spinlock Release at IRQL >= DISPATCH_LEVEL
750 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
752 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
753 UNREFERENCED_PARAMETER(SpinLock
);
759 #define KfLowerIrql KeLowerIrql
761 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
762 #define KiAcquireSpinLock(SpinLock)
763 #define KiReleaseSpinLock(SpinLock)
764 #define KfAcquireSpinLock(SpinLock) KfRaiseIrql(DISPATCH_LEVEL);
765 #define KfReleaseSpinLock(SpinLock, OldIrql) KeLowerIrql(OldIrql);
766 #endif // !CONFIG_SMP
769 extern BOOLEAN HalpNMIInProgress
;
771 extern ADDRESS_USAGE HalpDefaultIoSpace
;
773 extern KSPIN_LOCK HalpSystemHardwareLock
;
775 extern PADDRESS_USAGE HalpAddressUsageList
;
777 #endif /* __INTERNAL_HAL_HAL_H */