Home | History | Annotate | Line # | Download | only in apps
tcc.c revision 1.1.1.1
      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