From de8e4d930d435091ed41652749830024437732ac Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 27 Dec 2024 10:02:13 +0100 Subject: [PATCH] cpu/x86/64bit/mode_switch: Work around FSP bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-on: https://review.coreboot.org/c/coreboot/+/85789 Reviewed-by: Shuo Liu Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) Reviewed-by: Maximilian Brune --- src/cpu/x86/64bit/mode_switch.S | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/cpu/x86/64bit/mode_switch.S b/src/cpu/x86/64bit/mode_switch.S index 9555cefbbb..e5be44a318 100644 --- a/src/cpu/x86/64bit/mode_switch.S +++ b/src/cpu/x86/64bit/mode_switch.S @@ -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 + /* 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