There's no need to clobber %ax in ENTRY_INTO32. Now that %eax isn't clobbered, use ENTRY_INTO32 in entry_csm.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/entryfuncs.S | 5 ++--- src/romlayout.S | 10 ++-------- 2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/src/entryfuncs.S b/src/entryfuncs.S index 679b1fc..8438604 100644 --- a/src/entryfuncs.S +++ b/src/entryfuncs.S @@ -135,10 +135,9 @@ .endm
// Reset stack, transition to 32bit mode, and call a C function. - // Clobbers %ax .macro ENTRY_INTO32 cfunc - xorw %ax, %ax - movw %ax, %ss + xorw %dx, %dx + movw %dx, %ss movl $ BUILD_STACK_ADDR , %esp movl $ \cfunc , %edx jmp transition32 diff --git a/src/romlayout.S b/src/romlayout.S index cca4e43..4ebbdee 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -431,14 +431,8 @@ entry_csm: shll $4, %eax addl %esp, %eax
- // Change to BUILD_STACK_ADDR stack - xorl %ebx, %ebx - movw %bx, %ss - movl $BUILD_STACK_ADDR, %esp - - // Jump to 32bit mode and call handle_csm(bregs) - movl $_cfunc32flat_handle_csm, %edx - jmp transition32 + // Change to BUILD_STACK_ADDR stack and call handle_csm(bregs) + ENTRY_INTO32 _cfunc32flat_handle_csm
DECLFUNC __csm_return .code32
Create macros SAVEBREGS_POP_DSEAX and RESTOREBREGS_DSEAX for saving and restoring the cpu state. These are similar to the existing PUSHBREGS and POPBREGS macros.
This also fixes a bug in __farcall16 which inadvertently restored %ds in %es and vice-versa.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/entryfuncs.S | 44 ++++++++++++++++++++++++++++++++++++++++---- src/romlayout.S | 49 +++++-------------------------------------------- vgasrc/vgaentry.S | 22 ++-------------------- 3 files changed, 47 insertions(+), 68 deletions(-)
diff --git a/src/entryfuncs.S b/src/entryfuncs.S index 8438604..4e6151e 100644 --- a/src/entryfuncs.S +++ b/src/entryfuncs.S @@ -1,16 +1,17 @@ // Macros for entering C code // -// Copyright (C) 2008,2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2008-2014 Kevin O'Connor kevin@koconnor.net // // This file may be distributed under the terms of the GNU LGPLv3 license.
/**************************************************************** - * Entry macros + * Macros for save and restore of 'struct bregs' registers ****************************************************************/
+ // Save registers (matches struct bregs) to stack .macro PUSHBREGS - pushl %eax // Save registers (matches struct bregs) + pushl %eax pushl %ecx pushl %edx pushl %ebx @@ -21,8 +22,9 @@ pushw %ds .endm
+ // Restore registers (from struct bregs) from stack .macro POPBREGS - popw %ds // Restore registers (from struct bregs) + popw %ds popw %es popl %edi popl %esi @@ -33,6 +35,40 @@ popl %eax .endm
+ // Save registers to struct bregs at %ds:%eax. The caller + // should "pushw %ds ; pushl %eax" prior to calling - this macro + // will pop them off. + .macro SAVEBREGS_POP_DSEAX + popl BREGS_eax(%eax) + popw BREGS_ds(%eax) + movl %edi, BREGS_edi(%eax) + movl %esi, BREGS_esi(%eax) + movl %ebp, BREGS_ebp(%eax) + movl %ebx, BREGS_ebx(%eax) + movl %edx, BREGS_edx(%eax) + movl %ecx, BREGS_ecx(%eax) + movw %es, BREGS_es(%eax) + .endm + + // Restore registers from struct bregs at %ds:%eax + .macro RESTOREBREGS_DSEAX + movl BREGS_edi(%eax), %edi + movl BREGS_esi(%eax), %esi + movl BREGS_ebp(%eax), %ebp + movl BREGS_ebx(%eax), %ebx + movl BREGS_edx(%eax), %edx + movl BREGS_ecx(%eax), %ecx + movw BREGS_es(%eax), %es + pushl BREGS_eax(%eax) + movw BREGS_ds(%eax), %ds + popl %eax + .endm + + +/**************************************************************** + * 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. diff --git a/src/romlayout.S b/src/romlayout.S index 4ebbdee..a623138 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -151,19 +151,8 @@ __farcall16: pushw BREGS_flags(%eax) // flags pushl BREGS_code(%eax) // CS:IP
- // Load calling registers. - movl BREGS_edi(%eax), %edi - movl BREGS_esi(%eax), %esi - movl BREGS_ebp(%eax), %ebp - movl BREGS_ebx(%eax), %ebx - movl BREGS_edx(%eax), %edx - movl BREGS_ecx(%eax), %ecx - movw BREGS_es(%eax), %es - pushl BREGS_eax(%eax) - movw BREGS_ds(%eax), %ds - popl %eax - - // Invoke call + // Load calling registers and invoke call + RESTOREBREGS_DSEAX iretw // XXX - just do a lcalll 1: // Store flags, es, eax @@ -174,18 +163,8 @@ __farcall16: pushl %eax movw 0x08(%esp), %ds movl 0x0c(%esp), %eax - popl BREGS_eax(%eax) - popw BREGS_es(%eax) + SAVEBREGS_POP_DSEAX popw BREGS_flags(%eax) - - // Store remaining registers - movl %edi, BREGS_edi(%eax) - movl %esi, BREGS_esi(%eax) - movl %ebp, BREGS_ebp(%eax) - movl %ebx, BREGS_ebx(%eax) - movl %edx, BREGS_edx(%eax) - movl %ecx, BREGS_ecx(%eax) - movw %es, BREGS_ds(%eax) movw %ss, %cx movw %cx, %ds // Restore %ds == %ss
@@ -508,16 +487,8 @@ irqentry_arg_extrastack: movl %eax, %ds movl StackPos, %eax subl $BREGS_size+8, %eax - popl BREGS_eax(%eax) // Backup registers - popw BREGS_ds(%eax) - movl %edi, BREGS_edi(%eax) - movl %esi, BREGS_esi(%eax) - movl %ebp, BREGS_ebp(%eax) - movl %ebx, BREGS_ebx(%eax) - movl %edx, BREGS_edx(%eax) - movl %ecx, BREGS_ecx(%eax) + SAVEBREGS_POP_DSEAX // Save registers on extra stack popl %ecx - movw %es, BREGS_es(%eax) movl %esp, BREGS_size+0(%eax) movw %ss, BREGS_size+4(%eax) popl BREGS_code(%eax) @@ -535,17 +506,7 @@ irqentry_arg_extrastack: popw %dx pushw BREGS_flags(%eax) pushl BREGS_code(%eax) - movl BREGS_edi(%eax), %edi - movl BREGS_esi(%eax), %esi - movl BREGS_ebp(%eax), %ebp - movl BREGS_ebx(%eax), %ebx - movl BREGS_edx(%eax), %edx - movl BREGS_ecx(%eax), %ecx - movw BREGS_es(%eax), %es - pushw BREGS_ds(%eax) - pushl BREGS_eax(%eax) - popl %eax - popw %ds + RESTOREBREGS_DSEAX iretw
// Main entry point for interrupts with args diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S index 3c2c885..5d45380 100644 --- a/vgasrc/vgaentry.S +++ b/vgasrc/vgaentry.S @@ -113,15 +113,7 @@ entry_10_extrastack: pushl %eax movw %cs:ExtraStackSeg, %ds movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax - popl BREGS_eax(%eax) // Backup registers - popw BREGS_ds(%eax) - movl %edi, BREGS_edi(%eax) - movl %esi, BREGS_esi(%eax) - movl %ebp, BREGS_ebp(%eax) - movl %ebx, BREGS_ebx(%eax) - movl %edx, BREGS_edx(%eax) - movl %ecx, BREGS_ecx(%eax) - movw %es, BREGS_es(%eax) + SAVEBREGS_POP_DSEAX // Save registers on extra stack movl %esp, BREGS_size+0(%eax) movw %ss, BREGS_size+4(%eax) popl BREGS_code(%eax) @@ -139,15 +131,5 @@ entry_10_extrastack: popw %dx pushw BREGS_flags(%eax) pushl BREGS_code(%eax) - movl BREGS_edi(%eax), %edi - movl BREGS_esi(%eax), %esi - movl BREGS_ebp(%eax), %ebp - movl BREGS_ebx(%eax), %ebx - movl BREGS_edx(%eax), %edx - movl BREGS_ecx(%eax), %ecx - movw BREGS_es(%eax), %es - pushw BREGS_ds(%eax) - pushl BREGS_eax(%eax) - popl %eax - popw %ds + RESTOREBREGS_DSEAX iretw
Although these entry points only require backup and restore of the registers that the C code clobbers, there is no harm in backing up some additional registers. This allows the BREGS macros to be used which makes the code a little more readable.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/romlayout.S | 56 +++++++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 41 deletions(-)
diff --git a/src/romlayout.S b/src/romlayout.S index a623138..ee4212c 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -252,26 +252,18 @@ entry_pmm: pushfl // Save registers clobbered by C code cli cld - pushl %eax - pushl %ecx - pushl %edx - pushw %es - pushw %ds + PUSHBREGS movl %ss, %ecx // Move %ss to %ds movw %cx, %ds shll $4, %ecx movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1) - leal 28(%esp, %ecx), %edx // %edx points to start of args + leal BREGS_size+12(%esp, %ecx), %edx // %edx points to start of args movl $-1, %ecx calll call32 - movw %ax, 12(%esp) // Modify %ax:%dx to return %eax + movw %ax, BREGS_eax(%esp) // Modify %ax:%dx to return %eax shrl $16, %eax - movw %ax, 4(%esp) - popw %ds // Restore saved registers - popw %es - popl %edx - popl %ecx - popl %eax + movw %ax, BREGS_edx(%esp) + POPBREGS popfl popl %esp lretw @@ -289,21 +281,13 @@ entry_pnp_real: pushfl // Save registers clobbered by C code cli cld - pushl %eax - pushl %ecx - pushl %edx - pushw %es - pushw %ds + PUSHBREGS movw %ss, %cx // Move %ss to %ds movw %cx, %ds - leal 28(%esp), %eax // %eax points to start of u16 args + leal BREGS_size+12(%esp), %eax // %eax points to start of u16 args calll handle_pnp movw %ax, 12(%esp) // Modify %eax to return %ax - popw %ds - popw %es - popl %edx - popl %ecx - popl %eax + POPBREGS popfl popl %esp lretw @@ -449,15 +433,11 @@ irqentry_extrastack: movl $_zonelow_seg, %eax movl %eax, %ds movl StackPos, %eax - subl $24, %eax - popl 0(%eax) // Backup %eax, %ds, %es, %ecx, %edx - popw 4(%eax) - movw %es, 6(%eax) - movl %ecx, 8(%eax) + subl $BREGS_size+8, %eax + SAVEBREGS_POP_DSEAX popl %ecx - movl %edx, 12(%eax) - movl %esp, 16(%eax) - movw %ss, 20(%eax) + movl %esp, BREGS_size(%eax) + movw %ss, BREGS_size+4(%eax)
movw %ds, %dx // Setup %ss/%esp and call function movw %dx, %ss @@ -465,15 +445,9 @@ irqentry_extrastack: calll *%ecx
movl %esp, %eax // Restore registers and return - movw 20(%eax), %ss - movl 16(%eax), %esp - movl 12(%eax), %edx - movl 8(%eax), %ecx - movw 6(%eax), %es - pushw 4(%eax) - pushl 0(%eax) - popl %eax - popw %ds + movw BREGS_size+4(%eax), %ss + movl BREGS_size(%eax), %esp + RESTOREBREGS_DSEAX iretw
// Main entry point for interrupts handled on extra stack
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/entryfuncs.S | 23 ----------------------- 1 file changed, 23 deletions(-)
diff --git a/src/entryfuncs.S b/src/entryfuncs.S index 4e6151e..cc1f433 100644 --- a/src/entryfuncs.S +++ b/src/entryfuncs.S @@ -93,29 +93,6 @@ popl %eax .endm
- // As above, but get calling function from stack. - .macro ENTRY_ST - cli - cld - pushl %ecx - pushl %edx - pushw %es - pushw %ds - movw %ss, %cx // Move %ss to %ds - movw %cx, %ds - pushl %esp // Backup %esp, then clear high bits - movzwl %sp, %esp - movl 16(%esp), %ecx // Get calling function - movl %eax, 16(%esp) // Save %eax - calll *%ecx - popl %esp // Restore %esp (including high bits) - popw %ds // Restore registers saved above - 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
On Tue, Oct 21, 2014 at 02:53:42PM -0400, Kevin O'Connor wrote:
There's no need to clobber %ax in ENTRY_INTO32. Now that %eax isn't clobbered, use ENTRY_INTO32 in entry_csm.
FYI, I have pushed this series.
-Kevin