1/*++
2
3Copyright (c) 1999  Intel Corporation
4
5Module Name:
6
7    salpal.c
8
9Abstract:
10
11    Functions to make SAL and PAL proc calls
12
13Revision History
14
15--*/
16#include "lib.h"
17#include "palproc.h"
18#include "salproc.h"
19/*++
20
21Copyright (c) 1999  Intel Corporation
22
23Module Name:
24
25    EfiRtLib.h
26
27Abstract:
28
29    EFI Runtime library functions
30
31
32
33Revision History
34
35--*/
36
37#include "efi.h"
38#include "efilib.h"
39
40rArg
41MakeStaticPALCall (
42    IN UINT64   PALPROCPtr,
43    IN UINT64   Arg1,
44    IN UINT64   Arg2,
45    IN UINT64   Arg3,
46    IN UINT64   Arg4
47    );
48
49rArg
50MakeStackedPALCall (
51    IN UINT64   PALPROCPtr,
52    IN UINT64   Arg1,
53    IN UINT64   Arg2,
54    IN UINT64   Arg3,
55    IN UINT64   Arg4
56    );
57
58
59PLABEL   SalProcPlabel;
60PLABEL   PalProcPlabel;
61CALL_SAL_PROC   GlobalSalProc;
62CALL_PAL_PROC   GlobalPalProc;
63
64VOID
65LibInitSalAndPalProc (
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
106EFI_STATUS
107LibGetSalIoPortMapping (
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
150EFI_STATUS
151LibGetSalIpiBlock (
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
191EFI_STATUS
192LibGetSalWakeupVector (
193    OUT UINT64  *WakeVector
194    )
195/*++
196
197Get 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
212VOID *
213LibSearchSalSystemTable (
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
268VOID
269LibSalProc (
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
293VOID
294LibPalProc (
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