[NTOS]: Check registry for our CardList, check if the PCI hardware matches any entry...
[reactos.git] / reactos / 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 // Feature flags
490 //
491 #define HALP_CARD_FEATURE_FULL_DECODE 0x0001
492
493 //
494 // Match Flags
495 //
496 #define HALP_CHECK_CARD_REVISION_ID 0x10000
497 #define HALP_CHECK_CARD_SUBVENDOR_ID 0x20000
498 #define HALP_CHECK_CARD_SUBSYSTEM_ID 0x40000
499
500 //
501 // Mm PTE/PDE to Hal PTE/PDE
502 //
503 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
504 #define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
505
506 typedef struct _IDTUsageFlags
507 {
508 UCHAR Flags;
509 } IDTUsageFlags;
510
511 typedef struct
512 {
513 KIRQL Irql;
514 UCHAR BusReleativeVector;
515 } IDTUsage;
516
517 typedef struct _HalAddressUsage
518 {
519 struct _HalAddressUsage *Next;
520 CM_RESOURCE_TYPE Type;
521 UCHAR Flags;
522 struct
523 {
524 ULONG Start;
525 ULONG Length;
526 } Element[];
527 } ADDRESS_USAGE, *PADDRESS_USAGE;
528
529 /* adapter.c */
530 PADAPTER_OBJECT NTAPI HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
531
532 /* sysinfo.c */
533 VOID
534 NTAPI
535 HalpRegisterVector(IN UCHAR Flags,
536 IN ULONG BusVector,
537 IN ULONG SystemVector,
538 IN KIRQL Irql);
539
540 VOID
541 NTAPI
542 HalpEnableInterruptHandler(IN UCHAR Flags,
543 IN ULONG BusVector,
544 IN ULONG SystemVector,
545 IN KIRQL Irql,
546 IN PVOID Handler,
547 IN KINTERRUPT_MODE Mode);
548
549 /* pic.c */
550 VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
551 VOID HalpApcInterrupt(VOID);
552 VOID HalpDispatchInterrupt(VOID);
553 VOID HalpDispatchInterrupt2(VOID);
554 VOID FASTCALL DECLSPEC_NORETURN HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
555 VOID FASTCALL DECLSPEC_NORETURN HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
556
557 /* timer.c */
558 VOID NTAPI HalpInitializeClock(VOID);
559 VOID HalpClockInterrupt(VOID);
560 VOID HalpProfileInterrupt(VOID);
561
562 VOID
563 NTAPI
564 HalpCalibrateStallExecution(VOID);
565
566 /* pci.c */
567 VOID HalpInitPciBus (VOID);
568
569 /* dma.c */
570 VOID HalpInitDma (VOID);
571
572 /* Non-generic initialization */
573 VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
574 VOID HalpInitPhase1(VOID);
575
576 VOID
577 NTAPI
578 HalpFlushTLB(VOID);
579
580 //
581 // KD Support
582 //
583 VOID
584 NTAPI
585 HalpCheckPowerButton(
586 VOID
587 );
588
589 VOID
590 NTAPI
591 HalpRegisterKdSupportFunctions(
592 VOID
593 );
594
595 NTSTATUS
596 NTAPI
597 HalpSetupPciDeviceForDebugging(
598 IN PVOID LoaderBlock,
599 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
600 );
601
602 NTSTATUS
603 NTAPI
604 HalpReleasePciDeviceForDebugging(
605 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
606 );
607
608 //
609 // Memory routines
610 //
611 PVOID
612 NTAPI
613 HalpMapPhysicalMemory64(
614 IN PHYSICAL_ADDRESS PhysicalAddress,
615 IN ULONG NumberPage
616 );
617
618 VOID
619 NTAPI
620 HalpUnmapVirtualAddress(
621 IN PVOID VirtualAddress,
622 IN ULONG NumberPages
623 );
624
625 /* sysinfo.c */
626 NTSTATUS
627 NTAPI
628 HaliQuerySystemInformation(
629 IN HAL_QUERY_INFORMATION_CLASS InformationClass,
630 IN ULONG BufferSize,
631 IN OUT PVOID Buffer,
632 OUT PULONG ReturnedLength
633 );
634
635 NTSTATUS
636 NTAPI
637 HaliSetSystemInformation(
638 IN HAL_SET_INFORMATION_CLASS InformationClass,
639 IN ULONG BufferSize,
640 IN OUT PVOID Buffer
641 );
642
643 //
644 // BIOS Routines
645 //
646 BOOLEAN
647 NTAPI
648 HalpBiosDisplayReset(
649 VOID
650 );
651
652 VOID
653 FASTCALL
654 HalpExitToV86(
655 PKTRAP_FRAME TrapFrame
656 );
657
658 VOID
659 DECLSPEC_NORETURN
660 HalpRealModeStart(
661 VOID
662 );
663
664 //
665 // Processor Halt Routine
666 //
667 VOID
668 NTAPI
669 HaliHaltSystem(
670 VOID
671 );
672
673 //
674 // CMOS initialization
675 //
676 VOID
677 NTAPI
678 HalpInitializeCmos(
679 VOID
680 );
681
682 //
683 // Spinlock for protecting CMOS access
684 //
685 VOID
686 NTAPI
687 HalpAcquireSystemHardwareSpinLock(
688 VOID
689 );
690
691 VOID
692 NTAPI
693 HalpReleaseCmosSpinLock(
694 VOID
695 );
696
697 ULONG
698 NTAPI
699 HalpAllocPhysicalMemory(
700 IN PLOADER_PARAMETER_BLOCK LoaderBlock,
701 IN ULONG MaxAddress,
702 IN ULONG PageCount,
703 IN BOOLEAN Aligned
704 );
705
706 PVOID
707 NTAPI
708 HalpMapPhysicalMemory64(
709 IN PHYSICAL_ADDRESS PhysicalAddress,
710 IN ULONG PageCount
711 );
712
713 NTSTATUS
714 NTAPI
715 HalpOpenRegistryKey(
716 IN PHANDLE KeyHandle,
717 IN HANDLE RootKey,
718 IN PUNICODE_STRING KeyName,
719 IN ACCESS_MASK DesiredAccess,
720 IN BOOLEAN Create
721 );
722
723 VOID
724 NTAPI
725 HalpGetNMICrashFlag(
726 VOID
727 );
728
729 BOOLEAN
730 NTAPI
731 HalpGetDebugPortTable(
732 VOID
733 );
734
735 VOID
736 NTAPI
737 HalpReportSerialNumber(
738 VOID
739 );
740
741 NTSTATUS
742 NTAPI
743 HalpMarkAcpiHal(
744 VOID
745 );
746
747 VOID
748 NTAPI
749 HalpBuildAddressMap(
750 VOID
751 );
752
753 VOID
754 NTAPI
755 HalpReportResourceUsage(
756 IN PUNICODE_STRING HalName,
757 IN INTERFACE_TYPE InterfaceType
758 );
759
760 ULONG
761 NTAPI
762 HalpIs16BitPortDecodeSupported(
763 VOID
764 );
765
766 NTSTATUS
767 NTAPI
768 HalpQueryAcpiResourceRequirements(
769 OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
770 );
771
772 VOID
773 FASTCALL
774 KeUpdateSystemTime(
775 IN PKTRAP_FRAME TrapFrame,
776 IN ULONG Increment,
777 IN KIRQL OldIrql
778 );
779
780 VOID
781 NTAPI
782 HalpInitBusHandlers(
783 VOID
784 );
785
786 #ifdef _M_AMD64
787 #define KfLowerIrql KeLowerIrql
788 #ifndef CONFIG_SMP
789 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
790 #define KiAcquireSpinLock(SpinLock)
791 #define KiReleaseSpinLock(SpinLock)
792 #define KfAcquireSpinLock(SpinLock) KfRaiseIrql(DISPATCH_LEVEL);
793 #define KfReleaseSpinLock(SpinLock, OldIrql) KeLowerIrql(OldIrql);
794 #endif // !CONFIG_SMP
795 #endif // _M_AMD64
796
797 extern BOOLEAN HalpNMIInProgress;
798
799 extern ADDRESS_USAGE HalpDefaultIoSpace;
800
801 extern KSPIN_LOCK HalpSystemHardwareLock;
802
803 extern PADDRESS_USAGE HalpAddressUsageList;
804
805 extern LARGE_INTEGER HalpPerfCounter;
806
807 extern KAFFINITY HalpActiveProcessors;
808
809 extern BOOLEAN HalDisableFirmwareMapper;
810 extern PWCHAR HalHardwareIdString;
811 extern PWCHAR HalName;