mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-08 10:50:28 +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("_idt");
|
||||
STATIC_YOINK("EfiMain");
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
volatile int x = 1;
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
|
||||
#define INVERT(x) (BANE + PHYSICAL(x))
|
||||
#define NOPAGE ((uint64_t)-1)
|
||||
|
||||
struct ReclaimedPage {
|
||||
uint64_t next;
|
||||
|
@ -54,7 +55,7 @@ struct ReclaimedPage {
|
|||
*/
|
||||
noasan texthead uint64_t __new_page(struct mman *mm) {
|
||||
uint64_t p = mm->frp;
|
||||
if (p) {
|
||||
if (p != NOPAGE) {
|
||||
uint64_t q;
|
||||
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p);
|
||||
_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->pdpi = 0;
|
||||
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
|
||||
*/
|
||||
__msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||
EFI_SYSTEM_TABLE *SystemTable) {
|
||||
int type, x87cw;
|
||||
__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) {
|
||||
int type, x87cw = 0x037f;
|
||||
struct mman *mm;
|
||||
uint32_t DescVersion;
|
||||
uintptr_t i, j, MapSize;
|
||||
struct EfiArgs *ArgBlock;
|
||||
EFI_LOADED_IMAGE *ImgInfo;
|
||||
EFI_MEMORY_DESCRIPTOR *Map;
|
||||
EFI_MEMORY_DESCRIPTOR *Map, *Desc;
|
||||
uint64_t NewBase = 1024 * 1024;
|
||||
uintptr_t Args, MapKey, DescSize;
|
||||
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.
|
||||
*/
|
||||
SystemTable->BootServices->AllocatePages(
|
||||
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->CopyMem((void *)(1024 * 1024), _base,
|
||||
_end - _base);
|
||||
|
@ -104,16 +113,19 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
MapSize = 0;
|
||||
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
||||
&DescVersion);
|
||||
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, Map);
|
||||
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, &Map);
|
||||
MapSize *= 2;
|
||||
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
||||
&DescVersion);
|
||||
asm("xor\t%0,%0" : "=r"(mm)); /* gcc assumes null isn't mapped */
|
||||
for (j = i = 0; i < MapSize / sizeof(EFI_MEMORY_DESCRIPTOR); ++i) {
|
||||
if (Map[i].Type != EfiConventionalMemory) continue;
|
||||
mm->e820[j].addr = Map[i].PhysicalStart;
|
||||
mm->e820[j].size = Map[i].NumberOfPages * 4096;
|
||||
mm->e820[j].type = kMemoryUsable;
|
||||
++j;
|
||||
mm = (struct mman *)0x0500;
|
||||
for (j = i = 0, Desc = Map; i < MapSize / DescSize; ++i) {
|
||||
if (Desc->Type == EfiConventionalMemory) {
|
||||
mm->e820[j].addr = Desc->PhysicalStart;
|
||||
mm->e820[j].size = Desc->NumberOfPages * 4096;
|
||||
mm->e820[j].type = kMemoryUsable;
|
||||
++j;
|
||||
}
|
||||
Desc = (EFI_MEMORY_DESCRIPTOR *)((char *)Desc + DescSize);
|
||||
}
|
||||
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;
|
||||
pml4t[0] = (intptr_t)pdpt1 + 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?
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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_memsz\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%%eax,%%eax\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%%edi,%%edi\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%%r15d,%%r15d\n\t"
|
||||
".weak\t_start\n\t"
|
||||
"jmp\t_start"
|
||||
"push\t%5\n\t"
|
||||
"push\t$_start\n\t"
|
||||
"lretq"
|
||||
: /* no outputs */
|
||||
: "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");
|
||||
|
||||
unreachable;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue