qemu/tests/tcg/i386/system/boot.S
<<
>>
Prefs
   1/*
   2 * i386 boot code, based on  qemu-bmibug.
   3 *
   4 * Copyright 2019 Doug Gale
   5 * Copyright 2019 Linaro
   6 *
   7 * This work is licensed under the terms of the GNU GPL, version 3 or later.
   8 * See the COPYING file in the top-level directory.
   9 *
  10 * SPDX-License-Identifier: GPL-3.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 everthing
  75         * is garbage when we return, we won't need it.
  76         */
  77        call main
  78
  79        /* 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