Home | History | Annotate | Download | only in Event
      1 /** @file
      2   Task priority (TPL) functions.
      3 
      4 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "DxeMain.h"
     16 #include "Event.h"
     17 
     18 /**
     19   Set Interrupt State.
     20 
     21   @param  Enable  The state of enable or disable interrupt
     22 
     23 **/
     24 VOID
     25 CoreSetInterruptState (
     26   IN BOOLEAN      Enable
     27   )
     28 {
     29   EFI_STATUS  Status;
     30   BOOLEAN     InSmm;
     31 
     32   if (gCpu == NULL) {
     33     return;
     34   }
     35   if (!Enable) {
     36     gCpu->DisableInterrupt (gCpu);
     37     return;
     38   }
     39   if (gSmmBase2 == NULL) {
     40     gCpu->EnableInterrupt (gCpu);
     41     return;
     42   }
     43   Status = gSmmBase2->InSmm (gSmmBase2, &InSmm);
     44   if (!EFI_ERROR (Status) && !InSmm) {
     45     gCpu->EnableInterrupt(gCpu);
     46   }
     47 }
     48 
     49 
     50 /**
     51   Raise the task priority level to the new level.
     52   High level is implemented by disabling processor interrupts.
     53 
     54   @param  NewTpl  New task priority level
     55 
     56   @return The previous task priority level
     57 
     58 **/
     59 EFI_TPL
     60 EFIAPI
     61 CoreRaiseTpl (
     62   IN EFI_TPL      NewTpl
     63   )
     64 {
     65   EFI_TPL     OldTpl;
     66 
     67   OldTpl = gEfiCurrentTpl;
     68   if (OldTpl > NewTpl) {
     69     DEBUG ((EFI_D_ERROR, "FATAL ERROR - RaiseTpl with OldTpl(0x%x) > NewTpl(0x%x)\n", OldTpl, NewTpl));
     70     ASSERT (FALSE);
     71   }
     72   ASSERT (VALID_TPL (NewTpl));
     73 
     74   //
     75   // If raising to high level, disable interrupts
     76   //
     77   if (NewTpl >= TPL_HIGH_LEVEL  &&  OldTpl < TPL_HIGH_LEVEL) {
     78     CoreSetInterruptState (FALSE);
     79   }
     80 
     81   //
     82   // Set the new value
     83   //
     84   gEfiCurrentTpl = NewTpl;
     85 
     86   return OldTpl;
     87 }
     88 
     89 
     90 
     91 
     92 /**
     93   Lowers the task priority to the previous value.   If the new
     94   priority unmasks events at a higher priority, they are dispatched.
     95 
     96   @param  NewTpl  New, lower, task priority
     97 
     98 **/
     99 VOID
    100 EFIAPI
    101 CoreRestoreTpl (
    102   IN EFI_TPL NewTpl
    103   )
    104 {
    105   EFI_TPL     OldTpl;
    106 
    107   OldTpl = gEfiCurrentTpl;
    108   if (NewTpl > OldTpl) {
    109     DEBUG ((EFI_D_ERROR, "FATAL ERROR - RestoreTpl with NewTpl(0x%x) > OldTpl(0x%x)\n", NewTpl, OldTpl));
    110     ASSERT (FALSE);
    111   }
    112   ASSERT (VALID_TPL (NewTpl));
    113 
    114   //
    115   // If lowering below HIGH_LEVEL, make sure
    116   // interrupts are enabled
    117   //
    118 
    119   if (OldTpl >= TPL_HIGH_LEVEL  &&  NewTpl < TPL_HIGH_LEVEL) {
    120     gEfiCurrentTpl = TPL_HIGH_LEVEL;
    121   }
    122 
    123   //
    124   // Dispatch any pending events
    125   //
    126   while (((-2 << NewTpl) & gEventPending) != 0) {
    127     gEfiCurrentTpl = (UINTN) HighBitSet64 (gEventPending);
    128     if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
    129       CoreSetInterruptState (TRUE);
    130     }
    131     CoreDispatchEventNotifies (gEfiCurrentTpl);
    132   }
    133 
    134   //
    135   // Set the new value
    136   //
    137 
    138   gEfiCurrentTpl = NewTpl;
    139 
    140   //
    141   // If lowering below HIGH_LEVEL, make sure
    142   // interrupts are enabled
    143   //
    144   if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
    145     CoreSetInterruptState (TRUE);
    146   }
    147 
    148 }
    149