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
;
27 (*PHAL_SW_INTERRUPT_HANDLER
)(
34 (*PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY
)(
35 IN PKTRAP_FRAME TrapFrame
38 #define HAL_APC_REQUEST 0
39 #define HAL_DPC_REQUEST 1
41 /* CMOS Registers and Ports */
42 #define CMOS_CONTROL_PORT (PUCHAR)0x70
43 #define CMOS_DATA_PORT (PUCHAR)0x71
44 #define RTC_REGISTER_A 0x0A
45 #define RTC_REGISTER_B 0x0B
46 #define RTC_REG_A_UIP 0x80
47 #define RTC_REGISTER_CENTURY 0x32
50 #define IDT_REGISTERED 0x01
51 #define IDT_LATCHED 0x02
52 #define IDT_INTERNAL 0x11
53 #define IDT_DEVICE 0x21
55 /* Conversion functions */
56 #define BCD_INT(bcd) \
57 (((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
58 #define INT_BCD(int) \
59 (UCHAR)(((int / 10) << 4) + (int % 10))
64 #define VIDEO_SERVICES 0x10
67 // Operations for INT 10h (in AH)
69 #define SET_VIDEO_MODE 0x00
72 // Video Modes for INT10h AH=00 (in AL)
74 #define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
77 // Generates a 16-bit (real-mode or Virtual 8086) BIOS interrupt with a given AX */
81 HalpCallBiosInterrupt(IN ULONG Interrupt
,
87 "movl $%c[v], %%eax\n"
96 // Constructs a stack of the given size and alignment in the real-mode .text region */
100 HalpRealModeStack(IN ULONG Alignment
,
107 ".globl _HalpRealModeEnd\n_HalpRealModeEnd:\n"
109 : [v
] "i"(Alignment
),
115 // Nested Trap Trampoline
120 HalpNestedTrap(IN KIRQL PendingIrql
)
122 /* Use the second interrupt handler table */
123 extern PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2
[3];
126 "movl %c[t], %%ecx\n"
129 : "im"(SWInterruptHandlerTable2
[PendingIrql
]),
130 [t
] "i"(&PCR
->VdmAlert
)
137 // Commonly stated as being 1.19318MHz
139 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
142 // However, the true value is closer to 1.19318181[...]81MHz since this is 1/3rd
143 // of the NTSC color subcarrier frequency which runs at 3.57954545[...]45MHz.
145 // Note that Windows uses 1.193167MHz which seems to have no basis. However, if
146 // one takes the NTSC color subcarrier frequency as being 3.579545 (trimming the
147 // infinite series) and divides it by three, one obtains 1.19318167.
149 // It may be that the original NT HAL source code introduced a typo and turned
150 // 119318167 into 1193167 by ommitting the "18". This is very plausible as the
151 // number is quite long.
153 #define PIT_FREQUENCY 1193182
156 // These ports are controlled by the i8254 Programmable Interrupt Timer (PIT)
158 #define TIMER_CHANNEL0_DATA_PORT 0x40
159 #define TIMER_CHANNEL1_DATA_PORT 0x41
160 #define TIMER_CHANNEL2_DATA_PORT 0x42
161 #define TIMER_CONTROL_PORT 0x43
164 // Mode 0 - Interrupt On Terminal Count
165 // Mode 1 - Hardware Re-triggerable One-Shot
166 // Mode 2 - Rate Generator
167 // Mode 3 - Square Wave Generator
168 // Mode 4 - Software Triggered Strobe
169 // Mode 5 - Hardware Triggered Strobe
171 typedef enum _TIMER_OPERATING_MODES
179 PitOperatingMode2Reserved
,
180 PitOperatingMode5Reserved
181 } TIMER_OPERATING_MODES
;
183 typedef enum _TIMER_ACCESS_MODES
185 PitAccessModeCounterLatch
,
189 } TIMER_ACCESS_MODES
;
191 typedef enum _TIMER_CHANNELS
199 typedef union _TIMER_CONTROL_PORT_REGISTER
204 TIMER_OPERATING_MODES OperatingMode
:3;
205 TIMER_ACCESS_MODES AccessMode
:2;
206 TIMER_CHANNELS Channel
:2;
209 } TIMER_CONTROL_PORT_REGISTER
, *PTIMER_CONTROL_PORT_REGISTER
;
212 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
215 // This port is controled by the i8255 Programmable Peripheral Interface (PPI)
217 #define SYSTEM_CONTROL_PORT_A 0x92
218 #define SYSTEM_CONTROL_PORT_B 0x61
219 typedef union _SYSTEM_CONTROL_PORT_B_REGISTER
223 UCHAR Timer2GateToSpeaker
:1;
224 UCHAR SpeakerDataEnable
:1;
225 UCHAR ParityCheckEnable
:1;
226 UCHAR ChannelCheckEnable
:1;
227 UCHAR RefreshRequest
:1;
228 UCHAR Timer2Output
:1;
229 UCHAR ChannelCheck
:1;
233 } SYSTEM_CONTROL_PORT_B_REGISTER
, *PSYSTEM_CONTROL_PORT_B_REGISTER
;
236 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
239 // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
241 #define PIC1_CONTROL_PORT 0x20
242 #define PIC1_DATA_PORT 0x21
243 #define PIC2_CONTROL_PORT 0xA0
244 #define PIC2_DATA_PORT 0xA1
247 // Definitions for ICW/OCW Bits
249 typedef enum _I8259_ICW1_OPERATING_MODE
253 } I8259_ICW1_OPERATING_MODE
;
255 typedef enum _I8259_ICW1_INTERRUPT_MODE
259 } I8259_ICW1_INTERRUPT_MODE
;
261 typedef enum _I8259_ICW1_INTERVAL
265 } I8259_ICW1_INTERVAL
;
267 typedef enum _I8259_ICW4_SYSTEM_MODE
271 } I8259_ICW4_SYSTEM_MODE
;
273 typedef enum _I8259_ICW4_EOI_MODE
277 } I8259_ICW4_EOI_MODE
;
279 typedef enum _I8259_ICW4_BUFFERED_MODE
285 } I8259_ICW4_BUFFERED_MODE
;
287 typedef enum _I8259_READ_REQUEST
293 } I8259_READ_REQUEST
;
295 typedef enum _I8259_EOI_MODE
308 // Definitions for ICW Registers
310 typedef union _I8259_ICW1
315 I8259_ICW1_OPERATING_MODE OperatingMode
:1;
316 I8259_ICW1_INTERVAL Interval
:1;
317 I8259_ICW1_INTERRUPT_MODE InterruptMode
:1;
319 UCHAR InterruptVectorAddress
:3;
322 } I8259_ICW1
, *PI8259_ICW1
;
324 typedef union _I8259_ICW2
329 UCHAR InterruptVector
:5;
332 } I8259_ICW2
, *PI8259_ICW2
;
334 typedef union _I8259_ICW3
356 } I8259_ICW3
, *PI8259_ICW3
;
358 typedef union _I8259_ICW4
362 I8259_ICW4_SYSTEM_MODE SystemMode
:1;
363 I8259_ICW4_EOI_MODE EoiMode
:1;
364 I8259_ICW4_BUFFERED_MODE BufferedMode
:2;
365 UCHAR SpecialFullyNestedMode
:1;
369 } I8259_ICW4
, *PI8259_ICW4
;
371 typedef union _I8259_OCW2
377 I8259_EOI_MODE EoiMode
:3;
380 } I8259_OCW2
, *PI8259_OCW2
;
382 typedef union _I8259_OCW3
386 I8259_READ_REQUEST ReadRequest
:2;
390 UCHAR SpecialMaskMode
:2;
394 } I8259_OCW3
, *PI8259_OCW3
;
396 typedef union _I8259_ISR
413 } I8259_ISR
, *PI8259_ISR
;
415 typedef I8259_ISR I8259_IDR
, *PI8259_IDR
;
418 // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
421 // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
423 #define EISA_ELCR_MASTER 0x4D0
424 #define EISA_ELCR_SLAVE 0x4D1
426 typedef union _EISA_ELCR
454 } EISA_ELCR
, *PEISA_ELCR
;
456 typedef struct _PIC_MASK
467 } PIC_MASK
, *PPIC_MASK
;
471 __attribute__((regparm(3)))
472 (*PHAL_DISMISS_INTERRUPT
)(
479 __attribute__((regparm(3)))
480 HalpDismissIrqGeneric(
487 __attribute__((regparm(3)))
495 __attribute__((regparm(3)))
503 __attribute__((regparm(3)))
511 // Mm PTE/PDE to Hal PTE/PDE
513 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
514 #define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
516 typedef struct _IDTUsageFlags
524 UCHAR BusReleativeVector
;
527 typedef struct _HalAddressUsage
529 struct _HalAddressUsage
*Next
;
530 CM_RESOURCE_TYPE Type
;
537 } ADDRESS_USAGE
, *PADDRESS_USAGE
;
540 PADAPTER_OBJECT NTAPI
HalpAllocateAdapterEx(ULONG NumberOfMapRegisters
,BOOLEAN IsMaster
, BOOLEAN Dma32BitAddresses
);
545 HalpRegisterVector(IN UCHAR Flags
,
547 IN ULONG SystemVector
,
552 HalpEnableInterruptHandler(IN UCHAR Flags
,
554 IN ULONG SystemVector
,
557 IN KINTERRUPT_MODE Mode
);
560 VOID NTAPI
HalpInitializePICs(IN BOOLEAN EnableInterrupts
);
561 VOID
HalpApcInterrupt(VOID
);
562 VOID
HalpDispatchInterrupt(VOID
);
563 VOID FASTCALL
HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame
);
564 VOID FASTCALL
HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame
);
567 VOID NTAPI
HalpInitializeClock(VOID
);
568 VOID
HalpClockInterrupt(VOID
);
569 VOID
HalpProfileInterrupt(VOID
);
573 HalpCalibrateStallExecution(VOID
);
576 VOID
HalpInitPciBus (VOID
);
579 VOID
HalpInitDma (VOID
);
581 /* Non-generic initialization */
582 VOID
HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock
);
583 VOID
HalpInitPhase1(VOID
);
594 HalpCheckPowerButton(
600 HalpRegisterKdSupportFunctions(
606 HalpSetupPciDeviceForDebugging(
607 IN PVOID LoaderBlock
,
608 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
613 HalpReleasePciDeviceForDebugging(
614 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
622 HalpMapPhysicalMemory64(
623 IN PHYSICAL_ADDRESS PhysicalAddress
,
629 HalpUnmapVirtualAddress(
630 IN PVOID VirtualAddress
,
637 HaliQuerySystemInformation(
638 IN HAL_QUERY_INFORMATION_CLASS InformationClass
,
641 OUT PULONG ReturnedLength
646 HaliSetSystemInformation(
647 IN HAL_SET_INFORMATION_CLASS InformationClass
,
657 HalpBiosDisplayReset(
662 // Processor Halt Routine
671 // CMOS initialization
680 // Spinlock for protecting CMOS access
684 HalpAcquireSystemHardwareSpinLock(
690 HalpReleaseCmosSpinLock(
695 // This is duplicated from ke_x.h
699 // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
703 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
705 /* Make sure that we don't own the lock already */
706 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) == *SpinLock
)
708 /* We do, bugcheck! */
709 KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
714 /* Try to acquire it */
715 if (InterlockedBitTestAndSet((PLONG
)SpinLock
, 0))
717 /* Value changed... wait until it's locked */
718 while (*(volatile KSPIN_LOCK
*)SpinLock
== 1)
721 /* On debug builds, we use a much slower but useful routine */
722 //Kii386SpinOnSpinLock(SpinLock, 5);
724 /* FIXME: Do normal yield for now */
727 /* Otherwise, just yield and keep looping */
735 /* On debug builds, we OR in the KTHREAD */
736 *SpinLock
= (KSPIN_LOCK
)KeGetCurrentThread() | 1;
738 /* All is well, break out */
745 // Spinlock Release at IRQL >= DISPATCH_LEVEL
749 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
752 /* Make sure that the threads match */
753 if (((KSPIN_LOCK
)KeGetCurrentThread() | 1) != *SpinLock
)
755 /* They don't, bugcheck */
756 KeBugCheckEx(SPIN_LOCK_NOT_OWNED
, (ULONG_PTR
)SpinLock
, 0, 0, 0);
760 InterlockedAnd((PLONG
)SpinLock
, 0);
766 // Spinlock Acquire at IRQL >= DISPATCH_LEVEL
770 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock
)
772 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
773 UNREFERENCED_PARAMETER(SpinLock
);
777 // Spinlock Release at IRQL >= DISPATCH_LEVEL
781 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock
)
783 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
784 UNREFERENCED_PARAMETER(SpinLock
);
792 IN PKTRAP_FRAME TrapFrame
,
798 #define KfLowerIrql KeLowerIrql
800 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
801 #define KiAcquireSpinLock(SpinLock)
802 #define KiReleaseSpinLock(SpinLock)
803 #define KfAcquireSpinLock(SpinLock) KfRaiseIrql(DISPATCH_LEVEL);
804 #define KfReleaseSpinLock(SpinLock, OldIrql) KeLowerIrql(OldIrql);
805 #endif // !CONFIG_SMP
808 extern BOOLEAN HalpNMIInProgress
;
810 extern ADDRESS_USAGE HalpDefaultIoSpace
;
812 extern KSPIN_LOCK HalpSystemHardwareLock
;
814 extern PADDRESS_USAGE HalpAddressUsageList
;
816 extern LARGE_INTEGER HalpPerfCounter
;
818 #endif /* __INTERNAL_HAL_HAL_H */