/*-*- 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 $_base,%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