2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: mkernel/hal/irql.c
5 * PURPOSE: Implements IRQLs
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 /* INCLUDES *****************************************************************/
12 #include <ddk/ntddk.h>
13 #include <internal/bitops.h>
14 #include <internal/hal/io.h>
17 #include <internal/debug.h>
19 /* GLOBALS ******************************************************************/
22 * PURPOSE: Current irq level
24 static KIRQL CurrentIrql
= HIGH_LEVEL
;
26 /* FUNCTIONS ****************************************************************/
28 static unsigned int pic_get_current_mask(void)
33 mask
= mask
| (inb_p(0xa1)<<8);
36 static unsigned int pic_set_current_mask(unsigned int mask
)
38 outb_p(0x21,mask
& 0xff);
39 outb_p(0xa1,(mask
>> 8) & 0xff);
42 static void switch_irql(void)
44 * FUNCTION: Switches to the current irql
45 * NOTE: Must be called with interrupt disabled
50 if (CurrentIrql
== HIGH_LEVEL
)
52 pic_set_current_mask(0xffff);
55 if (CurrentIrql
> DISPATCH_LEVEL
)
57 unsigned int current_mask
= 0;
59 for (i
=(CurrentIrql
-DISPATCH_LEVEL
);i
>DISPATCH_LEVEL
;i
--)
61 set_bit(NR_DEVICE_SPECIFIC_LEVELS
- i
,¤t_mask
);
64 pic_set_current_mask(current_mask
);
69 if (CurrentIrql
<= DISPATCH_LEVEL
)
71 pic_set_current_mask(0);
77 VOID
KeSetCurrentIrql(KIRQL newlvl
)
79 * PURPOSE: Sets the current irq level without taking any action
82 DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl
);
86 KIRQL
KeGetCurrentIrql()
88 * PURPOSE: Returns the current irq level
89 * RETURNS: The current irq level
95 VOID
KeLowerIrql(KIRQL NewIrql
)
97 * PURPOSE: Restores the irq level on the current processor
99 * NewIrql = Irql to lower to
104 DPRINT("NewIrql %x CurrentIrql %x\n",NewIrql
,CurrentIrql
);
105 assert(NewIrql
<= CurrentIrql
);
106 CurrentIrql
= NewIrql
;
110 VOID
KeRaiseIrql(KIRQL NewIrql
, PKIRQL OldIrql
)
112 * FUNCTION: Raises the hardware priority (irql)
114 * NewIrql = Irql to raise to
115 * OldIrql (OUT) = Caller supplied storage for the previous irql
121 DPRINT("CurrentIrql %x NewIrql %x OldIrql %x\n",CurrentIrql
,NewIrql
,
123 if (NewIrql
< CurrentIrql
)
125 DbgPrint("%s:%d CurrentIrql %x NewIrql %x OldIrql %x\n",__FILE__
,__LINE__
,
126 CurrentIrql
,NewIrql
,OldIrql
);
131 *OldIrql
= CurrentIrql
;
132 CurrentIrql
= NewIrql
;
133 // *OldIrql = InterlockedExchange(&CurrentIrql,NewIrql);
134 DPRINT("NewIrql %x OldIrql %x CurrentIrql %x\n",NewIrql
,*OldIrql
,