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