xref: /netbsd-src/sys/external/bsd/gnu-efi/dist/apps/tcc.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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