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