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