cpu/x86/64bit/mode_switch: Work around FSP bug

FSP, that is build against EDK2 2018 or newer, is able to back up and
restore the bootloader IDT on entry/exit. Even though it sets up its
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
x86_32 FSP might die on entry. Work around this issue by:

* Back up and restore the IDT in protected_mode_call_wrapper
* Load zero IDT in protected mode before jumping to function

TEST: Can boot on SPR FSP (x86_32) using x86_64 coreboot with
      exceptions in romstage enabled.

Change-Id: I56367d8153aa10a9b1bcaa5ffde8ebe202e8c00c
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85789
Reviewed-by: Shuo Liu <shuo.liu@intel.com>
Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
This commit is contained in:
Patrick Rudolph 2024-12-27 10:02:13 +01:00
commit de8e4d930d

View file

@ -19,12 +19,22 @@ protected_mode_call_wrapper:
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 */
/* New IDT to stack */
pushq $0
pushq $0
/* Align stack */
movabs $0xfffffffffffffff0, %rax
andq %rax, %rsp
/* Make room for arguments on stack */
sub $16, %rsp
/* Arguments to stack */
@ -36,6 +46,9 @@ protected_mode_call_wrapper:
/* 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(%ebp)
/* Fetch function to call */
movl 12(%esp), %ebx
@ -52,6 +65,10 @@ protected_mode_call_wrapper:
/* Restore stack pointer */
mov %rbp, %rsp
/* Restore IDT */
lidt (%rsp)
add $16, %rsp
/* Restore registers */
pop %rbx
movl %ebx, %gs