aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c')
-rw-r--r--roms/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/roms/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c b/roms/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c
new file mode 100644
index 000000000..5ff8eb55b
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Core/Dxe/Event/Tpl.c
@@ -0,0 +1,148 @@
+/** @file
+ Task priority (TPL) functions.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "DxeMain.h"
+#include "Event.h"
+
+/**
+ Set Interrupt State.
+
+ @param Enable The state of enable or disable interrupt
+
+**/
+VOID
+CoreSetInterruptState (
+ IN BOOLEAN Enable
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN InSmm;
+
+ if (gCpu == NULL) {
+ return;
+ }
+ if (!Enable) {
+ gCpu->DisableInterrupt (gCpu);
+ return;
+ }
+ if (gSmmBase2 == NULL) {
+ gCpu->EnableInterrupt (gCpu);
+ return;
+ }
+ Status = gSmmBase2->InSmm (gSmmBase2, &InSmm);
+ if (!EFI_ERROR (Status) && !InSmm) {
+ gCpu->EnableInterrupt(gCpu);
+ }
+}
+
+
+/**
+ Raise the task priority level to the new level.
+ High level is implemented by disabling processor interrupts.
+
+ @param NewTpl New task priority level
+
+ @return The previous task priority level
+
+**/
+EFI_TPL
+EFIAPI
+CoreRaiseTpl (
+ IN EFI_TPL NewTpl
+ )
+{
+ EFI_TPL OldTpl;
+
+ OldTpl = gEfiCurrentTpl;
+ if (OldTpl > NewTpl) {
+ DEBUG ((EFI_D_ERROR, "FATAL ERROR - RaiseTpl with OldTpl(0x%x) > NewTpl(0x%x)\n", OldTpl, NewTpl));
+ ASSERT (FALSE);
+ }
+ ASSERT (VALID_TPL (NewTpl));
+
+ //
+ // If raising to high level, disable interrupts
+ //
+ if (NewTpl >= TPL_HIGH_LEVEL && OldTpl < TPL_HIGH_LEVEL) {
+ CoreSetInterruptState (FALSE);
+ }
+
+ //
+ // Set the new value
+ //
+ gEfiCurrentTpl = NewTpl;
+
+ return OldTpl;
+}
+
+
+
+
+/**
+ Lowers the task priority to the previous value. If the new
+ priority unmasks events at a higher priority, they are dispatched.
+
+ @param NewTpl New, lower, task priority
+
+**/
+VOID
+EFIAPI
+CoreRestoreTpl (
+ IN EFI_TPL NewTpl
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_TPL PendingTpl;
+
+ OldTpl = gEfiCurrentTpl;
+ if (NewTpl > OldTpl) {
+ DEBUG ((EFI_D_ERROR, "FATAL ERROR - RestoreTpl with NewTpl(0x%x) > OldTpl(0x%x)\n", NewTpl, OldTpl));
+ ASSERT (FALSE);
+ }
+ ASSERT (VALID_TPL (NewTpl));
+
+ //
+ // If lowering below HIGH_LEVEL, make sure
+ // interrupts are enabled
+ //
+
+ if (OldTpl >= TPL_HIGH_LEVEL && NewTpl < TPL_HIGH_LEVEL) {
+ gEfiCurrentTpl = TPL_HIGH_LEVEL;
+ }
+
+ //
+ // Dispatch any pending events
+ //
+ while (gEventPending != 0) {
+ PendingTpl = (UINTN) HighBitSet64 (gEventPending);
+ if (PendingTpl <= NewTpl) {
+ break;
+ }
+
+ gEfiCurrentTpl = PendingTpl;
+ if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
+ CoreSetInterruptState (TRUE);
+ }
+ CoreDispatchEventNotifies (gEfiCurrentTpl);
+ }
+
+ //
+ // Set the new value
+ //
+
+ gEfiCurrentTpl = NewTpl;
+
+ //
+ // If lowering below HIGH_LEVEL, make sure
+ // interrupts are enabled
+ //
+ if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
+ CoreSetInterruptState (TRUE);
+ }
+
+}