]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Library/EdkDxeSalLib/Ipf/EsalServiceLib.c
Move SAL "initialization/virtual address change notification" from EdkUefiRuntimeLib...
[mirror_edk2.git] / EdkModulePkg / Library / EdkDxeSalLib / Ipf / EsalServiceLib.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 EsalServiceLib.c
15
16 Abstract:
17
18 --*/
19
20 #include <Ipf/IpfDefines.h>
21
22
23 STATIC EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;
24 STATIC EFI_PLABEL mPlabel;
25
26 EFI_STATUS
27 EFIAPI
28 DxeSalLibConstruct (
29 IN EFI_HANDLE ImageHandle,
30 IN EFI_SYSTEM_TABLE *SystemTable
31 )
32 {
33 EFI_PLABEL *Plabel;
34 EFI_STATUS Status;
35
36 //
37 // The protocol contains a function pointer, which is an indirect procedure call.
38 // An indirect procedure call goes through a plabel, and pointer to a function is
39 // a pointer to a plabel. To implement indirect procedure calls that can work in
40 // both physical and virtual mode, two plabels are required (one physical and one
41 // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it
42 // away. We cache it in a module global, so we can register the vitrual version.
43 //
44 Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);
45 ASSERT_EFI_ERROR (Status);
46
47 Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;
48
49 mPlabel.EntryPoint = Plabel->EntryPoint;
50 mPlabel.GP = Plabel->GP;
51 SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
52
53 return Status;
54 }
55
56 VOID
57 EFIAPI
58 DxeSalVirtualNotifyEvent (
59 IN EFI_EVENT Event,
60 IN VOID *Context
61 )
62 /*++
63
64 Routine Description:
65
66 Fixup virtual address pointer of label.
67
68 Arguments:
69
70 Event - The Event that is being processed
71
72 Context - Event Context
73
74 Returns:
75
76 None
77
78 --*/
79 {
80 EfiConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);
81 EfiConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);
82
83 SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);
84 }
85
86 EFI_STATUS
87 EFIAPI
88 RegisterEsalFunction (
89 IN UINT64 FunctionId,
90 IN EFI_GUID *ClassGuid,
91 IN SAL_INTERNAL_EXTENDED_SAL_PROC Function,
92 IN VOID *ModuleGlobal
93 )
94 /*++
95
96 Routine Description:
97
98 Register ESAL Class Function and it's asociated global.
99 This function is boot service only!
100
101 Arguments:
102 FunctionId - ID of function to register
103 ClassGuid - GUID of function class
104 Function - Function to register under ClassGuid/FunctionId pair
105 ModuleGlobal - Module global for Function.
106
107 Returns:
108 EFI_SUCCESS - If ClassGuid/FunctionId Function was registered.
109
110 --*/
111 {
112 return mEsalBootService->AddExtendedSalProc (
113 mEsalBootService,
114 ClassGuid,
115 FunctionId,
116 Function,
117 ModuleGlobal
118 );
119 }
120
121 EFI_STATUS
122 EFIAPI
123 RegisterEsalClass (
124 IN EFI_GUID *ClassGuid,
125 IN VOID *ModuleGlobal,
126 ...
127 )
128 /*++
129
130 Routine Description:
131
132 Register ESAL Class and it's asociated global.
133 This function is boot service only!
134
135 Arguments:
136 ClassGuid - GUID of function class
137 ModuleGlobal - Module global for Function.
138 ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL
139 indicates the end of the list.
140
141 Returns:
142 EFI_SUCCESS - All members of ClassGuid registered
143
144 --*/
145 {
146 VA_LIST Args;
147 EFI_STATUS Status;
148 SAL_INTERNAL_EXTENDED_SAL_PROC Function;
149 UINT64 FunctionId;
150 EFI_HANDLE NewHandle;
151
152 VA_START (Args, ModuleGlobal);
153
154 Status = EFI_SUCCESS;
155 while (!EFI_ERROR (Status)) {
156 Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);
157 if (Function == NULL) {
158 break;
159 }
160
161 FunctionId = VA_ARG (Args, UINT64);
162
163 Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal);
164 }
165
166 if (EFI_ERROR (Status)) {
167 return Status;
168 }
169
170 NewHandle = NULL;
171 return gBS->InstallProtocolInterface (
172 &NewHandle,
173 ClassGuid,
174 EFI_NATIVE_INTERFACE,
175 NULL
176 );
177 }
178
179 SAL_RETURN_REGS
180 EFIAPI
181 EfiCallEsalService (
182 IN EFI_GUID *ClassGuid,
183 IN UINT64 FunctionId,
184 IN UINT64 Arg2,
185 IN UINT64 Arg3,
186 IN UINT64 Arg4,
187 IN UINT64 Arg5,
188 IN UINT64 Arg6,
189 IN UINT64 Arg7,
190 IN UINT64 Arg8
191 )
192 /*++
193
194 Routine Description:
195
196 Call module that is not linked direclty to this module. This code is IP
197 relative and hides the binding issues of virtual or physical calling. The
198 function that gets dispatched has extra arguments that include the registered
199 module global and a boolean flag to indicate if the system is in virutal mode.
200
201 Arguments:
202 ClassGuid - GUID of function
203 FunctionId - Function in ClassGuid to call
204 Arg2 - Argument 2 ClassGuid/FunctionId defined
205 Arg3 - Argument 3 ClassGuid/FunctionId defined
206 Arg4 - Argument 4 ClassGuid/FunctionId defined
207 Arg5 - Argument 5 ClassGuid/FunctionId defined
208 Arg6 - Argument 6 ClassGuid/FunctionId defined
209 Arg7 - Argument 7 ClassGuid/FunctionId defined
210 Arg8 - Argument 8 ClassGuid/FunctionId defined
211
212 Returns:
213 Status of ClassGuid/FuncitonId
214
215 --*/
216 {
217 SAL_RETURN_REGS ReturnReg;
218 SAL_EXTENDED_SAL_PROC EsalProc;
219
220 ReturnReg = GetEsalEntryPoint ();
221 if (ReturnReg.Status != EFI_SAL_SUCCESS) {
222 return ReturnReg;
223 }
224
225 if (ReturnReg.r11 & PSR_IT_MASK) {
226 //
227 // Virtual mode plabel to entry point
228 //
229 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10;
230 } else {
231 //
232 // Physical mode plabel to entry point
233 //
234 EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9;
235 }
236
237 return EsalProc (
238 ClassGuid,
239 FunctionId,
240 Arg2,
241 Arg3,
242 Arg4,
243 Arg5,
244 Arg6,
245 Arg7,
246 Arg8
247 );
248 }