xref: /DragonStub/lib/ia64/salpal.c (revision f1de0317e130286d7363f30f4f92961ab62fe191)
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
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
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
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
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 *
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
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
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