diff options
author | Gabe Black <gabeblack@google.com> | 2013-12-11 00:23:15 -0800 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2014-12-09 18:39:06 +0100 |
commit | 20cdb2439f7e76f78d2618220fc1a0061afd57cd (patch) | |
tree | b5b21e423a0ed6c3138074bc6d8655d70443aba2 /payloads/libpayload/arch/arm | |
parent | c09cf0b7e17cc48576d09d3c48df8625ea5c990b (diff) |
libpayload: Make it possible to install callbacks for particular exceptions.
To support a GDB stub, it will be necessary to trap various exceptions which
will be used to implement breakpoints, single stepping, etc.
BUG=None
TEST=Built and booted on Link with hooks installed and saw that they
triggered when exceptions occurred. Built and booted on nyan.
BRANCH=None
Original-Change-Id: Iab659365864a3055159a50b8f6e5c44290d3ba2b
Original-Signed-off-by: Gabe Black <gabeblack@google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/179602
Original-Reviewed-by: Gabe Black <gabeblack@chromium.org>
Original-Tested-by: Gabe Black <gabeblack@chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 8db0897b1ddad600e247cb4df147c757a8187626)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I5e7f724b99988cd259909dd3bd01166fa52317ec
Reviewed-on: http://review.coreboot.org/7656
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'payloads/libpayload/arch/arm')
-rw-r--r-- | payloads/libpayload/arch/arm/exception.c | 100 | ||||
-rw-r--r-- | payloads/libpayload/arch/arm/exception_asm.S | 32 | ||||
-rw-r--r-- | payloads/libpayload/arch/arm/main.c | 2 |
3 files changed, 53 insertions, 81 deletions
diff --git a/payloads/libpayload/arch/arm/exception.c b/payloads/libpayload/arch/arm/exception.c index 099d2a46fa..f0ce0ea8c3 100644 --- a/payloads/libpayload/arch/arm/exception.c +++ b/payloads/libpayload/arch/arm/exception.c @@ -29,19 +29,27 @@ #include <arch/cache.h> #include <arch/exception.h> +#include <exception.h> #include <libpayload.h> #include <stdint.h> -uint8_t exception_stack[0x100] __attribute__((aligned(8))); +uint8_t exception_stack[0x1000] __attribute__((aligned(8))); extern void *exception_stack_end; -void exception_undefined_instruction(uint32_t *); -void exception_software_interrupt(uint32_t *); -void exception_prefetch_abort(uint32_t *); -void exception_data_abort(uint32_t *); -void exception_not_used(uint32_t *); -void exception_irq(uint32_t *); -void exception_fiq(uint32_t *); +struct exception_handler_info +{ + const char *name; + exception_hook hook; +}; + +static struct exception_handler_info exceptions[EXC_COUNT] = { + [EXC_UNDEF] = { "_undefined_instruction" }, + [EXC_SWI] = { "_software_interrupt" }, + [EXC_PABORT] = { "_prefetch_abort" }, + [EXC_DABORT] = { "_data_abort" }, + [EXC_IRQ] = { "_irq" }, + [EXC_FIQ] = { "_fiq" }, +}; static void dump_stack(uintptr_t addr, size_t bytes) { @@ -77,59 +85,25 @@ static void print_regs(uint32_t *regs) } } -void exception_undefined_instruction(uint32_t *regs) -{ - printf("exception _undefined_instruction\n"); - print_regs(regs); - dump_stack(regs[13], 512); - halt(); -} - -void exception_software_interrupt(uint32_t *regs) -{ - printf("exception _software_interrupt\n"); - print_regs(regs); - dump_stack(regs[13], 512); - halt(); -} - -void exception_prefetch_abort(uint32_t *regs) -{ - printf("exception _prefetch_abort\n"); - print_regs(regs); - dump_stack(regs[13], 512); - halt(); -} - -void exception_data_abort(uint32_t *regs) -{ - printf("exception _data_abort\n"); - print_regs(regs); - dump_stack(regs[13], 512); - halt(); -} - -void exception_not_used(uint32_t *regs) -{ - printf("exception _not_used\n"); - print_regs(regs); - dump_stack(regs[13], 512); - halt(); -} - -void exception_irq(uint32_t *regs) +void exception_dispatch(struct exception_state *state, int idx); +void exception_dispatch(struct exception_state *state, int idx) { - printf("exception _irq\n"); - print_regs(regs); - dump_stack(regs[13], 512); - halt(); -} - -void exception_fiq(uint32_t *regs) -{ - printf("exception _fiq\n"); - print_regs(regs); - dump_stack(regs[13], 512); + if (idx >= EXC_COUNT) { + printf("Bad exception index %d.\n", idx); + } else { + struct exception_handler_info *info = &exceptions[idx]; + if (info->hook) { + info->hook(idx, state); + return; + } + + if (info->name) + printf("exception %s\n", info->name); + else + printf("exception _not_used.\n"); + } + print_regs(state->regs); + dump_stack(state->regs[13], 512); halt(); } @@ -146,3 +120,9 @@ void exception_init(void) set_vbar((uintptr_t)exception_table); exception_stack_end = exception_stack + sizeof(exception_stack); } + +void exception_install_hook(int type, exception_hook hook) +{ + die_if(type >= EXC_COUNT, "Out of bounds exception index %d.\n", type); + exceptions[type].hook = hook; +} diff --git a/payloads/libpayload/arch/arm/exception_asm.S b/payloads/libpayload/arch/arm/exception_asm.S index 1f369bcc05..6a28c5cdef 100644 --- a/payloads/libpayload/arch/arm/exception_asm.S +++ b/payloads/libpayload/arch/arm/exception_asm.S @@ -43,59 +43,51 @@ exception_table: b 8f 1: - ldr sp, _not_used + mov sp, $0 b exception_common 2: - ldr sp, _undefined_instruction + mov sp, $1 b exception_common 3: - ldr sp, _software_interrupt + mov sp, $2 b exception_common 4: - ldr sp, _prefetch_abort + mov sp, $3 b exception_common 5: - ldr sp, _data_abort + mov sp, $4 b exception_common 6: - ldr sp, _not_used + mov sp, $5 b exception_common 7: - ldr sp, _irq + mov sp, $6 b exception_common 8: - ldr sp, _fiq + mov sp, $7 b exception_common exception_common: - str sp, exception_handler + str sp, exception_idx ldr sp, exception_stack_end push { lr } stmfd sp, { sp, lr }^ sub sp, sp, $8 push { r0 - r12 } mov r0, sp - mov lr, pc - ldr pc, exception_handler + ldr r1, exception_idx + blx exception_dispatch pop { r0 - r12 } add sp, sp, $8 ldmfd sp!, { pc }^ .align 2 -_undefined_instruction: .word exception_undefined_instruction -_software_interrupt: .word exception_software_interrupt -_prefetch_abort: .word exception_prefetch_abort -_data_abort: .word exception_data_abort -_not_used: .word exception_not_used -_irq: .word exception_irq -_fiq: .word exception_fiq - .global exception_stack_end exception_stack_end: .word 0 -exception_handler: +exception_idx: .word 0 .thumb diff --git a/payloads/libpayload/arch/arm/main.c b/payloads/libpayload/arch/arm/main.c index 4e7c05dfe1..cff992fce6 100644 --- a/payloads/libpayload/arch/arm/main.c +++ b/payloads/libpayload/arch/arm/main.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ -#include <arch/exception.h> +#include <exception.h> #include <libpayload.h> unsigned int main_argc; /**< The argc value to pass to main() */ |