Reduce stack usage for ISRs; minor fixes.
authorKevin O'Connor <kevin@koconnor.net>
Tue, 11 Mar 2008 15:14:59 +0000 (11:14 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 11 Mar 2008 15:14:59 +0000 (11:14 -0400)
Don't back up all registers on isr handlers - they don't read/modify
    them.  This saves stack space.
extended_bios_data_area_s must be packed to match ebda spec.
Enable irqs on int 08 - follows old bochs bios code.
Fix bug in int 76 -- should clear disk_interrupt_flag not
    floppy_harddisk_info.
Make sure we alert in disk_ret on failure case.
int 18/19 entry points need to setup cld/%ds too.
asm in handle_1587 clobbers flags - note that in clobber list.

12 files changed:
TODO
src/biosvar.h
src/clock.c
src/disk.c
src/disk.h
src/floppy.c
src/kbd.c
src/mouse.c
src/output.c
src/romlayout.S
src/system.c
src/util.h

diff --git a/TODO b/TODO
index a32c4b7..603d763 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,8 @@
 Audit all sti/cli calls.
 
+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.
index 55e9481..885d308 100644 (file)
@@ -239,7 +239,7 @@ struct extended_bios_data_area_s {
 
     // El Torito Emulation data
     struct cdemu_s cdemu;
-};
+} PACKED;
 
 // Accessor functions
 #define GET_EBDA(var) \
index 8c4f301..c653c1f 100644 (file)
@@ -250,16 +250,17 @@ handle_1a(struct bregs *regs)
 
 // User Timer Tick
 void VISIBLE16
-handle_1c(struct bregs *regs)
+handle_1c()
 {
     //debug_enter(regs);
 }
 
 // INT 08h System Timer ISR Entry Point
 void VISIBLE16
-handle_08(struct bregs *regs)
+handle_08()
 {
-//    debug_isr(regs);
+    //debug_isr();
+    irq_enable();
 
     floppy_tick();
 
@@ -279,6 +280,8 @@ handle_08(struct bregs *regs)
     memset(&br, 0, sizeof(br));
     call16_int(0x1c, &br);
 
+    irq_disable();
+
     eoi_master_pic();
 }
 
@@ -338,9 +341,9 @@ handle_1583(struct bregs *regs)
 
 // int70h: IRQ8 - CMOS RTC
 void VISIBLE16
-handle_70(struct bregs *regs)
+handle_70()
 {
-    debug_isr(regs);
+    debug_isr();
 
     // Check which modes are enabled and have occurred.
     u8 registerB = inb_cmos(CMOS_STATUS_B);
index 32e4f4b..7f8833b 100644 (file)
@@ -160,7 +160,7 @@ emu_access(struct bregs *regs, u8 device, u16 command)
     disk_ret(regs, DISK_RET_SUCCESS);
 }
 
-void
+static void
 extended_access(struct bregs *regs, u8 device, u16 command)
 {
     u16 count = GET_INT13EXT(regs, count);
@@ -738,9 +738,9 @@ handle_13(struct bregs *regs)
 
 // record completion in BIOS task complete flag
 void VISIBLE16
-handle_76(struct bregs *regs)
+handle_76()
 {
-    debug_isr(regs);
-    SET_BDA(floppy_harddisk_info, 0xff);
+    debug_isr();
+    SET_BDA(disk_interrupt_flag, 0xff);
     eoi_both_pics();
 }
index 36e95e5..0f92b1e 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "ioport.h" // outb
 #include "biosvar.h" // struct bregs
+#include "util.h" // set_code_fail
 
 #define DISK_RET_SUCCESS       0x00
 #define DISK_RET_EPARAM        0x01
@@ -34,7 +35,7 @@ struct int13ext_s {
     u16 segment;
     u32 lba1;
     u32 lba2;
-};
+} PACKED;
 
 #define GET_INT13EXT(regs,var)                                          \
     GET_FARVAR((regs)->ds, ((struct int13ext_s*)((regs)->si+0))->var)
@@ -63,7 +64,7 @@ struct int13dpt_s {
     u8  device_path[8];
     u8  reserved3;
     u8  checksum;
-};
+} PACKED;
 
 #define GET_INT13DPT(regs,var)                                          \
     GET_FARVAR((regs)->ds, ((struct int13dpt_s*)((regs)->si+0))->var)
@@ -83,7 +84,7 @@ struct floppy_dbt_s {
     u8 fill_byte;
     u8 settle_time;
     u8 startup_time;
-};
+} PACKED;
 
 struct floppy_ext_dbt_s {
     struct floppy_dbt_s dbt;
@@ -91,15 +92,17 @@ struct floppy_ext_dbt_s {
     u8 max_track;
     u8 data_rate;
     u8 drive_type;
-};
+} PACKED;
 
 // Helper function for setting up a return code.
 static inline void
 disk_ret(struct bregs *regs, u8 code)
 {
-    regs->ah = code;
     SET_BDA(disk_last_status, code);
-    set_cf(regs, code);
+    if (code)
+        set_code_fail(regs, code);
+    else
+        set_code_success(regs);
 }
 
 // floppy.c
