1/*- 2 * Copyright (c) 2022 Netflix, Inc 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26/* 27 * This is the trampoline that starts the FreeBSD kernel. Since the Linux kernel 28 * calls this routine with no args, and has a different environment than the 29 * boot loader provides and that the kernel expects, this code is responsible 30 * for setting all that up and calling the normal kernel entry point. It's 31 * analogous to the "purgatory" code in the linux kernel. Details about these 32 * operations are contained in comments below. On amd64, the kernel starts all 33 * the APs so we don't have to worry about them here. 34 */ 35 36/* 37 * Keep in sync with elf64_freebsd.c. Kexec starts tramp w/o any parameters, so 38 * store them here. This is constructed to be a useful stack: 39 * 40 * struct trampoline_data { 41 * uint64_t pt4; // Page table address to pop 42 * uint64_t entry; // return address to jump to kernel 43 * uint32_t fill1; // 0 44 * uint32_t modulep; // 4 module metadata 45 * uint32_t kernend; // 8 kernel end 46 * uint32_t fill2; // 12 47 * }; 48 * 49 * loader.kboot will construct a stack that btext expects, which is arguments on 50 * the stack, not in registers, and these args are 32-bit not 64 51 * 52 * Processor is already in long mode when we're called, paging is enabled and 53 * boot loader loads things such that: 54 * - kernel mapped at KERNBASE, aligned to 2MB, below 4GB, contiguous memory 55 * - there is a 2M hole at KERNBASE (KERNSTART = KERNBASE + 2M) 56 * - kernel is mapped with 2M superpages 57 * - The kernel, modules and metadata is in first 4GB which is unity mapped 58 * - There's additional memory after loader provided data for early allocations 59 * 60 * Unlike EFI, we don't support copying the staging area. We tell Linux to land 61 * the kernel in its final location with the needed alignment, etc. We copy the 62 * trampoline code to 1MB offset above KERNBASE since that memory is otherwise 63 * free and safely above the lower 1MB swamp we inherited from IBM PC, though 64 * this code makes no assumptions about where that might. 65 * 66 * Thus, the trampoline just needs to set %rsp to that stack pop the %cr3 value, 67 * set it and then retq to jump to the kernel with its stack args filled in. 68 * Since the handoff to this code used to be from 32-bit code, it uses the i386 69 * calling conventions which put the arguments on the stack. The kernel's btext 70 * routine expects this setup. 71 */ 72 .text 73 .globl tramp 74tramp: 75 cli /* Make sure we don't get interrupted. */ 76 leaq tramp_pt4(%rip), %rsp /* Setup our pre-filled-in stack */ 77 popq %rax /* Pop off the PT4 ptr for %cr3 */ 78 movq %rax, %cr3 /* set the page table */ 79 retq /* Return addr and args already on stack */ 80/* 81 * The following is the stack for the above code. The stack will increase in 82 * address as things are popped off of it, so we start with the stack pointing 83 * to tramp_pt4. 84 */ 85 .p2align 3 /* Stack has to be 8 byte aligned */ 86trampoline_data: 87tramp_pt4: .quad 0 /* New %cr3 value */ 88tramp_entry: .quad 0 /* Entry to kernel (btext) */ 89 /* %rsp points here on entry to amd64 kernel's btext */ 90 .long 0 /* 0 filler, ignored (current loaders set to 0) */ 91tramp_modulep: .long 0 /* 4 moudlep */ 92tramp_kernend: .long 0 /* 8 kernend */ 93 .long 0 /* 12 alignment filler (also 0) */ 94tramp_end: 95 96 .data 97 .type tramp_size,@object 98 .globl tramp_size 99tramp_size: 100 .long tramp_end-tramp 101 .size tramp_size, 4 102 103 .type tramp_data_offset,@object 104 .globl tramp_data_offset 105tramp_data_offset: 106 .long trampoline_data-tramp 107 .size tramp_data_offset, 4 108