aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2008-03-11 11:14:59 -0400
committerKevin O'Connor <kevin@koconnor.net>2008-03-11 11:14:59 -0400
commited12849c9b06e371f11596a32da5997c96d9bc95 (patch)
tree690280737159fb0f8feb42301d37e660517928f2
parent2cdd8b6fb1aced4ec08c5e98705922c27285ddfb (diff)
downloadseabios-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--TODO3
-rw-r--r--src/biosvar.h2
-rw-r--r--src/clock.c13
-rw-r--r--src/disk.c8
-rw-r--r--src/disk.h16
-rw-r--r--src/floppy.c4
-rw-r--r--src/kbd.c6
-rw-r--r--src/mouse.c7
-rw-r--r--src/output.c2
-rw-r--r--src/romlayout.S104
-rw-r--r--src/system.c12
-rw-r--r--src/util.h6
12 files changed, 116 insertions, 67 deletions
diff --git a/TODO b/TODO
index a32c4b7c..603d7638 100644
--- 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.
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);
diff --git a/src/disk.c b/src/disk.c
index 32e4f4bc..7f8833b6 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -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();
}
diff --git a/src/disk.h b/src/disk.h
index 36e95e53..0f92b1e4 100644
--- a/src/disk.h
+++ b/src/disk.h
@@ -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)
diff --git a/src/kbd.c b/src/kbd.c
index c89899fe..86a470ee 100644
--- 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);
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);
diff --git a/src/util.h b/src/util.h
index 36e9a305..0ea4a01b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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 )