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:
parent
d9c6862809
commit
6663ad99cf
|
@ -42,7 +42,7 @@ At the moment *$n* is 4, which results in identity mapping the lower 4 GiB.
|
||||||
* Fix compilation errors - *DONE*
|
* Fix compilation errors - *DONE*
|
||||||
* Fix linker errors - *TODO*
|
* Fix linker errors - *TODO*
|
||||||
* Add x86_64 rmodule support - *DONE*
|
* 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*
|
* Setup page tables for long mode - *DONE*
|
||||||
* Add assembly code for long mode - *DONE*
|
* Add assembly code for long mode - *DONE*
|
||||||
* Add assembly code for postcar stage - *TODO*
|
* Add assembly code for postcar stage - *TODO*
|
||||||
|
|
|
@ -489,12 +489,38 @@ void x86_exception(struct eregs *info)
|
||||||
put_packet(out_buffer);
|
put_packet(out_buffer);
|
||||||
}
|
}
|
||||||
#else /* !CONFIG_GDB_STUB */
|
#else /* !CONFIG_GDB_STUB */
|
||||||
#define MDUMP_SIZE 0x80
|
|
||||||
int logical_processor = 0;
|
int logical_processor = 0;
|
||||||
|
|
||||||
#if ENV_RAMSTAGE
|
#if ENV_RAMSTAGE
|
||||||
logical_processor = cpu_index();
|
logical_processor = cpu_index();
|
||||||
#endif
|
#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,
|
printk(BIOS_EMERG,
|
||||||
"CPU Index %d - APIC %d Unexpected Exception:"
|
"CPU Index %d - APIC %d Unexpected Exception:"
|
||||||
"%d @ %02x:%08x - Halting\n"
|
"%d @ %02x:%08x - Halting\n"
|
||||||
|
@ -506,7 +532,8 @@ void x86_exception(struct eregs *info)
|
||||||
info->error_code, info->eflags, read_cr2(),
|
info->error_code, info->eflags, read_cr2(),
|
||||||
info->eax, info->ebx, info->ecx, info->edx,
|
info->eax, info->ebx, info->ecx, info->edx,
|
||||||
info->edi, info->esi, info->ebp, info->esp);
|
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.
|
/* Align to 8-byte boundary please, and print eight bytes per row.
|
||||||
* This is done to make DRAM burst timing/reordering errors more
|
* This is done to make DRAM burst timing/reordering errors more
|
||||||
* evident from the looking at the dump */
|
* evident from the looking at the dump */
|
||||||
|
|
|
@ -109,6 +109,68 @@ vec19:
|
||||||
|
|
||||||
.global int_hand
|
.global int_hand
|
||||||
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:
|
/* At this point, on x86-32, on the stack there is:
|
||||||
* 0(%esp) vector
|
* 0(%esp) vector
|
||||||
* 4(%esp) error code
|
* 4(%esp) error code
|
||||||
|
@ -116,33 +178,6 @@ int_hand:
|
||||||
* 12(%esp) cs
|
* 12(%esp) cs
|
||||||
* 16(%esp) eflags
|
* 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 %edi
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#if !defined(__ASSEMBLER__)
|
#if !defined(__ASSEMBLER__)
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define DOWNTO8(A) \
|
#define LONG_DOWNTO8(A) \
|
||||||
union { \
|
union { \
|
||||||
struct { \
|
struct { \
|
||||||
union { \
|
union { \
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
uint32_t e##A##x; \
|
uint32_t e##A##x; \
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define DOWNTO16(A) \
|
#define LONG_DOWNTO16(A) \
|
||||||
union { \
|
union { \
|
||||||
struct { \
|
struct { \
|
||||||
uint16_t A; \
|
uint16_t A; \
|
||||||
|
@ -30,21 +30,60 @@
|
||||||
uint32_t e##A; \
|
uint32_t e##A; \
|
||||||
} __packed;
|
} __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 {
|
struct eregs {
|
||||||
DOWNTO8(a);
|
QUAD_DOWNTO8(a);
|
||||||
DOWNTO8(c);
|
QUAD_DOWNTO8(c);
|
||||||
DOWNTO8(d);
|
QUAD_DOWNTO8(d);
|
||||||
DOWNTO8(b);
|
QUAD_DOWNTO8(b);
|
||||||
DOWNTO16(sp);
|
QUAD_DOWNTO16(bp);
|
||||||
DOWNTO16(bp);
|
QUAD_DOWNTO16(si);
|
||||||
DOWNTO16(si);
|
QUAD_DOWNTO16(di);
|
||||||
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 vector;
|
||||||
uint32_t error_code;
|
uint32_t error_code;
|
||||||
uint32_t eip;
|
uint32_t eip;
|
||||||
uint32_t cs;
|
uint32_t cs;
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
#endif // !ASSEMBLER
|
#endif // !ASSEMBLER
|
||||||
|
|
||||||
#if CONFIG(COMPILER_LLVM_CLANG)
|
#if CONFIG(COMPILER_LLVM_CLANG)
|
||||||
|
|
Loading…
Reference in New Issue