1 /*++
2
3 Copyright (c) 1999 Intel Corporation
4
5 Module Name:
6
7 salpal.c
8
9 Abstract:
10
11 Functions to make SAL and PAL proc calls
12
13 Revision History
14
15 --*/
16 #include "lib.h"
17 #include "palproc.h"
18 #include "salproc.h"
19 /*++
20
21 Copyright (c) 1999 Intel Corporation
22
23 Module Name:
24
25 EfiRtLib.h
26
27 Abstract:
28
29 EFI Runtime library functions
30
31
32
33 Revision History
34
35 --*/
36
37 #include "efi.h"
38 #include "efilib.h"
39
40 rArg
41 MakeStaticPALCall (
42 IN UINT64 PALPROCPtr,
43 IN UINT64 Arg1,
44 IN UINT64 Arg2,
45 IN UINT64 Arg3,
46 IN UINT64 Arg4
47 );
48
49 rArg
50 MakeStackedPALCall (
51 IN UINT64 PALPROCPtr,
52 IN UINT64 Arg1,
53 IN UINT64 Arg2,
54 IN UINT64 Arg3,
55 IN UINT64 Arg4
56 );
57
58
59 PLABEL SalProcPlabel;
60 PLABEL PalProcPlabel;
61 CALL_SAL_PROC GlobalSalProc;
62 CALL_PAL_PROC GlobalPalProc;
63
64 VOID
LibInitSalAndPalProc(OUT PLABEL * SalPlabel,OUT UINT64 * PalEntry)65 LibInitSalAndPalProc (
66 OUT PLABEL *SalPlabel,
67 OUT UINT64 *PalEntry
68 )
69 {
70 SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
71 EFI_STATUS Status;
72
73 GlobalSalProc = NULL;
74 GlobalPalProc = NULL;
75
76 Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable);
77 if (EFI_ERROR(Status)) {
78 return;
79 }
80
81 //
82 // BugBug: Add code to test checksum on the Sal System Table
83 //
84 if (SalSystemTable->Entry0.Type != 0) {
85 return;
86 }
87
88 SalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry;
89 SalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer;
90 GlobalSalProc = (CALL_SAL_PROC)&SalProcPlabel.ProcEntryPoint;
91
92 //
93 // Need to check the PAL spec to make sure I'm not responsible for
94 // storing more state.
95 // We are passing in a Plabel that should be ignorred by the PAL. Call
96 // this way will cause use to retore our gp after the PAL returns.
97 //
98 PalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.PalProcEntry;
99 PalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer;
100 GlobalPalProc = (CALL_PAL_PROC)PalProcPlabel.ProcEntryPoint;
101
102 *PalEntry = PalProcPlabel.ProcEntryPoint;
103 *SalPlabel = SalProcPlabel;
104 }
105
106 EFI_STATUS
LibGetSalIoPortMapping(OUT UINT64 * IoPortMapping)107 LibGetSalIoPortMapping (
108 OUT UINT64 *IoPortMapping
109 )
110 /*++
111
112 Get the IO Port Map from the SAL System Table.
113 DO NOT USE THIS TO DO YOU OWN IO's!!!!!!!!!!!!
114 Only use this for getting info, or initing the built in EFI IO abstraction.
115 Always use the EFI Device IO protoocl to access IO space.
116
117 --*/
118 {
119 SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
120 SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc;
121 EFI_STATUS Status;
122
123 Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable);
124 if (EFI_ERROR(Status)) {
125 return EFI_UNSUPPORTED;
126 }
127
128 //
129 // BugBug: Add code to test checksum on the Sal System Table
130 //
131 if (SalSystemTable->Entry0.Type != 0) {
132 return EFI_UNSUPPORTED;
133 }
134
135 //
136 // The SalSystemTable pointer includes the Type 0 entry.
137 // The SalMemDesc is Type 1 so it comes next.
138 //
139 SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1);
140 while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) {
141 if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) {
142 *IoPortMapping = SalMemDesc->PhysicalMemoryAddress;
143 return EFI_SUCCESS;
144 }
145 SalMemDesc++;
146 }
147 return EFI_UNSUPPORTED;
148 }
149
150 EFI_STATUS
LibGetSalIpiBlock(OUT UINT64 * IpiBlock)151 LibGetSalIpiBlock (
152 OUT UINT64 *IpiBlock
153 )
154 /*++
155
156 Get the IPI block from the SAL system table
157
158 --*/
159 {
160 SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
161 SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc;
162 EFI_STATUS Status;
163
164 Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable);
165 if (EFI_ERROR(Status)) {
166 return EFI_UNSUPPORTED;
167 }
168
169 //
170 // BugBug: Add code to test checksum on the Sal System Table
171 //
172 if (SalSystemTable->Entry0.Type != 0) {
173 return EFI_UNSUPPORTED;
174 }
175
176 //
177 // The SalSystemTable pointer includes the Type 0 entry.
178 // The SalMemDesc is Type 1 so it comes next.
179 //
180 SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1);
181 while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) {
182 if (SalMemDesc->MemoryType == SAL_SAPIC_IPI_BLOCK ) {
183 *IpiBlock = SalMemDesc->PhysicalMemoryAddress;
184 return EFI_SUCCESS;
185 }
186 SalMemDesc++;
187 }
188 return EFI_UNSUPPORTED;
189 }
190
191 EFI_STATUS
LibGetSalWakeupVector(OUT UINT64 * WakeVector)192 LibGetSalWakeupVector (
193 OUT UINT64 *WakeVector
194 )
195 /*++
196
197 Get the wakeup vector from the SAL system table
198
199 --*/
200 {
201 SAL_ST_AP_WAKEUP_DECRIPTOR *ApWakeUp;
202
203 ApWakeUp = LibSearchSalSystemTable (SAL_ST_AP_WAKEUP);
204 if (!ApWakeUp) {
205 *WakeVector = -1;
206 return EFI_UNSUPPORTED;
207 }
208 *WakeVector = ApWakeUp->ExternalInterruptVector;
209 return EFI_SUCCESS;
210 }
211
212 VOID *
LibSearchSalSystemTable(IN UINT8 EntryType)213 LibSearchSalSystemTable (
214 IN UINT8 EntryType
215 )
216 {
217 EFI_STATUS Status;
218 UINT8 *SalTableHack;
219 SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable;
220 UINT16 EntryCount;
221 UINT16 Count;
222
223 Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable);
224 if (EFI_ERROR(Status)) {
225 return NULL;
226 }
227
228 EntryCount = SalSystemTable->Header.EntryCount;
229 if (EntryCount == 0) {
230 return NULL;
231 }
232 //
233 // BugBug: Add code to test checksum on the Sal System Table
234 //
235
236 SalTableHack = (UINT8 *)&SalSystemTable->Entry0;
237 for (Count = 0; Count < EntryCount ;Count++) {
238 if (*SalTableHack == EntryType) {
239 return (VOID *)SalTableHack;
240 }
241 switch (*SalTableHack) {
242 case SAL_ST_ENTRY_POINT:
243 SalTableHack += 48;
244 break;
245 case SAL_ST_MEMORY_DESCRIPTOR:
246 SalTableHack += 32;
247 break;
248 case SAL_ST_PLATFORM_FEATURES:
249 SalTableHack += 16;
250 break;
251 case SAL_ST_TR_USAGE:
252 SalTableHack += 32;
253 break;
254 case SAL_ST_PTC:
255 SalTableHack += 16;
256 break;
257 case SAL_ST_AP_WAKEUP:
258 SalTableHack += 16;
259 break;
260 default:
261 ASSERT(FALSE);
262 break;
263 }
264 }
265 return NULL;
266 }
267
268 VOID
LibSalProc(IN UINT64 Arg1,IN UINT64 Arg2,IN UINT64 Arg3,IN UINT64 Arg4,IN UINT64 Arg5,IN UINT64 Arg6,IN UINT64 Arg7,IN UINT64 Arg8,OUT rArg * Results OPTIONAL)269 LibSalProc (
270 IN UINT64 Arg1,
271 IN UINT64 Arg2,
272 IN UINT64 Arg3,
273 IN UINT64 Arg4,
274 IN UINT64 Arg5,
275 IN UINT64 Arg6,
276 IN UINT64 Arg7,
277 IN UINT64 Arg8,
278 OUT rArg *Results OPTIONAL
279 )
280 {
281 rArg ReturnValue;
282
283 ReturnValue.p0 = -3; // SAL status return completed with error
284 if (GlobalSalProc) {
285 ReturnValue = GlobalSalProc(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
286 }
287
288 if (Results) {
289 CopyMem (Results, &ReturnValue, sizeof(rArg));
290 }
291 }
292
293 VOID
LibPalProc(IN UINT64 Arg1,IN UINT64 Arg2,IN UINT64 Arg3,IN UINT64 Arg4,OUT rArg * Results OPTIONAL)294 LibPalProc (
295 IN UINT64 Arg1, // Pal Proc index
296 IN UINT64 Arg2,
297 IN UINT64 Arg3,
298 IN UINT64 Arg4,
299 OUT rArg *Results OPTIONAL
300 )
301 {
302
303 rArg ReturnValue;
304
305 ReturnValue.p0 = -3; // PAL status return completed with error
306
307 //
308 // check for valid PalProc entry point
309 //
310
311 if (!GlobalPalProc) {
312 if (Results)
313 CopyMem (Results, &ReturnValue, sizeof(rArg));
314 return;
315 }
316
317 //
318 // check if index falls within stacked or static register calling conventions
319 // and call appropriate Pal stub call
320 //
321
322 if (((Arg1 >=255) && (Arg1 <=511)) ||
323 ((Arg1 >=768) && (Arg1 <=1023))) {
324 ReturnValue = MakeStackedPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4);
325 }
326 else {
327 ReturnValue = MakeStaticPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4);
328 }
329
330 if (Results)
331 CopyMem (Results, &ReturnValue, sizeof(rArg));
332
333 return;
334 }
335
336