]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/Event/Tpl.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Event / Tpl.c
1 /** @file
2 Task priority (TPL) functions.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "DxeMain.h"
10 #include "Event.h"
11
12 /**
13 Set Interrupt State.
14
15 @param Enable The state of enable or disable interrupt
16
17 **/
18 VOID
19 CoreSetInterruptState (
20 IN BOOLEAN Enable
21 )
22 {
23 EFI_STATUS Status;
24 BOOLEAN InSmm;
25
26 if (gCpu == NULL) {
27 return;
28 }
29 if (!Enable) {
30 gCpu->DisableInterrupt (gCpu);
31 return;
32 }
33 if (gSmmBase2 == NULL) {
34 gCpu->EnableInterrupt (gCpu);
35 return;
36 }
37 Status = gSmmBase2->InSmm (gSmmBase2, &InSmm);
38 if (!EFI_ERROR (Status) && !InSmm) {
39 gCpu->EnableInterrupt(gCpu);
40 }
41 }
42
43
44 /**
45 Raise the task priority level to the new level.
46 High level is implemented by disabling processor interrupts.
47
48 @param NewTpl New task priority level
49
50 @return The previous task priority level
51
52 **/
53 EFI_TPL
54 EFIAPI
55 CoreRaiseTpl (
56 IN EFI_TPL NewTpl
57 )
58 {
59 EFI_TPL OldTpl;
60
61 OldTpl = gEfiCurrentTpl;
62 if (OldTpl > NewTpl) {
63 DEBUG ((EFI_D_ERROR, "FATAL ERROR - RaiseTpl with OldTpl(0x%x) > NewTpl(0x%x)\n", OldTpl, NewTpl));
64 ASSERT (FALSE);
65 }
66 ASSERT (VALID_TPL (NewTpl));
67
68 //
69 // If raising to high level, disable interrupts
70 //
71 if (NewTpl >= TPL_HIGH_LEVEL && OldTpl < TPL_HIGH_LEVEL) {
72 CoreSetInterruptState (FALSE);
73 }
74
75 //
76 // Set the new value
77 //
78 gEfiCurrentTpl = NewTpl;
79
80 return OldTpl;
81 }
82
83
84
85
86 /**
87 Lowers the task priority to the previous value. If the new
88 priority unmasks events at a higher priority, they are dispatched.
89
90 @param NewTpl New, lower, task priority
91
92 **/
93 VOID
94 EFIAPI
95 CoreRestoreTpl (
96 IN EFI_TPL NewTpl
97 )
98 {
99 EFI_TPL OldTpl;
100 EFI_TPL PendingTpl;
101
102 OldTpl = gEfiCurrentTpl;
103 if (NewTpl > OldTpl) {
104 DEBUG ((EFI_D_ERROR, "FATAL ERROR - RestoreTpl with NewTpl(0x%x) > OldTpl(0x%x)\n", NewTpl, OldTpl));
105 ASSERT (FALSE);
106 }
107 ASSERT (VALID_TPL (NewTpl));
108
109 //
110 // If lowering below HIGH_LEVEL, make sure
111 // interrupts are enabled
112 //
113
114 if (OldTpl >= TPL_HIGH_LEVEL && NewTpl < TPL_HIGH_LEVEL) {
115 gEfiCurrentTpl = TPL_HIGH_LEVEL;
116 }
117
118 //
119 // Dispatch any pending events
120 //
121 while (gEventPending != 0) {
122 PendingTpl = (UINTN) HighBitSet64 (gEventPending);
123 if (PendingTpl <= NewTpl) {
124 break;
125 }
126
127 gEfiCurrentTpl = PendingTpl;
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 }