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