1 1.1 jakllsch /* $NetBSD: salpal.c,v 1.1.1.1 2014/04/01 16:16:07 jakllsch Exp $ */ 2 1.1 jakllsch 3 1.1 jakllsch /*++ 4 1.1 jakllsch 5 1.1 jakllsch Copyright (c) 1999 Intel Corporation 6 1.1 jakllsch 7 1.1 jakllsch Module Name: 8 1.1 jakllsch 9 1.1 jakllsch salpal.c 10 1.1 jakllsch 11 1.1 jakllsch Abstract: 12 1.1 jakllsch 13 1.1 jakllsch Functions to make SAL and PAL proc calls 14 1.1 jakllsch 15 1.1 jakllsch Revision History 16 1.1 jakllsch 17 1.1 jakllsch --*/ 18 1.1 jakllsch #include "lib.h" 19 1.1 jakllsch #include "palproc.h" 20 1.1 jakllsch #include "salproc.h" 21 1.1 jakllsch /*++ 22 1.1 jakllsch 23 1.1 jakllsch Copyright (c) 1999 Intel Corporation 24 1.1 jakllsch 25 1.1 jakllsch Module Name: 26 1.1 jakllsch 27 1.1 jakllsch EfiRtLib.h 28 1.1 jakllsch 29 1.1 jakllsch Abstract: 30 1.1 jakllsch 31 1.1 jakllsch EFI Runtime library functions 32 1.1 jakllsch 33 1.1 jakllsch 34 1.1 jakllsch 35 1.1 jakllsch Revision History 36 1.1 jakllsch 37 1.1 jakllsch --*/ 38 1.1 jakllsch 39 1.1 jakllsch #include "efi.h" 40 1.1 jakllsch #include "efilib.h" 41 1.1 jakllsch 42 1.1 jakllsch rArg 43 1.1 jakllsch MakeStaticPALCall ( 44 1.1 jakllsch IN UINT64 PALPROCPtr, 45 1.1 jakllsch IN UINT64 Arg1, 46 1.1 jakllsch IN UINT64 Arg2, 47 1.1 jakllsch IN UINT64 Arg3, 48 1.1 jakllsch IN UINT64 Arg4 49 1.1 jakllsch ); 50 1.1 jakllsch 51 1.1 jakllsch rArg 52 1.1 jakllsch MakeStackedPALCall ( 53 1.1 jakllsch IN UINT64 PALPROCPtr, 54 1.1 jakllsch IN UINT64 Arg1, 55 1.1 jakllsch IN UINT64 Arg2, 56 1.1 jakllsch IN UINT64 Arg3, 57 1.1 jakllsch IN UINT64 Arg4 58 1.1 jakllsch ); 59 1.1 jakllsch 60 1.1 jakllsch 61 1.1 jakllsch PLABEL SalProcPlabel; 62 1.1 jakllsch PLABEL PalProcPlabel; 63 1.1 jakllsch CALL_SAL_PROC GlobalSalProc; 64 1.1 jakllsch CALL_PAL_PROC GlobalPalProc; 65 1.1 jakllsch 66 1.1 jakllsch VOID 67 1.1 jakllsch LibInitSalAndPalProc ( 68 1.1 jakllsch OUT PLABEL *SalPlabel, 69 1.1 jakllsch OUT UINT64 *PalEntry 70 1.1 jakllsch ) 71 1.1 jakllsch { 72 1.1 jakllsch SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; 73 1.1 jakllsch EFI_STATUS Status; 74 1.1 jakllsch 75 1.1 jakllsch GlobalSalProc = NULL; 76 1.1 jakllsch GlobalPalProc = NULL; 77 1.1 jakllsch 78 1.1 jakllsch Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable); 79 1.1 jakllsch if (EFI_ERROR(Status)) { 80 1.1 jakllsch return; 81 1.1 jakllsch } 82 1.1 jakllsch 83 1.1 jakllsch // 84 1.1 jakllsch // BugBug: Add code to test checksum on the Sal System Table 85 1.1 jakllsch // 86 1.1 jakllsch if (SalSystemTable->Entry0.Type != 0) { 87 1.1 jakllsch return; 88 1.1 jakllsch } 89 1.1 jakllsch 90 1.1 jakllsch SalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.SalProcEntry; 91 1.1 jakllsch SalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer; 92 1.1 jakllsch GlobalSalProc = (CALL_SAL_PROC)&SalProcPlabel.ProcEntryPoint; 93 1.1 jakllsch 94 1.1 jakllsch // 95 1.1 jakllsch // Need to check the PAL spec to make sure I'm not responsible for 96 1.1 jakllsch // storing more state. 97 1.1 jakllsch // We are passing in a Plabel that should be ignorred by the PAL. Call 98 1.1 jakllsch // this way will cause use to retore our gp after the PAL returns. 99 1.1 jakllsch // 100 1.1 jakllsch PalProcPlabel.ProcEntryPoint = SalSystemTable->Entry0.PalProcEntry; 101 1.1 jakllsch PalProcPlabel.GP = SalSystemTable->Entry0.GlobalDataPointer; 102 1.1 jakllsch GlobalPalProc = (CALL_PAL_PROC)PalProcPlabel.ProcEntryPoint; 103 1.1 jakllsch 104 1.1 jakllsch *PalEntry = PalProcPlabel.ProcEntryPoint; 105 1.1 jakllsch *SalPlabel = SalProcPlabel; 106 1.1 jakllsch } 107 1.1 jakllsch 108 1.1 jakllsch EFI_STATUS 109 1.1 jakllsch LibGetSalIoPortMapping ( 110 1.1 jakllsch OUT UINT64 *IoPortMapping 111 1.1 jakllsch ) 112 1.1 jakllsch /*++ 113 1.1 jakllsch 114 1.1 jakllsch Get the IO Port Map from the SAL System Table. 115 1.1 jakllsch DO NOT USE THIS TO DO YOU OWN IO's!!!!!!!!!!!! 116 1.1 jakllsch Only use this for getting info, or initing the built in EFI IO abstraction. 117 1.1 jakllsch Always use the EFI Device IO protoocl to access IO space. 118 1.1 jakllsch 119 1.1 jakllsch --*/ 120 1.1 jakllsch { 121 1.1 jakllsch SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; 122 1.1 jakllsch SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc; 123 1.1 jakllsch EFI_STATUS Status; 124 1.1 jakllsch 125 1.1 jakllsch Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID **)&SalSystemTable); 126 1.1 jakllsch if (EFI_ERROR(Status)) { 127 1.1 jakllsch return EFI_UNSUPPORTED; 128 1.1 jakllsch } 129 1.1 jakllsch 130 1.1 jakllsch // 131 1.1 jakllsch // BugBug: Add code to test checksum on the Sal System Table 132 1.1 jakllsch // 133 1.1 jakllsch if (SalSystemTable->Entry0.Type != 0) { 134 1.1 jakllsch return EFI_UNSUPPORTED; 135 1.1 jakllsch } 136 1.1 jakllsch 137 1.1 jakllsch // 138 1.1 jakllsch // The SalSystemTable pointer includes the Type 0 entry. 139 1.1 jakllsch // The SalMemDesc is Type 1 so it comes next. 140 1.1 jakllsch // 141 1.1 jakllsch SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1); 142 1.1 jakllsch while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) { 143 1.1 jakllsch if (SalMemDesc->MemoryType == SAL_IO_PORT_MAPPING) { 144 1.1 jakllsch *IoPortMapping = SalMemDesc->PhysicalMemoryAddress; 145 1.1 jakllsch return EFI_SUCCESS; 146 1.1 jakllsch } 147 1.1 jakllsch SalMemDesc++; 148 1.1 jakllsch } 149 1.1 jakllsch return EFI_UNSUPPORTED; 150 1.1 jakllsch } 151 1.1 jakllsch 152 1.1 jakllsch EFI_STATUS 153 1.1 jakllsch LibGetSalIpiBlock ( 154 1.1 jakllsch OUT UINT64 *IpiBlock 155 1.1 jakllsch ) 156 1.1 jakllsch /*++ 157 1.1 jakllsch 158 1.1 jakllsch Get the IPI block from the SAL system table 159 1.1 jakllsch 160 1.1 jakllsch --*/ 161 1.1 jakllsch { 162 1.1 jakllsch SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; 163 1.1 jakllsch SAL_ST_MEMORY_DESCRIPTOR_ENTRY *SalMemDesc; 164 1.1 jakllsch EFI_STATUS Status; 165 1.1 jakllsch 166 1.1 jakllsch Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable); 167 1.1 jakllsch if (EFI_ERROR(Status)) { 168 1.1 jakllsch return EFI_UNSUPPORTED; 169 1.1 jakllsch } 170 1.1 jakllsch 171 1.1 jakllsch // 172 1.1 jakllsch // BugBug: Add code to test checksum on the Sal System Table 173 1.1 jakllsch // 174 1.1 jakllsch if (SalSystemTable->Entry0.Type != 0) { 175 1.1 jakllsch return EFI_UNSUPPORTED; 176 1.1 jakllsch } 177 1.1 jakllsch 178 1.1 jakllsch // 179 1.1 jakllsch // The SalSystemTable pointer includes the Type 0 entry. 180 1.1 jakllsch // The SalMemDesc is Type 1 so it comes next. 181 1.1 jakllsch // 182 1.1 jakllsch SalMemDesc = (SAL_ST_MEMORY_DESCRIPTOR_ENTRY *)(SalSystemTable + 1); 183 1.1 jakllsch while (SalMemDesc->Type == SAL_ST_MEMORY_DESCRIPTOR) { 184 1.1 jakllsch if (SalMemDesc->MemoryType == SAL_SAPIC_IPI_BLOCK ) { 185 1.1 jakllsch *IpiBlock = SalMemDesc->PhysicalMemoryAddress; 186 1.1 jakllsch return EFI_SUCCESS; 187 1.1 jakllsch } 188 1.1 jakllsch SalMemDesc++; 189 1.1 jakllsch } 190 1.1 jakllsch return EFI_UNSUPPORTED; 191 1.1 jakllsch } 192 1.1 jakllsch 193 1.1 jakllsch EFI_STATUS 194 1.1 jakllsch LibGetSalWakeupVector ( 195 1.1 jakllsch OUT UINT64 *WakeVector 196 1.1 jakllsch ) 197 1.1 jakllsch /*++ 198 1.1 jakllsch 199 1.1 jakllsch Get the wakeup vector from the SAL system table 200 1.1 jakllsch 201 1.1 jakllsch --*/ 202 1.1 jakllsch { 203 1.1 jakllsch SAL_ST_AP_WAKEUP_DECRIPTOR *ApWakeUp; 204 1.1 jakllsch 205 1.1 jakllsch ApWakeUp = LibSearchSalSystemTable (SAL_ST_AP_WAKEUP); 206 1.1 jakllsch if (!ApWakeUp) { 207 1.1 jakllsch *WakeVector = -1; 208 1.1 jakllsch return EFI_UNSUPPORTED; 209 1.1 jakllsch } 210 1.1 jakllsch *WakeVector = ApWakeUp->ExternalInterruptVector; 211 1.1 jakllsch return EFI_SUCCESS; 212 1.1 jakllsch } 213 1.1 jakllsch 214 1.1 jakllsch VOID * 215 1.1 jakllsch LibSearchSalSystemTable ( 216 1.1 jakllsch IN UINT8 EntryType 217 1.1 jakllsch ) 218 1.1 jakllsch { 219 1.1 jakllsch EFI_STATUS Status; 220 1.1 jakllsch UINT8 *SalTableHack; 221 1.1 jakllsch SAL_SYSTEM_TABLE_ASCENDING_ORDER *SalSystemTable; 222 1.1 jakllsch UINT16 EntryCount; 223 1.1 jakllsch UINT16 Count; 224 1.1 jakllsch 225 1.1 jakllsch Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, (VOID*)&SalSystemTable); 226 1.1 jakllsch if (EFI_ERROR(Status)) { 227 1.1 jakllsch return NULL; 228 1.1 jakllsch } 229 1.1 jakllsch 230 1.1 jakllsch EntryCount = SalSystemTable->Header.EntryCount; 231 1.1 jakllsch if (EntryCount == 0) { 232 1.1 jakllsch return NULL; 233 1.1 jakllsch } 234 1.1 jakllsch // 235 1.1 jakllsch // BugBug: Add code to test checksum on the Sal System Table 236 1.1 jakllsch // 237 1.1 jakllsch 238 1.1 jakllsch SalTableHack = (UINT8 *)&SalSystemTable->Entry0; 239 1.1 jakllsch for (Count = 0; Count < EntryCount ;Count++) { 240 1.1 jakllsch if (*SalTableHack == EntryType) { 241 1.1 jakllsch return (VOID *)SalTableHack; 242 1.1 jakllsch } 243 1.1 jakllsch switch (*SalTableHack) { 244 1.1 jakllsch case SAL_ST_ENTRY_POINT: 245 1.1 jakllsch SalTableHack += 48; 246 1.1 jakllsch break; 247 1.1 jakllsch case SAL_ST_MEMORY_DESCRIPTOR: 248 1.1 jakllsch SalTableHack += 32; 249 1.1 jakllsch break; 250 1.1 jakllsch case SAL_ST_PLATFORM_FEATURES: 251 1.1 jakllsch SalTableHack += 16; 252 1.1 jakllsch break; 253 1.1 jakllsch case SAL_ST_TR_USAGE: 254 1.1 jakllsch SalTableHack += 32; 255 1.1 jakllsch break; 256 1.1 jakllsch case SAL_ST_PTC: 257 1.1 jakllsch SalTableHack += 16; 258 1.1 jakllsch break; 259 1.1 jakllsch case SAL_ST_AP_WAKEUP: 260 1.1 jakllsch SalTableHack += 16; 261 1.1 jakllsch break; 262 1.1 jakllsch default: 263 1.1 jakllsch ASSERT(FALSE); 264 1.1 jakllsch break; 265 1.1 jakllsch } 266 1.1 jakllsch } 267 1.1 jakllsch return NULL; 268 1.1 jakllsch } 269 1.1 jakllsch 270 1.1 jakllsch VOID 271 1.1 jakllsch LibSalProc ( 272 1.1 jakllsch IN UINT64 Arg1, 273 1.1 jakllsch IN UINT64 Arg2, 274 1.1 jakllsch IN UINT64 Arg3, 275 1.1 jakllsch IN UINT64 Arg4, 276 1.1 jakllsch IN UINT64 Arg5, 277 1.1 jakllsch IN UINT64 Arg6, 278 1.1 jakllsch IN UINT64 Arg7, 279 1.1 jakllsch IN UINT64 Arg8, 280 1.1 jakllsch OUT rArg *Results OPTIONAL 281 1.1 jakllsch ) 282 1.1 jakllsch { 283 1.1 jakllsch rArg ReturnValue; 284 1.1 jakllsch 285 1.1 jakllsch ReturnValue.p0 = -3; // SAL status return completed with error 286 1.1 jakllsch if (GlobalSalProc) { 287 1.1 jakllsch ReturnValue = GlobalSalProc(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); 288 1.1 jakllsch } 289 1.1 jakllsch 290 1.1 jakllsch if (Results) { 291 1.1 jakllsch CopyMem (Results, &ReturnValue, sizeof(rArg)); 292 1.1 jakllsch } 293 1.1 jakllsch } 294 1.1 jakllsch 295 1.1 jakllsch VOID 296 1.1 jakllsch LibPalProc ( 297 1.1 jakllsch IN UINT64 Arg1, // Pal Proc index 298 1.1 jakllsch IN UINT64 Arg2, 299 1.1 jakllsch IN UINT64 Arg3, 300 1.1 jakllsch IN UINT64 Arg4, 301 1.1 jakllsch OUT rArg *Results OPTIONAL 302 1.1 jakllsch ) 303 1.1 jakllsch { 304 1.1 jakllsch 305 1.1 jakllsch rArg ReturnValue; 306 1.1 jakllsch 307 1.1 jakllsch ReturnValue.p0 = -3; // PAL status return completed with error 308 1.1 jakllsch 309 1.1 jakllsch // 310 1.1 jakllsch // check for valid PalProc entry point 311 1.1 jakllsch // 312 1.1 jakllsch 313 1.1 jakllsch if (!GlobalPalProc) { 314 1.1 jakllsch if (Results) 315 1.1 jakllsch CopyMem (Results, &ReturnValue, sizeof(rArg)); 316 1.1 jakllsch return; 317 1.1 jakllsch } 318 1.1 jakllsch 319 1.1 jakllsch // 320 1.1 jakllsch // check if index falls within stacked or static register calling conventions 321 1.1 jakllsch // and call appropriate Pal stub call 322 1.1 jakllsch // 323 1.1 jakllsch 324 1.1 jakllsch if (((Arg1 >=255) && (Arg1 <=511)) || 325 1.1 jakllsch ((Arg1 >=768) && (Arg1 <=1023))) { 326 1.1 jakllsch ReturnValue = MakeStackedPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4); 327 1.1 jakllsch } 328 1.1 jakllsch else { 329 1.1 jakllsch ReturnValue = MakeStaticPALCall((UINT64)GlobalPalProc,Arg1,Arg2,Arg3,Arg4); 330 1.1 jakllsch } 331 1.1 jakllsch 332 1.1 jakllsch if (Results) 333 1.1 jakllsch CopyMem (Results, &ReturnValue, sizeof(rArg)); 334 1.1 jakllsch 335 1.1 jakllsch return; 336 1.1 jakllsch } 337 1.1 jakllsch 338