#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);
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);
}
/****************************************************************
- * 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
movl $ CONFIG_STACK_OFFSET , %esp
.endm
+
+/****************************************************************
+ * POST handler
+ ****************************************************************/
+
.org 0xe05b
.globl post16
post16:
// 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
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
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
* 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
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
IRQ_ENTRY 1c
IRQ_ENTRY 70
IRQ_ENTRY 74
- IRQ_ENTRY 75
.org 0xe3fe
jmp entry_13
.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: