source: mainline/kernel/arch/amd64/src/boot/multiboot.S@ 76d0981d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 76d0981d was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 14.8 KB
Line 
1/*
2 * Copyright (c) 2005 Ondrej Palkovsky
3 * Copyright (c) 2006 Martin Decky
4 * Copyright (c) 2008 Jakub Jermar
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <abi/asmtool.h>
32#include <arch/boot/boot.h>
33#include <arch/mm/page.h>
34#include <arch/mm/ptl.h>
35#include <arch/pm.h>
36#include <genarch/multiboot/multiboot.h>
37#include <arch/cpuid.h>
38#include <arch/cpu.h>
39
40#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
41
42.section K_TEXT_START, "ax"
43
44.code32
45
46.macro pm_error msg
47 movl \msg, %esi
48 jmp pm_error_halt
49.endm
50
51.macro pm_status msg
52#ifdef CONFIG_EGA
53 pushl %esi
54 movl \msg, %esi
55 call pm_early_puts
56 popl %esi
57#endif
58.endm
59
60.macro pm2_status msg
61#ifndef CONFIG_FB
62 pm_status \msg
63#endif
64.endm
65
66.align 4
67multiboot_header:
68 .long MULTIBOOT_HEADER_MAGIC
69 .long MULTIBOOT_HEADER_FLAGS
70 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */
71 .long multiboot_header
72 .long unmapped_ktext_start
73 .long 0
74 .long 0
75 .long multiboot_image_start
76
77SYMBOL(multiboot_image_start)
78 cli
79 cld
80
81 /* Initialize stack pointer */
82 movl $START_STACK, %esp
83
84 /*
85 * Initialize Global Descriptor Table and
86 * Interrupt Descriptor Table registers
87 */
88 lgdtl bootstrap_gdtr
89 lidtl bootstrap_idtr
90
91 /* Kernel data + stack */
92 movw $GDT_SELECTOR(KDATA_DES), %cx
93 movw %cx, %es
94 movw %cx, %ds
95 movw %cx, %ss
96
97 /*
98 * Simics seems to remove hidden part of GS on entering user mode
99 * when _visible_ part of GS does not point to user-mode segment.
100 */
101 movw $GDT_SELECTOR(UDATA_DES), %cx
102 movw %cx, %fs
103 movw %cx, %gs
104
105 jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot_meeting_point
106 multiboot_meeting_point:
107
108 /*
109 * Protected 32-bit. We want to reuse the code-seg descriptor,
110 * the Default operand size must not be 1 when entering long mode.
111 */
112
113 /* Save multiboot arguments */
114 movl %eax, multiboot_eax
115 movl %ebx, multiboot_ebx
116
117 pm_status $status_prot
118
119 movl $(INTEL_CPUID_EXTENDED), %eax
120 cpuid
121 cmp $(INTEL_CPUID_EXTENDED), %eax
122 ja extended_cpuid_supported
123
124 pm_error $err_extended_cpuid
125
126 extended_cpuid_supported:
127
128 movl $(AMD_CPUID_EXTENDED), %eax
129 cpuid
130 bt $(AMD_EXT_LONG_MODE), %edx
131 jc long_mode_supported
132
133 pm_error $err_long_mode
134
135 long_mode_supported:
136
137 bt $(AMD_EXT_NOEXECUTE), %edx
138 jc noexecute_supported
139
140 pm_error $err_noexecute
141
142 noexecute_supported:
143
144 movl $(INTEL_CPUID_STANDARD), %eax
145 cpuid
146 bt $(INTEL_FXSAVE), %edx
147 jc fx_supported
148
149 pm_error $err_fx
150
151 fx_supported:
152
153 bt $(INTEL_SSE2), %edx
154 jc sse2_supported
155
156 pm_error $err_sse2
157
158 sse2_supported:
159
160#include "vesa_prot.inc"
161
162 pm2_status $status_prot2
163
164 /*
165 * Enable 64-bit page translation entries - CR4.PAE = 1.
166 * Paging is not enabled until after long mode is enabled.
167 */
168
169 movl %cr4, %eax
170 orl $CR4_PAE, %eax
171 movl %eax, %cr4
172
173 /* Set up paging tables */
174 leal ptl_0, %eax
175 movl %eax, %cr3
176
177 /* Enable long mode */
178 movl $AMD_MSR_EFER, %ecx
179 rdmsr /* read EFER */
180 orl $AMD_LME, %eax /* set LME = 1 */
181 wrmsr
182
183 /* Enable paging to activate long mode (set CR0.PG = 1) */
184 movl %cr0, %eax
185 orl $CR0_PG, %eax
186 movl %eax, %cr0
187
188 /* At this point we are in compatibility mode */
189 jmpl $GDT_SELECTOR(KTEXT_DES), $start64
190
191/** Print string to EGA display (in light red) and halt.
192 *
193 * Should be executed from 32 bit protected mode with paging
194 * turned off. Stack is not required. This routine is used even
195 * if CONFIG_EGA is not enabled. Since we are going to halt the
196 * CPU anyway, it is always better to at least try to print
197 * some hints.
198 *
199 * @param %esi Pointer to the NULL-terminated string
200 * to be print.
201 *
202 */
203pm_error_halt:
204 movl $0xb8000, %edi /* base of EGA text mode memory */
205 xorl %eax, %eax
206
207 /* Read bits 8 - 15 of the cursor address */
208 movw $0x3d4, %dx
209 movb $0xe, %al
210 outb %al, %dx
211
212 movw $0x3d5, %dx
213 inb %dx, %al
214 shl $8, %ax
215
216 /* Read bits 0 - 7 of the cursor address */
217 movw $0x3d4, %dx
218 movb $0xf, %al
219 outb %al, %dx
220
221 movw $0x3d5, %dx
222 inb %dx, %al
223
224 /* Sanity check for the cursor on screen */
225 cmp $2000, %ax
226 jb err_cursor_ok
227
228 movw $1998, %ax
229
230 err_cursor_ok:
231
232 movw %ax, %bx
233 shl $1, %eax
234 addl %eax, %edi
235
236 err_ploop:
237 lodsb
238
239 cmp $0, %al
240 je err_ploop_end
241
242 movb $0x0c, %ah /* black background, light red foreground */
243 stosw
244
245 /* Sanity check for the cursor on the last line */
246 inc %bx
247 cmp $2000, %bx
248 jb err_ploop
249
250 /* Scroll the screen (24 rows) */
251 movl %esi, %edx
252 movl $0xb80a0, %esi
253 movl $0xb8000, %edi
254 movl $960, %ecx
255 rep movsl
256
257 /* Clear the 24th row */
258 xorl %eax, %eax
259 movl $40, %ecx
260 rep stosl
261
262 /* Go to row 24 */
263 movl %edx, %esi
264 movl $0xb8f00, %edi
265 movw $1920, %bx
266
267 jmp err_ploop
268 err_ploop_end:
269
270 /* Write bits 8 - 15 of the cursor address */
271 movw $0x3d4, %dx
272 movb $0xe, %al
273 outb %al, %dx
274
275 movw $0x3d5, %dx
276 movb %bh, %al
277 outb %al, %dx
278
279 /* Write bits 0 - 7 of the cursor address */
280 movw $0x3d4, %dx
281 movb $0xf, %al
282 outb %al, %dx
283
284 movw $0x3d5, %dx
285 movb %bl, %al
286 outb %al, %dx
287
288 cli
289 hlt1:
290 hlt
291 jmp hlt1
292
293/** Print string to EGA display (in light green).
294 *
295 * Should be called from 32 bit protected mode with paging
296 * turned off. A stack space of at least 24 bytes is required,
297 * but the function does not establish a stack frame.
298 *
299 * Macros such as pm_status and pm2_status take care that
300 * this function is used only when CONFIG_EGA is enabled
301 * and CONFIG_FB is disabled.
302 *
303 * @param %esi Pointer to the NULL-terminated string
304 * to be print.
305 *
306 */
307pm_early_puts:
308 pushl %eax
309 pushl %ebx
310 pushl %ecx
311 pushl %edx
312 pushl %edi
313
314 movl $0xb8000, %edi /* base of EGA text mode memory */
315 xorl %eax, %eax
316
317 /* Read bits 8 - 15 of the cursor address */
318 movw $0x3d4, %dx
319 movb $0xe, %al
320 outb %al, %dx
321
322 movw $0x3d5, %dx
323 inb %dx, %al
324 shl $8, %ax
325
326 /* Read bits 0 - 7 of the cursor address */
327 movw $0x3d4, %dx
328 movb $0xf, %al
329 outb %al, %dx
330
331 movw $0x3d5, %dx
332 inb %dx, %al
333
334 /* Sanity check for the cursor on screen */
335 cmp $2000, %ax
336 jb pm_puts_cursor_ok
337
338 movw $1998, %ax
339
340 pm_puts_cursor_ok:
341
342 movw %ax, %bx
343 shl $1, %eax
344 addl %eax, %edi
345
346 pm_puts_ploop:
347 lodsb
348
349 cmp $0, %al
350 je pm_puts_ploop_end
351
352 movb $0x0a, %ah /* black background, light green foreground */
353 stosw
354
355 /* Sanity check for the cursor on the last line */
356 inc %bx
357 cmp $2000, %bx
358 jb pm_puts_ploop
359
360 /* Scroll the screen (24 rows) */
361 movl %esi, %edx
362 movl $0xb80a0, %esi
363 movl $0xb8000, %edi
364 movl $960, %ecx
365 rep movsl
366
367 /* Clear the 24th row */
368 xorl %eax, %eax
369 movl $40, %ecx
370 rep stosl
371
372 /* Go to row 24 */
373 movl %edx, %esi
374 movl $0xb8f00, %edi
375 movw $1920, %bx
376
377 jmp pm_puts_ploop
378 pm_puts_ploop_end:
379
380 /* Write bits 8 - 15 of the cursor address */
381 movw $0x3d4, %dx
382 movb $0xe, %al
383 outb %al, %dx
384
385 movw $0x3d5, %dx
386 movb %bh, %al
387 outb %al, %dx
388
389 /* Write bits 0 - 7 of the cursor address */
390 movw $0x3d4, %dx
391 movb $0xf, %al
392 outb %al, %dx
393
394 movw $0x3d5, %dx
395 movb %bl, %al
396 outb %al, %dx
397
398 popl %edi
399 popl %edx
400 popl %ecx
401 popl %ebx
402 popl %eax
403
404 ret
405
406.code64
407
408.macro long_status msg
409 pushq %rdi
410 movq \msg, %rdi
411 call early_puts
412 popq %rdi
413.endm
414
415start64:
416
417 /*
418 * Long mode.
419 */
420
421 movq $(PA2KA(START_STACK)), %rsp
422
423 /* Create the first stack frame */
424 pushq $0
425 movq %rsp, %rbp
426
427 long_status $status_long
428
429 /* Call amd64_pre_main(multiboot_eax, multiboot_ebx) */
430 movl multiboot_eax, %edi
431 movl multiboot_ebx, %esi
432
433#ifdef MEMORY_MODEL_large
434 movabsq $amd64_pre_main, %rax
435 callq *%rax
436#else
437 callq amd64_pre_main
438#endif
439
440 long_status $status_main
441
442 /* Call main_bsp() */
443#ifdef MEMORY_MODEL_large
444 movabsq $main_bsp, %rax
445 callq *%rax
446#else
447 callq main_bsp
448#endif
449
450 /* Not reached */
451 cli
452 hlt0:
453 hlt
454 jmp hlt0
455
456/** Print string to EGA display.
457 *
458 * Should be called from long mode (with paging enabled
459 * and stack established). This function is ABI compliant
460 * (without red-zone).
461 *
462 * If CONFIG_EGA is undefined or CONFIG_FB is defined
463 * then this function does nothing.
464 *
465 * @param %rdi Pointer to the NULL-terminated string
466 * to be printed.
467 *
468 */
469early_puts:
470
471#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
472
473 /* Prologue, save preserved registers */
474 pushq %rbp
475 movq %rsp, %rbp
476 pushq %rbx
477
478 movq %rdi, %rsi
479 movq $(PA2KA(0xb8000)), %rdi /* base of EGA text mode memory */
480 xorq %rax, %rax
481
482 /* Read bits 8 - 15 of the cursor address */
483 movw $0x3d4, %dx
484 movb $0xe, %al
485 outb %al, %dx
486
487 movw $0x3d5, %dx
488 inb %dx, %al
489 shl $8, %ax
490
491 /* Read bits 0 - 7 of the cursor address */
492 movw $0x3d4, %dx
493 movb $0xf, %al
494 outb %al, %dx
495
496 movw $0x3d5, %dx
497 inb %dx, %al
498
499 /* Sanity check for the cursor on screen */
500 cmp $2000, %ax
501 jb early_puts_cursor_ok
502
503 movw $1998, %ax
504
505 early_puts_cursor_ok:
506
507 movw %ax, %bx
508 shl $1, %rax
509 addq %rax, %rdi
510
511 early_puts_ploop:
512 lodsb
513
514 cmp $0, %al
515 je early_puts_ploop_end
516
517 movb $0x0e, %ah /* black background, yellow foreground */
518 stosw
519
520 /* Sanity check for the cursor on the last line */
521 inc %bx
522 cmp $2000, %bx
523 jb early_puts_ploop
524
525 /* Scroll the screen (24 rows) */
526 movq %rsi, %rdx
527 movq $(PA2KA(0xb80a0)), %rsi
528 movq $(PA2KA(0xb8000)), %rdi
529 movl $480, %ecx
530 rep movsq
531
532 /* Clear the 24th row */
533 xorl %eax, %eax
534 movl $20, %ecx
535 rep stosq
536
537 /* Go to row 24 */
538 movq %rdx, %rsi
539 movq $(PA2KA(0xb8f00)), %rdi
540 movw $1920, %bx
541
542 jmp early_puts_ploop
543 early_puts_ploop_end:
544
545 /* Write bits 8 - 15 of the cursor address */
546 movw $0x3d4, %dx
547 movb $0xe, %al
548 outb %al, %dx
549
550 movw $0x3d5, %dx
551 movb %bh, %al
552 outb %al, %dx
553
554 /* Write bits 0 - 7 of the cursor address */
555 movw $0x3d4, %dx
556 movb $0xf, %al
557 outb %al, %dx
558
559 movw $0x3d5, %dx
560 movb %bl, %al
561 outb %al, %dx
562
563 /* Epilogue, restore preserved registers */
564 popq %rbx
565 leave
566
567#endif
568
569 ret
570
571#include "vesa_real.inc"
572
573.section K_INI_PTLS, "aw", @progbits
574
575/** Generate initial page table contents.
576 *
577 * @param cnt Number of entries to generate. Must be multiple of 8.
578 * @param g Number of GB that will be added to the mapping.
579 *
580 */
581.macro ptl2gen cnt g
582 .if \cnt
583 ptl2gen "\cnt - 8" \g
584 .quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
585 .quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
586 .quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
587 .quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
588 .quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
589 .quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
590 .quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
591 .quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
592 .endif
593.endm
594
595/* Page table for pages in the 1st gigabyte. */
596.align 4096
597ptl_2_0g:
598 ptl2gen 512 0
599
600/* Page table for pages in the 2nd gigabyte. */
601.align 4096
602ptl_2_1g:
603 ptl2gen 512 1
604
605/* Page table for pages in the 3rd gigabyte. */
606.align 4096
607ptl_2_2g:
608 ptl2gen 512 2
609
610/* Page table for pages in the 4th gigabyte. */
611.align 4096
612ptl_2_3g:
613 ptl2gen 512 3
614
615/* Page table for pages in the 5th gigabyte. */
616.align 4096
617ptl_2_4g:
618 ptl2gen 512 4
619
620/* Page table for pages in the 6th gigabyte. */
621.align 4096
622ptl_2_5g:
623 ptl2gen 512 5
624
625/* Page table for pages in the 7th gigabyte. */
626.align 4096
627ptl_2_6g:
628 ptl2gen 512 6
629
630/* Page table for pages in the 8th gigabyte. */
631.align 4096
632ptl_2_7g:
633 ptl2gen 512 7
634
635#ifdef MEMORY_MODEL_kernel
636.align 4096
637ptl_1:
638 /* Identity mapping for [0; 8G) */
639 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
640 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
641 .quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT)
642 .quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT)
643 .quad ptl_2_4g + (PTL_WRITABLE | PTL_PRESENT)
644 .quad ptl_2_5g + (PTL_WRITABLE | PTL_PRESENT)
645 .quad ptl_2_6g + (PTL_WRITABLE | PTL_PRESENT)
646 .quad ptl_2_7g + (PTL_WRITABLE | PTL_PRESENT)
647 .fill 502, 8, 0
648 /* Mapping of [0; 2G) at -2G */
649 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
650 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
651
652.align 4096
653SYMBOL(ptl_0)
654 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
655 .fill 510, 8, 0
656 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
657#endif
658
659#ifdef MEMORY_MODEL_large
660.align 4096
661ptl_1:
662 /* Identity mapping for [0; 8G) */
663 .quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
664 .quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
665 .quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT)
666 .quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT)
667 .quad ptl_2_4g + (PTL_WRITABLE | PTL_PRESENT)
668 .quad ptl_2_5g + (PTL_WRITABLE | PTL_PRESENT)
669 .quad ptl_2_6g + (PTL_WRITABLE | PTL_PRESENT)
670 .quad ptl_2_7g + (PTL_WRITABLE | PTL_PRESENT)
671 .fill 504, 8, 0
672
673.align 4096
674SYMBOL(ptl_0)
675 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
676 .fill 255, 8, 0
677 .quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
678 .fill 255, 8, 0
679#endif
680
681.section K_DATA_START, "aw", @progbits
682
683SYMBOL(bootstrap_idtr)
684 .word 0
685 .long 0
686
687SYMBOL(bootstrap_gdtr)
688 .word GDT_SELECTOR(GDT_ITEMS)
689 .long KA2PA(gdt)
690
691SYMBOL(multiboot_eax)
692 .long 0
693
694SYMBOL(multiboot_ebx)
695 .long 0
696
697err_extended_cpuid:
698 .asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
699err_long_mode:
700 .asciz "Error: 64-bit long mode not supported. System halted."
701err_noexecute:
702 .asciz "Error: No-execute pages not supported. System halted."
703err_fx:
704 .asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
705err_sse2:
706 .asciz "Error: SSE2 instructions not supported. System halted."
707
708status_prot:
709 .asciz "[prot] "
710status_vesa_copy:
711 .asciz "[vesa_copy] "
712status_multiboot_cmdline:
713 .asciz "[multiboot_cmdline] "
714status_vesa_real:
715 .asciz "[vesa_real] "
716status_prot2:
717 .asciz "[prot2] "
718status_long:
719 .asciz "[long] "
720status_main:
721 .asciz "[main] "
Note: See TracBrowser for help on using the repository browser.