diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /EDK/Foundation/Core/Dxe/Event/tpl.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'EDK/Foundation/Core/Dxe/Event/tpl.c')
-rw-r--r-- | EDK/Foundation/Core/Dxe/Event/tpl.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/EDK/Foundation/Core/Dxe/Event/tpl.c b/EDK/Foundation/Core/Dxe/Event/tpl.c new file mode 100644 index 0000000..3ac99fc --- /dev/null +++ b/EDK/Foundation/Core/Dxe/Event/tpl.c @@ -0,0 +1,198 @@ +/*++ + +Copyright (c) 2004 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + tpl.c + +Abstract: + + Task priority function + +--*/ + +#include "exec.h" + +STATIC +VOID +CoreSetInterruptState ( + IN BOOLEAN Enable + ) +/*++ + +Routine Description: + + Set Interrupt State + +Arguments: + + Enable - The state of enable or disable interrupt + +Returns: + + None + +--*/ + +{ + if (gCpu != NULL) { + if (Enable) { + gCpu->EnableInterrupt(gCpu); + } else { + gCpu->DisableInterrupt(gCpu); + } + } +} + +// +// Return the highest set bit +// +UINTN +CoreHighestSetBit ( + IN UINTN Number + ) +/*++ + +Routine Description: + + Return the highest set bit + +Arguments: + + Number - The value to check + +Returns: + + Bit position of the highest set bit + +--*/ +{ + UINTN msb; + + msb = 31; + while ((msb > 0) && ((Number & ((UINTN)1 << msb)) == 0)) { + msb--; + } + + return msb; +} + + +EFI_BOOTSERVICE +EFI_TPL +EFIAPI +CoreRaiseTpl ( + IN EFI_TPL NewTpl + ) +/*++ + +Routine Description: + + Raise the task priority level to the new level. + High level is implemented by disabling processor interrupts. + +Arguments: + + NewTpl - New task priority level + +Returns: + + The previous task priority level + +--*/ +{ + EFI_TPL OldTpl; + + OldTpl = gEfiCurrentTpl; + ASSERT (OldTpl <= NewTpl); + ASSERT (VALID_TPL (NewTpl)); + + // + // If raising to high level, disable interrupts + // + if (NewTpl >= EFI_TPL_HIGH_LEVEL && OldTpl < EFI_TPL_HIGH_LEVEL) { + CoreSetInterruptState (FALSE); + } + + // + // Set the new value + // + gEfiCurrentTpl = NewTpl; + + return OldTpl; +} + + +EFI_BOOTSERVICE +VOID +EFIAPI +CoreRestoreTpl ( + IN EFI_TPL NewTpl + ) +/*++ + +Routine Description: + + Lowers the task priority to the previous value. If the new + priority unmasks events at a higher priority, they are dispatched. + +Arguments: + + NewTpl - New, lower, task priority + +Returns: + + None + +--*/ +{ + EFI_TPL OldTpl; + + OldTpl = gEfiCurrentTpl; + ASSERT (NewTpl <= OldTpl); + ASSERT (VALID_TPL (NewTpl)); + + // + // If lowering below HIGH_LEVEL, make sure + // interrupts are enabled + // + + if (OldTpl >= EFI_TPL_HIGH_LEVEL && NewTpl < EFI_TPL_HIGH_LEVEL) { + gEfiCurrentTpl = EFI_TPL_HIGH_LEVEL; + } + + // + // Dispatch any pending events + // + + while ((-2 << NewTpl) & gEventPending) { + gEfiCurrentTpl = CoreHighestSetBit (gEventPending); + if (gEfiCurrentTpl < EFI_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 < EFI_TPL_HIGH_LEVEL) { + CoreSetInterruptState (TRUE); + } + +} |