Add tool for generating assembler offset definition file.
[seabios.git] / src / romlayout.S
index 6eda03681874de5b0906854b051e2f5a49de9f90..a6bad458d7ccf25d938cb0ce89abb308e9fbca12 100644 (file)
@@ -5,12 +5,10 @@
 //
 // This file may be distributed under the terms of the GNU GPLv3 license.
 
-#include "config.h"
-
-#define PROTECTED_MODE_CS (2 << 3) // 0x10
-#define PROTECTED_MODE_DS (3 << 3) // 0x18
-#define REAL_MODE_CS      (4 << 3) // 0x20
-#define REAL_MODE_DS      (5 << 3) // 0x28
+#include "config.h" // CONFIG_*
+#include "ioport.h" // PORT_A20
+#include "bregs.h" // CR0_*
+#include "../out/asm-offsets.h" // BREGS_*
 
 
 /****************************************************************
 
         ORG 0xe05b
 post16:
+        // enable cache
+        movl %cr0, %eax
+        andl $~(CR0_CD|CR0_NW), %eax
+        movl %eax, %cr0
+
         // init the stack pointer
         RESET_STACK
 
@@ -145,26 +148,26 @@ transition32:
         cli
 
         // enable a20
-        inb $0x92, %al
-        orb $0x02, %al
-        outb %al, $0x92
+        inb $PORT_A20, %al
+        orb $A20_ENABLE_BIT, %al
+        outb %al, $PORT_A20
 
         // Set segment descriptors
         lidt %cs:pmode_IDT_info
         lgdt %cs:rombios32_gdt_48
 
-        // set PE bit in CR0
-        movl  %cr0, %eax
-        orb   $0x01, %al
-        movl  %eax, %cr0
+        // Enable protected mode
+        movl %cr0, %eax
+        orl $CR0_PE, %eax
+        movl %eax, %cr0
 
         // start protected mode code
-        ljmpl $PROTECTED_MODE_CS, $(BUILD_BIOS_ADDR + 1f)
+        ljmpl $SEG32_MODE32_CS, $(BUILD_BIOS_ADDR + 1f)
 
         .code32
 1:
         // init data segments
-        movl $PROTECTED_MODE_DS, %eax
+        movl $SEG32_MODE32_DS, %eax
         movw %ax, %ds
         movw %ax, %es
         movw %ax, %ss
@@ -181,22 +184,27 @@ transition32:
 __call16_from32:
         pushl %eax
 
-        // Jump to 16bit mode
-        ljmpw $REAL_MODE_CS, $1f
-
-        .code16gcc
-1:
         // restore data segment limits to 0xffff
-        movw $REAL_MODE_DS, %ax
+        movw $SEG32_MODE16_DS, %ax
         movw %ax, %ds
         movw %ax, %es
         movw %ax, %ss
         movw %ax, %fs
         movw %ax, %gs
 
-        // reset PE bit in CR0
+        // disable a20
+        inb $PORT_A20, %al
+        andb $~A20_ENABLE_BIT, %al
+        outb %al, $PORT_A20
+
+        // Jump to 16bit mode
+        ljmpw $SEG32_MODE16_CS, $1f
+
+        .code16gcc
+1:
+        // Disable protected mode
         movl %cr0, %eax
-        andb $0xfe, %al
+        andl $~CR0_PE, %eax
         movl %eax, %cr0
 
         // far jump to flush CPU queue after transition to real mode
@@ -233,17 +241,18 @@ __call16:
         // Setup for iretw call
         pushw $SEG_BIOS
         pushw $1f               // return point
-        pushw 0x20(%eax)        // flags
-        pushl 0x1c(%eax)        // CS:IP
+        pushw BREGS_flags(%eax) // flags
+        pushl BREGS_ip(%eax)    // CS:IP
 
         // Load calling registers.
-        movl 0x04(%eax), %edi
-        movl 0x08(%eax), %esi
-        movl 0x0c(%eax), %ebx
-        movl 0x10(%eax), %edx
-        movl 0x14(%eax), %ecx
-        movw 0x02(%eax), %es    // XXX - should load %ds too
-        movl 0x18(%eax), %eax
+        movl BREGS_edi(%eax), %edi
+        movl BREGS_esi(%eax), %esi
+        movl BREGS_ebx(%eax), %ebx
+        movl BREGS_edx(%eax), %edx
+        movl BREGS_ecx(%eax), %ecx
+        movw BREGS_es(%eax), %es
+        movw BREGS_ds(%eax), %ds
+        movl %ss:BREGS_eax(%eax), %eax
 
         // Invoke call
         iretw                   // XXX - just do a lcalll
@@ -252,20 +261,21 @@ __call16:
         pushfw
         pushl %eax
         movl 0x06(%esp), %eax
-        movl %ecx, %ss:0x14(%eax)       // Save %ecx
+        movl %ecx, %ss:BREGS_ecx(%eax)
+        movw %ds, %ss:BREGS_ds(%eax)
         movw %ss, %cx
-        movw %cx, %ds                   // Restore %ds == %ss
+        movw %cx, %ds           // Restore %ds == %ss
         popl %ecx
-        movl %ecx, 0x18(%eax)           // Save %eax
+        movl %ecx, BREGS_eax(%eax)
         popw %cx
-        movw %cx, 0x20(%eax)            // Save flags
+        movw %cx, BREGS_flags(%eax)
 
         // Store remaining registers
-        movw %es, 0x02(%eax)
-        movl %edi, 0x04(%eax)
-        movl %esi, 0x08(%eax)
-        movl %ebx, 0x0c(%eax)
-        movl %edx, 0x10(%eax)
+        movw %es, BREGS_es(%eax)
+        movl %edi, BREGS_edi(%eax)
+        movl %esi, BREGS_esi(%eax)
+        movl %ebx, BREGS_ebx(%eax)
+        movl %edx, BREGS_edx(%eax)
 
         // Remove %eax
         popl %eax
@@ -314,10 +324,20 @@ post32:
         lidtl (BUILD_BIOS_ADDR + pmode_IDT_info)
         lgdtl (BUILD_BIOS_ADDR + rombios32_gdt_48)
         movl $BUILD_STACK_ADDR, %esp
-        ljmpl $PROTECTED_MODE_CS, $_code32__start
+        ljmpl $SEG32_MODE32_CS, $_code32__start
 
         .code16gcc
 
+// Shutdown a CPU.  We want this in the 0xf000 section to ensure that
+// the code wont be overwritten with something else.  (Should
+// something spurious wake up the CPU, we want to be sure that the hlt
+// insn will still be present and will shutdown the CPU.)
+        .global permanent_halt
+permanent_halt:
+        cli
+1:      hlt
+        jmp 1b
+
 
 /****************************************************************
  * GDT and IDT tables
@@ -354,13 +374,13 @@ rombios32_gdt_48:
 rombios32_gdt:
         .word 0, 0, 0, 0
         .word 0, 0, 0, 0
-        // 32 bit flat code segment (PROTECTED_MODE_CS)
+        // 32 bit flat code segment (SEG32_MODE32_CS)
         .word 0xffff, 0, 0x9b00, 0x00cf
-        // 32 bit flat data segment (PROTECTED_MODE_DS)
+        // 32 bit flat data segment (SEG32_MODE32_DS)
         .word 0xffff, 0, 0x9300, 0x00cf
-        // 16 bit code segment base=0xf0000 limit=0xffff (REAL_MODE_CS)
+        // 16 bit code segment base=0xf0000 limit=0xffff (SEG32_MODE16_CS)
         .word 0xffff, 0, 0x9b0f, 0x0000
-        // 16 bit data segment base=0x0 limit=0xffff (REAL_MODE_DS)
+        // 16 bit data segment base=0x0 limit=0xffff (SEG32_MODE16_DS)
         .word 0xffff, 0, 0x9300, 0x0000
 
 // We need a copy of this string in the 0xf000 segment, but we are not