summaryrefslogtreecommitdiff
path: root/efi/hello.c
blob: 35cd86de7b396ea33ff55bd1cf1b29da26d3c7b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * Болваночный EFI-апп для amd64 (bootx64.efi), PE32+.
 * Собирается ПОРТИРОВАННЫМ тулчейном Plan9 (6c/6a/6l) на Linux/musl:
 *   PE-заголовок и entry -> pe64.s (ассемблер 6a), из 9legacy nboot/efi.
 *   Печать -> UEFI SIMPLE_TEXT_OUTPUT_PROTOCOL (efi.h из 9legacy).
 * Контракт входа задаёт pe64.s: reloc кладёт SystemTable, прыгает на efimain(ih, st).
 */
#include <u.h>
#include "efi.h"

/* глобалы, которых ждёт контракт (как в референсном efi.c) */
EFI_HANDLE IH;
EFI_SYSTEM_TABLE *ST;

/* вызов EFI-функции по MS-x64 ABI — реализован в pe64.s */
extern uintptr eficall(void *fn, ...);

/* печать ASCII-строки через ConOut (конверт в UTF-16, \n -> \r\n) */
static void
eputs(char *s)
{
	CHAR16 w[2];

	w[1] = 0;
	for(; *s; s++){
		if(*s == '\n'){
			w[0] = '\r';
			eficall(ST->ConOut->OutputString, ST->ConOut, w);
		}
		w[0] = (uchar)*s;
		eficall(ST->ConOut->OutputString, ST->ConOut, w);
	}
}

void
efimain(EFI_HANDLE ih, EFI_SYSTEM_TABLE *st)
{
	IH = ih;
	ST = st;

	eputs("\n");
	eputs("+--------------------------------------------------+\n");
	eputs("|  Hello from a Plan 9 kencc EFI application        |\n");
	eputs("|  compiler/assembler/linker: 6c / 6a / 6l         |\n");
	eputs("|  cross-built on Linux/musl, wrapped as PE32+     |\n");
	eputs("+--------------------------------------------------+\n");
	eputs("\nefimain reached OK. Idling via BootServices->Stall.\n");

	/* болванка: просто крутимся, чтобы прошивка не считала нас упавшими */
	for(;;)
		eficall(ST->BootServices->Stall, (UINTN)1000000);
}