ReactOS  0.4.13-dev-982-g9853eab
irql.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/halppc/generic/irql.c
5  * PURPOSE: Implements IRQLs
6  * PROGRAMMER: David Welch (welch@cwcom.net)
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS ******************************************************************/
16 
17 /*
18  * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
19 */
20 
21 typedef union
22 {
24  struct
25  {
28  };
29 }
30 PIC_MASK;
31 
32 /*
33  * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
34  * - At startup enable timer and cascade
35  */
36 #if defined(__GNUC__)
37 static PIC_MASK pic_mask = {.both = 0xFFFA};
38 #else
39 static PIC_MASK pic_mask = { 0xFFFA };
40 #endif
41 
42 
43 /*
44  * PURPOSE: Mask for disabling of acknowledged interrupts
45  */
46 #if defined(__GNUC__)
47 static PIC_MASK pic_mask_intr = {.both = 0x0000};
48 #else
49 static PIC_MASK pic_mask_intr = { 0 };
50 #endif
51 
53 
54 #define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x)
55 #define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x)
56 
57 #ifdef _MSC_VER
58 
59 #define KiInterruptDispatch2(x, y)
60 
61 #else
62 
63 VOID NTAPI
64 KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
65 
66 #endif
67 
68 /* FUNCTIONS ****************************************************************/
69 
70 #undef KeGetCurrentIrql
72 /*
73  * PURPOSE: Returns the current irq level
74  * RETURNS: The current irq level
75  */
76 {
77  return(KeGetPcr()->Irql);
78 }
79 
81 {
83 
84  /* Initialization sequence */
85  WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
86  WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
87  /* Start of hardware irqs (0x24) */
89  WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
90  /* 8259-1 is master */
91  WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
92  /* 8259-2 is slave */
93  WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
94  /* 8086 mode */
95  WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
96  WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
97  /* Enable interrupts */
98  WRITE_PORT_UCHAR((PUCHAR)0x21, 0xFF);
99  WRITE_PORT_UCHAR((PUCHAR)0xa1, 0xFF);
100 
101  /* We can now enable interrupts */
102  _enable();
103 }
104 
106 /*
107  * FUNCTION: Enable all irqs with higher priority.
108  */
109 {
110  const USHORT mask[] =
111  {
112  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
113  0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
114  0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
115  0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
116  };
117 
118  /* Interrupts should be disable while enabling irqs of both pics */
119  _disable();
120 
124 
125  /* restore ints */
126  _enable();
127 }
128 
129 VOID
131 {
132  ULONG IrqLimit, i;
133  IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
134 
135  /*
136  * For each irq if there have been any deferred interrupts then now
137  * dispatch them.
138  */
139  for (i = 0; i < IrqLimit; i++)
140  {
141  if (HalpPendingInterruptCount[i] > 0)
142  {
143  KeGetPcr()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
144 
145  while (HalpPendingInterruptCount[i] > 0)
146  {
147  /*
148  * For each deferred interrupt execute all the handlers at DIRQL.
149  */
151  //HalpHardwareInt[i]();
152  }
153  //KeGetPcr()->Irql--;
154  //HalpEndSystemInterrupt(KeGetPcr()->Irql);
155  }
156  }
157 
158 }
159 
160 VOID
162 {
163  if (NewIrql >= PROFILE_LEVEL)
164  {
165  KeGetPcr()->Irql = NewIrql;
166  return;
167  }
169  if (NewIrql >= DISPATCH_LEVEL)
170  {
171  KeGetPcr()->Irql = NewIrql;
172  return;
173  }
174  KeGetPcr()->Irql = DISPATCH_LEVEL;
175  if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST])
176  {
177  ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
179  }
180  KeGetPcr()->Irql = APC_LEVEL;
181  if (NewIrql == APC_LEVEL)
182  {
183  return;
184  }
185  if (KeGetCurrentThread() != NULL &&
186  KeGetCurrentThread()->ApcState.KernelApcPending)
187  {
189  }
190  KeGetPcr()->Irql = PASSIVE_LEVEL;
191 }
192 
193 /**********************************************************************
194  * NAME EXPORTED
195  * KfLowerIrql
196  *
197  * DESCRIPTION
198  * Restores the irq level on the current processor
199  *
200  * ARGUMENTS
201  * NewIrql = Irql to lower to
202  *
203  * RETURN VALUE
204  * None
205  *
206  * NOTES
207  * Uses fastcall convention
208  */
211 {
212  DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
213 
214  if (NewIrql > KeGetPcr()->Irql)
215  {
216  DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
217  __FILE__, __LINE__, NewIrql, KeGetPcr()->Irql);
218  KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
219  for(;;);
220  }
221 
223 }
224 
225 /**********************************************************************
226  * NAME EXPORTED
227  * KfRaiseIrql
228  *
229  * DESCRIPTION
230  * Raises the hardware priority (irql)
231  *
232  * ARGUMENTS
233  * NewIrql = Irql to raise to
234  *
235  * RETURN VALUE
236  * previous irq level
237  *
238  * NOTES
239  * Uses fastcall convention
240  */
241 
244 {
245  KIRQL OldIrql;
246 
247  DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
248 
249  if (NewIrql < KeGetPcr()->Irql)
250  {
251  DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
252  __FILE__,__LINE__,KeGetPcr()->Irql,NewIrql);
253  KeBugCheck (IRQL_NOT_GREATER_OR_EQUAL);
254  for(;;);
255  }
256 
257  OldIrql = KeGetPcr()->Irql;
258  KeGetPcr()->Irql = NewIrql;
259  return OldIrql;
260 }
261 
262 /**********************************************************************
263  * NAME EXPORTED
264  * KeRaiseIrqlToDpcLevel
265  *
266  * DESCRIPTION
267  * Raises the hardware priority (irql) to DISPATCH level
268  *
269  * ARGUMENTS
270  * None
271  *
272  * RETURN VALUE
273  * Previous irq level
274  *
275  * NOTES
276  * Calls KfRaiseIrql
277  */
278 
279 KIRQL NTAPI
281 {
282  return KfRaiseIrql (DISPATCH_LEVEL);
283 }
284 
285 
286 /**********************************************************************
287  * NAME EXPORTED
288  * KeRaiseIrqlToSynchLevel
289  *
290  * DESCRIPTION
291  * Raises the hardware priority (irql) to CLOCK2 level
292  *
293  * ARGUMENTS
294  * None
295  *
296  * RETURN VALUE
297  * Previous irq level
298  *
299  * NOTES
300  * Calls KfRaiseIrql
301  */
302 
303 KIRQL NTAPI
305 {
306  return KfRaiseIrql (DISPATCH_LEVEL);
307 }
308 
309 
312  ULONG Vector,
313  PKIRQL OldIrql)
314 {
315  ULONG irq;
317  {
318  return(FALSE);
319  }
320  irq = Vector - IRQ_BASE;
321  pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt
322 
323  if (irq < 8)
324  {
326  WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
327  }
328  else
329  {
331  /* Send EOI to the PICs */
332  WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
333  WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
334  }
335 #if 0
336  if (KeGetPcr()->Irql >= Irql)
337  {
339  return(FALSE);
340  }
341 #endif
342  *OldIrql = KeGetPcr()->Irql;
343  KeGetPcr()->Irql = Irql;
344 
345  return(TRUE);
346 }
347 
348 
350 /*
351  * FUNCTION: Finish a system interrupt and restore the specified irq level.
352  */
353 {
356 }
357 
358 VOID
359 NTAPI
361  ULONG Vector,
362  KIRQL Irql)
363 {
364  ULONG irq;
365 
367  {
368  ASSERT(FALSE);
369  return;
370  }
371 
372  irq = Vector - IRQ_BASE;
373  pic_mask.both |= (1 << irq);
374  if (irq < 8)
375  {
377  }
378  else
379  {
381  }
382 
383  return;
384 }
385 
386 
387 BOOLEAN
388 NTAPI
390  ULONG Vector,
391  KIRQL Irql,
393 {
394  ULONG irq;
395 
397  return FALSE;
398 
399  irq = Vector - IRQ_BASE;
400  pic_mask.both &= ~(1 << irq);
401  if (irq < 8)
402  {
404  }
405  else
406  {
408  }
409 
410  return TRUE;
411 }
412 
413 
416  IN KIRQL Request)
417 {
418  switch (Request)
419  {
420  case APC_LEVEL:
421  ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE;
422  break;
423 
424  case DISPATCH_LEVEL:
425  ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE;
426  break;
427 
428  default:
429  DbgBreakPoint();
430  }
431 }
432 
435  IN KIRQL Request)
436 {
437  switch (Request)
438  {
439  case APC_LEVEL:
440  ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = FALSE;
441  break;
442 
443  case DISPATCH_LEVEL:
444  ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
445  break;
446 
447  default:
448  DbgBreakPoint();
449  }
450 }
451 
452 /* EOF */
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Request)
Definition: irql.c:415
#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 FASTCALL KfLowerIrql(KIRQL NewIrql)
Definition: irql.c:210
#define IRQ_BASE
Definition: halirq.h:22
VOID HalpExecuteIrqs(KIRQL NewIrql)
Definition: irql.c:130
#define DbgPrint
Definition: loader.c:25
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
void __cdecl _enable(void)
Definition: intrin_arm.h:373
struct _KIPCR * PKIPCR
struct _PIC_MASK PIC_MASK
VOID NTAPI HalDisableSystemInterrupt(ULONG Vector, KIRQL Irql)
Definition: irql.c:360
void DbgBreakPoint()
Definition: mach.c:558
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
unsigned char irq
Definition: dsp.h:13
#define KeGetPcr()
Definition: ke.h:25
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLenum GLint GLuint mask
Definition: glext.h:6028
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
BOOLEAN NTAPI HalEnableSystemInterrupt(ULONG Vector, KIRQL Irql, KINTERRUPT_MODE InterruptMode)
Definition: irql.c:389
VOID HalpLowerIrql(KIRQL NewIrql)
Definition: irql.c:161
VOID NTAPI HalEndSystemInterrupt(KIRQL Irql, ULONG Unknown2)
Definition: irql.c:349
#define HAL_APC_REQUEST
Definition: halp.h:10
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
static ULONG HalpPendingInterruptCount[NR_IRQS]
Definition: irql.c:52
VOID NTAPI HalpInitPICs(VOID)
Definition: irql.c:80
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
VOID NTAPI KiInterruptDispatch2(ULONG Irq, KIRQL old_level)
Definition: ppc_irq.c:365
USHORT both
Definition: irql.c:23
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: irql.c:304
Definition: irql.c:21
static PIC_MASK pic_mask
Definition: irql.c:39
VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Request)
Definition: irql.c:434
KIRQL FASTCALL KfRaiseIrql(KIRQL NewIrql)
Definition: irql.c:243
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 HalpEndSystemInterrupt(KIRQL Irql)
Definition: irql.c:105
VOID NTAPI KiDispatchInterrupt(VOID)
Definition: thrdini.c:295
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
UCHAR slave
Definition: irql.c:27
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define NR_IRQS
Definition: halirq.h:23
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define HAL_DPC_REQUEST
Definition: halp.h:11
BOOLEAN NTAPI HalBeginSystemInterrupt(KIRQL Irql, ULONG Vector, PKIRQL OldIrql)
Definition: irql.c:311
unsigned short USHORT
Definition: pedump.c:61
#define PROFILE_LEVEL
Definition: env_spec_w32.h:698
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1492
#define min(a, b)
Definition: monoChain.cc:55
UCHAR master
Definition: irql.c:26
KIRQL NTAPI KeGetCurrentIrql(VOID)
Definition: irql.c:71
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
static PIC_MASK pic_mask_intr
Definition: irql.c:49
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:539
#define KeGetCurrentThread
Definition: hal.h:44
#define IRQ_TO_DIRQL(x)
Definition: irql.c:55
#define memset(x, y, z)
Definition: compat.h:39
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
_Requires_lock_held_ SpinLock _Releases_lock_ SpinLock _In_ _IRQL_restores_ KIRQL NewIrql
Definition: ke.h:114
KIRQL NTAPI KeRaiseIrqlToDpcLevel(VOID)
Definition: irql.c:280