x86: bios: Synchronize stack between real and protected mode

PCI option rom may use different SS during its execution, so it is not
safe to assume esp pointed to the same location in the protected mode.

Signed-off-by: Jian Luo <jian.luo4@boschrexroth.de>
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Jian Luo 2015-07-06 16:42:06 +08:00 committed by Simon Glass
parent b018a8c716
commit 7b5c349890
1 changed files with 23 additions and 0 deletions

View File

@ -246,6 +246,9 @@ __interrupt_handler_16bit = PTR_TO_REAL_MODE(.)
push %fs
push %gs
/* Save real mode SS */
movw %ss, %cs:__realmode_ss
/* Clear DF to not break ABI assumptions */
cld
@ -258,12 +261,29 @@ __interrupt_handler_16bit = PTR_TO_REAL_MODE(.)
enter_protected_mode
/*
* Now we are in protected mode. We need compute the right ESP based
* on saved real mode SS otherwise interrupt_handler() won't get
* correct parameters from the stack.
*/
movzwl %cs:__realmode_ss, %ecx
shll $4, %ecx
addl %ecx, %esp
/* Call the C interrupt handler */
movl $interrupt_handler, %eax
call *%eax
/* Restore real mode ESP based on saved SS */
movzwl %cs:__realmode_ss, %ecx
shll $4, %ecx
subl %ecx, %esp
enter_real_mode
/* Restore real mode SS */
movw %cs:__realmode_ss, %ss
/*
* Restore all registers, including those manipulated by the C
* handler
@ -276,6 +296,9 @@ __interrupt_handler_16bit = PTR_TO_REAL_MODE(.)
popal
iret
__realmode_ss = PTR_TO_REAL_MODE(.)
.word 0
.globl asm_realmode_code_size
asm_realmode_code_size:
.long . - asm_realmode_code