diff mbox

[U-Boot,v2,02/11] x86: bios: Synchronize stack between real and protected mode

Message ID BLU436-SMTP137847CF4664A5D26694FDBF930@phx.gbl
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Bin Meng July 6, 2015, 8:31 a.m. UTC
From: Jian Luo <jian.luo4@boschrexroth.de>

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>

---

Changes in v2:
- Add comments for the changes in the assembly codes

 arch/x86/lib/bios_asm.S | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Comments

Bin Meng July 6, 2015, 8:43 a.m. UTC | #1
Hi Simon,

On Mon, Jul 6, 2015 at 4:31 PM, Bin Meng <bmeng.cn@gmail.com> wrote:
> From: Jian Luo <jian.luo4@boschrexroth.de>
>
> 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>
>
> ---
>
> Changes in v2:
> - Add comments for the changes in the assembly codes
>
>  arch/x86/lib/bios_asm.S | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/arch/x86/lib/bios_asm.S b/arch/x86/lib/bios_asm.S
> index 4faa70e..e559228 100644
> --- a/arch/x86/lib/bios_asm.S
> +++ b/arch/x86/lib/bios_asm.S
> @@ -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 protect 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 read 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
> --

Sorry I have to respin this patch. Please check the new one here:
http://patchwork.ozlabs.org/patch/491496/

Regards,
Bin
diff mbox

Patch

diff --git a/arch/x86/lib/bios_asm.S b/arch/x86/lib/bios_asm.S
index 4faa70e..e559228 100644
--- a/arch/x86/lib/bios_asm.S
+++ b/arch/x86/lib/bios_asm.S
@@ -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 protect 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 read 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