1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef X86_ASM_TRAMPOLINE_H 3 #define X86_ASM_TRAMPOLINE_H 4 5 /* 6 * Data in or about the low memory trampoline. 7 * 8 * x86 systems software typically needs a block of logic below the 1M 9 * boundary, commonly called the trampoline, containing 16-bit logic. Xen has 10 * a combined trampoline of all necessary 16-bit logic, formed of two parts. 11 * 12 * 1) The permanent trampoline; a single 4k page containing: 13 * 14 * - The INIT-SIPI-SIPI entrypoint for APs, and 15 * - The S3 wakeup vector. 16 * 17 * Both of these are 16-bit entrypoints, responsible for activating paging 18 * and getting into 64-bit mode. This requires the permanent trampoline to 19 * be identity mapped in idle_pg_table[]. 20 * 21 * The SIPI64 spec deprecates the 16-bit AP entrypoint, while S0ix (also 22 * called Low Power Idle or Connected Standby) deprecates S3. 23 * 24 * 2) The boot trampoline: 25 * 26 * This is used by the BSP to drop into 16-bit mode, make various BIOS 27 * calls to obtain E820/EDID/etc. It follows the permanent and exceeds 4k, 28 * but is only used in 16-bit and 32-bit unpaged mode so does not need 29 * mapping in pagetables. 30 * 31 * When the BIOS calls are complete, execution does join back with the AP 32 * path, and becomes subject to the same paging requirements. This path is 33 * not needed for non-BIOS boots. 34 * 35 * The location of trampoline is not fixed. The layout of low memory varies 36 * greatly from platform to platform. Therefore, the trampoline is relocated 37 * manually as part of placement. 38 */ 39 40 /* 41 * Layout of the trampoline. Logical areas, in ascending order: 42 * 43 * 1) AP boot: 44 * 45 * The INIT-SIPI-SIPI entrypoint. This logic is stack-less so the identity 46 * mapping (which must be executable) can at least be Read Only. 47 * 48 * 2) S3 resume: 49 * 50 * The S3 wakeup logic may need to interact with the BIOS, so needs a 51 * stack. The stack pointer is set to trampoline_phys + 4k and clobbers an 52 * arbitrary part of the the boot trampoline. The stack is only used with 53 * paging disabled. 54 * 55 * 3) Boot trampoline: 56 * 57 * The boot trampoline collects data from the BIOS (E820/EDD/EDID/etc), so 58 * needs a stack. The stack pointer is set to trampoline_phys + 64k, is 4k 59 * in size, and only used with paging disabled. 60 * 61 * 4) Heap space: 62 * 63 * The first 1k of heap space is statically allocated scratch space for 64 * VESA information. 65 * 66 * The remainder of the heap is used by reloc(), logic which is otherwise 67 * outside of the trampoline, to collect the bootloader metadata (cmdline, 68 * module list, etc). It does so with a bump allocator starting from the 69 * end of the heap and allocating backwards. 70 * 71 * 5) Boot stack: 72 * 73 * The boot stack is 4k in size at the end of the trampoline, taking the 74 * total trampoline size to 64k. 75 * 76 * Therefore, when placed, it looks somewhat like this: 77 * 78 * +--- trampoline_phys 79 * v 80 * |<-------------------------------64K------------------------------->| 81 * |<-----4K----->| |<---4K--->| 82 * +-------+------+-+---------------------------------------+----------+ 83 * | AP+S3 | Boot | Heap | Stack | 84 * +-------+------+-+---------------------------------------+----------+ 85 * ^ ^ <~~^ ^ <~~^ <~~^ 86 * | | | +- trampoline_end[] | | 87 * | | +--- wakeup_stack reloc() allocator -+ | 88 * | +---------- trampoline_perm_end Boot Stack ------------+ 89 * +------------------ trampoline_start[] 90 * 91 * Note: trampoline_start[] and trampoline_end[] represent the shown 92 * boundaries, but are addresses as linked into Xen's .init section. 93 */ 94 95 #define TRAMPOLINE_SIZE KB(64) 96 #define TRAMPOLINE_HEAP_END (TRAMPOLINE_SIZE - PAGE_SIZE) 97 #define MBI_SPACE_MIN (2 * PAGE_SIZE) 98 99 #ifndef __ASSEMBLY__ 100 101 #include <xen/compiler.h> 102 #include <xen/types.h> 103 104 /* 105 * Start and end of the trampoline section, as linked into Xen. It is within 106 * the .init section and reclaimed after boot. 107 */ 108 /* SAF-0-safe */ 109 extern char trampoline_start[], trampoline_end[]; 110 111 /* 112 * The physical address of trampoline_start[] in low memory. It must be below 113 * the 1M boundary (as the trampoline contains 16-bit code), and must be 4k 114 * aligned (SIPI requirement for APs). 115 */ 116 extern uint32_t trampoline_phys; 117 118 /* 119 * Calculate the physical address of a symbol in the trampoline. 120 * 121 * Should only be used on symbols declared later in this header. Specifying 122 * other symbols will compile but malfunction when used, as will using this 123 * helper before the trampoline is placed. 124 */ 125 #define bootsym_phys(sym) \ 126 (trampoline_phys + ((unsigned long)&(sym) - \ 127 (unsigned long)trampoline_start)) 128 129 /* Given a trampoline symbol, construct a pointer to it in the directmap. */ 130 #define bootsym(sym) (*((typeof(sym) *)__va(bootsym_phys(sym)))) 131 132 /* The INIT-SIPI-SIPI entrypoint. 16-bit code. */ 133 void nocall entry_SIPI16(void); 134 135 /* The S3 wakeup vector. 16-bit code. */ 136 void nocall entry_S3(void); 137 138 /* 139 * A variable in the trampoline, containing Xen's physical address. Amongst 140 * other things, it is used to find idle_pg_table[] in order to enable paging 141 * and activate 64-bit mode. This variable needs keeping in sync with 142 * xen_phys_start. 143 */ 144 extern uint32_t trampoline_xen_phys_start; 145 146 /* A semaphore to indicate signs-of-life at the start of the AP boot path. */ 147 extern uint8_t trampoline_cpu_started; 148 149 /* 150 * Extra MSR_EFER settings when activating Long Mode. EFER_NXE is necessary 151 * for APs to boot if the BSP found and activated support. 152 */ 153 extern uint32_t trampoline_efer; 154 155 /* 156 * When nonzero, clear the specified bits in MSR_MISC_ENABLE. This is 157 * necessary to clobber XD_DISABLE before trying to set MSR_EFER.NXE. 158 */ 159 extern uint64_t trampoline_misc_enable_off; 160 161 /* Quirks about video mode-setting on S3 resume. */ 162 extern uint8_t video_flags; 163 164 /* BIOS Int 16h, Fn 02h. The keyboard shift status. */ 165 extern uint8_t kbd_shift_flags; 166 167 /* Extended Display Identification Data, gathered from the BIOS. */ 168 extern uint16_t boot_edid_caps; 169 extern uint8_t boot_edid_info[128]; 170 171 #endif /* !__ASSEMBLY__ */ 172 #endif /* X86_ASM_TRAMPOLINE_H */ 173