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

mpsirql.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS kernel
00004  * FILE:            hal/halx86/mp/mpsirql.c
00005  * PURPOSE:         Implements IRQLs for multiprocessor systems
00006  * PROGRAMMERS:     David Welch (welch@cwcom.net)
00007  *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
00008  * UPDATE HISTORY:
00009  *     12/04/2001  CSH  Created
00010  */
00011 
00012 /* INCLUDES *****************************************************************/
00013 
00014 #include <hal.h>
00015 #define NDEBUG
00016 #include <debug.h>
00017 
00018 /* GLOBALS ******************************************************************/
00019 
00020 
00021 /* FUNCTIONS ****************************************************************/
00022 
00023 #undef KeGetCurrentIrql
00024 KIRQL NTAPI KeGetCurrentIrql (VOID)
00025 /*
00026  * PURPOSE: Returns the current irq level
00027  * RETURNS: The current irq level
00028  */
00029 {
00030   KIRQL irql;
00031   ULONG Flags;
00032 
00033   Flags = __readeflags();
00034   _disable();
00035 
00036   irql = __readfsbyte(FIELD_OFFSET(KPCR, Irql));
00037   if (irql > HIGH_LEVEL)
00038     {
00039       DPRINT1 ("CurrentIrql %x\n", irql);
00040       ASSERT(FALSE);
00041     }
00042   if (Flags & EFLAGS_INTERRUPT_MASK)
00043     {
00044       _enable();
00045     }
00046   return irql;
00047 }
00048 
00049 
00050 #undef KeSetCurrentIrql
00051 VOID KeSetCurrentIrql (KIRQL NewIrql)
00052 /*
00053  * PURPOSE: Sets the current irq level without taking any action
00054  */
00055 {
00056   ULONG Flags;
00057   if (NewIrql > HIGH_LEVEL)
00058   {
00059     DPRINT1 ("NewIrql %x\n", NewIrql);
00060     ASSERT(FALSE);
00061   }
00062   Flags = __readeflags();
00063   _disable();
00064   __writefsbyte(FIELD_OFFSET(KPCR, Irql), NewIrql);
00065   if (Flags & EFLAGS_INTERRUPT_MASK)
00066     {
00067       _enable();
00068     }
00069 }
00070 
00071 VOID
00072 HalpLowerIrql(KIRQL NewIrql, BOOLEAN FromHalEndSystemInterrupt)
00073 {
00074   ULONG Flags;
00075   UCHAR DpcRequested;
00076   if (NewIrql >= DISPATCH_LEVEL)
00077     {
00078       KeSetCurrentIrql (NewIrql);
00079       APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
00080       return;
00081     }
00082   Flags = __readeflags();
00083   if (KeGetCurrentIrql() > APC_LEVEL)
00084     {
00085       KeSetCurrentIrql (DISPATCH_LEVEL);
00086       APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI);
00087       DpcRequested = __readfsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]));
00088       if (FromHalEndSystemInterrupt || DpcRequested)
00089         {
00090           __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]), 0);
00091           _enable();
00092           KiDispatchInterrupt();
00093           if (!(Flags & EFLAGS_INTERRUPT_MASK))
00094             {
00095               _disable();
00096             }
00097     }
00098       KeSetCurrentIrql (APC_LEVEL);
00099     }
00100   if (NewIrql == APC_LEVEL)
00101     {
00102       return;
00103     }
00104   if (KeGetCurrentThread () != NULL &&
00105       KeGetCurrentThread ()->ApcState.KernelApcPending)
00106     {
00107       _enable();
00108       KiDeliverApc(KernelMode, NULL, NULL);
00109       if (!(Flags & EFLAGS_INTERRUPT_MASK))
00110         {
00111           _disable();
00112         }
00113     }
00114   KeSetCurrentIrql (PASSIVE_LEVEL);
00115 }
00116 
00117 
00118 /**********************************************************************
00119  * NAME                         EXPORTED
00120  *  KfLowerIrql
00121  *
00122  * DESCRIPTION
00123  *  Restores the irq level on the current processor
00124  *
00125  * ARGUMENTS
00126  *  NewIrql = Irql to lower to
00127  *
00128  * RETURN VALUE
00129  *  None
00130  *
00131  * NOTES
00132  *  Uses fastcall convention
00133  */
00134 VOID FASTCALL
00135 KfLowerIrql (KIRQL  NewIrql)
00136 {
00137   KIRQL oldIrql = KeGetCurrentIrql();
00138   if (NewIrql > oldIrql)
00139     {
00140       DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
00141       ASSERT(FALSE);
00142     }
00143   HalpLowerIrql (NewIrql, FALSE);
00144 }
00145 
00146 
00147 /**********************************************************************
00148  * NAME                         EXPORTED
00149  *  KfRaiseIrql
00150  *
00151  * DESCRIPTION
00152  *  Raises the hardware priority (irql)
00153  *
00154  * ARGUMENTS
00155  *  NewIrql = Irql to raise to
00156  *
00157  * RETURN VALUE
00158  *  previous irq level
00159  *
00160  * NOTES
00161  *  Uses fastcall convention
00162  */
00163 
00164 KIRQL FASTCALL
00165 KfRaiseIrql (KIRQL  NewIrql)
00166 {
00167   KIRQL OldIrql;
00168   ULONG Flags;
00169 
00170   Flags = __readeflags();
00171   _disable();
00172 
00173   OldIrql = KeGetCurrentIrql ();
00174 
00175   if (NewIrql < OldIrql)
00176     {
00177       DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql);
00178       ASSERT(FALSE);
00179     }
00180 
00181 
00182   if (NewIrql > DISPATCH_LEVEL)
00183     {
00184       APICWrite (APIC_TPR, IRQL2TPR(NewIrql) & APIC_TPR_PRI);
00185     }
00186   KeSetCurrentIrql (NewIrql);
00187   if (Flags & EFLAGS_INTERRUPT_MASK)
00188     {
00189       _enable();
00190     }
00191 
00192   return OldIrql;
00193 }
00194 
00195 /**********************************************************************
00196  * NAME                         EXPORTED
00197  *  KeRaiseIrqlToDpcLevel
00198  *
00199  * DESCRIPTION
00200  *  Raises the hardware priority (irql) to DISPATCH level
00201  *
00202  * ARGUMENTS
00203  *  None
00204  *
00205  * RETURN VALUE
00206  *  Previous irq level
00207  *
00208  * NOTES
00209  *  Calls KfRaiseIrql
00210  */
00211 
00212 KIRQL NTAPI
00213 KeRaiseIrqlToDpcLevel (VOID)
00214 {
00215   return KfRaiseIrql (DISPATCH_LEVEL);
00216 }
00217 
00218 
00219 /**********************************************************************
00220  * NAME                         EXPORTED
00221  *  KeRaiseIrqlToSynchLevel
00222  *
00223  * DESCRIPTION
00224  *  Raises the hardware priority (irql) to CLOCK2 level
00225  *
00226  * ARGUMENTS
00227  *  None
00228  *
00229  * RETURN VALUE
00230  *  Previous irq level
00231  *
00232  * NOTES
00233  *  Calls KfRaiseIrql
00234  */
00235 
00236 KIRQL NTAPI
00237 KeRaiseIrqlToSynchLevel (VOID)
00238 {
00239   return KfRaiseIrql (CLOCK2_LEVEL);
00240 }
00241 
00242 
00243 BOOLEAN NTAPI
00244 HalBeginSystemInterrupt (KIRQL Irql,
00245              ULONG Vector,
00246              PKIRQL OldIrql)
00247 {
00248   ULONG Flags;
00249   DPRINT("Vector (0x%X)  Irql (0x%X)\n", Vector, Irql);
00250 
00251   if (KeGetCurrentIrql () >= Irql)
00252   {
00253     DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
00254     ASSERT(FALSE);
00255   }
00256 
00257   Flags = __readeflags();
00258   if (Flags & EFLAGS_INTERRUPT_MASK)
00259   {
00260      DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n");
00261      ASSERT(FALSE);
00262   }
00263   APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
00264   *OldIrql = KeGetCurrentIrql ();
00265   KeSetCurrentIrql (Irql);
00266   return(TRUE);
00267 }
00268 
00269 
00270 VOID NTAPI
00271 HalEndSystemInterrupt (KIRQL Irql,
00272                        IN PKTRAP_FRAME TrapFrame)
00273 /*
00274  * FUNCTION: Finish a system interrupt and restore the specified irq level.
00275  */
00276 {
00277   ULONG Flags;
00278   Flags = __readeflags();
00279 
00280   if (Flags & EFLAGS_INTERRUPT_MASK)
00281   {
00282      DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n");
00283      ASSERT(FALSE);
00284   }
00285   APICSendEOI();
00286   HalpLowerIrql (Irql, TRUE);
00287 }
00288 
00289 VOID
00290 NTAPI
00291 HalDisableSystemInterrupt(ULONG Vector,
00292               KIRQL Irql)
00293 {
00294   ULONG irq;
00295 
00296   DPRINT ("Vector (0x%X)\n", Vector);
00297 
00298   if (Vector < FIRST_DEVICE_VECTOR ||
00299       Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
00300   {
00301     DPRINT1("Not a device interrupt, vector=%x\n", Vector);
00302     ASSERT(FALSE);
00303     return;
00304   }
00305 
00306   irq = VECTOR2IRQ (Vector);
00307   IOAPICMaskIrq (irq);
00308 
00309   return;
00310 }
00311 
00312 
00313 BOOLEAN NTAPI
00314 HalEnableSystemInterrupt (ULONG Vector,
00315               KIRQL Irql,
00316               KINTERRUPT_MODE InterruptMode)
00317 {
00318   ULONG irq;
00319 
00320   if (Vector < FIRST_DEVICE_VECTOR ||
00321       Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
00322   {
00323     DPRINT("Not a device interrupt\n");
00324     return FALSE;
00325   }
00326 
00327   /* FIXME: We must check if the requested and the assigned interrupt mode is the same */
00328 
00329   irq = VECTOR2IRQ (Vector);
00330   IOAPICUnmaskIrq (irq);
00331 
00332   return TRUE;
00333 }
00334 
00335 VOID FASTCALL
00336 HalRequestSoftwareInterrupt(IN KIRQL Request)
00337 {
00338   switch (Request)
00339   {
00340     case APC_LEVEL:
00341       __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_APC_REQUEST]), 1);
00342       break;
00343 
00344     case DISPATCH_LEVEL:
00345       __writefsbyte(FIELD_OFFSET(KIPCR, HalReserved[HAL_DPC_REQUEST]), 1);
00346       break;
00347 
00348     default:
00349       ASSERT(FALSE);
00350   }
00351 }
00352 
00353 VOID FASTCALL
00354 HalClearSoftwareInterrupt(
00355   IN KIRQL Request)
00356 {
00357   UNIMPLEMENTED;
00358 }

Generated on Sun May 27 2012 04:28:45 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.