summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2013-12-16 04:07:50 -0800
committerMarc Jones <marc.jones@se-eng.com>2014-12-09 18:39:14 +0100
commit97345dbc6c2f031158f249b3dda89200784b86b4 (patch)
tree9d5dfc98cd2f06269500d250d6c4f62fa38fce24
parent20cdb2439f7e76f78d2618220fc1a0061afd57cd (diff)
downloadcoreboot-97345dbc6c2f031158f249b3dda89200784b86b4.tar.xz
libpayload: ARM: Keep track of the CPSR when exceptions happen.
Use the SPSR to extract and inject CPSR values when an exception happens and pass that information to exception hooks. The register structure GDB expects when using its remote protocol has a spot for the CPSR. BUG=None TEST=Built and booted on link, nyan. BRANCH=None Original-Change-Id: Id950fb09d72fb0f81e4eef2489c0849ce5dd8aca Original-Signed-off-by: Gabe Black <gabeblack@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/180253 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 8e7014f24a580f84c91fa7b0369dfa922918adcc) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: I49357fb6a65edeff7a9a48d54254308a6b0efdb7 Reviewed-on: http://review.coreboot.org/7657 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
-rw-r--r--payloads/libpayload/arch/arm/exception.c7
-rw-r--r--payloads/libpayload/arch/arm/exception_asm.S4
-rw-r--r--payloads/libpayload/include/arm/arch/exception.h1
3 files changed, 9 insertions, 3 deletions
diff --git a/payloads/libpayload/arch/arm/exception.c b/payloads/libpayload/arch/arm/exception.c
index f0ce0ea8c3..45b77a7460 100644
--- a/payloads/libpayload/arch/arm/exception.c
+++ b/payloads/libpayload/arch/arm/exception.c
@@ -66,7 +66,7 @@ static void dump_stack(uintptr_t addr, size_t bytes)
}
}
-static void print_regs(uint32_t *regs)
+static void print_regs(struct exception_state *state)
{
int i;
@@ -81,8 +81,9 @@ static void print_regs(uint32_t *regs)
printf("IP");
else
printf("R%d", i);
- printf(" = 0x%08x\n", regs[i]);
+ printf(" = 0x%08x\n", state->regs[i]);
}
+ printf("CPSR = 0x%08x\n", state->cpsr);
}
void exception_dispatch(struct exception_state *state, int idx);
@@ -102,7 +103,7 @@ void exception_dispatch(struct exception_state *state, int idx)
else
printf("exception _not_used.\n");
}
- print_regs(state->regs);
+ print_regs(state);
dump_stack(state->regs[13], 512);
halt();
}
diff --git a/payloads/libpayload/arch/arm/exception_asm.S b/payloads/libpayload/arch/arm/exception_asm.S
index 6a28c5cdef..974d1724b5 100644
--- a/payloads/libpayload/arch/arm/exception_asm.S
+++ b/payloads/libpayload/arch/arm/exception_asm.S
@@ -74,9 +74,13 @@ exception_common:
stmfd sp, { sp, lr }^
sub sp, sp, $8
push { r0 - r12 }
+ mrs r0, SPSR
+ push { r0 }
mov r0, sp
ldr r1, exception_idx
blx exception_dispatch
+ pop { r0 }
+ msr SPSR_cxsf, r0
pop { r0 - r12 }
add sp, sp, $8
ldmfd sp!, { pc }^
diff --git a/payloads/libpayload/include/arm/arch/exception.h b/payloads/libpayload/include/arm/arch/exception.h
index 13fda57aa7..c6864a5ad2 100644
--- a/payloads/libpayload/include/arm/arch/exception.h
+++ b/payloads/libpayload/include/arm/arch/exception.h
@@ -36,6 +36,7 @@ void set_vbar(uint32_t vbar);
struct exception_state
{
+ uint32_t cpsr;
uint32_t regs[16];
} __attribute__((packed));