1/* 2 * Copyright (c) 2019 Mike Larkin <mlarkin@openbsd.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include <machine/asm.h> 18#include <machine/specialreg.h> 19 20#define CODE_SEGMENT 0x8 21#define DATA_SEGMENT 0x10 22 23 .text 24 .code32 25 .global launch_amd64_kernel_long 26 /* 27 * void launch_amd64_kernel_long(caddr_t base, caddr_t pml4, 28 * caddr_t rsp, uint64_t entry, int boothowto, int bootdev, 29 * int bootapiver, uint64_t end, int extmem, int cnvmem, 30 * int ac, uint64_t av); 31 */ 32launch_amd64_kernel_long: 33asm_start: 34 xchg %bx, %bx 35 36 /* 37 * We are in 32 bit mode 38 * - compute indirect jump targets 39 * - compute GDT locations 40 */ 41 popl %edi /* Discard return address */ 42 popl %edi /* %edi = bootloader base address */ 43 44 /* Current mode -> 32 bit jump target */ 45 leal (prot_mode - asm_start)(%edi), %eax 46 movl %eax, (start32r - asm_start)(%edi) 47 48 /* 32 bit -> 64 bit jump target */ 49 leal (long_mode - asm_start)(%edi), %eax 50 movl %eax, (start64r - asm_start)(%edi) 51 52 /* Current mode -> 32 bit GDT */ 53 leal (gdt32 - asm_start)(%edi), %eax 54 movl %eax, (gdtrr32 - asm_start)(%edi) 55 56 /* 32 bit -> 64 bit GDT */ 57 leal (gdt64 - asm_start)(%edi), %eax 58 movl %eax, (gdtrr64 - asm_start)(%edi) 59 60 cli 61 62 lgdtl (gdtr32 - asm_start)(%edi) 63 64 mov %cr0, %eax 65 orl $(CR0_PE), %eax 66 mov %eax, %cr0 67 68 ljmpl *(start32r - asm_start)(%edi) 69 70 .align 4 71prot_mode: 72 movw $DATA_SEGMENT, %ax 73 movw %ax, %ds 74 movw %ax, %es 75 movw %ax, %gs 76 movw %ax, %ss 77 movw %ax, %fs 78 79 mov $(CR4_PAE | CR4_PSE), %eax 80 mov %eax, %cr4 81 82 lgdtl (gdtr64 - asm_start)(%edi) 83 movl $MSR_EFER, %ecx 84 xorl %edx, %edx 85 movl $(EFER_LME | EFER_NXE | EFER_SCE), %eax 86 wrmsr 87 88 movl (%esp), %eax /* first arg - PML4 */ 89 movl 4(%esp), %ebx /* second arg - kernel stack */ 90 movl %eax, %cr3 91 92 jmp 1f 931: jmp 1f 941: movl %cr0, %eax 95 orl $CR0_DEFAULT, %eax 96 movl %eax, %cr0 97 98 jmp 1f 991: jmp 1f 1001: ljmpl *(start64r - asm_start)(%edi) 101 102long_mode: 103 .code64 104 movq %rsp, %rax 105 movq %rbx, %rsp 106 107 /* 108 * params stack at %rax right now: 109 * 110 * +0 32 bit PML4 ptr 111 * +4 32 bit kernel stack 112 * +8 start va low bytes 113 + +12 start va high bytes 114 * +16 boothowto (%rdi) 115 * +20 bootdev (%rsi) 116 * +24 BOOTARG_APIVER (%rdx) 117 * +28 marks[MARK_END] low bytes (%rcx) 118 * +32 marks[MARK_END] high bytes (%rcx) 119 * +36 extmem (%r8) 120 * +40 cnvmem (%r9) 121 * +44 ac (%rsp, will be %rsp + 8 after call below) 122 * +48 av low bytes (%rsp + 8, will be %rsp + 16 after call below) 123 * +52 av high bytes (%rsp + 16, will be %rsp + 24 after call below) 124 */ 125 126 movl 16(%rax), %edi 127 movl 20(%rax), %esi 128 movl 24(%rax), %edx 129 movq 28(%rax), %rcx 130 movl 36(%rax), %r8d 131 movl 40(%rax), %r9d 132 movq 48(%rax), %rbx /* av */ 133 pushq %rbx 134 movl 44(%rax), %ebx /* ac */ 135 pushq %rbx 136 movq 8(%rax), %r11 137 138 /* 139 * start(howto, bootdev, BOOTARG_APIVER, marks[MARK_END], 140 * extmem, cnvmem, ac, av); 141 */ 142 call *%r11 143 144 cli 145 hlt 146 /* NOTREACHED */ 147 148 .align 4 149start32r: 150 .long 0 151 .long CODE_SEGMENT 152 153start64r: 154 .long 0 155 .long CODE_SEGMENT 156 157gdt32: 158 .long 0, 0 159 .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00 160 .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 161gdtr32: 162 .word gdtr32 - gdt32 163gdtrr32: 164 .quad 165 166 .align 8 167gdt64: 168 .quad 0x0000000000000000 169 .quad 0x00af9a000000ffff 170 .quad 0x00cf92000000ffff 171 172gdtr64: 173 .word gdtr64 - gdt64 174gdtrr64: 175 .quad 176