]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Core/Dxe/Event/tpl.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Core / Dxe / Event / tpl.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 tpl.c
15
16 Abstract:
17
18 Task priority function
19
20 --*/
21
22 #include <DxeMain.h>
23
24 STATIC
25 VOID
26 CoreSetInterruptState (
27 IN BOOLEAN Enable
28 )
29 /*++
30
31 Routine Description:
32
33 Set Interrupt State
34
35 Arguments:
36
37 Enable - The state of enable or disable interrupt
38
39 Returns:
40
41 None
42
43 --*/
44
45 {
46 if (gCpu != NULL) {
47 if (Enable) {
48 gCpu->EnableInterrupt(gCpu);
49 } else {
50 gCpu->DisableInterrupt(gCpu);
51 }
52 }
53 }
54
55 //
56 // Return the highest set bit
57 //
58 UINTN
59 CoreHighestSetBit (
60 IN UINTN Number
61 )
62 /*++
63
64 Routine Description:
65
66 Return the highest set bit
67
68 Arguments:
69
70 Number - The value to check
71
72 Returns:
73
74 Bit position of the highest set bit
75
76 --*/
77 {
78 UINTN msb;
79
80 msb = 31;
81 while ((msb > 0) && ((Number & (UINTN)(1 << msb)) == 0)) {
82 msb--;
83 }
84
85 return msb;
86 }
87
88
89
90 EFI_TPL
91 EFIAPI
92 CoreRaiseTpl (
93 IN EFI_TPL NewTpl
94 )
95 /*++
96
97 Routine Description:
98
99 Raise the task priority level to the new level.
100 High level is implemented by disabling processor interrupts.
101
102 Arguments:
103
104 NewTpl - New task priority level
105
106 Returns:
107
108 The previous task priority level
109
110 --*/
111 {
112 EFI_TPL OldTpl;
113
114 OldTpl = gEfiCurrentTpl;
115 ASSERT (OldTpl <= NewTpl);
116 ASSERT (VALID_TPL (NewTpl));
117
118 //
119 // If raising to high level, disable interrupts
120 //
121 if (NewTpl >= EFI_TPL_HIGH_LEVEL && OldTpl < EFI_TPL_HIGH_LEVEL) {
122 CoreSetInterruptState (FALSE);
123 }
124
125 //
126 // Set the new value
127 //
128 gEfiCurrentTpl = NewTpl;
129
130 return OldTpl;
131 }
132
133
134
135 VOID
136 EFIAPI
137 CoreRestoreTpl (
138 IN EFI_TPL NewTpl
139 )
140 /*++
141
142 Routine Description:
143
144 Lowers the task priority to the previous value. If the new
145 priority unmasks events at a higher priority, they are dispatched.
146
147 Arguments:
148
149 NewTpl - New, lower, task priority
150
151 Returns:
152
153 None
154
155 --*/
156 {
157 EFI_TPL OldTpl;
158
159 OldTpl = gEfiCurrentTpl;
160 ASSERT (NewTpl <= OldTpl);
161 ASSERT (VALID_TPL (NewTpl));
162
163 //
164 // If lowering below HIGH_LEVEL, make sure
165 // interrupts are enabled
166 //
167
168 if (OldTpl >= EFI_TPL_HIGH_LEVEL && NewTpl < EFI_TPL_HIGH_LEVEL) {
169 gEfiCurrentTpl = EFI_TPL_HIGH_LEVEL;
170 }
171
172 //
173 // Dispatch any pending events
174 //
175
176 while ((-2 << NewTpl) & gEventPending) {
177 gEfiCurrentTpl = CoreHighestSetBit (gEventPending);
178 if (gEfiCurrentTpl < EFI_TPL_HIGH_LEVEL) {
179 CoreSetInterruptState (TRUE);
180 }
181 CoreDispatchEventNotifies (gEfiCurrentTpl);
182 }
183
184 //
185 // Set the new value
186 //
187
188 gEfiCurrentTpl = NewTpl;
189
190 //
191 // If lowering below HIGH_LEVEL, make sure
192 // interrupts are enabled
193 //
194 if (gEfiCurrentTpl < EFI_TPL_HIGH_LEVEL) {
195 CoreSetInterruptState (TRUE);
196 }
197
198 }