2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/hal/x86/irql.c
5 * PURPOSE: Implements IRQLs
6 * PROGRAMMER: David Welch (welch@cwcom.net)
9 /* INCLUDES *****************************************************************/
11 #include <ddk/ntddk.h>
12 #include <internal/bitops.h>
13 #include <internal/halio.h>
14 #include <internal/ke.h>
15 #include <internal/ps.h>
18 #include <internal/debug.h>
20 /* GLOBALS ******************************************************************/
23 * PURPOSE: Current irq level
25 static KIRQL CurrentIrql
= HIGH_LEVEL
;
27 extern ULONG DpcQueueSize
;
29 /* FUNCTIONS ****************************************************************/
32 static unsigned int HiGetCurrentPICMask(void)
37 mask
= mask
| (inb_p(0xa1)<<8);
43 static unsigned int HiSetCurrentPICMask(unsigned int mask
)
45 outb_p(0x21,mask
& 0xff);
46 outb_p(0xa1,(mask
>> 8) & 0xff);
51 static VOID
HiSwitchIrql(KIRQL oldIrql
)
53 * FUNCTION: Switches to the current irql
54 * NOTE: Must be called with interrupt disabled
58 PKTHREAD CurrentThread
;
60 CurrentThread
= KeGetCurrentThread();
62 if (CurrentIrql
== HIGH_LEVEL
)
64 HiSetCurrentPICMask(0xffff);
67 if (CurrentIrql
> DISPATCH_LEVEL
)
69 unsigned int current_mask
= 0;
71 for (i
=(CurrentIrql
-DISPATCH_LEVEL
);i
>DISPATCH_LEVEL
;i
--)
73 set_bit(NR_DEVICE_SPECIFIC_LEVELS
- i
,¤t_mask
);
76 HiSetCurrentPICMask(current_mask
);
81 if (CurrentIrql
== DISPATCH_LEVEL
)
83 HiSetCurrentPICMask(0);
88 HiSetCurrentPICMask(0);
89 if (CurrentIrql
== APC_LEVEL
)
91 if (DpcQueueSize
> 0 )
93 KeSetCurrentIrql(DISPATCH_LEVEL
);
97 KeSetCurrentIrql(PASSIVE_LEVEL
);
103 if (CurrentIrql
== PASSIVE_LEVEL
&&
104 CurrentThread
!= NULL
&&
105 CurrentThread
->ApcState
.KernelApcPending
)
107 KeSetCurrentIrql(APC_LEVEL
);
111 KeSetCurrentIrql(PASSIVE_LEVEL
);
121 VOID
KeSetCurrentIrql(KIRQL newlvl
)
123 * PURPOSE: Sets the current irq level without taking any action
126 // DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl);
127 CurrentIrql
= newlvl
;
131 KIRQL STDCALL
KeGetCurrentIrql (VOID
)
133 * PURPOSE: Returns the current irq level
134 * RETURNS: The current irq level
141 /**********************************************************************
146 * Restores the irq level on the current processor
149 * NewIrql = Irql to lower to
155 * Uses fastcall convention
168 DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql
);
170 if (NewIrql
> CurrentIrql
)
172 DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
173 __FILE__
, __LINE__
, NewIrql
, CurrentIrql
);
174 KeDumpStackFrames (0, 32);
178 OldIrql
= CurrentIrql
;
179 CurrentIrql
= NewIrql
;
180 HiSwitchIrql(OldIrql
);
184 /**********************************************************************
189 * Restores the irq level on the current processor
192 * NewIrql = Irql to lower to
206 KfLowerIrql (NewIrql
);
210 /**********************************************************************
215 * Raises the hardware priority (irql)
218 * NewIrql = Irql to raise to
224 * Uses fastcall convention
235 DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql
);
237 if (NewIrql
< CurrentIrql
)
239 DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
240 __FILE__
,__LINE__
,CurrentIrql
,NewIrql
);
246 OldIrql
= CurrentIrql
;
247 CurrentIrql
= NewIrql
;
249 DPRINT ("NewIrql %x OldIrql %x CurrentIrql %x\n",
250 NewIrql
, OldIrql
, CurrentIrql
);
251 HiSwitchIrql(OldIrql
);
257 /**********************************************************************
262 * Raises the hardware priority (irql)
265 * NewIrql = Irql to raise to
266 * OldIrql (OUT) = Caller supplied storage for the previous irql
282 *OldIrql
= KfRaiseIrql (NewIrql
);