Don't pass in ebp/esp to irq handlers.
authorKevin O'Connor <kevin@koconnor.net>
Wed, 12 Mar 2008 01:21:47 +0000 (21:21 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 12 Mar 2008 01:21:47 +0000 (21:21 -0400)
The C code won't clobber these registers, so backing them up isn't needed.
Removing them saves a few bytes on the stack.

TODO
src/biosvar.h
src/output.c
src/romlayout.S

diff --git a/TODO b/TODO
index e9c9d86..c19b5a8 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,9 +4,7 @@ setup properly with respect to irqs.
 Audit statements where a 32bit intermediary changes meaning of a 16bit
 comparison.
 
-Look into ways to reduce stack usage.  For example, %esp, %ebp, %esi
-(high bits), %edi (high bits) are already restored by the C code if
-they're changed - they probably don't need to be backed up on entry.
+Look into ways to reduce stack usage.
 
 Code assumes ebda segment is static - it doesn't read 0x40e.
 
index 4def7f3..36794c3 100644 (file)
@@ -287,13 +287,14 @@ struct ipl_s {
 
 #define UREG(ER, R, RH, RL) union { u32 ER; struct { u16 R; u16 R ## _hi; }; struct { u8 RL; u8 RH; u8 R ## _hilo; u8 R ## _hihi; }; }
 
+// Layout of registers passed in to irq handlers.  Note that this
+// layout corresponds to code in romlayout.S - don't change it here
+// without also updating the assembler code.
 struct bregs {
     u16 ds;
     u16 es;
     UREG(edi, di, di_hi, di_lo);
     UREG(esi, si, si_hi, si_lo);
-    UREG(ebp, bp, bp_hi, bp_lo);
-    UREG(esp, sp, sp_hi, sp_lo);
     UREG(ebx, bx, bh, bl);
     UREG(edx, dx, dh, dl);
     UREG(ecx, cx, ch, cl);
index 760ea41..0336610 100644 (file)
@@ -178,8 +178,8 @@ dump_regs(const char *fname, const char *type, struct bregs *regs)
     bprintf(0, "%s %s: a=%x b=%x c=%x d=%x si=%x di=%x\n"
             , type, fname, regs->eax, regs->ebx, regs->ecx, regs->edx
             , regs->esi, regs->edi);
-    bprintf(0, "  ds=%x es=%x bp=%x sp=%x ip=%x cs=%x f=%x\n"
-            , regs->ds, regs->es, regs->ebp, regs->esp
+    bprintf(0, "  ds=%x es=%x ip=%x cs=%x f=%x\n"
+            , regs->ds, regs->es
             , regs->ip, regs->cs, regs->flags);
 }
 
index d525345..2fd0f83 100644 (file)
@@ -27,9 +27,58 @@ bios16c_end:
 
 
 /****************************************************************
- * POST handler
+ * Entry macros
  ****************************************************************/
 
+        // Call a C function - this does the minimal work necessary to
+        // call into C.  It sets up %ds, backs up %es, and backs up
+        // those registers that are call clobbered by the C compiler.
+        .macro ENTRY cfunc
+        cld
+        pushl %eax
+        pushl %ecx
+        pushl %edx
+        pushw %es
+        pushw %ds
+        movw %ss, %ax
+        movw %ax, %ds
+        calll \cfunc
+        popw %ds
+        popw %es
+        popl %edx
+        popl %ecx
+        popl %eax
+        .endm
+
+        // Call a C function with current register list as an
+        // argument.  This backs up the registers and sets %eax
+        // to point to the backup.  On return, the registers are
+        // restored from the structure.
+        .macro ENTRY_ARG cfunc
+        cld
+        pushl %eax
+        pushl %ecx
+        pushl %edx
+        pushl %ebx
+        pushl %esi
+        pushl %edi
+        pushw %es
+        pushw %ds
+        movw %ss, %ax
+        movw %ax, %ds
+        movzwl %sp, %esp
+        movl %esp, %eax
+        calll \cfunc
+        popw %ds
+        popw %es
+        popl %edi
+        popl %esi
+        popl %ebx
+        popl %edx
+        popl %ecx
+        popl %eax
+        .endm
+
         // Macro to reset the 16bit stack
         // Clobbers %ax
         .macro RESET_STACK
@@ -38,6 +87,11 @@ bios16c_end:
         movl $ CONFIG_STACK_OFFSET , %esp
         .endm
 
+
+/****************************************************************
+ * POST handler
+ ****************************************************************/
+
         .org 0xe05b
         .globl post16
 post16:
@@ -153,18 +207,17 @@ __call16:
         // Setup for iretw call
         pushw $0xf000
         pushw $1f               // return point
-        pushw 0x28(%eax)        // flags
-        pushl 0x24(%eax)        // CS:IP
+        pushw 0x20(%eax)        // flags
+        pushl 0x1c(%eax)        // CS:IP
 
         // Load calling registers.
         movl 0x04(%eax), %edi
         movl 0x08(%eax), %esi
-        movl 0x0c(%eax), %ebp
-        movl 0x14(%eax), %ebx
-        movl 0x18(%eax), %edx
-        movl 0x1c(%eax), %ecx
+        movl 0x0c(%eax), %ebx
+        movl 0x10(%eax), %edx
+        movl 0x14(%eax), %ecx
         movw 0x02(%eax), %es    // XXX - should load %ds too
-        movl 0x20(%eax), %eax
+        movl 0x18(%eax), %eax
 
         // Invoke call
         iretw                   // XXX - just do a lcalll
@@ -173,21 +226,20 @@ __call16:
         pushfw
         pushl %eax
         movl 0x06(%esp), %eax
-        movl %ecx, %ss:0x1c(%eax)       // Save %ecx
+        movl %ecx, %ss:0x14(%eax)       // Save %ecx
         movw %ss, %cx
         movw %cx, %ds                   // Restore %ds == %ss
         popl %ecx
-        movl %ecx, 0x20(%eax)           // Save %eax
+        movl %ecx, 0x18(%eax)           // Save %eax
         popw %cx
-        movw %cx, 0x28(%eax)            // Save flags
+        movw %cx, 0x20(%eax)            // Save flags
 
         // Store remaining registers
         movw %es, 0x02(%eax)
         movl %edi, 0x04(%eax)
         movl %esi, 0x08(%eax)
-        movl %ebp, 0x0c(%eax)
-        movl %ebx, 0x14(%eax)
-        movl %edx, 0x18(%eax)
+        movl %ebx, 0x0c(%eax)
+        movl %edx, 0x10(%eax)
 
         // Remove %eax
         popl %eax
@@ -196,6 +248,32 @@ __call16:
 
         retl
 
+        // APM trampolines
+        .globl apm16protected_entry
+apm16protected_entry:
+        pushfw          // save flags
+        pushl %eax      // dummy
+        ENTRY_ARG handle_1553
+        addw $4, %sp    // pop dummy
+        popfw           // restore flags
+        lretw
+
+        .code32
+        .globl apm32protected_entry
+apm32protected_entry:
+        pushfw          // save flags
+        pushw %cs       // Setup for long jump to 16bitmode
+        incw (%esp)
+        pushw 1f
+        lcallw *(%esp)
+        addl $4, %esp   // pop call address
+        popfw
+        lretl
+        .code16gcc
+1:                      // 16bit entry point for apm32 code.
+        ENTRY_ARG handle_1553
+        lretw
+
 
 /****************************************************************
  * GDT and IDT tables
@@ -246,45 +324,6 @@ rombios32_gdt:
  * Interrupt entry points
  ****************************************************************/
 
-        // Call a C function - this does the minimal work necessary to
-        // call into C.  It sets up %ds, backs up %es, and backs up
-        // those registers that are call clobbered by the C compiler.
-        .macro ENTRY cfunc
-        cld
-        pushl %eax
-        pushl %ecx
-        pushl %edx
-        pushw %es
-        pushw %ds
-        movw %ss, %ax
-        movw %ax, %ds
-        calll \cfunc
-        popw %ds
-        popw %es
-        popl %edx
-        popl %ecx
-        popl %eax
-        .endm
-
-        // Call a C function with current register list as an
-        // argument.  This backs up the registers and sets %eax
-        // to point to the backup.  On return, the registers are
-        // restored from the structur.
-        .macro ENTRY_ARG cfunc
-        cld
-        pushal
-        pushw %es
-        pushw %ds
-        movw %ss, %ax
-        movw %ax, %ds
-        movzwl %sp, %esp
-        movl %esp, %eax
-        calll \cfunc
-        popw %ds
-        popw %es
-        popal
-        .endm
-
         // Define an entry point for an interrupt (no args passed).
         .macro IRQ_ENTRY num
         .globl entry_\num
@@ -303,32 +342,6 @@ rombios32_gdt:
         iretw
         .endm
 
-        // APM trampolines
-        .globl apm16protected_entry
-apm16protected_entry:
-        pushfw          // save flags
-        pushl %eax      // dummy
-        ENTRY_ARG handle_1553
-        addw $4, %sp    // pop dummy
-        popfw           // restore flags
-        lretw
-
-        .code32
-        .globl apm32protected_entry
-apm32protected_entry:
-        pushfw          // save flags
-        pushw %cs       // Setup for long jump to 16bitmode
-        incw (%esp)
-        pushw 1f
-        lcallw *(%esp)
-        addl $4, %esp   // pop call address
-        popfw
-        lretl
-        .code16gcc
-1:                      // 16bit entry point for apm32 code.
-        ENTRY_ARG handle_1553
-        lretw
-
         .org 0xe2c3
         IRQ_ENTRY nmi
 
@@ -339,7 +352,6 @@ apm32protected_entry:
         IRQ_ENTRY 1c
         IRQ_ENTRY 70
         IRQ_ENTRY 74
-        IRQ_ENTRY 75
 
         .org 0xe3fe
         jmp entry_13
@@ -360,6 +372,8 @@ apm32protected_entry:
         .org 0xe739
         IRQ_ENTRY_ARG 14
 
+        IRQ_ENTRY 75
+
         // int 18/19 are special - they reset the stack and do not return.
         .globl entry_19
 entry_19: