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

Change-Id: Id950fb09d72fb0f81e4eef2489c0849ce5dd8aca
Signed-off-by: Gabe Black <gabeblack@google.com>
Reviewed-on: https://chromium-review.googlesource.com/180253
Reviewed-by: Gabe Black <gabeblack@chromium.org>
Tested-by: Gabe Black <gabeblack@chromium.org>
Commit-Queue: Gabe Black <gabeblack@chromium.org>
This commit is contained in:
Gabe Black 2013-12-16 04:07:50 -08:00 committed by chrome-internal-fetch
commit 8e7014f24a
3 changed files with 9 additions and 3 deletions

View file

@ -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();
}

View file

@ -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 }^

View file

@ -36,6 +36,7 @@ void set_vbar(uint32_t vbar);
struct exception_state
{
uint32_t cpsr;
uint32_t regs[16];
} __attribute__((packed));