Use an aligned stack offset when entering on the extra stack
The size of 'struct bregs' is not evenly divisible by four and where the assembler placed a 'struct bregs' on the extra stack as part of entering into the C functions it caused the C functions to run with a non-aligned stack. It's technically not correct to use an unaligned stack and it is certainly less efficient. This patch avoids using BREGS_size (the sizeof struct bregs) and instead introduces PUSHBREGS_size (the size of the general purpose registers in struct bregs) in the assembler. Where the code actually did use the %cs:%ip and flags, an extra 8 (instead of 6) bytes are added to maintain a sane alignment. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
b4eb6fc5cc
commit
aa66d6539c
|
@ -20,5 +20,4 @@ void foo(void)
|
|||
OFFSET(BREGS_edi, bregs, edi);
|
||||
OFFSET(BREGS_flags, bregs, flags);
|
||||
OFFSET(BREGS_code, bregs, code);
|
||||
DEFINE(BREGS_size, sizeof(struct bregs));
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
* Macros for save and restore of 'struct bregs' registers
|
||||
****************************************************************/
|
||||
|
||||
#define PUSHBREGS_size 32
|
||||
|
||||
// Save registers (matches struct bregs) to stack
|
||||
.macro PUSHBREGS
|
||||
pushl %eax
|
||||
|
|
|
@ -257,7 +257,7 @@ entry_pmm:
|
|||
movw %cx, %ds
|
||||
shll $4, %ecx
|
||||
movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
|
||||
leal BREGS_size-6+12(%esp, %ecx), %edx // %edx points to start of args
|
||||
leal PUSHBREGS_size+12(%esp, %ecx), %edx // %edx points to start of args
|
||||
movl $-1, %ecx
|
||||
calll call32
|
||||
movw %ax, BREGS_eax(%esp) // Modify %ax:%dx to return %eax
|
||||
|
@ -284,7 +284,7 @@ entry_pnp_real:
|
|||
PUSHBREGS
|
||||
movw %ss, %cx // Move %ss to %ds
|
||||
movw %cx, %ds
|
||||
leal BREGS_size-6+12(%esp), %eax // %eax points to start of u16 args
|
||||
leal PUSHBREGS_size+12(%esp), %eax // %eax points to start of u16 args
|
||||
calll handle_pnp
|
||||
movw %ax, BREGS_eax(%esp) // Modify %eax to return %ax
|
||||
POPBREGS
|
||||
|
@ -433,11 +433,11 @@ irqentry_extrastack:
|
|||
movl $_zonelow_seg, %eax
|
||||
movl %eax, %ds
|
||||
movl StackPos, %eax
|
||||
subl $BREGS_size+8, %eax
|
||||
subl $PUSHBREGS_size+8, %eax
|
||||
SAVEBREGS_POP_DSEAX
|
||||
popl %ecx
|
||||
movl %esp, BREGS_size(%eax)
|
||||
movw %ss, BREGS_size+4(%eax)
|
||||
movl %esp, PUSHBREGS_size(%eax)
|
||||
movw %ss, PUSHBREGS_size+4(%eax)
|
||||
|
||||
movw %ds, %dx // Setup %ss/%esp and call function
|
||||
movw %dx, %ss
|
||||
|
@ -445,8 +445,8 @@ irqentry_extrastack:
|
|||
calll *%ecx
|
||||
|
||||
movl %esp, %eax // Restore registers and return
|
||||
movw BREGS_size+4(%eax), %ss
|
||||
movl BREGS_size(%eax), %esp
|
||||
movw PUSHBREGS_size+4(%eax), %ss
|
||||
movl PUSHBREGS_size(%eax), %esp
|
||||
RESTOREBREGS_DSEAX
|
||||
iretw
|
||||
|
||||
|
@ -460,11 +460,11 @@ irqentry_arg_extrastack:
|
|||
movl $_zonelow_seg, %eax
|
||||
movl %eax, %ds
|
||||
movl StackPos, %eax
|
||||
subl $BREGS_size+8, %eax
|
||||
subl $PUSHBREGS_size+16, %eax
|
||||
SAVEBREGS_POP_DSEAX // Save registers on extra stack
|
||||
popl %ecx
|
||||
movl %esp, BREGS_size+0(%eax)
|
||||
movw %ss, BREGS_size+4(%eax)
|
||||
movl %esp, PUSHBREGS_size+8(%eax)
|
||||
movw %ss, PUSHBREGS_size+12(%eax)
|
||||
popl BREGS_code(%eax)
|
||||
popw BREGS_flags(%eax)
|
||||
|
||||
|
@ -474,8 +474,8 @@ irqentry_arg_extrastack:
|
|||
calll *%ecx
|
||||
|
||||
movl %esp, %eax // Restore registers and return
|
||||
movw BREGS_size+4(%eax), %ss
|
||||
movl BREGS_size+0(%eax), %esp
|
||||
movw PUSHBREGS_size+12(%eax), %ss
|
||||
movl PUSHBREGS_size+8(%eax), %esp
|
||||
popl %edx
|
||||
popw %dx
|
||||
pushw BREGS_flags(%eax)
|
||||
|
|
|
@ -112,10 +112,10 @@ entry_10_extrastack:
|
|||
pushw %ds // Set %ds:%eax to space on ExtraStack
|
||||
pushl %eax
|
||||
movw %cs:ExtraStackSeg, %ds
|
||||
movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
|
||||
movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-16), %eax
|
||||
SAVEBREGS_POP_DSEAX // Save registers on extra stack
|
||||
movl %esp, BREGS_size+0(%eax)
|
||||
movw %ss, BREGS_size+4(%eax)
|
||||
movl %esp, PUSHBREGS_size+8(%eax)
|
||||
movw %ss, PUSHBREGS_size+12(%eax)
|
||||
popl BREGS_code(%eax)
|
||||
popw BREGS_flags(%eax)
|
||||
|
||||
|
@ -125,8 +125,8 @@ entry_10_extrastack:
|
|||
VGA_CALLL handle_10
|
||||
|
||||
movl %esp, %eax // Restore registers and return
|
||||
movw BREGS_size+4(%eax), %ss
|
||||
movl BREGS_size+0(%eax), %esp
|
||||
movw PUSHBREGS_size+12(%eax), %ss
|
||||
movl PUSHBREGS_size+8(%eax), %esp
|
||||
popl %edx
|
||||
popw %dx
|
||||
pushw BREGS_flags(%eax)
|
||||
|
@ -148,10 +148,10 @@ entry_timer_hook_extrastack:
|
|||
pushw %ds // Set %ds:%eax to space on ExtraStack
|
||||
pushl %eax
|
||||
movw %cs:ExtraStackSeg, %ds
|
||||
movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
|
||||
movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-8), %eax
|
||||
SAVEBREGS_POP_DSEAX
|
||||
movl %esp, BREGS_size(%eax)
|
||||
movw %ss, BREGS_size+4(%eax)
|
||||
movl %esp, PUSHBREGS_size(%eax)
|
||||
movw %ss, PUSHBREGS_size+4(%eax)
|
||||
|
||||
movw %ds, %dx // Setup %ss/%esp and call function
|
||||
movw %dx, %ss
|
||||
|
@ -159,7 +159,7 @@ entry_timer_hook_extrastack:
|
|||
calll handle_timer_hook
|
||||
|
||||
movl %esp, %eax // Restore registers and return
|
||||
movw BREGS_size+4(%eax), %ss
|
||||
movl BREGS_size(%eax), %esp
|
||||
movw PUSHBREGS_size+4(%eax), %ss
|
||||
movl PUSHBREGS_size(%eax), %esp
|
||||
RESTOREBREGS_DSEAX
|
||||
ljmpw *%cs:Timer_Hook_Resume
|
||||
|
|
Loading…
Reference in New Issue