xref: /openbmc/qemu/tests/tcg/i386/system/boot.S (revision d316f1b14615854de1bf4c0a9789e9c8951cc437)
140d6ee94SAlex Bennée/*
240d6ee94SAlex Bennée * i386 boot code, based on  qemu-bmibug.
340d6ee94SAlex Bennée *
440d6ee94SAlex Bennée * Copyright 2019 Doug Gale
5*542b10bdSAlex Bennée * Copyright 2019, 2024 Linaro
640d6ee94SAlex Bennée *
7*542b10bdSAlex Bennée * This work is licensed under the terms of the GNU GPL, version 2 or later.
840d6ee94SAlex Bennée * See the COPYING file in the top-level directory.
940d6ee94SAlex Bennée *
10*542b10bdSAlex Bennée * SPDX-License-Identifier: GPL-2.0-or-later
1140d6ee94SAlex Bennée */
1240d6ee94SAlex Bennée
1340d6ee94SAlex Bennée        .section .head
1440d6ee94SAlex Bennée
1540d6ee94SAlex Bennée        /* Multi-boot header */
1640d6ee94SAlex Bennéemultiboot_st:
1740d6ee94SAlex Bennée        .int 0x1BADB002
1840d6ee94SAlex Bennée        .int 0x10000
1940d6ee94SAlex Bennée        .int -(0x10000+0x1BADB002)
2040d6ee94SAlex Bennée        // Load address
2140d6ee94SAlex Bennée        .int __load_st
2240d6ee94SAlex Bennée        .int __load_st
2340d6ee94SAlex Bennée        .int __load_en
2440d6ee94SAlex Bennée        .int __bss_en
2540d6ee94SAlex Bennée        .int _start
2640d6ee94SAlex Bennée        // mode
2740d6ee94SAlex Bennée        .int 0
2840d6ee94SAlex Bennée        // width
2940d6ee94SAlex Bennée        .int 0
3040d6ee94SAlex Bennée        // height
3140d6ee94SAlex Bennée        .int 0
3240d6ee94SAlex Bennée        // depth
3340d6ee94SAlex Bennée        .int 0
3440d6ee94SAlex Bennée
3540d6ee94SAlex Bennée        .code32
3640d6ee94SAlex Bennée        .section .text
3740d6ee94SAlex Bennée
3840d6ee94SAlex Bennée        /* Kernel Entry Point */
3940d6ee94SAlex Bennée.global _start
4040d6ee94SAlex Bennée_start:
4140d6ee94SAlex Bennée        // Setup stack ASAP
4240d6ee94SAlex Bennée        mov $stack_end,%esp
4340d6ee94SAlex Bennée
4440d6ee94SAlex Bennée        // Load GDT ASAP
4540d6ee94SAlex Bennée        lgdt gdtr
4640d6ee94SAlex Bennée        ljmp $0x8,$.Lloadcs
4740d6ee94SAlex Bennée.Lloadcs:
4840d6ee94SAlex Bennée        mov $0x10,%eax
4940d6ee94SAlex Bennée        mov %eax,%ds
5040d6ee94SAlex Bennée        mov %eax,%es
5140d6ee94SAlex Bennée        mov %eax,%fs
5240d6ee94SAlex Bennée        mov %eax,%gs
5340d6ee94SAlex Bennée        mov %eax,%ss
5440d6ee94SAlex Bennée
5540d6ee94SAlex Bennée        // Fixup the IDT to the ridiculous i386 layout
5640d6ee94SAlex Bennée        xor %ebx,%ebx
5740d6ee94SAlex Bennée.Lnextidt:
5840d6ee94SAlex Bennée        mov idt_00(,%ebx,8),%eax
5940d6ee94SAlex Bennée        shr $16,%eax
6040d6ee94SAlex Bennée        movw $0x8,idt_00+2(,%ebx,8)
6140d6ee94SAlex Bennée        movw $0x8E00,idt_00+4(,%ebx,8)
6240d6ee94SAlex Bennée        movw %ax,idt_00+6(,%ebx,8)
6340d6ee94SAlex Bennée        add $1,%ebx
6440d6ee94SAlex Bennée        cmp $32,%ebx
6540d6ee94SAlex Bennée        jl .Lnextidt
6640d6ee94SAlex Bennée
6740d6ee94SAlex Bennée        // Load IDTR
6840d6ee94SAlex Bennée        push $idt_00
6940d6ee94SAlex Bennée        push $((32 * 8 - 1) << 16)
7040d6ee94SAlex Bennée        lidt 2(%esp)
7140d6ee94SAlex Bennée        add $8,%esp
7240d6ee94SAlex Bennée
7340d6ee94SAlex Bennée        /*
74bad5cfcdSMichael Tokarev         * Don't worry about stack frame, assume everything
7540d6ee94SAlex Bennée         * is garbage when we return, we won't need it.
7640d6ee94SAlex Bennée         */
7740d6ee94SAlex Bennée        call main
7840d6ee94SAlex Bennée
79c00506aaSAlex Bennée_exit:	/* output any non-zero result in eax to isa-debug-exit device */
8040d6ee94SAlex Bennée        test %al, %al
8140d6ee94SAlex Bennée        jz 1f
8240d6ee94SAlex Bennée        out %ax, $0xf4
8340d6ee94SAlex Bennée
8440d6ee94SAlex Bennée1:      /* QEMU ACPI poweroff */
8540d6ee94SAlex Bennée        mov $0x604,%edx
8640d6ee94SAlex Bennée        mov $0x2000,%eax
8740d6ee94SAlex Bennée        out %ax,%dx
8840d6ee94SAlex Bennée        hlt
8940d6ee94SAlex Bennée        jmp 1b
9040d6ee94SAlex Bennée
9140d6ee94SAlex Bennée        /*
9240d6ee94SAlex Bennée         * Helper Functions
9340d6ee94SAlex Bennée         */
9440d6ee94SAlex Bennée
9540d6ee94SAlex Bennée        /* Output a single character to serial port */
9640d6ee94SAlex Bennée        .global __sys_outc
9740d6ee94SAlex Bennée__sys_outc:
9840d6ee94SAlex Bennée        pushl %ebp
9940d6ee94SAlex Bennée        movl %esp, %ebp
10040d6ee94SAlex Bennée        out %al,$0xE9
10140d6ee94SAlex Bennée        movl %ebp, %esp
10240d6ee94SAlex Bennée        popl %ebp
10340d6ee94SAlex Bennée        ret
10440d6ee94SAlex Bennée
10540d6ee94SAlex Bennée
10640d6ee94SAlex Bennée        /* Interrupt Descriptor Table */
10740d6ee94SAlex Bennée
10840d6ee94SAlex Bennée        .section .data
10940d6ee94SAlex Bennée        .align 16
11040d6ee94SAlex Bennée
11140d6ee94SAlex Bennéeidt_00: .int 0, 0
11240d6ee94SAlex Bennéeidt_01: .int 0, 0
11340d6ee94SAlex Bennéeidt_02: .int 0, 0
11440d6ee94SAlex Bennéeidt_03: .int 0, 0
11540d6ee94SAlex Bennéeidt_04: .int 0, 0
11640d6ee94SAlex Bennéeidt_05: .int 0, 0
11740d6ee94SAlex Bennéeidt_06: .int 0, 0 /* intr_6_opcode, Invalid Opcode */
11840d6ee94SAlex Bennéeidt_07: .int 0, 0
11940d6ee94SAlex Bennéeidt_08: .int 0, 0
12040d6ee94SAlex Bennéeidt_09: .int 0, 0
12140d6ee94SAlex Bennéeidt_0A: .int 0, 0
12240d6ee94SAlex Bennéeidt_0B: .int 0, 0
12340d6ee94SAlex Bennéeidt_0C: .int 0, 0
12440d6ee94SAlex Bennéeidt_0D: .int 0, 0
12540d6ee94SAlex Bennéeidt_0E: .int 0, 0
12640d6ee94SAlex Bennéeidt_0F: .int 0, 0
12740d6ee94SAlex Bennéeidt_10: .int 0, 0
12840d6ee94SAlex Bennéeidt_11: .int 0, 0
12940d6ee94SAlex Bennéeidt_12: .int 0, 0
13040d6ee94SAlex Bennéeidt_13: .int 0, 0
13140d6ee94SAlex Bennéeidt_14: .int 0, 0
13240d6ee94SAlex Bennéeidt_15: .int 0, 0
13340d6ee94SAlex Bennéeidt_16: .int 0, 0
13440d6ee94SAlex Bennéeidt_17: .int 0, 0
13540d6ee94SAlex Bennéeidt_18: .int 0, 0
13640d6ee94SAlex Bennéeidt_19: .int 0, 0
13740d6ee94SAlex Bennéeidt_1A: .int 0, 0
13840d6ee94SAlex Bennéeidt_1B: .int 0, 0
13940d6ee94SAlex Bennéeidt_1C: .int 0, 0
14040d6ee94SAlex Bennéeidt_1D: .int 0, 0
14140d6ee94SAlex Bennéeidt_1E: .int 0, 0
14240d6ee94SAlex Bennéeidt_1F: .int 0, 0
14340d6ee94SAlex Bennée
14440d6ee94SAlex Bennéegdt:
14540d6ee94SAlex Bennée        .short 0
14640d6ee94SAlex Bennéegdtr:
14740d6ee94SAlex Bennée        .short gdt_en - gdt - 1
14840d6ee94SAlex Bennée        .int gdt
14940d6ee94SAlex Bennée
15040d6ee94SAlex Bennée        // Code
15140d6ee94SAlex Bennée        .short 0xFFFF
15240d6ee94SAlex Bennée        .short 0
15340d6ee94SAlex Bennée        .byte 0
15440d6ee94SAlex Bennée        .byte 0x9b
15540d6ee94SAlex Bennée        .byte 0xCF
15640d6ee94SAlex Bennée        .byte 0
15740d6ee94SAlex Bennée
15840d6ee94SAlex Bennée        // Data
15940d6ee94SAlex Bennée        .short 0xFFFF
16040d6ee94SAlex Bennée        .short 0
16140d6ee94SAlex Bennée        .byte 0
16240d6ee94SAlex Bennée        .byte 0x93
16340d6ee94SAlex Bennée        .byte 0xCF
16440d6ee94SAlex Bennée        .byte 0
16540d6ee94SAlex Bennée
16640d6ee94SAlex Bennéegdt_en:
16740d6ee94SAlex Bennée
16840d6ee94SAlex Bennée        .section .bss
16940d6ee94SAlex Bennée        .align 16
17040d6ee94SAlex Bennée
17140d6ee94SAlex Bennéestack: .space 65536
17240d6ee94SAlex Bennéestack_end:
173