mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-08 19:00:27 +00:00
[metal] Get examples/vga2.c serial output working for UEFI boot
This commit is contained in:
parent
36b06ab73e
commit
9fe2f55113
3 changed files with 68 additions and 24 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
STATIC_YOINK("vga_console");
|
STATIC_YOINK("vga_console");
|
||||||
STATIC_YOINK("_idt");
|
STATIC_YOINK("_idt");
|
||||||
|
STATIC_YOINK("EfiMain");
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
volatile int x = 1;
|
volatile int x = 1;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
#define INVERT(x) (BANE + PHYSICAL(x))
|
#define INVERT(x) (BANE + PHYSICAL(x))
|
||||||
|
#define NOPAGE ((uint64_t)-1)
|
||||||
|
|
||||||
struct ReclaimedPage {
|
struct ReclaimedPage {
|
||||||
uint64_t next;
|
uint64_t next;
|
||||||
|
@ -54,7 +55,7 @@ struct ReclaimedPage {
|
||||||
*/
|
*/
|
||||||
noasan texthead uint64_t __new_page(struct mman *mm) {
|
noasan texthead uint64_t __new_page(struct mman *mm) {
|
||||||
uint64_t p = mm->frp;
|
uint64_t p = mm->frp;
|
||||||
if (p) {
|
if (p != NOPAGE) {
|
||||||
uint64_t q;
|
uint64_t q;
|
||||||
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p);
|
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p);
|
||||||
_unassert(p == (p & PAGE_TA));
|
_unassert(p == (p & PAGE_TA));
|
||||||
|
@ -126,7 +127,7 @@ static noasan textreal void __normalize_e820(struct mman *mm, uint64_t top) {
|
||||||
mm->pdp = MAX(top, mm->e820[0].addr);
|
mm->pdp = MAX(top, mm->e820[0].addr);
|
||||||
mm->pdpi = 0;
|
mm->pdpi = 0;
|
||||||
mm->e820n = n;
|
mm->e820n = n;
|
||||||
mm->frp = 0;
|
mm->frp = NOPAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -62,27 +62,36 @@ static const EFI_GUID kEfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
||||||
*
|
*
|
||||||
* @see libc/dce.h
|
* @see libc/dce.h
|
||||||
*/
|
*/
|
||||||
__msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
__msabi noasan __attribute__((__naked__))
|
||||||
|
EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
||||||
|
asm volatile("mov\t$0f,%esp\n\t"
|
||||||
|
"and\t$-16,%esp\n\t"
|
||||||
|
"jmp\t_DoEfiMain\n\t"
|
||||||
|
".bss\n\t"
|
||||||
|
".space\t8192\n"
|
||||||
|
"0:\n\t"
|
||||||
|
".previous");
|
||||||
|
}
|
||||||
|
|
||||||
|
__msabi noasan EFI_STATUS _DoEfiMain(EFI_HANDLE ImageHandle,
|
||||||
EFI_SYSTEM_TABLE *SystemTable) {
|
EFI_SYSTEM_TABLE *SystemTable) {
|
||||||
int type, x87cw;
|
int type, x87cw = 0x037f;
|
||||||
struct mman *mm;
|
struct mman *mm;
|
||||||
uint32_t DescVersion;
|
uint32_t DescVersion;
|
||||||
uintptr_t i, j, MapSize;
|
uintptr_t i, j, MapSize;
|
||||||
struct EfiArgs *ArgBlock;
|
struct EfiArgs *ArgBlock;
|
||||||
EFI_LOADED_IMAGE *ImgInfo;
|
EFI_LOADED_IMAGE *ImgInfo;
|
||||||
EFI_MEMORY_DESCRIPTOR *Map;
|
EFI_MEMORY_DESCRIPTOR *Map, *Desc;
|
||||||
|
uint64_t NewBase = 1024 * 1024;
|
||||||
uintptr_t Args, MapKey, DescSize;
|
uintptr_t Args, MapKey, DescSize;
|
||||||
uint64_t p, pe, cr4, *m, *pd, *sp, *pml4t, *pdt1, *pdt2, *pdpt1, *pdpt2;
|
uint64_t p, pe, cr4, *m, *pd, *sp, *pml4t, *pdt1, *pdt2, *pdpt1, *pdpt2;
|
||||||
extern char __os asm("__hostos");
|
|
||||||
|
|
||||||
__os = _HOSTMETAL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocates and clears PC-compatible memory and copies image.
|
* Allocates and clears PC-compatible memory and copies image.
|
||||||
*/
|
*/
|
||||||
SystemTable->BootServices->AllocatePages(
|
SystemTable->BootServices->AllocatePages(
|
||||||
AllocateAddress, EfiConventionalMemory,
|
AllocateAddress, EfiConventionalMemory,
|
||||||
MAX(2 * 1024 * 1024, 1024 * 1024 + (_end - _base)) / 4096, 0);
|
MAX(2 * 1024 * 1024, 1024 * 1024 + (_end - _base)) / 4096, &NewBase);
|
||||||
SystemTable->BootServices->SetMem(0, 0x80000, 0);
|
SystemTable->BootServices->SetMem(0, 0x80000, 0);
|
||||||
SystemTable->BootServices->CopyMem((void *)(1024 * 1024), _base,
|
SystemTable->BootServices->CopyMem((void *)(1024 * 1024), _base,
|
||||||
_end - _base);
|
_end - _base);
|
||||||
|
@ -104,17 +113,20 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||||
MapSize = 0;
|
MapSize = 0;
|
||||||
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
||||||
&DescVersion);
|
&DescVersion);
|
||||||
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, Map);
|
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, &Map);
|
||||||
|
MapSize *= 2;
|
||||||
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
||||||
&DescVersion);
|
&DescVersion);
|
||||||
asm("xor\t%0,%0" : "=r"(mm)); /* gcc assumes null isn't mapped */
|
mm = (struct mman *)0x0500;
|
||||||
for (j = i = 0; i < MapSize / sizeof(EFI_MEMORY_DESCRIPTOR); ++i) {
|
for (j = i = 0, Desc = Map; i < MapSize / DescSize; ++i) {
|
||||||
if (Map[i].Type != EfiConventionalMemory) continue;
|
if (Desc->Type == EfiConventionalMemory) {
|
||||||
mm->e820[j].addr = Map[i].PhysicalStart;
|
mm->e820[j].addr = Desc->PhysicalStart;
|
||||||
mm->e820[j].size = Map[i].NumberOfPages * 4096;
|
mm->e820[j].size = Desc->NumberOfPages * 4096;
|
||||||
mm->e820[j].type = kMemoryUsable;
|
mm->e820[j].type = kMemoryUsable;
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
Desc = (EFI_MEMORY_DESCRIPTOR *)((char *)Desc + DescSize);
|
||||||
|
}
|
||||||
SystemTable->BootServices->FreePool(Map);
|
SystemTable->BootServices->FreePool(Map);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -135,19 +147,46 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||||
pdpt2[0] = (intptr_t)pdt2 + PAGE_V + PAGE_RW;
|
pdpt2[0] = (intptr_t)pdt2 + PAGE_V + PAGE_RW;
|
||||||
pml4t[0] = (intptr_t)pdpt1 + PAGE_V + PAGE_RW;
|
pml4t[0] = (intptr_t)pdpt1 + PAGE_V + PAGE_RW;
|
||||||
pml4t[256] = (intptr_t)pdpt2 + PAGE_V + PAGE_RW;
|
pml4t[256] = (intptr_t)pdpt2 + PAGE_V + PAGE_RW;
|
||||||
__map_phdrs(mm, pml4t, 1024 * 1024, 1024 * 1024 + (_end - _base));
|
|
||||||
__reclaim_boot_pages(mm, 0x79000, 0x7f000);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asks UEFI to handover control?
|
* Asks UEFI to handover control?
|
||||||
*/
|
*/
|
||||||
SystemTable->BootServices->ExitBootServices(ImageHandle, MapKey);
|
SystemTable->BootServices->ExitBootServices(ImageHandle, MapKey);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switches to copied image.
|
||||||
|
*/
|
||||||
|
asm volatile("cli\n\t"
|
||||||
|
"add\t%1,%%rsp\n\t"
|
||||||
|
"lea\t0f(%1),%0\n\t"
|
||||||
|
"jmp\t*%0\n"
|
||||||
|
"0:\n\t"
|
||||||
|
"mov\t%2,%%cr3\n\t"
|
||||||
|
"add\t%3,%%rsp\n\t"
|
||||||
|
"lea\t1f(%1),%0\n\t"
|
||||||
|
"add\t%3,%0\n\t"
|
||||||
|
"jmp\t*%0\n"
|
||||||
|
"1:"
|
||||||
|
: "=&r"(p)
|
||||||
|
: "r"(1024 * 1024 - (uint64_t)_base), "r"(pml4t), "r"(BANE));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets up virtual memory mapping.
|
||||||
|
*/
|
||||||
|
__map_phdrs(mm, pml4t, 1024 * 1024, 1024 * 1024 + (_end - _base));
|
||||||
|
__reclaim_boot_pages(mm, 0x79000, 0x7f000);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Launches program.
|
* Launches program.
|
||||||
*/
|
*/
|
||||||
asm volatile("fldcw\t%3\n\t"
|
asm volatile("fldcw\t%3\n\t"
|
||||||
"mov\t%4,%%cr3\n\t"
|
".weak\t_gdtr\n\t"
|
||||||
|
"lgdt\t_gdtr\n\t"
|
||||||
|
"mov\t%w6,%%ds\n\t"
|
||||||
|
"mov\t%w6,%%ss\n\t"
|
||||||
|
"mov\t%w6,%%es\n\t"
|
||||||
|
"mov\t%w6,%%fs\n\t"
|
||||||
|
"mov\t%w6,%%gs\n\t"
|
||||||
".weak\tape_stack_vaddr\n\t"
|
".weak\tape_stack_vaddr\n\t"
|
||||||
".weak\tape_stack_memsz\n\t"
|
".weak\tape_stack_memsz\n\t"
|
||||||
"movabs\t$ape_stack_vaddr,%%rsp\n\t"
|
"movabs\t$ape_stack_vaddr,%%rsp\n\t"
|
||||||
|
@ -164,7 +203,7 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||||
"xor\t%%edi,%%edi\n\t"
|
"xor\t%%edi,%%edi\n\t"
|
||||||
"xor\t%%eax,%%eax\n\t"
|
"xor\t%%eax,%%eax\n\t"
|
||||||
"xor\t%%ebx,%%ebx\n\t"
|
"xor\t%%ebx,%%ebx\n\t"
|
||||||
"xor\t%%ecx,%%ecx\n\t"
|
"mov\t%4,%%ecx\n\t"
|
||||||
"xor\t%%edx,%%edx\n\t"
|
"xor\t%%edx,%%edx\n\t"
|
||||||
"xor\t%%edi,%%edi\n\t"
|
"xor\t%%edi,%%edi\n\t"
|
||||||
"xor\t%%esi,%%esi\n\t"
|
"xor\t%%esi,%%esi\n\t"
|
||||||
|
@ -178,10 +217,13 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||||
"xor\t%%r14d,%%r14d\n\t"
|
"xor\t%%r14d,%%r14d\n\t"
|
||||||
"xor\t%%r15d,%%r15d\n\t"
|
"xor\t%%r15d,%%r15d\n\t"
|
||||||
".weak\t_start\n\t"
|
".weak\t_start\n\t"
|
||||||
"jmp\t_start"
|
"push\t%5\n\t"
|
||||||
|
"push\t$_start\n\t"
|
||||||
|
"lretq"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
: "a"(Args), "S"(ArgBlock->Args), "c"((Args + 1) * 8),
|
: "a"(Args), "S"(ArgBlock->Args), "c"((Args + 1) * 8),
|
||||||
"m"(x87cw), "r"(pml4t)
|
"m"(x87cw), "i"(_HOSTMETAL), "i"(GDT_LONG_CODE),
|
||||||
|
"r"(GDT_LONG_DATA)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
unreachable;
|
unreachable;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue