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