ReactOS  0.4.14-dev-52-g6116262
mpsirql.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: hal/halx86/mp/mpsirql.c
5  * PURPOSE: Implements IRQLs for multiprocessor systems
6  * PROGRAMMERS: David Welch (welch@cwcom.net)
7  * Casper S. Hornstrup (chorns@users.sourceforge.net)
8  * UPDATE HISTORY:
9  * 12/04/2001 CSH Created
10  */
11 
12 /* INCLUDES *****************************************************************/
13 
14 #include <hal.h>
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* GLOBALS ******************************************************************/
19 
20 
21 /* FUNCTIONS ****************************************************************/
22 
23 #undef KeGetCurrentIrql
25 /*
26  * PURPOSE: Returns the current irq level
27  * RETURNS: The current irq level
28  */
29 {
30  KIRQL irql;
31  ULONG Flags;
32 
33  Flags = __readeflags();
34  _disable();
35 
37  if (irql > HIGH_LEVEL)
38  {
39  DPRINT1 ("CurrentIrql %x\n", irql);
40  ASSERT(FALSE);
41  }
43  {
44  _enable();
45  }
46  return irql;
47 }
48 
49 
50 #undef KeSetCurrentIrql
52 /*
53  * PURPOSE: Sets the current irq level without taking any action
54  */
55 {
56  ULONG Flags;
57  if (NewIrql > HIGH_LEVEL)
58  {
59  DPRINT1 ("NewIrql %x\n", NewIrql);
60  ASSERT(FALSE);
61  }
62  Flags = __readeflags();
63  _disable();
66  {
67  _enable();
68  }
69 }
70 
71 VOID
72 HalpLowerIrql(KIRQL NewIrql, BOOLEAN FromHalEndSystemInterrupt)
73 {
74  ULONG Flags;
75  UCHAR DpcRequested;
76  if (NewIrql >= DISPATCH_LEVEL)
77  {
80  return;
81  }
82  Flags = __readeflags();
84  {
87  DpcRequested = __readfsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]));
88  if (FromHalEndSystemInterrupt || DpcRequested)
89  {
91  _enable();
94  {
95  _disable();
96  }
97  }
99  }
100  if (NewIrql == APC_LEVEL)
101  {
102  return;
103  }
104  if (KeGetCurrentThread () != NULL &&
105  KeGetCurrentThread ()->ApcState.KernelApcPending)
106  {
107  _enable();
109  if (!(Flags & EFLAGS_INTERRUPT_MASK))
110  {
111  _disable();
112  }
113  }
115 }
116 
117 
118 /**********************************************************************
119  * NAME EXPORTED
120  * KfLowerIrql
121  *
122  * DESCRIPTION
123  * Restores the irq level on the current processor
124  *
125  * ARGUMENTS
126  * NewIrql = Irql to lower to
127  *
128  * RETURN VALUE
129  * None
130  *
131  * NOTES
132  * Uses fastcall convention
133  */
136 {
137  KIRQL oldIrql = KeGetCurrentIrql();
138  if (NewIrql > oldIrql)
139  {
140  DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
141  ASSERT(FALSE);
142  }
144 }
145 
146 
147 /**********************************************************************
148  * NAME EXPORTED
149  * KfRaiseIrql
150  *
151  * DESCRIPTION
152  * Raises the hardware priority (irql)
153  *
154  * ARGUMENTS
155  * NewIrql = Irql to raise to
156  *
157  * RETURN VALUE
158  * previous irq level
159  *
160  * NOTES
161  * Uses fastcall convention
162  */
163 
166 {
167  KIRQL OldIrql;
168  ULONG Flags;
169 
170  Flags = __readeflags();
171  _disable();
172 
174 
175  if (NewIrql < OldIrql)
176  {
177  DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql);
178  ASSERT(FALSE);
179  }
180 
181 
182  if (NewIrql > DISPATCH_LEVEL)
183  {
185  }
188  {
189  _enable();
190  }
191 
192  return OldIrql;
193 }
194 
195 /**********************************************************************
196  * NAME EXPORTED
197  * KeRaiseIrqlToDpcLevel
198  *
199  * DESCRIPTION
200  * Raises the hardware priority (irql) to DISPATCH level
201  *
202  * ARGUMENTS
203  * None
204  *
205  * RETURN VALUE
206  * Previous irq level
207  *
208  * NOTES
209  * Calls KfRaiseIrql
210  */
211 
212 KIRQL NTAPI
214 {
215  return KfRaiseIrql (DISPATCH_LEVEL);
216 }
217 
218 
219 /**********************************************************************
220  * NAME EXPORTED
221  * KeRaiseIrqlToSynchLevel
222  *
223  * DESCRIPTION
224  * Raises the hardware priority (irql) to CLOCK2 level
225  *
226  * ARGUMENTS
227  * None
228  *
229  * RETURN VALUE
230  * Previous irq level
231  *
232  * NOTES
233  * Calls KfRaiseIrql
234  */
235 
236 KIRQL NTAPI
238 {
239  return KfRaiseIrql (CLOCK2_LEVEL);
240 }
241 
242 
245  ULONG Vector,
246  PKIRQL OldIrql)
247 {
248  ULONG Flags;
249  DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql);
250 
251  if (KeGetCurrentIrql () >= Irql)
252  {
253  DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
254  ASSERT(FALSE);
255  }
256 
257  Flags = __readeflags();
259  {
260  DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n");
261  ASSERT(FALSE);
262  }
266  return(TRUE);
267 }
268 
269 
270 VOID NTAPI
272  IN PKTRAP_FRAME TrapFrame)
273 /*
274  * FUNCTION: Finish a system interrupt and restore the specified irq level.
275  */
276 {
277  ULONG Flags;
278  Flags = __readeflags();
279 
281  {
282  DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n");
283  ASSERT(FALSE);
284  }
285  APICSendEOI();
287 }
288 
289 VOID
290 NTAPI
292  KIRQL Irql)
293 {
294  ULONG irq;
295 
296  DPRINT ("Vector (0x%X)\n", Vector);
297 
298  if (Vector < FIRST_DEVICE_VECTOR ||
299  Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
300  {
301  DPRINT1("Not a device interrupt, vector=%x\n", Vector);
302  ASSERT(FALSE);
303  return;
304  }
305 
306  irq = VECTOR2IRQ (Vector);
307  IOAPICMaskIrq (irq);
308 
309  return;
310 }
311 
312 
315  KIRQL Irql,
317 {
318  ULONG irq;
319 
320  if (Vector < FIRST_DEVICE_VECTOR ||
321  Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
322  {
323  DPRINT("Not a device interrupt\n");
324  return FALSE;
325  }
326 
327  /* FIXME: We must check if the requested and the assigned interrupt mode is the same */
328 
329  irq = VECTOR2IRQ (Vector);
331 
332  return TRUE;
333 }
334 
337 {
338  switch (Request)
339  {
340  case APC_LEVEL:
341  __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_APC_REQUEST]), 1);
342  break;
343 
344  case DISPATCH_LEVEL:
345  __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]), 1);
346  break;
347 
348  default:
349  ASSERT(FALSE);
350  }
351 }
352 
355  IN KIRQL Request)
356 {
358 }
VOID HalpLowerIrql(KIRQL NewIrql, BOOLEAN FromHalEndSystemInterrupt)
Definition: mpsirql.c:72
__inline VOID APICSendEOI(VOID)
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
void __cdecl _enable(void)
Definition: intrin_arm.h:373
Definition: ke.h:280
VOID IOAPICMaskIrq(ULONG Irq)
Definition: ioapic.c:497
VOID KeSetCurrentIrql(KIRQL NewIrql)
Definition: mpsirql.c:51
__inline VOID APICWrite(ULONG Offset, ULONG Value)
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: mpsirql.c:237
unsigned char irq
Definition: dsp.h:13
#define NUMBER_DEVICE_VECTORS
Definition: mps.h:37
#define APIC_TPR
Definition: apic.h:12
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
KIRQL NTAPI KeRaiseIrqlToDpcLevel(VOID)
Definition: mpsirql.c:213
VOID FASTCALL KfLowerIrql(KIRQL NewIrql)
Definition: mpsirql.c:135
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1555
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Request)
Definition: mpsirql.c:354
#define VECTOR2IRQ(vector)
Definition: halirq.h:25
#define HAL_APC_REQUEST
Definition: halp.h:10
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
void DPRINT(...)
Definition: polytest.cpp:61
#define APIC_TPR_PRI
Definition: apic.h:42
#define CLOCK2_LEVEL
Definition: env_spec_w32.h:700
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
Definition: intrin_ppc.h:360
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
Definition: intrin_ppc.h:342
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:295
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define IRQL2TPR(irql)
Definition: mps.h:9
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define HAL_DPC_REQUEST
Definition: halp.h:11
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1492
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID IOAPICUnmaskIrq(ULONG Irq)
Definition: ioapic.c:514
VOID NTAPI HalEndSystemInterrupt(KIRQL Irql, IN PKTRAP_FRAME TrapFrame)
Definition: mpsirql.c:271
#define DPRINT1
Definition: precomp.h:8
KIRQL irql
Definition: wave.h:1
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
KIRQL FASTCALL KfRaiseIrql(KIRQL NewIrql)
Definition: mpsirql.c:165
VOID NTAPI HalDisableSystemInterrupt(ULONG Vector, KIRQL Irql)
Definition: mpsirql.c:291
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Request)
Definition: mpsirql.c:336
#define KeGetCurrentThread
Definition: hal.h:44
BOOLEAN NTAPI HalEnableSystemInterrupt(ULONG Vector, KIRQL Irql, KINTERRUPT_MODE InterruptMode)
Definition: mpsirql.c:314
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
#define APC_LEVEL
Definition: env_spec_w32.h:695
BOOLEAN NTAPI HalBeginSystemInterrupt(KIRQL Irql, ULONG Vector, PKIRQL OldIrql)
Definition: mpsirql.c:244
_Requires_lock_held_ SpinLock _Releases_lock_ SpinLock _In_ _IRQL_restores_ KIRQL NewIrql
Definition: ke.h:114
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126
KIRQL NTAPI KeGetCurrentIrql(VOID)
Definition: mpsirql.c:24