Files
system76-coreboot/src/arch/x86/assembly_entry.S
Patrick Rudolph 29ed4f56b5 arch/x86/gdt: Work around assembler bug
The GDT loading did work fine on x86_64 a few months ago, but today it
only works in QEMU, but not on real hardware or KVM-enabled QEMU. This
might be related to toolchain changes.

Use 64bit GDT loading on x86_64 and force the assembler to generate a
64bit address load on the GDT. This will make sure no 32bit (signed)
displacement op is being generated, which points to the wrong address
in longmode.

Verified using readelf and made sure no R_X86_64_32S relocation symbol
is emitted. Disassembled the romstage ELF and made sure the GDT address
is 64bit in size.

Tested on QEMU and KVM-enabled QEMU: Doesn't crash any more on KVM.

Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Change-Id: Ia824f90d9611e6e8db09bd62a05e6f990581f09a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/43136
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
2020-08-21 16:01:42 +00:00

71 lines
1.3 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0-only */
#include <rules.h>
/*
* This path is for stages that are post bootblock. The gdt is reloaded
* to accommodate platforms that are executing out of CAR. In order to
* continue with C code execution one needs to set stack pointer and
* clear .bss variables that are stage specific.
*/
#if CONFIG(RESET_VECTOR_IN_RAM)
#define _STACK_TOP _eearlyram_stack
#else
#define _STACK_TOP _ecar_stack
#endif
#ifdef __x86_64__
.code64
#else
.code32
#endif
.section ".text._start", "ax", @progbits
.global _start
_start:
/* Migrate GDT to this text segment */
#ifdef __x86_64__
call gdt_init64
#else
call gdt_init
#endif
/* reset stack pointer to CAR/EARLYRAM stack */
mov $_STACK_TOP, %esp
/* clear .bss section as it is not shared */
cld
xor %eax, %eax
movl $(_ebss), %ecx
movl $(_bss), %edi
sub %edi, %ecx
shrl $2, %ecx
rep stosl
#if ((ENV_SEPARATE_VERSTAGE && CONFIG(VERSTAGE_DEBUG_SPINLOOP)) \
|| (ENV_ROMSTAGE && CONFIG(ROMSTAGE_DEBUG_SPINLOOP)))
/* Wait for a JTAG debugger to break in and set EBX non-zero */
xor %ebx, %ebx
debug_spinloop:
cmp $0, %ebx
jz debug_spinloop
#endif
andl $0xfffffff0, %esp
#if CONFIG(IDT_IN_EVERY_STAGE)
call exception_init
#endif
#if CONFIG(ASAN_IN_ROMSTAGE)
call asan_init
#endif
call car_stage_entry
/* Expect to never return. */
1:
jmp 1b