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