[coreboot] New patch to review for coreboot: 1d6bf8b x86, oprom: ensure DF is always cleared

Mathias Krause (minipli@googlemail.com) gerrit at coreboot.org
Sun Apr 1 11:48:21 CEST 2012


Mathias Krause (minipli at googlemail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/837

-gerrit

commit 1d6bf8be4ee126217544fabe1c39fe22317ddda0
Author: Mathias Krause <minipli at googlemail.com>
Date:   Sun Apr 1 11:32:09 2012 +0200

    x86, oprom: ensure DF is always cleared
    
    The Option ROM might mess with the EFLAGS register and break assumptions
    the C part of coreboot implicitly has, e.g. the state of the direction
    flag.
    
    Prevent Option ROMs from confusing coreboot by restoring the old EFLAGS
    value after the Option ROMs has finished and always clear the direction
    flag before calling the C part of the interrupt handler.
    
    Change-Id: I84663be6681b17f95f48d93f0b730e443336b4a8
    Signed-off-by: Mathias Krause <minipli at googlemail.com>
---
 src/devices/oprom/x86_asm.S |   65 ++++++++++++++++++++++++------------------
 1 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/src/devices/oprom/x86_asm.S b/src/devices/oprom/x86_asm.S
index 488bfa6..56ebb3a 100644
--- a/src/devices/oprom/x86_asm.S
+++ b/src/devices/oprom/x86_asm.S
@@ -75,35 +75,36 @@ __buffer = RELOCATED(.)
 	.globl __realmode_call
 __realmode_call = RELOCATED(.)
 	/* save all registers to the stack */
-	pushal
+	pusha
+	pushf
 
-	/* Move the protected mode stack to a safe place */
+	/* Move the protected mode stack pointer to a safe place */
 	movl	%esp, __stack
-	movl    %esp, %ebp
+	movl	%esp, %ebp
 
-	/* This function is called with regparm=0 and we have
-	 * to skip the 32 byte from pushal. Hence start at 36.
+	/* This function is called with regparm=0 and we have to
+	 * skip the 36 byte from pushf+pusha. Hence start at 40.
 	 */
 
 	/* entry point */
-	movl    36(%ebp), %eax
+	movl	40(%ebp), %eax
 	mov	%ax, __lcall_instr + 1
 	andl	$0xffff0000, %eax
 	shrl	$4, %eax
 	mov	%ax, __lcall_instr + 3
 
 	/* initial register values */
-	movl	40(%ebp), %eax
-	movl	%eax, __registers +  0 /* eax */
 	movl	44(%ebp), %eax
-	movl	%eax, __registers +  4 /* ebx */
+	movl	%eax, __registers +  0 /* eax */
 	movl	48(%ebp), %eax
-	movl	%eax, __registers +  8 /* ecx */
+	movl	%eax, __registers +  4 /* ebx */
 	movl	52(%ebp), %eax
-	movl	%eax, __registers + 12 /* edx */
+	movl	%eax, __registers +  8 /* ecx */
 	movl	56(%ebp), %eax
-	movl	%eax, __registers + 16 /* esi */
+	movl	%eax, __registers + 12 /* edx */
 	movl	60(%ebp), %eax
+	movl	%eax, __registers + 16 /* esi */
+	movl	64(%ebp), %eax
 	movl	%eax, __registers + 20 /* edi */
 
 	/* Activate the right segment descriptor real mode. */
@@ -193,41 +194,45 @@ __lcall_instr = RELOCATED(.)
 	/* restore proper idt */
 	lidt	idtarg
 
-	/* and exit */
+	/* restore stack pointer, eflags and register values */
 	movl	__stack, %esp
-	popal
+	popf
+	popa
 
+	/* and exit */
 	// TODO return AX from OPROM call
 	ret
 
 	.globl __realmode_interrupt
 __realmode_interrupt = RELOCATED(.)
 	/* save all registers to the stack */
-	pushal
-	/* save the stack */
+	pusha
+	pushf
+
+	/* save the stack pointer */
 	movl	%esp, __stack
-	movl    %esp, %ebp
+	movl	%esp, %ebp
 
-	/* This function is called with regparm=0 and we have
-	 * to skip the 32 byte from pushal. Hence start at 36.
+	/* This function is called with regparm=0 and we have to
+	 * skip the 36 byte from pushf+pusha. Hence start at 40.
 	 */
 
 	/* prepare interrupt calling code */
-	movl    36(%ebp), %eax
+	movl	40(%ebp), %eax
 	movb	%al, __intXX_instr + 1 /* intno */
 
 	/* initial register values */
-	movl	40(%ebp), %eax
-	movl	%eax, __registers +  0 /* eax */
 	movl	44(%ebp), %eax
-	movl	%eax, __registers +  4 /* ebx */
+	movl	%eax, __registers +  0 /* eax */
 	movl	48(%ebp), %eax
-	movl	%eax, __registers +  8 /* ecx */
+	movl	%eax, __registers +  4 /* ebx */
 	movl	52(%ebp), %eax
-	movl	%eax, __registers + 12 /* edx */
+	movl	%eax, __registers +  8 /* ecx */
 	movl	56(%ebp), %eax
-	movl	%eax, __registers + 16 /* esi */
+	movl	%eax, __registers + 12 /* edx */
 	movl	60(%ebp), %eax
+	movl	%eax, __registers + 16 /* esi */
+	movl	64(%ebp), %eax
 	movl	%eax, __registers + 20 /* edi */
 
 	/*  This configures CS properly for real mode. */
@@ -309,9 +314,10 @@ __intXX_instr = RELOCATED(.)
 	/* restore coreboot's 32-bit IDT */
 	lidt	idtarg
 
-	/* Exit */
+	/* restore stack pointer, eflags and register values and exit */
 	movl	__stack, %esp
-	popal
+	popf
+	popa
 	ret
 
 /* This is the 16-bit interrupt entry point called by the IDT stub code.
@@ -327,6 +333,9 @@ __interrupt_handler_16bit = RELOCATED(.)
 	push	%fs
 	push	%gs
 
+	/* Clear DF to not break ABI assumptions */
+	cld
+
 	/* Clean up the interrupt number. We could have done this in the stub,
 	 * but it would have cost 2 more bytes per stub entry.
 	 */




More information about the coreboot mailing list