Imported Upstream version 3.0
[platform/upstream/gnu-efi.git] / lib / ia64 / salpal.c
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