arch/x86: Support x86_64 exceptions

*   Doesn't affect existing x86_32 code.

Tested on qemu using division by zero.
Tested on Lenovo T410 with additional x86_64 patches.

Change-Id: Idd12c90a95cc2989eb9b2a718740a84222193f48
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/30117
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
This commit is contained in:
Paul Menzel 2019-06-24 18:44:33 +02:00 committed by Philipp Deppenwiese
parent d9c6862809
commit 6663ad99cf
4 changed files with 141 additions and 40 deletions

View File

@ -42,7 +42,7 @@ At the moment *$n* is 4, which results in identity mapping the lower 4 GiB.
* Fix compilation errors - *DONE*
* Fix linker errors - *TODO*
* Add x86_64 rmodule support - *DONE*
* Add x86_64 exception handlers - *TODO*
* Add x86_64 exception handlers - *DONE*
* Setup page tables for long mode - *DONE*
* Add assembly code for long mode - *DONE*
* Add assembly code for postcar stage - *TODO*

View File

@ -489,12 +489,38 @@ void x86_exception(struct eregs *info)
put_packet(out_buffer);
}
#else /* !CONFIG_GDB_STUB */
#define MDUMP_SIZE 0x80
int logical_processor = 0;
#if ENV_RAMSTAGE
logical_processor = cpu_index();
#endif
u8 *code;
#ifdef __x86_64__
#define MDUMP_SIZE 0x100
printk(BIOS_EMERG,
"CPU Index %d - APIC %d Unexpected Exception:\n"
"%lld @ %02llx:%016llx - Halting\n"
"Code: %lld rflags: %016llx cr2: %016llx\n"
"rax: %016llx rbx: %016llx\n"
"rcx: %016llx rdx: %016llx\n"
"rdi: %016llx rsi: %016llx\n"
"rbp: %016llx rsp: %016llx\n"
"r08: %016llx r09: %016llx\n"
"r10: %016llx r11: %016llx\n"
"r12: %016llx r13: %016llx\n"
"r14: %016llx r15: %016llx\n",
logical_processor, (unsigned int)lapicid(),
info->vector, info->cs, info->rip,
info->error_code, info->rflags, read_cr2(),
info->rax, info->rbx, info->rcx, info->rdx,
info->rdi, info->rsi, info->rbp, info->rsp,
info->r8, info->r9, info->r10, info->r11,
info->r12, info->r13, info->r14, info->r15);
code = (u8 *)((uintptr_t)info->rip - (MDUMP_SIZE >> 2));
#else
#define MDUMP_SIZE 0x80
printk(BIOS_EMERG,
"CPU Index %d - APIC %d Unexpected Exception:"
"%d @ %02x:%08x - Halting\n"
@ -506,7 +532,8 @@ void x86_exception(struct eregs *info)
info->error_code, info->eflags, read_cr2(),
info->eax, info->ebx, info->ecx, info->edx,
info->edi, info->esi, info->ebp, info->esp);
u8 *code = (u8 *)((uintptr_t)info->eip - (MDUMP_SIZE >> 1));
code = (u8 *)((uintptr_t)info->eip - (MDUMP_SIZE >> 1));
#endif
/* Align to 8-byte boundary please, and print eight bytes per row.
* This is done to make DRAM burst timing/reordering errors more
* evident from the looking at the dump */

View File

@ -109,6 +109,68 @@ vec19:
.global int_hand
int_hand:
#ifdef __x86_64__
/* At this point, on x86-64, on the stack there is:
* 0(%rsp) vector
* 8(%rsp) error code
* 16(%rsp) rip
* 24(%rsp) cs
* 32(%rsp) rflags
* 40(%rsp) rsp
* 48(%rsp) ss
*/
push %r15
push %r14
push %r13
push %r12
push %r11
push %r10
push %r9
push %r8
push %rdi
push %rsi
push %rbp
push %rbx
push %rdx
push %rcx
push %rax
/* Pass pointer to struct as first argument */
mov %rsp, %rdi
/* Back up stack pointer */
mov %rsp, %rbp
/* Align stack to 16 bytes. */
and $(~0xf), %rsp
call x86_exception
/* Restore stack pointer from backup */
mov %rbp, %rsp
pop %rax
pop %rcx
pop %rdx
pop %rbx
pop %rbp
pop %rsi
pop %rdi
pop %r8
pop %r9
pop %r10
pop %r11
pop %r12
pop %r13
pop %r14
pop %r15
add $16, %rsp /* pop of the vector and error code */
#else
/* At this point, on x86-32, on the stack there is:
* 0(%esp) vector
* 4(%esp) error code
@ -116,33 +178,6 @@ int_hand:
* 12(%esp) cs
* 16(%esp) eflags
*/
#ifdef __x86_64__
push %rdi
push %rsi
push %rbp
/* Original stack pointer */
lea 32(%rsp), %rbp
push %rbp
push %rbx
push %rdx
push %rcx
push %rax
push %rsp /* Pointer to structure on the stack */
call x86_exception
pop %rax /* Drop the pointer */
pop %rax
pop %rcx
pop %rdx
pop %rbx
pop %rbp /* Ignore saved %rsp value */
pop %rbp
pop %rsi
pop %rdi
add $8, %rsp /* pop of the vector and error code */
#else
pushl %edi
pushl %esi
pushl %ebp

View File

@ -6,7 +6,7 @@
#if !defined(__ASSEMBLER__)
#include <stdint.h>
#define DOWNTO8(A) \
#define LONG_DOWNTO8(A) \
union { \
struct { \
union { \
@ -21,7 +21,7 @@
uint32_t e##A##x; \
} __packed;
#define DOWNTO16(A) \
#define LONG_DOWNTO16(A) \
union { \
struct { \
uint16_t A; \
@ -30,21 +30,60 @@
uint32_t e##A; \
} __packed;
#define QUAD_DOWNTO8(A) \
union { \
LONG_DOWNTO8(A) \
uint64_t r##A##x; \
} __packed
#define QUAD_DOWNTO16(A) \
union {\
LONG_DOWNTO16(A) \
uint64_t r##A; \
} __packed
#ifdef __ARCH_x86_64__
struct eregs {
DOWNTO8(a);
DOWNTO8(c);
DOWNTO8(d);
DOWNTO8(b);
DOWNTO16(sp);
DOWNTO16(bp);
DOWNTO16(si);
DOWNTO16(di);
QUAD_DOWNTO8(a);
QUAD_DOWNTO8(c);
QUAD_DOWNTO8(d);
QUAD_DOWNTO8(b);
QUAD_DOWNTO16(bp);
QUAD_DOWNTO16(si);
QUAD_DOWNTO16(di);
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t vector;
uint64_t error_code;
uint64_t rip;
uint64_t cs;
uint64_t rflags;
QUAD_DOWNTO16(sp);
uint64_t ss;
};
#else
struct eregs {
LONG_DOWNTO8(a);
LONG_DOWNTO8(c);
LONG_DOWNTO8(d);
LONG_DOWNTO8(b);
LONG_DOWNTO16(sp);
LONG_DOWNTO16(bp);
LONG_DOWNTO16(si);
LONG_DOWNTO16(di);
uint32_t vector;
uint32_t error_code;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
};
#endif
#endif // !ASSEMBLER
#if CONFIG(COMPILER_LLVM_CLANG)