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