]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c
Update RuntimeLib.
[mirror_edk2.git] / EdkModulePkg / Library / EdkUefiRuntimeLib / Ipf / RuntimeLib.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 RuntimeLib.c
15
16 --*/
17
18 #include <SalApi.h>
19 #include <RuntimeLibInternal.h>
20
21 //
22 // Driver Lib Module Globals
23 //
24
25 STATIC EFI_EVENT mRuntimeNotifyEvent;
26 STATIC EFI_EVENT mEfiVirtualNotifyEvent;
27 STATIC EFI_PLABEL mPlabel;
28 STATIC EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;
29
30 EFI_RUNTIME_SERVICES *mRT;
31
32 STATIC
33 VOID
34 EFIAPI
35 RuntimeDriverExitBootServices (
36 IN EFI_EVENT Event,
37 IN VOID *Context
38 )
39 /*++
40
41 Routine Description:
42
43 Set AtRuntime flag as TRUE after ExitBootServices
44
45 Arguments:
46
47 Event - The Event that is being processed
48
49 Context - Event Context
50
51 Returns:
52
53 None
54
55 --*/
56 {
57 EFI_EVENT_NOTIFY ChildNotifyEventHandler;
58 UINTN Index;
59
60 for (Index = 0; _gDriverExitBootServicesEvent[Index] != NULL; Index++) {
61 ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index];
62 ChildNotifyEventHandler (Event, NULL);
63 }
64
65 //
66 // Clear out BootService globals
67 //
68 gBS = NULL;
69 }
70
71 STATIC
72 VOID
73 EFIAPI
74 RuntimeLibVirtualNotifyEvent (
75 IN EFI_EVENT Event,
76 IN VOID *Context
77 )
78 /*++
79
80 Routine Description:
81
82 Fixup internal data so that EFI can be call in virtual mode.
83 Call the passed in Child Notify event and convert any pointers in
84 lib to virtual mode.
85
86 Arguments:
87
88 Event - The Event that is being processed
89
90 Context - Event Context
91
92 Returns:
93
94 None
95
96 --*/
97 {
98 UINTN Index;
99 EFI_EVENT_NOTIFY ChildNotifyEventHandler;
100
101 for (Index = 0; _gDriverSetVirtualAddressMapEvent[Index] != NULL; Index++) {
102 ChildNotifyEventHandler = _gDriverSetVirtualAddressMapEvent[Index];
103 ChildNotifyEventHandler (Event, NULL);
104 }
105
106 mRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);
107 mRT->ConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);
108
109 SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
110 }
111
112 EFI_STATUS
113 EFIAPI
114 RuntimeDriverLibConstruct (
115 IN EFI_HANDLE ImageHandle,
116 IN EFI_SYSTEM_TABLE *SystemTable
117 )
118 /*++
119
120 Routine Description:
121
122 Intialize runtime Driver Lib if it has not yet been initialized.
123
124 Arguments:
125
126 ImageHandle - The firmware allocated handle for the EFI image.
127
128 SystemTable - A pointer to the EFI System Table.
129
130 GoVirtualChildEvent - Caller can register a virtual notification event.
131
132 Returns:
133
134 EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.
135
136 --*/
137 {
138 EFI_PLABEL *Plabel;
139 EFI_STATUS Status;
140
141 mRT = SystemTable->RuntimeServices;
142
143 //
144 // The protocol contains a function pointer, which is an indirect procedure call.
145 // An indirect procedure call goes through a plabel, and pointer to a function is
146 // a pointer to a plabel. To implement indirect procedure calls that can work in
147 // both physical and virtual mode, two plabels are required (one physical and one
148 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
149 // away. We cache it in a module global, so we can register the vitrual version.
150 //
151 Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);
152 ASSERT_EFI_ERROR (Status);
153
154 Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
155
156 mPlabel.EntryPoint = Plabel->EntryPoint;
157 mPlabel.GP = Plabel->GP;
158
159 SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
160
161 //
162 // Register our ExitBootServices () notify function
163 //
164
165 Status = gBS->CreateEvent (
166 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
167 EFI_TPL_NOTIFY,
168 RuntimeDriverExitBootServices,
169 NULL,
170 &mRuntimeNotifyEvent
171 );
172 ASSERT_EFI_ERROR (Status);
173
174 //
175 // Register SetVirtualAddressMap () notify function
176 //
177
178 Status = gBS->CreateEvent (
179 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
180 EFI_TPL_NOTIFY,
181 RuntimeLibVirtualNotifyEvent,
182 NULL,
183 mEfiVirtualNotifyEvent
184 );
185 ASSERT_EFI_ERROR (Status);
186
187 return EFI_SUCCESS;
188 }
189
190 EFI_STATUS
191 EFIAPI
192 RuntimeDriverLibDeconstruct (
193 VOID
194 )
195 /*++
196
197 Routine Description:
198
199 This routine will free some resources which have been allocated in
200 EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error,
201 it must call this routine to free the allocated resource before the exiting.
202
203 Arguments:
204
205 None
206
207 Returns:
208
209 EFI_SUCCESS - Shotdown the Runtime Driver Lib successfully
210 EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all
211
212 --*/
213 {
214 EFI_STATUS Status;
215
216 //
217 // Close our ExitBootServices () notify function
218 //
219 Status = gBS->CloseEvent (mRuntimeNotifyEvent);
220 ASSERT_EFI_ERROR (Status);
221
222 //
223 // Close SetVirtualAddressMap () notify function
224 //
225 Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);
226 ASSERT_EFI_ERROR (Status);
227
228 return EFI_SUCCESS;
229 }
230
231 BOOLEAN
232 EFIAPI
233 EfiAtRuntime (
234 VOID
235 )
236 /*++
237
238 Routine Description:
239 Return TRUE if ExitBootService () has been called
240
241 Arguments:
242 NONE
243
244 Returns:
245 TRUE - If ExitBootService () has been called
246
247 --*/
248 {
249 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
250 SAL_RETURN_REGS ReturnReg;
251
252 ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);
253
254 return (BOOLEAN) (ReturnReg.r9 == 1);
255 }
256
257 BOOLEAN
258 EFIAPI
259 EfiGoneVirtual (
260 VOID
261 )
262 /*++
263
264 Routine Description:
265 Return TRUE if SetVirtualAddressMap () has been called
266
267 Arguments:
268 NONE
269
270 Returns:
271 TRUE - If SetVirtualAddressMap () has been called
272
273 --*/
274 {
275 EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;
276 SAL_RETURN_REGS ReturnReg;
277
278 ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);
279
280 return (BOOLEAN) (ReturnReg.r9 == 1);
281 }
282