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