Sync with trunk (r47116), hopefully without breaking anything.
[reactos.git] / hal / halx86 / include / halp.h
1 /*
2 *
3 */
4
5 #pragma once
6
7 typedef struct _HAL_BIOS_FRAME
8 {
9 ULONG SegSs;
10 ULONG Esp;
11 ULONG EFlags;
12 ULONG SegCs;
13 ULONG Eip;
14 PKTRAP_FRAME TrapFrame;
15 ULONG CsLimit;
16 ULONG CsBase;
17 ULONG CsFlags;
18 ULONG SsLimit;
19 ULONG SsBase;
20 ULONG SsFlags;
21 ULONG Prefix;
22 } HAL_BIOS_FRAME, *PHAL_BIOS_FRAME;
23
24 typedef
25 VOID
26 (*PHAL_SW_INTERRUPT_HANDLER)(
27 VOID
28 );
29
30 typedef
31 FASTCALL
32 VOID
33 DECLSPEC_NORETURN
34 (*PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)(
35 IN PKTRAP_FRAME TrapFrame
36 );
37
38 #define HAL_APC_REQUEST 0
39 #define HAL_DPC_REQUEST 1
40
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
48
49 /* Usage flags */
50 #define IDT_REGISTERED 0x01
51 #define IDT_LATCHED 0x02
52 #define IDT_READ_ONLY 0x04
53 #define IDT_INTERNAL 0x11
54 #define IDT_DEVICE 0x21
55
56 /* Conversion functions */
57 #define BCD_INT(bcd) \
58 (((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
59 #define INT_BCD(int) \
60 (UCHAR)(((int / 10) << 4) + (int % 10))
61
62 //
63 // BIOS Interrupts
64 //
65 #define VIDEO_SERVICES 0x10
66
67 //
68 // Operations for INT 10h (in AH)
69 //
70 #define SET_VIDEO_MODE 0x00
71
72 //
73 // Video Modes for INT10h AH=00 (in AL)
74 //
75 #define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
76
77 //
78 // Commonly stated as being 1.19318MHz
79 //
80 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
81 // P. 471
82 //
83 // However, the true value is closer to 1.19318181[...]81MHz since this is 1/3rd
84 // of the NTSC color subcarrier frequency which runs at 3.57954545[...]45MHz.
85 //
86 // Note that Windows uses 1.193167MHz which seems to have no basis. However, if
87 // one takes the NTSC color subcarrier frequency as being 3.579545 (trimming the
88 // infinite series) and divides it by three, one obtains 1.19318167.
89 //
90 // It may be that the original NT HAL source code introduced a typo and turned
91 // 119318167 into 1193167 by ommitting the "18". This is very plausible as the
92 // number is quite long.
93 //
94 #define PIT_FREQUENCY 1193182
95
96 //
97 // These ports are controlled by the i8254 Programmable Interrupt Timer (PIT)
98 //
99 #define TIMER_CHANNEL0_DATA_PORT 0x40
100 #define TIMER_CHANNEL1_DATA_PORT 0x41
101 #define TIMER_CHANNEL2_DATA_PORT 0x42
102 #define TIMER_CONTROL_PORT 0x43
103
104 //
105 // Mode 0 - Interrupt On Terminal Count
106 // Mode 1 - Hardware Re-triggerable One-Shot
107 // Mode 2 - Rate Generator
108 // Mode 3 - Square Wave Generator
109 // Mode 4 - Software Triggered Strobe
110 // Mode 5 - Hardware Triggered Strobe
111 //
112 typedef enum _TIMER_OPERATING_MODES
113 {
114 PitOperatingMode0,
115 PitOperatingMode1,
116 PitOperatingMode2,
117 PitOperatingMode3,
118 PitOperatingMode4,
119 PitOperatingMode5,
120 PitOperatingMode2Reserved,
121 PitOperatingMode5Reserved
122 } TIMER_OPERATING_MODES;
123
124 typedef enum _TIMER_ACCESS_MODES
125 {
126 PitAccessModeCounterLatch,
127 PitAccessModeLow,
128 PitAccessModeHigh,
129 PitAccessModeLowHigh
130 } TIMER_ACCESS_MODES;
131
132 typedef enum _TIMER_CHANNELS
133 {
134 PitChannel0,
135 PitChannel1,
136 PitChannel2,
137 PitReadBack
138 } TIMER_CHANNELS;
139
140 typedef union _TIMER_CONTROL_PORT_REGISTER
141 {
142 struct
143 {
144 UCHAR BcdMode:1;
145 TIMER_OPERATING_MODES OperatingMode:3;
146 TIMER_ACCESS_MODES AccessMode:2;
147 TIMER_CHANNELS Channel:2;
148 };
149 UCHAR Bits;
150 } TIMER_CONTROL_PORT_REGISTER, *PTIMER_CONTROL_PORT_REGISTER;
151
152 //
153 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
154 // P. 400
155 //
156 // This port is controled by the i8255 Programmable Peripheral Interface (PPI)
157 //
158 #define SYSTEM_CONTROL_PORT_A 0x92
159 #define SYSTEM_CONTROL_PORT_B 0x61
160 typedef union _SYSTEM_CONTROL_PORT_B_REGISTER
161 {
162 struct
163 {
164 UCHAR Timer2GateToSpeaker:1;
165 UCHAR SpeakerDataEnable:1;
166 UCHAR ParityCheckEnable:1;
167 UCHAR ChannelCheckEnable:1;
168 UCHAR RefreshRequest:1;
169 UCHAR Timer2Output:1;
170 UCHAR ChannelCheck:1;
171 UCHAR ParityCheck:1;
172 };
173 UCHAR Bits;
174 } SYSTEM_CONTROL_PORT_B_REGISTER, *PSYSTEM_CONTROL_PORT_B_REGISTER;
175
176 //
177 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
178 // P. 396, 397
179 //
180 // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
181 //
182 #define PIC1_CONTROL_PORT 0x20
183 #define PIC1_DATA_PORT 0x21
184 #define PIC2_CONTROL_PORT 0xA0
185 #define PIC2_DATA_PORT 0xA1
186
187 //
188 // Definitions for ICW/OCW Bits
189 //
190 typedef enum _I8259_ICW1_OPERATING_MODE
191 {
192 Cascade,
193 Single
194 } I8259_ICW1_OPERATING_MODE;
195
196 typedef enum _I8259_ICW1_INTERRUPT_MODE
197 {
198 EdgeTriggered,
199 LevelTriggered
200 } I8259_ICW1_INTERRUPT_MODE;
201
202 typedef enum _I8259_ICW1_INTERVAL
203 {
204 Interval8,
205 Interval4
206 } I8259_ICW1_INTERVAL;
207
208 typedef enum _I8259_ICW4_SYSTEM_MODE
209 {
210 Mcs8085Mode,
211 New8086Mode
212 } I8259_ICW4_SYSTEM_MODE;
213
214 typedef enum _I8259_ICW4_EOI_MODE
215 {
216 NormalEoi,
217 AutomaticEoi
218 } I8259_ICW4_EOI_MODE;
219
220 typedef enum _I8259_ICW4_BUFFERED_MODE
221 {
222 NonBuffered,
223 NonBuffered2,
224 BufferedSlave,
225 BufferedMaster
226 } I8259_ICW4_BUFFERED_MODE;
227
228 typedef enum _I8259_READ_REQUEST
229 {
230 InvalidRequest,
231 InvalidRequest2,
232 ReadIdr,
233 ReadIsr
234 } I8259_READ_REQUEST;
235
236 typedef enum _I8259_EOI_MODE
237 {
238 RotateAutoEoiClear,
239 NonSpecificEoi,
240 InvalidEoiMode,
241 SpecificEoi,
242 RotateAutoEoiSet,
243 RotateNonSpecific,
244 SetPriority,
245 RotateSpecific
246 } I8259_EOI_MODE;
247
248 //
249 // Definitions for ICW Registers
250 //
251 typedef union _I8259_ICW1
252 {
253 struct
254 {
255 UCHAR NeedIcw4:1;
256 I8259_ICW1_OPERATING_MODE OperatingMode:1;
257 I8259_ICW1_INTERVAL Interval:1;
258 I8259_ICW1_INTERRUPT_MODE InterruptMode:1;
259 UCHAR Init:1;
260 UCHAR InterruptVectorAddress:3;
261 };
262 UCHAR Bits;
263 } I8259_ICW1, *PI8259_ICW1;
264
265 typedef union _I8259_ICW2
266 {
267 struct
268 {
269 UCHAR Sbz:3;
270 UCHAR InterruptVector:5;
271 };
272 UCHAR Bits;
273 } I8259_ICW2, *PI8259_ICW2;
274
275 typedef union _I8259_ICW3
276 {
277 union
278 {
279 struct
280 {
281 UCHAR SlaveIrq0:1;
282 UCHAR SlaveIrq1:1;
283 UCHAR SlaveIrq2:1;
284 UCHAR SlaveIrq3:1;
285 UCHAR SlaveIrq4:1;
286 UCHAR SlaveIrq5:1;
287 UCHAR SlaveIrq6:1;
288 UCHAR SlaveIrq7:1;
289 };
290 struct
291 {
292 UCHAR SlaveId:3;
293 UCHAR Reserved:5;
294 };
295 };
296 UCHAR Bits;
297 } I8259_ICW3, *PI8259_ICW3;
298
299 typedef union _I8259_ICW4
300 {
301 struct
302 {
303 I8259_ICW4_SYSTEM_MODE SystemMode:1;
304 I8259_ICW4_EOI_MODE EoiMode:1;
305 I8259_ICW4_BUFFERED_MODE BufferedMode:2;
306 UCHAR SpecialFullyNestedMode:1;
307 UCHAR Reserved:3;
308 };
309 UCHAR Bits;
310 } I8259_ICW4, *PI8259_ICW4;
311
312 typedef union _I8259_OCW2
313 {
314 struct
315 {
316 UCHAR IrqNumber:3;
317 UCHAR Sbz:2;
318 I8259_EOI_MODE EoiMode:3;
319 };
320 UCHAR Bits;
321 } I8259_OCW2, *PI8259_OCW2;
322
323 typedef union _I8259_OCW3
324 {
325 struct
326 {
327 I8259_READ_REQUEST ReadRequest:2;
328 UCHAR PollCommand:1;
329 UCHAR Sbo:1;
330 UCHAR Sbz:1;
331 UCHAR SpecialMaskMode:2;
332 UCHAR Reserved:1;
333 };
334 UCHAR Bits;
335 } I8259_OCW3, *PI8259_OCW3;
336
337 typedef union _I8259_ISR
338 {
339 union
340 {
341 struct
342 {
343 UCHAR Irq0:1;
344 UCHAR Irq1:1;
345 UCHAR Irq2:1;
346 UCHAR Irq3:1;
347 UCHAR Irq4:1;
348 UCHAR Irq5:1;
349 UCHAR Irq6:1;
350 UCHAR Irq7:1;
351 };
352 };
353 UCHAR Bits;
354 } I8259_ISR, *PI8259_ISR;
355
356 typedef I8259_ISR I8259_IDR, *PI8259_IDR;
357
358 //
359 // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
360 // P. 34, 35
361 //
362 // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
363 //
364 #define EISA_ELCR_MASTER 0x4D0
365 #define EISA_ELCR_SLAVE 0x4D1
366
367 typedef union _EISA_ELCR
368 {
369 struct
370 {
371 struct
372 {
373 UCHAR Irq0Level:1;
374 UCHAR Irq1Level:1;
375 UCHAR Irq2Level:1;
376 UCHAR Irq3Level:1;
377 UCHAR Irq4Level:1;
378 UCHAR Irq5Level:1;
379 UCHAR Irq6Level:1;
380 UCHAR Irq7Level:1;
381 } Master;
382 struct
383 {
384 UCHAR Irq8Level:1;
385 UCHAR Irq9Level:1;
386 UCHAR Irq10Level:1;
387 UCHAR Irq11Level:1;
388 UCHAR Irq12Level:1;
389 UCHAR Irq13Level:1;
390 UCHAR Irq14Level:1;
391 UCHAR Irq15Level:1;
392 } Slave;
393 };
394 USHORT Bits;
395 } EISA_ELCR, *PEISA_ELCR;
396
397 typedef struct _PIC_MASK
398 {
399 union
400 {
401 struct
402 {
403 UCHAR Master;
404 UCHAR Slave;
405 };
406 USHORT Both;
407 };
408 } PIC_MASK, *PPIC_MASK;
409
410 typedef
411 BOOLEAN
412 __attribute__((regparm(3)))
413 (*PHAL_DISMISS_INTERRUPT)(
414 IN KIRQL Irql,
415 IN ULONG Irq,
416 OUT PKIRQL OldIrql
417 );
418
419 BOOLEAN
420 __attribute__((regparm(3)))
421 HalpDismissIrqGeneric(
422 IN KIRQL Irql,
423 IN ULONG Irq,
424 OUT PKIRQL OldIrql
425 );
426
427 BOOLEAN
428 __attribute__((regparm(3)))
429 HalpDismissIrq15(
430 IN KIRQL Irql,
431 IN ULONG Irq,
432 OUT PKIRQL OldIrql
433 );
434
435 BOOLEAN
436 __attribute__((regparm(3)))
437 HalpDismissIrq13(
438 IN KIRQL Irql,
439 IN ULONG Irq,
440 OUT PKIRQL OldIrql
441 );
442
443 BOOLEAN
444 __attribute__((regparm(3)))
445 HalpDismissIrq07(
446 IN KIRQL Irql,
447 IN ULONG Irq,
448 OUT PKIRQL OldIrql
449 );
450
451 BOOLEAN
452 __attribute__((regparm(3)))
453 HalpDismissIrqLevel(
454 IN KIRQL Irql,
455 IN ULONG Irq,
456 OUT PKIRQL OldIrql
457 );
458
459 BOOLEAN
460 __attribute__((regparm(3)))
461 HalpDismissIrq15Level(
462 IN KIRQL Irql,
463 IN ULONG Irq,
464 OUT PKIRQL OldIrql
465 );
466
467 BOOLEAN
468 __attribute__((regparm(3)))
469 HalpDismissIrq13Level(
470 IN KIRQL Irql,
471 IN ULONG Irq,
472 OUT PKIRQL OldIrql
473 );
474
475 BOOLEAN
476 __attribute__((regparm(3)))
477 HalpDismissIrq07Level(
478 IN KIRQL Irql,
479 IN ULONG Irq,
480 OUT PKIRQL OldIrql
481 );
482
483 VOID
484 HalpHardwareInterruptLevel(
485 VOID
486 );
487
488 //
489 // Mm PTE/PDE to Hal PTE/PDE
490 //
491 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
492 #define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
493
494 typedef struct _IDTUsageFlags
495 {
496 UCHAR Flags;
497 } IDTUsageFlags;
498
499 typedef struct
500 {
501 KIRQL Irql;
502 UCHAR BusReleativeVector;
503 } IDTUsage;
504
505 typedef struct _HalAddressUsage
506 {
507 struct _HalAddressUsage *Next;
508 CM_RESOURCE_TYPE Type;
509 UCHAR Flags;
510 struct
511 {
512 ULONG Start;
513 ULONG Length;
514 } Element[];
515 } ADDRESS_USAGE, *PADDRESS_USAGE;
516
517 /* adapter.c */
518 PADAPTER_OBJECT NTAPI HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
519
520 /* sysinfo.c */
521 VOID
522 NTAPI
523 HalpRegisterVector(IN UCHAR Flags,
524 IN ULONG BusVector,
525 IN ULONG SystemVector,
526 IN KIRQL Irql);
527
528 VOID
529 NTAPI
530 HalpEnableInterruptHandler(IN UCHAR Flags,
531 IN ULONG BusVector,
532 IN ULONG SystemVector,
533 IN KIRQL Irql,
534 IN PVOID Handler,
535 IN KINTERRUPT_MODE Mode);
536
537 /* pic.c */
538 VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
539 VOID HalpApcInterrupt(VOID);
540 VOID HalpDispatchInterrupt(VOID);
541 VOID HalpDispatchInterrupt2(VOID);
542 VOID FASTCALL DECLSPEC_NORETURN HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
543 VOID FASTCALL DECLSPEC_NORETURN HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
544
545 /* timer.c */
546 VOID NTAPI HalpInitializeClock(VOID);
547 VOID HalpClockInterrupt(VOID);
548 VOID HalpProfileInterrupt(VOID);
549
550 VOID
551 NTAPI
552 HalpCalibrateStallExecution(VOID);
553
554 /* pci.c */
555 VOID HalpInitPciBus (VOID);
556
557 /* dma.c */
558 VOID HalpInitDma (VOID);
559
560 /* Non-generic initialization */
561 VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
562 VOID HalpInitPhase1(VOID);
563
564 VOID
565 NTAPI
566 HalpFlushTLB(VOID);
567
568 //
569 // KD Support
570 //
571 VOID
572 NTAPI
573 HalpCheckPowerButton(
574 VOID
575 );
576
577 VOID
578 NTAPI
579 HalpRegisterKdSupportFunctions(
580 VOID
581 );
582
583 NTSTATUS
584 NTAPI
585 HalpSetupPciDeviceForDebugging(
586 IN PVOID LoaderBlock,
587 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
588 );
589
590 NTSTATUS
591 NTAPI
592 HalpReleasePciDeviceForDebugging(
593 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
594 );
595
596 //
597 // Memory routines
598 //
599 PVOID
600 NTAPI
601 HalpMapPhysicalMemory64(
602 IN PHYSICAL_ADDRESS PhysicalAddress,
603 IN ULONG NumberPage
604 );
605
606 VOID
607 NTAPI
608 HalpUnmapVirtualAddress(
609 IN PVOID VirtualAddress,
610 IN ULONG NumberPages
611 );
612
613 /* sysinfo.c */
614 NTSTATUS
615 NTAPI
616 HaliQuerySystemInformation(
617 IN HAL_QUERY_INFORMATION_CLASS InformationClass,
618 IN ULONG BufferSize,
619 IN OUT PVOID Buffer,
620 OUT PULONG ReturnedLength
621 );
622
623 NTSTATUS
624 NTAPI
625 HaliSetSystemInformation(
626 IN HAL_SET_INFORMATION_CLASS InformationClass,
627 IN ULONG BufferSize,
628 IN OUT PVOID Buffer
629 );
630
631 //
632 // BIOS Routines
633 //
634 BOOLEAN
635 NTAPI
636 HalpBiosDisplayReset(
637 VOID
638 );
639
640 VOID
641 FASTCALL
642 HalpExitToV86(
643 PKTRAP_FRAME TrapFrame
644 );
645
646 VOID
647 DECLSPEC_NORETURN
648 HalpRealModeStart(
649 VOID
650 );
651
652 //
653 // Processor Halt Routine
654 //
655 VOID
656 NTAPI
657 HaliHaltSystem(
658 VOID
659 );
660
661 //
662 // CMOS initialization
663 //
664 VOID
665 NTAPI
666 HalpInitializeCmos(
667 VOID
668 );
669
670 //
671 // Spinlock for protecting CMOS access
672 //
673 VOID
674 NTAPI
675 HalpAcquireSystemHardwareSpinLock(
676 VOID
677 );
678
679 VOID
680 NTAPI
681 HalpReleaseCmosSpinLock(
682 VOID
683 );
684
685 ULONG
686 NTAPI
687 HalpAllocPhysicalMemory(
688 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
689 IN ULONG MaxAddress,
690 IN ULONG PageCount,
691 IN BOOLEAN Aligned
692 );
693
694 PVOID
695 NTAPI
696 HalpMapPhysicalMemory64(
697 IN PHYSICAL_ADDRESS PhysicalAddress,
698 IN ULONG PageCount
699 );
700
701 NTSTATUS
702 NTAPI
703 HalpOpenRegistryKey(
704 IN PHANDLE KeyHandle,
705 IN HANDLE RootKey,
706 IN PUNICODE_STRING KeyName,
707 IN ACCESS_MASK DesiredAccess,
708 IN BOOLEAN Create
709 );
710
711 VOID
712 NTAPI
713 HalpGetNMICrashFlag(
714 VOID
715 );
716
717 BOOLEAN
718 NTAPI
719 HalpGetDebugPortTable(
720 VOID
721 );
722
723 VOID
724 NTAPI
725 HalpReportSerialNumber(
726 VOID
727 );
728
729 NTSTATUS
730 NTAPI
731 HalpMarkAcpiHal(
732 VOID
733 );
734
735 VOID
736 NTAPI
737 HalpBuildAddressMap(
738 VOID
739 );
740
741 VOID
742 NTAPI
743 HalpReportResourceUsage(
744 IN PUNICODE_STRING HalName,
745 IN INTERFACE_TYPE InterfaceType
746 );
747
748 ULONG
749 NTAPI
750 HalpIs16BitPortDecodeSupported(
751 VOID
752 );
753
754 NTSTATUS
755 NTAPI
756 HalpQueryAcpiResourceRequirements(
757 OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
758 );
759
760 VOID
761 FASTCALL
762 KeUpdateSystemTime(
763 IN PKTRAP_FRAME TrapFrame,
764 IN ULONG Increment,
765 IN KIRQL OldIrql
766 );
767
768 #ifdef _M_AMD64
769 #define KfLowerIrql KeLowerIrql
770 #ifndef CONFIG_SMP
771 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
772 #define KiAcquireSpinLock(SpinLock)
773 #define KiReleaseSpinLock(SpinLock)
774 #define KfAcquireSpinLock(SpinLock) KfRaiseIrql(DISPATCH_LEVEL);
775 #define KfReleaseSpinLock(SpinLock, OldIrql) KeLowerIrql(OldIrql);
776 #endif // !CONFIG_SMP
777 #endif // _M_AMD64
778
779 extern BOOLEAN HalpNMIInProgress;
780
781 extern ADDRESS_USAGE HalpDefaultIoSpace;
782
783 extern KSPIN_LOCK HalpSystemHardwareLock;
784
785 extern PADDRESS_USAGE HalpAddressUsageList;
786
787 extern LARGE_INTEGER HalpPerfCounter;
788
789 extern KAFFINITY HalpActiveProcessors;
790
791 extern BOOLEAN HalDisableFirmwareMapper;
792 extern PWCHAR HalHardwareIdString;
793 extern PWCHAR HalName;