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