diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2008-03-11 11:14:59 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2008-03-11 11:14:59 -0400 |
commit | ed12849c9b06e371f11596a32da5997c96d9bc95 (patch) | |
tree | 690280737159fb0f8feb42301d37e660517928f2 | |
parent | 2cdd8b6fb1aced4ec08c5e98705922c27285ddfb (diff) | |
download | seabios-ed12849c9b06e371f11596a32da5997c96d9bc95.tar.gz |
Reduce stack usage for ISRs; minor fixes.
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.
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | src/biosvar.h | 2 | ||||
-rw-r--r-- | src/clock.c | 13 | ||||
-rw-r--r-- | src/disk.c | 8 | ||||
-rw-r--r-- | src/disk.h | 16 | ||||
-rw-r--r-- | src/floppy.c | 4 | ||||
-rw-r--r-- | src/kbd.c | 6 | ||||
-rw-r--r-- | src/mouse.c | 7 | ||||
-rw-r--r-- | src/output.c | 2 | ||||
-rw-r--r-- | src/romlayout.S | 104 | ||||
-rw-r--r-- | src/system.c | 12 | ||||
-rw-r--r-- | src/util.h | 6 |
12 files changed, 116 insertions, 67 deletions
@@ -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. diff --git a/src/biosvar.h b/src/biosvar.h index 55e9481b..885d3084 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -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) \ diff --git a/src/clock.c b/src/clock.c index 8c4f301b..c653c1f3 100644 --- a/src/clock.c +++ b/src/clock.c @@ -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); @@ -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(); } @@ -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); diff --git a/src/floppy.c b/src/floppy.c index 1c10f14b..0954720e 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -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) @@ -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); diff --git a/src/mouse.c b/src/mouse.c index 62070da9..569488b7 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -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(); diff --git a/src/output.c b/src/output.c index df9ecb43..760ea417 100644 --- a/src/output.c +++ b/src/output.c @@ -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'); diff --git a/src/romlayout.S b/src/romlayout.S index 96e2e8b1..9f0541a7 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -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 diff --git a/src/system.c b/src/system.c index 7c871008..0cd1c6e4 100644 --- a/src/system.c +++ b/src/system.c @@ -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); @@ -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 ) |