1 /* 2 * Test if our calling convention gymnastics actually work 3 */ 4 5 #include <efi.h> 6 #include <efilib.h> 7 8 #ifdef __x86_64__ 9 #include <x86_64/pe.h> 10 #include <x86_64/efibind.h> 11 #endif 12 13 #if 0 14 asm volatile("out %0,%1" : : "a" ((uint8_t)a), "dN" (0x80)); 15 16 extern void dump_stack(void); 17 asm( ".globl dump_stack\n" 18 "dump_stack:\n" 19 " movq %rsp, %rdi\n" 20 " jmp *dump_stack_helper@GOTPCREL(%rip)\n" 21 ".size dump_stack, .-dump_stack"); 22 23 void dump_stack_helper(uint64_t rsp_val) 24 { 25 uint64_t *rsp = (uint64_t *)rsp_val; 26 int x; 27 28 Print(L"%%rsp: 0x%08x%08x stack:\r\n", 29 (rsp_val & 0xffffffff00000000) >>32, 30 rsp_val & 0xffffffff); 31 for (x = 0; x < 8; x++) { 32 Print(L"%08x: ", ((uint64_t)rsp) & 0xffffffff); 33 Print(L"%016x ", *rsp++); 34 Print(L"%016x ", *rsp++); 35 Print(L"%016x ", *rsp++); 36 Print(L"%016x\r\n", *rsp++); 37 } 38 } 39 #endif 40 41 EFI_STATUS EFI_FUNCTION test_failure_callback(void) 42 { 43 return EFI_UNSUPPORTED; 44 } 45 46 EFI_STATUS test_failure(void) 47 { 48 return uefi_call_wrapper(test_failure_callback, 0); 49 } 50 51 EFI_STATUS EFI_FUNCTION test_call0_callback(void) 52 { 53 return EFI_SUCCESS; 54 } 55 56 EFI_STATUS test_call0(void) 57 { 58 return uefi_call_wrapper(test_call0_callback, 0); 59 } 60 61 EFI_STATUS EFI_FUNCTION test_call1_callback(UINT32 a) 62 { 63 if (a != 0x12345678) { 64 return EFI_LOAD_ERROR; 65 } 66 return EFI_SUCCESS; 67 } 68 69 EFI_STATUS test_call1(void) 70 { 71 return uefi_call_wrapper(test_call1_callback, 1,0x12345678); 72 } 73 74 EFI_STATUS EFI_FUNCTION test_call2_callback(UINT32 a, UINT32 b) 75 { 76 if (a != 0x12345678) { 77 return EFI_LOAD_ERROR; 78 } 79 if (b != 0x23456789) { 80 return EFI_INVALID_PARAMETER; 81 } 82 return EFI_SUCCESS; 83 } 84 85 EFI_STATUS test_call2(void) 86 { 87 return uefi_call_wrapper(test_call2_callback, 2, 88 0x12345678, 0x23456789); 89 } 90 91 EFI_STATUS EFI_FUNCTION test_call3_callback(UINT32 a, UINT32 b, 92 UINT32 c) 93 { 94 if (a != 0x12345678) 95 return EFI_LOAD_ERROR; 96 if (b != 0x23456789) 97 return EFI_INVALID_PARAMETER; 98 if (c != 0x3456789a) 99 return EFI_UNSUPPORTED; 100 return EFI_SUCCESS; 101 } 102 103 EFI_STATUS test_call3(void) 104 { 105 return uefi_call_wrapper(test_call3_callback, 3, 106 0x12345678, 0x23456789, 0x3456789a); 107 } 108 109 EFI_STATUS EFI_FUNCTION test_call4_callback(UINT32 a, UINT32 b, 110 UINT32 c, UINT32 d) 111 { 112 if (a != 0x12345678) 113 return EFI_LOAD_ERROR; 114 if (b != 0x23456789) 115 return EFI_INVALID_PARAMETER; 116 if (c != 0x3456789a) 117 return EFI_UNSUPPORTED; 118 if (d != 0x456789ab) 119 return EFI_BAD_BUFFER_SIZE; 120 121 return EFI_SUCCESS; 122 } 123 124 EFI_STATUS test_call4(void) 125 { 126 return uefi_call_wrapper(test_call4_callback, 4, 127 0x12345678, 0x23456789, 0x3456789a, 0x456789ab); 128 } 129 130 EFI_STATUS EFI_FUNCTION test_call5_callback(UINT32 a, UINT32 b, 131 UINT32 c, UINT32 d, UINT32 e) 132 { 133 if (a != 0x12345678) 134 return EFI_LOAD_ERROR; 135 if (b != 0x23456789) 136 return EFI_INVALID_PARAMETER; 137 if (c != 0x3456789a) 138 return EFI_UNSUPPORTED; 139 if (d != 0x456789ab) 140 return EFI_BAD_BUFFER_SIZE; 141 if (e != 0x56789abc) 142 return EFI_BUFFER_TOO_SMALL; 143 144 return EFI_SUCCESS; 145 } 146 147 EFI_STATUS test_call5(void) 148 { 149 return uefi_call_wrapper(test_call5_callback, 5, 150 0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 0x56789abc); 151 } 152 153 EFI_STATUS EFI_FUNCTION test_call6_callback(UINT32 a, UINT32 b, 154 UINT32 c, UINT32 d, UINT32 e, UINT32 f) 155 { 156 if (a != 0x12345678) 157 return EFI_LOAD_ERROR; 158 if (b != 0x23456789) 159 return EFI_INVALID_PARAMETER; 160 if (c != 0x3456789a) 161 return EFI_UNSUPPORTED; 162 if (d != 0x456789ab) 163 return EFI_BAD_BUFFER_SIZE; 164 if (e != 0x56789abc) 165 return EFI_BUFFER_TOO_SMALL; 166 if (f != 0x6789abcd) 167 return EFI_NOT_READY; 168 169 return EFI_SUCCESS; 170 } 171 172 EFI_STATUS test_call6(void) 173 { 174 return uefi_call_wrapper(test_call6_callback, 6, 175 0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 0x56789abc, 176 0x6789abcd); 177 } 178 179 EFI_STATUS EFI_FUNCTION test_call7_callback(UINT32 a, UINT32 b, 180 UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g) 181 { 182 if (a != 0x12345678) 183 return EFI_LOAD_ERROR; 184 if (b != 0x23456789) 185 return EFI_INVALID_PARAMETER; 186 if (c != 0x3456789a) 187 return EFI_UNSUPPORTED; 188 if (d != 0x456789ab) 189 return EFI_BAD_BUFFER_SIZE; 190 if (e != 0x56789abc) 191 return EFI_BUFFER_TOO_SMALL; 192 if (f != 0x6789abcd) 193 return EFI_NOT_READY; 194 if (g != 0x789abcde) 195 return EFI_DEVICE_ERROR; 196 197 return EFI_SUCCESS; 198 } 199 200 EFI_STATUS test_call7(void) 201 { 202 return uefi_call_wrapper(test_call7_callback, 7, 203 0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 204 0x56789abc, 0x6789abcd, 0x789abcde); 205 } 206 207 EFI_STATUS EFI_FUNCTION test_call8_callback(UINT32 a, UINT32 b, 208 UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g, UINT32 h) 209 { 210 if (a != 0x12345678) 211 return EFI_LOAD_ERROR; 212 if (b != 0x23456789) 213 return EFI_INVALID_PARAMETER; 214 if (c != 0x3456789a) 215 return EFI_UNSUPPORTED; 216 if (d != 0x456789ab) 217 return EFI_BAD_BUFFER_SIZE; 218 if (e != 0x56789abc) 219 return EFI_BUFFER_TOO_SMALL; 220 if (f != 0x6789abcd) 221 return EFI_NOT_READY; 222 if (g != 0x789abcde) 223 return EFI_DEVICE_ERROR; 224 if (h != 0x89abcdef) 225 return EFI_WRITE_PROTECTED; 226 227 return EFI_SUCCESS; 228 } 229 230 EFI_STATUS test_call8(void) 231 { 232 return uefi_call_wrapper(test_call8_callback, 8, 233 0x12345678, 234 0x23456789, 235 0x3456789a, 236 0x456789ab, 237 0x56789abc, 238 0x6789abcd, 239 0x789abcde, 240 0x89abcdef); 241 } 242 243 EFI_STATUS EFI_FUNCTION test_call9_callback(UINT32 a, UINT32 b, 244 UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g, UINT32 h, UINT32 i) 245 { 246 if (a != 0x12345678) 247 return EFI_LOAD_ERROR; 248 if (b != 0x23456789) 249 return EFI_INVALID_PARAMETER; 250 if (c != 0x3456789a) 251 return EFI_UNSUPPORTED; 252 if (d != 0x456789ab) 253 return EFI_BAD_BUFFER_SIZE; 254 if (e != 0x56789abc) 255 return EFI_BUFFER_TOO_SMALL; 256 if (f != 0x6789abcd) 257 return EFI_NOT_READY; 258 if (g != 0x789abcde) 259 return EFI_DEVICE_ERROR; 260 if (h != 0x89abcdef) 261 return EFI_WRITE_PROTECTED; 262 if (i != 0x9abcdef0) 263 return EFI_OUT_OF_RESOURCES; 264 265 return EFI_SUCCESS; 266 } 267 268 EFI_STATUS test_call9(void) 269 { 270 return uefi_call_wrapper(test_call9_callback, 9, 271 0x12345678, 272 0x23456789, 273 0x3456789a, 274 0x456789ab, 275 0x56789abc, 276 0x6789abcd, 277 0x789abcde, 278 0x89abcdef, 279 0x9abcdef0); 280 } 281 282 extern EFI_STATUS test_call10(void); 283 EFI_STATUS EFI_FUNCTION test_call10_callback(UINT32 a, UINT32 b, 284 UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g, UINT32 h, UINT32 i, 285 UINT32 j) 286 { 287 if (a != 0x12345678) 288 return EFI_LOAD_ERROR; 289 if (b != 0x23456789) 290 return EFI_INVALID_PARAMETER; 291 if (c != 0x3456789a) 292 return EFI_UNSUPPORTED; 293 if (d != 0x456789ab) 294 return EFI_BAD_BUFFER_SIZE; 295 if (e != 0x56789abc) 296 return EFI_BUFFER_TOO_SMALL; 297 if (f != 0x6789abcd) 298 return EFI_NOT_READY; 299 if (g != 0x789abcde) 300 return EFI_DEVICE_ERROR; 301 if (h != 0x89abcdef) 302 return EFI_WRITE_PROTECTED; 303 if (i != 0x9abcdef0) 304 return EFI_OUT_OF_RESOURCES; 305 if (j != 0xabcdef01) 306 return EFI_VOLUME_CORRUPTED; 307 308 return EFI_SUCCESS; 309 } 310 311 EFI_STATUS test_call10(void) 312 { 313 return uefi_call_wrapper(test_call10_callback, 10, 314 0x12345678, 315 0x23456789, 316 0x3456789a, 317 0x456789ab, 318 0x56789abc, 319 0x6789abcd, 320 0x789abcde, 321 0x89abcdef, 322 0x9abcdef0, 323 0xabcdef01); 324 } 325 326 EFI_STATUS 327 efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab) 328 { 329 EFI_STATUS rc = EFI_SUCCESS; 330 331 InitializeLib(image, systab); 332 PoolAllocationType = 2; /* klooj */ 333 334 #ifndef __x86_64__ 335 uefi_call_wrapper(systab->ConOut->OutputString, 2, systab->ConOut, 336 L"This test is only valid on x86_64\n"); 337 return EFI_UNSUPPORTED; 338 #endif 339 340 __asm__ volatile("out %0,%1" : : "a" ((uint8_t)0x14), "dN" (0x80)); 341 342 Print(L"Hello\r\n"); 343 rc = test_failure(); 344 if (EFI_ERROR(rc)) { 345 Print(L"Returning Failure works\n"); 346 } else { 347 Print(L"Returning failure doesn't work.\r\n"); 348 Print(L"%%rax was 0x%016x, should have been 0x%016x\n", 349 rc, EFI_UNSUPPORTED); 350 return EFI_INVALID_PARAMETER; 351 } 352 353 rc = test_call0(); 354 if (!EFI_ERROR(rc)) { 355 Print(L"0 args works just fine here.\r\n"); 356 } else { 357 Print(L"0 args failed: 0x%016x\n", rc); 358 return rc; 359 } 360 361 rc = test_call1(); 362 if (!EFI_ERROR(rc)) { 363 Print(L"1 arg works just fine here.\r\n"); 364 } else { 365 Print(L"1 arg failed: 0x%016x\n", rc); 366 return rc; 367 } 368 369 rc = test_call2(); 370 if (!EFI_ERROR(rc)) { 371 Print(L"2 args works just fine here.\r\n"); 372 } else { 373 Print(L"2 args failed: 0x%016x\n", rc); 374 return rc; 375 } 376 377 rc = test_call3(); 378 if (!EFI_ERROR(rc)) { 379 Print(L"3 args works just fine here.\r\n"); 380 } else { 381 Print(L"3 args failed: 0x%016x\n", rc); 382 return rc; 383 } 384 385 rc = test_call4(); 386 if (!EFI_ERROR(rc)) { 387 Print(L"4 args works just fine here.\r\n"); 388 } else { 389 Print(L"4 args failed: 0x%016x\n", rc); 390 return rc; 391 } 392 393 rc = test_call5(); 394 if (!EFI_ERROR(rc)) { 395 Print(L"5 args works just fine here.\r\n"); 396 } else { 397 Print(L"5 args failed: 0x%016x\n", rc); 398 return rc; 399 } 400 401 rc = test_call6(); 402 if (!EFI_ERROR(rc)) { 403 Print(L"6 args works just fine here.\r\n"); 404 } else { 405 Print(L"6 args failed: 0x%016x\n", rc); 406 return rc; 407 } 408 409 rc = test_call7(); 410 if (!EFI_ERROR(rc)) { 411 Print(L"7 args works just fine here.\r\n"); 412 } else { 413 Print(L"7 args failed: 0x%016x\n", rc); 414 return rc; 415 } 416 417 rc = test_call8(); 418 if (!EFI_ERROR(rc)) { 419 Print(L"8 args works just fine here.\r\n"); 420 } else { 421 Print(L"8 args failed: 0x%016x\n", rc); 422 return rc; 423 } 424 425 rc = test_call9(); 426 if (!EFI_ERROR(rc)) { 427 Print(L"9 args works just fine here.\r\n"); 428 } else { 429 Print(L"9 args failed: 0x%016x\n", rc); 430 return rc; 431 } 432 433 rc = test_call10(); 434 if (!EFI_ERROR(rc)) { 435 Print(L"10 args works just fine here.\r\n"); 436 } else { 437 Print(L"10 args failed: 0x%016x\n", rc); 438 return rc; 439 } 440 441 return rc; 442 } 443