xref: /qemu/tests/tcg/i386/system/boot.S (revision 7653b1ea)
1/*
2 * i386 boot code, based on  qemu-bmibug.
3 *
4 * Copyright 2019 Doug Gale
5 * Copyright 2019, 2024 Linaro
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13        .section .head
14
15        /* Multi-boot header */
16multiboot_st:
17        .int 0x1BADB002
18        .int 0x10000
19        .int -(0x10000+0x1BADB002)
20        // Load address
21        .int __load_st
22        .int __load_st
23        .int __load_en
24        .int __bss_en
25        .int _start
26        // mode
27        .int 0
28        // width
29        .int 0
30        // height
31        .int 0
32        // depth
33        .int 0
34
35        .code32
36        .section .text
37
38        /* Kernel Entry Point */
39.global _start
40_start:
41        // Setup stack ASAP
42        mov $stack_end,%esp
43
44        // Load GDT ASAP
45        lgdt gdtr
46        ljmp $0x8,$.Lloadcs
47.Lloadcs:
48        mov $0x10,%eax
49        mov %eax,%ds
50        mov %eax,%es
51        mov %eax,%fs
52        mov %eax,%gs
53        mov %eax,%ss
54
55        // Fixup the IDT to the ridiculous i386 layout
56        xor %ebx,%ebx
57.Lnextidt:
58        mov idt_00(,%ebx,8),%eax
59        shr $16,%eax
60        movw $0x8,idt_00+2(,%ebx,8)
61        movw $0x8E00,idt_00+4(,%ebx,8)
62        movw %ax,idt_00+6(,%ebx,8)
63        add $1,%ebx
64        cmp $32,%ebx
65        jl .Lnextidt
66
67        // Load IDTR
68        push $idt_00
69        push $((32 * 8 - 1) << 16)
70        lidt 2(%esp)
71        add $8,%esp
72
73        /*
74         * Don't worry about stack frame, assume everything
75         * is garbage when we return, we won't need it.
76         */
77        call main
78
79_exit:	/* output any non-zero result in eax to isa-debug-exit device */
80        test %al, %al
81        jz 1f
82        out %ax, $0xf4
83
841:      /* QEMU ACPI poweroff */
85        mov $0x604,%edx
86        mov $0x2000,%eax
87        out %ax,%dx
88        hlt
89        jmp 1b
90
91        /*
92         * Helper Functions
93         */
94
95        /* Output a single character to serial port */
96        .global __sys_outc
97__sys_outc:
98        pushl %ebp
99        movl %esp, %ebp
100        out %al,$0xE9
101        movl %ebp, %esp
102        popl %ebp
103        ret
104
105
106        /* Interrupt Descriptor Table */
107
108        .section .data
109        .align 16
110
111idt_00: .int 0, 0
112idt_01: .int 0, 0
113idt_02: .int 0, 0
114idt_03: .int 0, 0
115idt_04: .int 0, 0
116idt_05: .int 0, 0
117idt_06: .int 0, 0 /* intr_6_opcode, Invalid Opcode */
118idt_07: .int 0, 0
119idt_08: .int 0, 0
120idt_09: .int 0, 0
121idt_0A: .int 0, 0
122idt_0B: .int 0, 0
123idt_0C: .int 0, 0
124idt_0D: .int 0, 0
125idt_0E: .int 0, 0
126idt_0F: .int 0, 0
127idt_10: .int 0, 0
128idt_11: .int 0, 0
129idt_12: .int 0, 0
130idt_13: .int 0, 0
131idt_14: .int 0, 0
132idt_15: .int 0, 0
133idt_16: .int 0, 0
134idt_17: .int 0, 0
135idt_18: .int 0, 0
136idt_19: .int 0, 0
137idt_1A: .int 0, 0
138idt_1B: .int 0, 0
139idt_1C: .int 0, 0
140idt_1D: .int 0, 0
141idt_1E: .int 0, 0
142idt_1F: .int 0, 0
143
144gdt:
145        .short 0
146gdtr:
147        .short gdt_en - gdt - 1
148        .int gdt
149
150        // Code
151        .short 0xFFFF
152        .short 0
153        .byte 0
154        .byte 0x9b
155        .byte 0xCF
156        .byte 0
157
158        // Data
159        .short 0xFFFF
160        .short 0
161        .byte 0
162        .byte 0x93
163        .byte 0xCF
164        .byte 0
165
166gdt_en:
167
168        .section .bss
169        .align 16
170
171stack: .space 65536
172stack_end:
173