Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/85789?usp=email )
Change subject: cpu/x86/64bit/mode_switch: Add workaround for FSP bug ......................................................................
cpu/x86/64bit/mode_switch: Add workaround for FSP bug
FSP is able to backup and restore the bootloader IDT on entry/exit. Even though it sets up it's own IDT, FSP checks the bootloader IDT size and deadloops without warning if it's too big.
On x86_64 coreboot the IDT is naturally bigger than on x86_32 and thus FSP might die on entry. To workaround this issue do:
* Backup and restore the IDT in protected_mode_call_wrapper * Load zero IDT in protected mode before jumping to function
Change-Id: I56367d8153aa10a9b1bcaa5ffde8ebe202e8c00c Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/cpu/x86/64bit/mode_switch.S 1 file changed, 19 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/89/85789/1
diff --git a/src/cpu/x86/64bit/mode_switch.S b/src/cpu/x86/64bit/mode_switch.S index 9555cef..71d47ef 100644 --- a/src/cpu/x86/64bit/mode_switch.S +++ b/src/cpu/x86/64bit/mode_switch.S @@ -19,15 +19,25 @@ movl %gs, %eax push %rax
+ /* Backup IDT to stack */ + sub $16, %rsp + sidt (%rsp) + /* Store stack pointer */ mov %rsp, %rbp
- /* Align stack and make space for arguments */ + /* Align stack */ movabs $0xfffffffffffffff0, %rax andq %rax, %rsp + + /* New IDT to stack */ + push $0 + push $0 + + /* Make room for arguments on stack */ sub $16, %rsp
- /* Arguments to stack */ + /* Protected mode arguments to stack */ movl %edi, 12(%rsp) movl %esi, 0(%rsp) movl %edx, 4(%rsp) @@ -36,6 +46,9 @@ /* Drop to protected mode */ #include <cpu/x86/64bit/exit32.inc>
+ /* Load zero IDT. x86_32 FSP doesn't like to find a x86_64 IDT */ + lidt 16(%esp) + /* Fetch function to call */ movl 12(%esp), %ebx
@@ -52,6 +65,10 @@ /* Restore stack pointer */ mov %rbp, %rsp
+ /* Restore IDT */ + lidt (%rsp) + add $16, %rsp + /* Restore registers */ pop %rbx movl %ebx, %gs