@@ -109,7 +112,6 @@ void floppy_tick();
 
 // disk.c
 void emu_access(struct bregs *regs, u8 device, u16 command);
-void extended_access(struct bregs *regs, u8 device, u16 command);
 void disk_13(struct bregs *regs, u8 device);
 void disk_13XX(struct bregs *regs, u8 device);
 
index 1c10f14..0954720 100644 (file)
@@ -717,9 +717,9 @@ floppy_13(struct bregs *regs, u8 drive)
 
 // INT 0Eh Diskette Hardware ISR Entry Point
 void VISIBLE16
-handle_0e(struct bregs *regs)
+handle_0e()
 {
-    //debug_isr(regs);
+    //debug_isr();
     if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0) {
         outb(0x08, PORT_FD_DATA); // sense interrupt status
         while ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0)
index c89899f..86a470e 100644 (file)
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -237,7 +237,7 @@ set_leds()
 void VISIBLE16
 handle_16(struct bregs *regs)
 {
-//    debug_enter(regs);
+    //debug_enter(regs);
 
     set_leds();
 
@@ -542,9 +542,9 @@ process_key(u8 scancode)
 
 // INT09h : Keyboard Hardware Service Entry Point
 void VISIBLE16
-handle_09(struct bregs *regs)
+handle_09()
 {
-    //debug_isr(regs);
+    //debug_isr();
 
     // disable keyboard
     outb(0xad, PORT_PS2_STATUS);
index 62070da..569488b 100644 (file)
@@ -8,6 +8,9 @@
 #include "biosvar.h" // struct bregs
 #include "util.h" // debug_enter
 
+#define DEBUGF1(fmt, args...) bprintf(0, fmt , ##args)
+#define DEBUGF(fmt, args...)
+
 static char panic_msg_keyb_buffer_full[] = "%s: keyboard input buffer full\n";
 
 static void
@@ -413,9 +416,9 @@ int74_function()
 
 // INT74h : PS/2 mouse hardware interrupt
 void VISIBLE16
-handle_74(struct bregs *regs)
+handle_74()
 {
-    //debug_isr(regs);
+    //debug_isr();
 
     irq_enable();
     int74_function();
index df9ecb4..760ea41 100644 (file)
@@ -184,7 +184,7 @@ dump_regs(const char *fname, const char *type, struct bregs *regs)
 }
 
 void
-__debug_isr(const char *fname, struct bregs *regs)
+__debug_isr(const char *fname)
 {
     puts_cs(0, fname);
     putc(0, '\n');
index 96e2e8b..9f0541a 100644 (file)
@@ -192,6 +192,8 @@ __call16:
         // Remove %eax
         popl %eax
 
+        cld
+
         retl
 
 
@@ -244,8 +246,32 @@ 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
@@ -259,6 +285,7 @@ rombios32_gdt:
         popal
         .endm
 
+        // Define an entry point for an interrupt (no args passed).
         .macro IRQ_ENTRY num
         .globl entry_\num
         entry_\num :
@@ -267,12 +294,21 @@ rombios32_gdt:
         iretw
         .endm
 
+        // Define an entry point for an interrupt (can read/modify args).
+        .macro IRQ_ENTRY_ARG num
+        .globl entry_\num
+        entry_\num :
+        cli         // In case something far-calls instead of using "int"
+        ENTRY_ARG handle_\num
+        iretw
+        .endm
+
         // APM trampolines
         .globl apm16protected_entry
 apm16protected_entry:
         pushfw          // save flags
         pushl %eax      // dummy
-        ENTRY handle_1553
+        ENTRY_ARG handle_1553
         addw $4, %sp    // pop dummy
         popfw           // restore flags
         lretw
@@ -290,31 +326,50 @@ apm32protected_entry:
         lretl
         .code16gcc
 1:                      // 16bit entry point for apm32 code.
-        ENTRY handle_1553
+        ENTRY_ARG handle_1553
         lretw
 
         .org 0xe2c3
         IRQ_ENTRY nmi
 
-        IRQ_ENTRY 13
-        IRQ_ENTRY 12
-        IRQ_ENTRY 11
+        IRQ_ENTRY_ARG 13
+        IRQ_ENTRY_ARG 12
+        IRQ_ENTRY_ARG 11
         IRQ_ENTRY 76
         IRQ_ENTRY 1c
         IRQ_ENTRY 70
         IRQ_ENTRY 74
         IRQ_ENTRY 75
 
+        .org 0xe3fe
+        jmp entry_13
+
+        .org 0xe401
+        // XXX - Fixed Disk Parameter Table
+
+        .org 0xe6f2
+        jmp entry_19
+
+        .org 0xe6f5
+.include "out/cbt.proc.16.s"
+        .text
+
+        .org 0xe729
+        // XXX - Baud Rate Generator Table
+
+        .org 0xe739
+        IRQ_ENTRY_ARG 14
+
+        // int 18/19 are special - they reset the stack and do not return.
         .globl entry_19
 entry_19:
         RESET_STACK
-        calll handle_19
+        ENTRY handle_19
 
         .globl entry_18
 entry_18:
         RESET_STACK
-        calll handle_18
-
+        ENTRY handle_18
 
         // IRQ trampolines
         .macro IRQ_TRAMPOLINE num
@@ -333,33 +388,14 @@ entry_18:
         IRQ_TRAMPOLINE 1c
         IRQ_TRAMPOLINE 4a
 
-        .org 0xe3fe
-        jmp entry_13
-
-        .org 0xe401
-        // XXX - Fixed Disk Parameter Table
-
-        .org 0xe6f2
-        jmp entry_19
-
-        .org 0xe6f5
-.include "out/cbt.proc.16.s"
-        .text
-
-        .org 0xe729
-        // XXX - Baud Rate Generator Table
-
-        .org 0xe739
-        IRQ_ENTRY 14
-
         .org 0xe82e
-        IRQ_ENTRY 16
+        IRQ_ENTRY_ARG 16
 
         .org 0xe987
         IRQ_ENTRY 09
 
         .org 0xec59
-        IRQ_ENTRY 40
+        IRQ_ENTRY_ARG 40
 
         .org 0xef57
         IRQ_ENTRY 0e
@@ -369,14 +405,14 @@ entry_18:
         .text
 
         .org 0xefd2
-        IRQ_ENTRY 17
+        IRQ_ENTRY_ARG 17
 
         .org 0xf045
         // XXX int 10
         iretw
 
         .org 0xf065
-        IRQ_ENTRY 10
+        IRQ_ENTRY_ARG 10
 
         .org 0xf0a4
         // XXX int 1D
@@ -393,14 +429,14 @@ freespace2_end:
         jmp entry_11
 
         .org 0xf859
-        IRQ_ENTRY 15
+        IRQ_ENTRY_ARG 15
 
         .org 0xfa6e
 .include "out/font.proc.16.s"
         .text
 
         .org 0xfe6e
-        IRQ_ENTRY 1a
+        IRQ_ENTRY_ARG 1a
 
         .org 0xfea5
         IRQ_ENTRY 08
@@ -418,7 +454,7 @@ dummy_iret_handler:
         iretw
 
         .org 0xff54
-        IRQ_ENTRY 05
+        IRQ_ENTRY_ARG 05
 
         .org 0xfff0 // Power-up Entry Point
         ljmpw $0xf000, $post16
index 7c87100..0cd1c6e 100644 (file)
@@ -194,7 +194,7 @@ handle_1587(struct bregs *regs)
         "movw %%ss, %%ax\n"
         "movw %%ax, %%ds\n"
         : "+c"(count), "+S"(si)
-        : : "eax", "di"); // XXX - also clobbers %es
+        : : "eax", "di", "cc"); // XXX - also clobbers %es
 
     set_a20(prev_a20_enable);
 
@@ -439,17 +439,17 @@ handle_10(struct bregs *regs)
 }
 
 void VISIBLE16
