aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--src/biosvar.h5
-rw-r--r--src/output.c4
-rw-r--r--src/romlayout.S174
4 files changed, 100 insertions, 87 deletions
diff --git a/TODO b/TODO
index e9c9d864..c19b5a85 100644
--- 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.
diff --git a/src/biosvar.h b/src/biosvar.h
index 4def7f39..36794c38 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -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);
diff --git a/src/output.c b/src/output.c
index 760ea417..0336610e 100644
--- a/src/output.c
+++ b/src/output.c
@@ -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);
}
diff --git a/src/romlayout.S b/src/romlayout.S
index d5253457..2fd0f839 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -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: