/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │ vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi │ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2022 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ │ above copyright notice and this permission notice appear in all copies. │ │ │ │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/relocations.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/runtime/pc.internal.h" .real // Start the Cosmopolitan runtime after exiting UEFI Boot Services. // // @param rdi is mm // @param rsi is new pml4t // @param rdx is argc // @param rcx is argv // @see libc/runtime/efimain.greg.c _EfiPostboot: cli // Define handy mnemonics for parameters & constants stored in // call-saved registers. #define rMm %r12 #define rArgc %r13 #define rArgv %r14 #define rBane %r15 movabs $BANE,rBane mov %rdi,rMm mov %rdx,rArgc lea (rBane,%rcx),rArgv mov $PHYSICAL(.Ltmpstk),%rax // switch to temporary stack and $-16,%al // in physical space xchg %rax,%rsp mov $PHYSICAL(0f),%eax // resume execution in copied jmp *%rax // image 0: mov $EFER,%ecx // enable syscall/sysret & nx rdmsr or $EFER_SCE|EFER_NXE,%eax wrmsr mov %rsi,%cr3 // load new page table add rBane,%rsp // we can now switch stack to add rBane,rMm // negative address space mov $1024*1024,%edx // set up virtual memory mov $1024*1024+_end,%ecx // mapping sub $__executable_start,%ecx call __map_phdrs mov $1f,%eax // switch rip to virtual jmp *%rax // address space 1: push $0x037f fldcw (%rsp) .weak _gdtr lgdt _gdtr // switch to our own GDT mov $GDT_LONG_DATA,%ax mov %ax,%ds mov %ax,%ss mov %ax,%es mov %ax,%fs mov %ax,%gs .weak ape_stack_vaddr .weak ape_stack_memsz movabs $ape_stack_vaddr,%rsp // switch to final stack in add $ape_stack_memsz,%rsp // virtual address space movl $0,0x7b000 // unmap null 2mb mov rMm,%rdi xor %esi,%esi // free up now-unused pages xor %edx,%edx call __reclaim_boot_pages push .Lenv0(%rip) // envp[0][0] mov %rsp,%rbp push $0 // auxv[1][1] push $0 // auxv[1][0] mov (rArgv),%rax add rBane,%rax push %rax // auxv[0][1] push $31 // auxv[0][0] AT_EXECFN push $0 // envp[1] push %rbp // envp[0] push $0 // argv[argc] NULL lea -8(rArgv,rArgc,8),%rsi // push rest of argv, & mov rArgc,%rcx // adjust pointers to point to std // negative space 2: lodsq add rBane,%rax push %rax loop 2b cld push rArgc // argc pushpop _HOSTMETAL,%rcx // sets __hostos in crt.S xor %ebp,%ebp xor %eax,%eax xor %ebx,%ebx xor %edx,%edx xor %edi,%edi xor %esi,%esi xor %r8d,%r8d xor %r9d,%r9d xor %r10d,%r10d xor %r11d,%r11d xor %r12d,%r12d xor %r13d,%r13d xor %r14d,%r14d xor %r15d,%r15d push $GDT_LONG_CODE .weak _start push $_start lretq .endfn _EfiPostboot,globl,hidden .rodata .Lenv0: .asciz "METAL=1" .bss .space 0x1000 .Ltmpstk: .previous .weak __executable_start .weak _end