ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

irql.c
Go to the documentation of this file.
00001 /* $Id$
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS kernel
00005  * FILE:            ntoskrnl/hal/x86/irql.c
00006  * PURPOSE:         Implements IRQLs
00007  * PROGRAMMER:      David Welch (welch@cwcom.net)
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include <hal.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* GLOBALS ******************************************************************/
00017 
00018 /*
00019  * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
00020 */
00021 
00022 typedef union
00023 {
00024    USHORT both;
00025    struct
00026    {
00027       UCHAR master;
00028       UCHAR slave;
00029    };
00030 }
00031 PIC_MASK;
00032 
00033 /*
00034  * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
00035  *          - At startup enable timer and cascade
00036  */
00037 #if defined(__GNUC__)
00038 static PIC_MASK pic_mask = {.both = 0xFFFA};
00039 #else
00040 static PIC_MASK pic_mask = { 0xFFFA };
00041 #endif
00042 
00043 
00044 /*
00045  * PURPOSE: Mask for disabling of acknowledged interrupts
00046  */
00047 #if defined(__GNUC__)
00048 static PIC_MASK pic_mask_intr = {.both = 0x0000};
00049 #else
00050 static PIC_MASK pic_mask_intr = { 0 };
00051 #endif
00052 
00053 static ULONG HalpPendingInterruptCount[NR_IRQS];
00054 
00055 #define DIRQL_TO_IRQ(x)  (PROFILE_LEVEL - x)
00056 #define IRQ_TO_DIRQL(x)  (PROFILE_LEVEL - x)
00057 
00058 #ifdef _MSC_VER
00059 
00060 #define KiInterruptDispatch2(x, y)
00061 
00062 #else
00063 
00064 VOID NTAPI
00065 KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
00066 
00067 #endif
00068 
00069 /* FUNCTIONS ****************************************************************/
00070 
00071 #undef KeGetCurrentIrql
00072 KIRQL NTAPI KeGetCurrentIrql (VOID)
00073 /*
00074  * PURPOSE: Returns the current irq level
00075  * RETURNS: The current irq level
00076  */
00077 {
00078   return(KeGetPcr()->Irql);
00079 }
00080 
00081 VOID NTAPI HalpInitPICs(VOID)
00082 {
00083   memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount));
00084 
00085   /* Initialization sequence */
00086   WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
00087   WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
00088   /* Start of hardware irqs (0x24) */
00089   WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE);
00090   WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
00091   /* 8259-1 is master */
00092   WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
00093   /* 8259-2 is slave */
00094   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
00095   /* 8086 mode */
00096   WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
00097   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
00098   /* Enable interrupts */
00099   WRITE_PORT_UCHAR((PUCHAR)0x21, 0xFF);
00100   WRITE_PORT_UCHAR((PUCHAR)0xa1, 0xFF);
00101 
00102   /* We can now enable interrupts */
00103   _enable();
00104 }
00105 
00106 VOID HalpEndSystemInterrupt(KIRQL Irql)
00107 /*
00108  * FUNCTION: Enable all irqs with higher priority.
00109  */
00110 {
00111   const USHORT mask[] =
00112   {
00113      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00114      0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
00115      0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
00116      0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
00117   };
00118 
00119   /* Interrupts should be disable while enabling irqs of both pics */
00120   _disable();
00121 
00122   pic_mask_intr.both &= mask[Irql];
00123   WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
00124   WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
00125 
00126   /* restore ints */
00127   _enable();
00128 }
00129 
00130 VOID
00131 HalpExecuteIrqs(KIRQL NewIrql)
00132 {
00133   ULONG IrqLimit, i;
00134   IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
00135 
00136   /*
00137    * For each irq if there have been any deferred interrupts then now
00138    * dispatch them.
00139    */
00140   for (i = 0; i < IrqLimit; i++)
00141     {
00142       if (HalpPendingInterruptCount[i] > 0)
00143     {
00144        KeGetPcr()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
00145 
00146            while (HalpPendingInterruptCount[i] > 0)
00147          {
00148            /*
00149             * For each deferred interrupt execute all the handlers at DIRQL.
00150             */
00151            HalpPendingInterruptCount[i]--;
00152            //HalpHardwareInt[i]();
00153          }
00154        //KeGetPcr()->Irql--;
00155        //HalpEndSystemInterrupt(KeGetPcr()->Irql);
00156     }
00157     }
00158 
00159 }
00160 
00161 VOID
00162 HalpLowerIrql(KIRQL NewIrql)
00163 {
00164   if (NewIrql >= PROFILE_LEVEL)
00165     {
00166       KeGetPcr()->Irql = NewIrql;
00167       return;
00168     }
00169   HalpExecuteIrqs(NewIrql);
00170   if (NewIrql >= DISPATCH_LEVEL)
00171     {
00172       KeGetPcr()->Irql = NewIrql;
00173       return;
00174     }
00175   KeGetPcr()->Irql = DISPATCH_LEVEL;
00176   if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST])
00177     {
00178       ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
00179       KiDispatchInterrupt();
00180     }
00181   KeGetPcr()->Irql = APC_LEVEL;
00182   if (NewIrql == APC_LEVEL)
00183     {
00184       return;
00185     }
00186   if (KeGetCurrentThread() != NULL &&
00187       KeGetCurrentThread()->ApcState.KernelApcPending)
00188     {
00189       KiDeliverApc(KernelMode, NULL, NULL);
00190     }
00191   KeGetPcr()->Irql = PASSIVE_LEVEL;
00192 }
00193 
00194 /**********************************************************************
00195  * NAME                         EXPORTED
00196  *  KfLowerIrql
00197  *
00198  * DESCRIPTION
00199  *  Restores the irq level on the current processor
00200  *
00201  * ARGUMENTS
00202  *  NewIrql = Irql to lower to
00203  *
00204  * RETURN VALUE
00205  *  None
00206  *
00207  * NOTES
00208  *  Uses fastcall convention
00209  */
00210 VOID FASTCALL
00211 KfLowerIrql (KIRQL  NewIrql)
00212 {
00213   DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
00214 
00215   if (NewIrql > KeGetPcr()->Irql)
00216     {
00217       DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
00218         __FILE__, __LINE__, NewIrql, KeGetPcr()->Irql);
00219       KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
00220       for(;;);
00221     }
00222 
00223   HalpLowerIrql(NewIrql);
00224 }
00225 
00226 /**********************************************************************
00227  * NAME                         EXPORTED
00228  *  KfRaiseIrql
00229  *
00230  * DESCRIPTION
00231  *  Raises the hardware priority (irql)
00232  *
00233  * ARGUMENTS
00234  *  NewIrql = Irql to raise to
00235  *
00236  * RETURN VALUE
00237  *  previous irq level
00238  *
00239  * NOTES
00240  *  Uses fastcall convention
00241  */
00242 
00243 KIRQL FASTCALL
00244 KfRaiseIrql (KIRQL  NewIrql)
00245 {
00246   KIRQL OldIrql;
00247 
00248   DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
00249 
00250   if (NewIrql < KeGetPcr()->Irql)
00251     {
00252       DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
00253         __FILE__,__LINE__,KeGetPcr()->Irql,NewIrql);
00254       KeBugCheck (IRQL_NOT_GREATER_OR_EQUAL);
00255       for(;;);
00256     }
00257 
00258   OldIrql = KeGetPcr()->Irql;
00259   KeGetPcr()->Irql = NewIrql;
00260   return OldIrql;
00261 }
00262 
00263 /**********************************************************************
00264  * NAME                         EXPORTED
00265  *  KeRaiseIrqlToDpcLevel
00266  *
00267  * DESCRIPTION
00268  *  Raises the hardware priority (irql) to DISPATCH level
00269  *
00270  * ARGUMENTS
00271  *  None
00272  *
00273  * RETURN VALUE
00274  *  Previous irq level
00275  *
00276  * NOTES
00277  *  Calls KfRaiseIrql
00278  */
00279 
00280 KIRQL NTAPI
00281 KeRaiseIrqlToDpcLevel (VOID)
00282 {
00283   return KfRaiseIrql (DISPATCH_LEVEL);
00284 }
00285 
00286 
00287 /**********************************************************************
00288  * NAME                         EXPORTED
00289  *  KeRaiseIrqlToSynchLevel
00290  *
00291  * DESCRIPTION
00292  *  Raises the hardware priority (irql) to CLOCK2 level
00293  *
00294  * ARGUMENTS
00295  *  None
00296  *
00297  * RETURN VALUE
00298  *  Previous irq level
00299  *
00300  * NOTES
00301  *  Calls KfRaiseIrql
00302  */
00303 
00304 KIRQL NTAPI
00305 KeRaiseIrqlToSynchLevel (VOID)
00306 {
00307   return KfRaiseIrql (DISPATCH_LEVEL);
00308 }
00309 
00310 
00311 BOOLEAN NTAPI
00312 HalBeginSystemInterrupt (KIRQL Irql,
00313              ULONG Vector,
00314              PKIRQL OldIrql)
00315 {
00316   ULONG irq;
00317   if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
00318     {
00319       return(FALSE);
00320     }
00321   irq = Vector - IRQ_BASE;
00322   pic_mask_intr.both |= ((1 << irq) & 0xfffe);  // do not disable the timer interrupt
00323 
00324   if (irq < 8)
00325   {
00326      WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
00327      WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
00328   }
00329   else
00330   {
00331      WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
00332      /* Send EOI to the PICs */
00333      WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
00334      WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
00335   }
00336 #if 0
00337   if (KeGetPcr()->Irql >= Irql)
00338     {
00339       HalpPendingInterruptCount[irq]++;
00340       return(FALSE);
00341     }
00342 #endif
00343   *OldIrql = KeGetPcr()->Irql;
00344   KeGetPcr()->Irql = Irql;
00345 
00346   return(TRUE);
00347 }
00348 
00349 
00350 VOID NTAPI HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
00351 /*
00352  * FUNCTION: Finish a system interrupt and restore the specified irq level.
00353  */
00354 {
00355   HalpLowerIrql(Irql);
00356   HalpEndSystemInterrupt(Irql);
00357 }
00358 
00359 VOID
00360 NTAPI
00361 HalDisableSystemInterrupt(
00362   ULONG Vector,
00363   KIRQL Irql)
00364 {
00365   ULONG irq;
00366 
00367   if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
00368   {
00369     ASSERT(FALSE);
00370     return;
00371   }
00372 
00373   irq = Vector - IRQ_BASE;
00374   pic_mask.both |= (1 << irq);
00375   if (irq < 8)
00376      {
00377       WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave));
00378      }
00379   else
00380     {
00381       WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
00382     }
00383 
00384   return;
00385 }
00386 
00387 
00388 BOOLEAN
00389 NTAPI
00390 HalEnableSystemInterrupt(
00391   ULONG Vector,
00392   KIRQL Irql,
00393   KINTERRUPT_MODE InterruptMode)
00394 {
00395   ULONG irq;
00396 
00397   if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
00398     return FALSE;
00399 
00400   irq = Vector - IRQ_BASE;
00401   pic_mask.both &= ~(1 << irq);
00402   if (irq < 8)
00403     {
00404       WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
00405     }
00406   else
00407      {
00408        WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
00409      }
00410 
00411   return TRUE;
00412 }
00413 
00414 
00415 VOID FASTCALL
00416 HalRequestSoftwareInterrupt(
00417   IN KIRQL Request)
00418 {
00419   switch (Request)
00420   {
00421     case APC_LEVEL:
00422       ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE;
00423       break;
00424 
00425     case DISPATCH_LEVEL:
00426       ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE;
00427       break;
00428 
00429     default:
00430       DbgBreakPoint();
00431   }
00432 }
00433 
00434 VOID FASTCALL
00435 HalClearSoftwareInterrupt(
00436   IN KIRQL Request)
00437 {
00438   switch (Request)
00439   {
00440     case APC_LEVEL:
00441       ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = FALSE;
00442       break;
00443 
00444     case DISPATCH_LEVEL:
00445       ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
00446       break;
00447 
00448     default:
00449       DbgBreakPoint();
00450   }
00451 }
00452 
00453 /* EOF */

Generated on Sun May 27 2012 04:28:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.