-handle_nmi(struct bregs *regs)
+handle_nmi()
 {
-    debug_isr(regs);
-    // XXX
+    debug_isr();
+    BX_PANIC("NMI Handler called\n");
 }
 
 // INT 75 - IRQ13 - MATH COPROCESSOR EXCEPTION
 void VISIBLE16
-handle_75(struct bregs *regs)
+handle_75()
 {
-    debug_isr(regs);
+    debug_isr();
 
     // clear irq13
     outb(0, PORT_MATH_CLEAR);
index 36e9a30..0ea4a01 100644 (file)
@@ -42,7 +42,9 @@ static inline void hlt(void)
     asm volatile("hlt");
 }
 
+// XXX - should halt machine
 #define BX_PANIC(fmt, args...) bprintf(0, fmt , ##args)
+
 #define BX_INFO(fmt, args...) bprintf(0, fmt , ##args)
 
 static inline void
@@ -120,13 +122,13 @@ void bprintf(u16 action, const char *fmt, ...)
 void __debug_enter(const char *fname, struct bregs *regs);
 void __debug_fail(const char *fname, struct bregs *regs);
 void __debug_stub(const char *fname, struct bregs *regs);
-void __debug_isr(const char *fname, struct bregs *regs);
+void __debug_isr(const char *fname);
 #define debug_enter(regs) \
     __debug_enter(__func__, regs)
 #define debug_stub(regs) \
     __debug_stub(__func__, regs)
 #define debug_isr(regs) \
-    __debug_isr(__func__, regs)
+    __debug_isr(__func__)
 #define printf(fmt, args...)                     \
     bprintf(1, fmt , ##args )