xref: /netbsd-src/sys/external/bsd/gnu-efi/dist/lib/ia64/salpal.c (revision b2c829d73acfa2ef1ac1967460ebcec8f439b096)
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