[PERF]: Optimize nested interrupt cases (where a pending interrupt exists at the...
[reactos.git] / reactos / hal / halx86 / include / halp.h
1 /*
2 *
3 */
4
5 #ifndef __INTERNAL_HAL_HAL_H
6 #define __INTERNAL_HAL_HAL_H
7
8 typedef struct _HAL_BIOS_FRAME
9 {
10 ULONG SegSs;
11 ULONG Esp;
12 ULONG EFlags;
13 ULONG SegCs;
14 ULONG Eip;
15 PKTRAP_FRAME TrapFrame;
16 ULONG CsLimit;
17 ULONG CsBase;
18 ULONG CsFlags;
19 ULONG SsLimit;
20 ULONG SsBase;
21 ULONG SsFlags;
22 ULONG Prefix;
23 } HAL_BIOS_FRAME, *PHAL_BIOS_FRAME;
24
25 typedef
26 VOID
27 (*PHAL_SW_INTERRUPT_HANDLER)(
28 VOID
29 );
30
31 typedef
32 FASTCALL
33 VOID
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_INTERNAL 0x11
53 #define IDT_DEVICE 0x21
54
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))
60
61 //
62 // BIOS Interrupts
63 //
64 #define VIDEO_SERVICES 0x10
65
66 //
67 // Operations for INT 10h (in AH)
68 //
69 #define SET_VIDEO_MODE 0x00
70
71 //
72 // Video Modes for INT10h AH=00 (in AL)
73 //
74 #define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
75
76 //
77 // Generates a 16-bit (real-mode or Virtual 8086) BIOS interrupt with a given AX */
78 //
79 VOID
80 FORCEINLINE
81 HalpCallBiosInterrupt(IN ULONG Interrupt,
82 IN ULONG Ax)
83 {
84 __asm__ __volatile__
85 (
86 ".byte 0x66\n"
87 "movl $%c[v], %%eax\n"
88 "int $%c[i]\n"
89 :
90 : [v] "i"(Ax),
91 [i] "i"(Interrupt)
92 );
93 }
94
95 //
96 // Constructs a stack of the given size and alignment in the real-mode .text region */
97 //
98 VOID
99 FORCEINLINE
100 HalpRealModeStack(IN ULONG Alignment,
101 IN ULONG Size)
102 {
103 __asm__ __volatile__
104 (
105 ".align %c[v]\n"
106 ".space %c[i]\n"
107 ".globl _HalpRealModeEnd\n_HalpRealModeEnd:\n"
108 :
109 : [v] "i"(Alignment),
110 [i] "i"(Size)
111 );
112 }
113
114 //
115 // Nested Trap Trampoline
116 //
117 VOID
118 DECLSPEC_NORETURN
119 FORCEINLINE
120 HalpNestedTrap(IN KIRQL PendingIrql)
121 {
122 /* Use the second interrupt handler table */
123 extern PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3];
124 __asm__ __volatile__
125 (
126 "movl %c[t], %%ecx\n"
127 "jmp *%0\n"
128 :
129 : "im"(SWInterruptHandlerTable2[PendingIrql]),
130 [t] "i"(&PCR->VdmAlert)
131 : "%esp"
132 );
133 UNREACHABLE;
134 }
135
136 //
137 // Commonly stated as being 1.19318MHz
138 //
139 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
140 // P. 471
141 //
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.
144 //
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.
148 //
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.
152 //
153 #define PIT_FREQUENCY 1193182
154
155 //
156 // These ports are controlled by the i8254 Programmable Interrupt Timer (PIT)
157 //
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
162
163 //
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
170 //
171 typedef enum _TIMER_OPERATING_MODES
172 {
173 PitOperatingMode0,
174 PitOperatingMode1,
175 PitOperatingMode2,
176 PitOperatingMode3,
177 PitOperatingMode4,
178 PitOperatingMode5,
179 PitOperatingMode2Reserved,
180 PitOperatingMode5Reserved
181 } TIMER_OPERATING_MODES;
182
183 typedef enum _TIMER_ACCESS_MODES
184 {
185 PitAccessModeCounterLatch,
186 PitAccessModeLow,
187 PitAccessModeHigh,
188 PitAccessModeLowHigh
189 } TIMER_ACCESS_MODES;
190
191 typedef enum _TIMER_CHANNELS
192 {
193 PitChannel0,
194 PitChannel1,
195 PitChannel2,
196 PitReadBack
197 } TIMER_CHANNELS;
198
199 typedef union _TIMER_CONTROL_PORT_REGISTER
200 {
201 struct
202 {
203 UCHAR BcdMode:1;
204 TIMER_OPERATING_MODES OperatingMode:3;
205 TIMER_ACCESS_MODES AccessMode:2;
206 TIMER_CHANNELS Channel:2;
207 };
208 UCHAR Bits;
209 } TIMER_CONTROL_PORT_REGISTER, *PTIMER_CONTROL_PORT_REGISTER;
210
211 //
212 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
213 // P. 400
214 //
215 // This port is controled by the i8255 Programmable Peripheral Interface (PPI)
216 //
217 #define SYSTEM_CONTROL_PORT_A 0x92
218 #define SYSTEM_CONTROL_PORT_B 0x61
219 typedef union _SYSTEM_CONTROL_PORT_B_REGISTER
220 {
221 struct
222 {
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;
230 UCHAR ParityCheck:1;
231 };
232 UCHAR Bits;
233 } SYSTEM_CONTROL_PORT_B_REGISTER, *PSYSTEM_CONTROL_PORT_B_REGISTER;
234
235 //
236 // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
237 // P. 396, 397
238 //
239 // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
240 //
241 #define PIC1_CONTROL_PORT 0x20
242 #define PIC1_DATA_PORT 0x21
243 #define PIC2_CONTROL_PORT 0xA0
244 #define PIC2_DATA_PORT 0xA1
245
246 //
247 // Definitions for ICW/OCW Bits
248 //
249 typedef enum _I8259_ICW1_OPERATING_MODE
250 {
251 Cascade,
252 Single
253 } I8259_ICW1_OPERATING_MODE;
254
255 typedef enum _I8259_ICW1_INTERRUPT_MODE
256 {
257 EdgeTriggered,
258 LevelTriggered
259 } I8259_ICW1_INTERRUPT_MODE;
260
261 typedef enum _I8259_ICW1_INTERVAL
262 {
263 Interval8,
264 Interval4
265 } I8259_ICW1_INTERVAL;
266
267 typedef enum _I8259_ICW4_SYSTEM_MODE
268 {
269 Mcs8085Mode,
270 New8086Mode
271 } I8259_ICW4_SYSTEM_MODE;
272
273 typedef enum _I8259_ICW4_EOI_MODE
274 {
275 NormalEoi,
276 AutomaticEoi
277 } I8259_ICW4_EOI_MODE;
278
279 typedef enum _I8259_ICW4_BUFFERED_MODE
280 {
281 NonBuffered,
282 NonBuffered2,
283 BufferedSlave,
284 BufferedMaster
285 } I8259_ICW4_BUFFERED_MODE;
286
287 typedef enum _I8259_READ_REQUEST
288 {
289 InvalidRequest,
290 InvalidRequest2,
291 ReadIdr,
292 ReadIsr
293 } I8259_READ_REQUEST;
294
295 typedef enum _I8259_EOI_MODE
296 {
297 RotateAutoEoiClear,
298 NonSpecificEoi,
299 InvalidEoiMode,
300 SpecificEoi,
301 RotateAutoEoiSet,
302 RotateNonSpecific,
303 SetPriority,
304 RotateSpecific
305 } I8259_EOI_MODE;
306
307 //
308 // Definitions for ICW Registers
309 //
310 typedef union _I8259_ICW1
311 {
312 struct
313 {
314 UCHAR NeedIcw4:1;
315 I8259_ICW1_OPERATING_MODE OperatingMode:1;
316 I8259_ICW1_INTERVAL Interval:1;
317 I8259_ICW1_INTERRUPT_MODE InterruptMode:1;
318 UCHAR Init:1;
319 UCHAR InterruptVectorAddress:3;
320 };
321 UCHAR Bits;
322 } I8259_ICW1, *PI8259_ICW1;
323
324 typedef union _I8259_ICW2
325 {
326 struct
327 {
328 UCHAR Sbz:3;
329 UCHAR InterruptVector:5;
330 };
331 UCHAR Bits;
332 } I8259_ICW2, *PI8259_ICW2;
333
334 typedef union _I8259_ICW3
335 {
336 union
337 {
338 struct
339 {
340 UCHAR SlaveIrq0:1;
341 UCHAR SlaveIrq1:1;
342 UCHAR SlaveIrq2:1;
343 UCHAR SlaveIrq3:1;
344 UCHAR SlaveIrq4:1;
345 UCHAR SlaveIrq5:1;
346 UCHAR SlaveIrq6:1;
347 UCHAR SlaveIrq7:1;
348 };
349 struct
350 {
351 UCHAR SlaveId:3;
352 UCHAR Reserved:5;
353 };
354 };
355 UCHAR Bits;
356 } I8259_ICW3, *PI8259_ICW3;
357
358 typedef union _I8259_ICW4
359 {
360 struct
361 {
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;
366 UCHAR Reserved:3;
367 };
368 UCHAR Bits;
369 } I8259_ICW4, *PI8259_ICW4;
370
371 typedef union _I8259_OCW2
372 {
373 struct
374 {
375 UCHAR IrqNumber:3;
376 UCHAR Sbz:2;
377 I8259_EOI_MODE EoiMode:3;
378 };
379 UCHAR Bits;
380 } I8259_OCW2, *PI8259_OCW2;
381
382 typedef union _I8259_OCW3
383 {
384 struct
385 {
386 I8259_READ_REQUEST ReadRequest:2;
387 UCHAR PollCommand:1;
388 UCHAR Sbo:1;
389 UCHAR Sbz:1;
390 UCHAR SpecialMaskMode:2;
391 UCHAR Reserved:1;
392 };
393 UCHAR Bits;
394 } I8259_OCW3, *PI8259_OCW3;
395
396 typedef union _I8259_ISR
397 {
398 union
399 {
400 struct
401 {
402 UCHAR Irq0:1;
403 UCHAR Irq1:1;
404 UCHAR Irq2:1;
405 UCHAR Irq3:1;
406 UCHAR Irq4:1;
407 UCHAR Irq5:1;
408 UCHAR Irq6:1;
409 UCHAR Irq7:1;
410 };
411 };
412 UCHAR Bits;
413 } I8259_ISR, *PI8259_ISR;
414
415 typedef I8259_ISR I8259_IDR, *PI8259_IDR;
416
417 //
418 // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
419 // P. 34, 35
420 //
421 // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
422 //
423 #define EISA_ELCR_MASTER 0x4D0
424 #define EISA_ELCR_SLAVE 0x4D1
425
426 typedef union _EISA_ELCR
427 {
428 struct
429 {
430 struct
431 {
432 UCHAR Irq0Level:1;
433 UCHAR Irq1Level:1;
434 UCHAR Irq2Level:1;
435 UCHAR Irq3Level:1;
436 UCHAR Irq4Level:1;
437 UCHAR Irq5Level:1;
438 UCHAR Irq6Level:1;
439 UCHAR Irq7Level:1;
440 } Master;
441 struct
442 {
443 UCHAR Irq8Level:1;
444 UCHAR Irq9Level:1;
445 UCHAR Irq10Level:1;
446 UCHAR Irq11Level:1;
447 UCHAR Irq12Level:1;
448 UCHAR Irq13Level:1;
449 UCHAR Irq14Level:1;
450 UCHAR Irq15Level:1;
451 } Slave;
452 };
453 USHORT Bits;
454 } EISA_ELCR, *PEISA_ELCR;
455
456 typedef struct _PIC_MASK
457 {
458 union
459 {
460 struct
461 {
462 UCHAR Master;
463 UCHAR Slave;
464 };
465 USHORT Both;
466 };
467 } PIC_MASK, *PPIC_MASK;
468
469 typedef
470 BOOLEAN
471 __attribute__((regparm(3)))
472 (*PHAL_DISMISS_INTERRUPT)(
473 IN KIRQL Irql,
474 IN ULONG Irq,
475 OUT PKIRQL OldIrql
476 );
477
478 BOOLEAN
479 __attribute__((regparm(3)))
480 HalpDismissIrqGeneric(
481 IN KIRQL Irql,
482 IN ULONG Irq,
483 OUT PKIRQL OldIrql
484 );
485
486 BOOLEAN
487 __attribute__((regparm(3)))
488 HalpDismissIrq15(
489 IN KIRQL Irql,
490 IN ULONG Irq,
491 OUT PKIRQL OldIrql
492 );
493
494 BOOLEAN
495 __attribute__((regparm(3)))
496 HalpDismissIrq13(
497 IN KIRQL Irql,
498 IN ULONG Irq,
499 OUT PKIRQL OldIrql
500 );
501
502 BOOLEAN
503 __attribute__((regparm(3)))
504 HalpDismissIrq07(
505 IN KIRQL Irql,
506 IN ULONG Irq,
507 OUT PKIRQL OldIrql
508 );
509
510 //
511 // Mm PTE/PDE to Hal PTE/PDE
512 //
513 #define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
514 #define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
515
516 typedef struct _IDTUsageFlags
517 {
518 UCHAR Flags;
519 } IDTUsageFlags;
520
521 typedef struct
522 {
523 KIRQL Irql;
524 UCHAR BusReleativeVector;
525 } IDTUsage;
526
527 typedef struct _HalAddressUsage
528 {
529 struct _HalAddressUsage *Next;
530 CM_RESOURCE_TYPE Type;
531 UCHAR Flags;
532 struct
533 {
534 ULONG Start;
535 ULONG Length;
536 } Element[];
537 } ADDRESS_USAGE, *PADDRESS_USAGE;
538
539 /* adapter.c */
540 PADAPTER_OBJECT NTAPI HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
541
542 /* sysinfo.c */
543 VOID
544 NTAPI
545 HalpRegisterVector(IN UCHAR Flags,
546 IN ULONG BusVector,
547 IN ULONG SystemVector,
548 IN KIRQL Irql);
549
550 VOID
551 NTAPI
552 HalpEnableInterruptHandler(IN UCHAR Flags,
553 IN ULONG BusVector,
554 IN ULONG SystemVector,
555 IN KIRQL Irql,
556 IN PVOID Handler,
557 IN KINTERRUPT_MODE Mode);
558
559 /* pic.c */
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);
565
566 /* timer.c */
567 VOID NTAPI HalpInitializeClock(VOID);
568 VOID HalpClockInterrupt(VOID);
569 VOID HalpProfileInterrupt(VOID);
570
571 VOID
572 NTAPI
573 HalpCalibrateStallExecution(VOID);
574
575 /* pci.c */
576 VOID HalpInitPciBus (VOID);
577
578 /* dma.c */
579 VOID HalpInitDma (VOID);
580
581 /* Non-generic initialization */
582 VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
583 VOID HalpInitPhase1(VOID);
584
585 VOID
586 NTAPI
587 HalpFlushTLB(VOID);
588
589 //
590 // KD Support
591 //
592 VOID
593 NTAPI
594 HalpCheckPowerButton(
595 VOID
596 );
597
598 VOID
599 NTAPI
600 HalpRegisterKdSupportFunctions(
601 VOID
602 );
603
604 NTSTATUS
605 NTAPI
606 HalpSetupPciDeviceForDebugging(
607 IN PVOID LoaderBlock,
608 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
609 );
610
611 NTSTATUS
612 NTAPI
613 HalpReleasePciDeviceForDebugging(
614 IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
615 );
616
617 //
618 // Memory routines
619 //
620 PVOID
621 NTAPI
622 HalpMapPhysicalMemory64(
623 IN PHYSICAL_ADDRESS PhysicalAddress,
624 IN ULONG NumberPage
625 );
626
627 VOID
628 NTAPI
629 HalpUnmapVirtualAddress(
630 IN PVOID VirtualAddress,
631 IN ULONG NumberPages
632 );
633
634 /* sysinfo.c */
635 NTSTATUS
636 NTAPI
637 HaliQuerySystemInformation(
638 IN HAL_QUERY_INFORMATION_CLASS InformationClass,
639 IN ULONG BufferSize,
640 IN OUT PVOID Buffer,
641 OUT PULONG ReturnedLength
642 );
643
644 NTSTATUS
645 NTAPI
646 HaliSetSystemInformation(
647 IN HAL_SET_INFORMATION_CLASS InformationClass,
648 IN ULONG BufferSize,
649 IN OUT PVOID Buffer
650 );
651
652 //
653 // BIOS Routines
654 //
655 BOOLEAN
656 NTAPI
657 HalpBiosDisplayReset(
658 VOID
659 );
660
661 //
662 // Processor Halt Routine
663 //
664 VOID
665 NTAPI
666 HaliHaltSystem(
667 VOID
668 );
669
670 //
671 // CMOS initialization
672 //
673 VOID
674 NTAPI
675 HalpInitializeCmos(
676 VOID
677 );
678
679 //
680 // Spinlock for protecting CMOS access
681 //
682 VOID
683 NTAPI
684 HalpAcquireSystemHardwareSpinLock(
685 VOID
686 );
687
688 VOID
689 NTAPI
690 HalpReleaseCmosSpinLock(
691 VOID
692 );
693
694 //
695 // This is duplicated from ke_x.h
696 //
697 #ifdef CONFIG_SMP
698 //
699 // Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
700 //
701 FORCEINLINE
702 VOID
703 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
704 {
705 /* Make sure that we don't own the lock already */
706 if (((KSPIN_LOCK)KeGetCurrentThread() | 1) == *SpinLock)
707 {
708 /* We do, bugcheck! */
709 KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
710 }
711
712 for (;;)
713 {
714 /* Try to acquire it */
715 if (InterlockedBitTestAndSet((PLONG)SpinLock, 0))
716 {
717 /* Value changed... wait until it's locked */
718 while (*(volatile KSPIN_LOCK *)SpinLock == 1)
719 {
720 #ifdef DBG
721 /* On debug builds, we use a much slower but useful routine */
722 //Kii386SpinOnSpinLock(SpinLock, 5);
723
724 /* FIXME: Do normal yield for now */
725 YieldProcessor();
726 #else
727 /* Otherwise, just yield and keep looping */
728 YieldProcessor();
729 #endif
730 }
731 }
732 else
733 {
734 #ifdef DBG
735 /* On debug builds, we OR in the KTHREAD */
736 *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
737 #endif
738 /* All is well, break out */
739 break;
740 }
741 }
742 }
743
744 //
745 // Spinlock Release at IRQL >= DISPATCH_LEVEL
746 //
747 FORCEINLINE
748 VOID
749 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
750 {
751 #ifdef DBG
752 /* Make sure that the threads match */
753 if (((KSPIN_LOCK)KeGetCurrentThread() | 1) != *SpinLock)
754 {
755 /* They don't, bugcheck */
756 KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
757 }
758 #endif
759 /* Clear the lock */
760 InterlockedAnd((PLONG)SpinLock, 0);
761 }
762
763 #else
764
765 //
766 // Spinlock Acquire at IRQL >= DISPATCH_LEVEL
767 //
768 FORCEINLINE
769 VOID
770 KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
771 {
772 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
773 UNREFERENCED_PARAMETER(SpinLock);
774 }
775
776 //
777 // Spinlock Release at IRQL >= DISPATCH_LEVEL
778 //
779 FORCEINLINE
780 VOID
781 KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
782 {
783 /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
784 UNREFERENCED_PARAMETER(SpinLock);
785 }
786
787 #endif
788
789 VOID
790 FASTCALL
791 KeUpdateSystemTime(
792 IN PKTRAP_FRAME TrapFrame,
793 IN ULONG Increment,
794 IN KIRQL OldIrql
795 );
796
797 #ifdef _M_AMD64
798 #define KfLowerIrql KeLowerIrql
799 #ifndef CONFIG_SMP
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
806 #endif // _M_AMD64
807
808 extern BOOLEAN HalpNMIInProgress;
809
810 extern ADDRESS_USAGE HalpDefaultIoSpace;
811
812 extern KSPIN_LOCK HalpSystemHardwareLock;
813
814 extern PADDRESS_USAGE HalpAddressUsageList;
815
816 extern LARGE_INTEGER HalpPerfCounter;
817
818 #endif /* __INTERNAL_HAL_HAL_H */