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