source: mainline/kernel/arch/amd64/src/boot/multiboot2.S

Last change on this file was ec18e454, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Revert "Deduplicate bootstrap code" - needs more work

This reverts commit 17aa6d19228b3aab97f8e989dd9a36d576f1d896.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <abi/asmtool.h>
30#include <arch/boot/boot.h>
31#include <arch/mm/page.h>
32#include <arch/pm.h>
33#include <arch/cpuid.h>
34#include <arch/cpu.h>
35#include <genarch/multiboot/multiboot2.h>
36
37#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
38
39.section K_TEXT_START, "ax"
40
41.code32
42
43.align 8
44multiboot2_header_start:
45 .long MULTIBOOT2_HEADER_MAGIC
46 .long MULTIBOOT2_HEADER_ARCH_I386
47 .long multiboot2_header_end - multiboot2_header_start
48 .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_HEADER_ARCH_I386 + (multiboot2_header_end - multiboot2_header_start))
49
50 /* Information request tag */
51 .align 8
52 tag_info_req_start:
53 .word MULTIBOOT2_TAG_INFO_REQ
54 .word MULTIBOOT2_FLAGS_REQUIRED
55 .long tag_info_req_end - tag_info_req_start
56 .long MULTIBOOT2_TAG_CMDLINE
57 .long MULTIBOOT2_TAG_MODULE
58 .long MULTIBOOT2_TAG_MEMMAP
59#ifdef CONFIG_FB
60 .long MULTIBOOT2_TAG_FBINFO
61#endif
62 tag_info_req_end:
63
64 /* Address tag */
65 .align 8
66 tag_address_start:
67 .word MULTIBOOT2_TAG_ADDRESS
68 .word MULTIBOOT2_FLAGS_REQUIRED
69 .long tag_address_end - tag_address_start
70 .long multiboot2_header_start
71 .long unmapped_start
72 .long 0
73 .long 0
74 tag_address_end:
75
76 /* Entry address tag */
77 .align 8
78 tag_entry_address_start:
79 .word MULTIBOOT2_TAG_ENTRY_ADDRESS
80 .word MULTIBOOT2_FLAGS_REQUIRED
81 .long tag_entry_address_end - tag_entry_address_start
82 .long multiboot2_image_start
83 tag_entry_address_end:
84
85 /* Flags tag */
86 .align 8
87 tag_flags_start:
88 .word MULTIBOOT2_TAG_FLAGS
89 .word MULTIBOOT2_FLAGS_REQUIRED
90 .long tag_flags_end - tag_flags_start
91 .long MULTIBOOT2_FLAGS_CONSOLE
92 tag_flags_end:
93
94#ifdef CONFIG_FB
95 /* Framebuffer tag */
96 .align 8
97 tag_framebuffer_start:
98 .word MULTIBOOT2_TAG_FRAMEBUFFER
99 .word MULTIBOOT2_FLAGS_REQUIRED
100 .long tag_framebuffer_end - tag_framebuffer_start
101 .long CONFIG_BFB_WIDTH
102 .long CONFIG_BFB_HEIGHT
103 .long CONFIG_BFB_BPP
104 tag_framebuffer_end:
105#endif
106
107 /* Module alignment tag */
108 .align 8
109 tag_module_align_start:
110 .word MULTIBOOT2_TAG_MODULE_ALIGN
111 .word MULTIBOOT2_FLAGS_REQUIRED
112 .long tag_module_align_end - tag_module_align_start
113 .long 0
114 tag_module_align_end:
115
116 /* Tag terminator */
117 .align 8
118 tag_terminator_start:
119 .word MULTIBOOT2_TAG_TERMINATOR
120 .word MULTIBOOT2_FLAGS_REQUIRED
121 .long tag_terminator_end - tag_terminator_start
122 tag_terminator_end:
123multiboot2_header_end:
124
125SYMBOL(multiboot2_image_start)
126 cli
127 cld
128
129 /* Initialize stack pointer */
130 movl $START_STACK, %esp
131
132 /*
133 * Initialize Global Descriptor Table and
134 * Interrupt Descriptor Table registers
135 */
136 lgdtl bootstrap_gdtr
137 lidtl bootstrap_idtr
138
139 /* Kernel data + stack */
140 movw $GDT_SELECTOR(KDATA_DES), %cx
141 movw %cx, %es
142 movw %cx, %ds
143 movw %cx, %ss
144
145 /*
146 * Simics seems to remove hidden part of GS on entering user mode
147 * when _visible_ part of GS does not point to user-mode segment.
148 */
149 movw $GDT_SELECTOR(UDATA_DES), %cx
150 movw %cx, %fs
151 movw %cx, %gs
152
153 jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot2_meeting_point
154 multiboot2_meeting_point:
155
156 /*
157 * Protected 32-bit. We want to reuse the code-seg descriptor,
158 * the Default operand size must not be 1 when entering long mode.
159 */
160
161 /* Save multiboot arguments */
162 movl %eax, multiboot_eax
163 movl %ebx, multiboot_ebx
164
165 movl $(INTEL_CPUID_EXTENDED), %eax
166 cpuid
167 cmp $(INTEL_CPUID_EXTENDED), %eax
168 ja extended_cpuid_supported
169
170 jmp pm_error_halt
171
172 extended_cpuid_supported:
173
174 movl $(AMD_CPUID_EXTENDED), %eax
175 cpuid
176 bt $(AMD_EXT_LONG_MODE), %edx
177 jc long_mode_supported
178
179 jmp pm_error_halt
180
181 long_mode_supported:
182
183 bt $(AMD_EXT_NOEXECUTE), %edx
184 jc noexecute_supported
185
186 jmp pm_error_halt
187
188 noexecute_supported:
189
190 movl $(INTEL_CPUID_STANDARD), %eax
191 cpuid
192 bt $(INTEL_FXSAVE), %edx
193 jc fx_supported
194
195 jmp pm_error_halt
196
197 fx_supported:
198
199 bt $(INTEL_SSE2), %edx
200 jc sse2_supported
201
202 jmp pm_error_halt
203
204 sse2_supported:
205
206 /*
207 * Enable 64-bit page translation entries - CR4.PAE = 1.
208 * Paging is not enabled until after long mode is enabled.
209 */
210
211 movl %cr4, %eax
212 orl $CR4_PAE, %eax
213 movl %eax, %cr4
214
215 /* Set up paging tables */
216 leal ptl_0, %eax
217 movl %eax, %cr3
218
219 /* Enable long mode */
220 movl $AMD_MSR_EFER, %ecx
221 rdmsr /* read EFER */
222 orl $AMD_LME, %eax /* set LME = 1 */
223 wrmsr
224
225 /* Enable paging to activate long mode (set CR0.PG = 1) */
226 movl %cr0, %eax
227 orl $CR0_PG, %eax
228 movl %eax, %cr0
229
230 /* At this point we are in compatibility mode */
231 jmpl $GDT_SELECTOR(KTEXT_DES), $start64
232
233pm_error_halt:
234 cli
235 hlt1:
236 hlt
237 jmp hlt1
238
239.code64
240
241start64:
242
243 /*
244 * Long mode.
245 */
246
247 movq $(PA2KA(START_STACK)), %rsp
248
249 /* Create the first stack frame */
250 pushq $0
251 movq %rsp, %rbp
252
253 /* Call amd64_pre_main(multiboot_eax, multiboot_ebx) */
254 movl multiboot_eax, %edi
255 movl multiboot_ebx, %esi
256
257#ifdef MEMORY_MODEL_large
258 movabsq $amd64_pre_main, %rax
259 callq *%rax
260#else
261 callq amd64_pre_main
262#endif
263
264 /* Call main_bsp() */
265#ifdef MEMORY_MODEL_large
266 movabsq $main_bsp, %rax
267 callq *%rax
268#else
269 callq main_bsp
270#endif
271
272 /* Not reached */
273 cli
274 hlt0:
275 hlt
276 jmp hlt0
Note: See TracBrowser for help on using the repository browser.