diff options
author | Julius Werner <jwerner@chromium.org> | 2014-05-14 14:53:18 -0700 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2015-01-03 00:26:18 +0100 |
commit | 989e12bb6387bd06037805dcefa249d998b55b74 (patch) | |
tree | ed3c6e76eac6026ca939df452622d27bc555d864 /payloads/libpayload/arch | |
parent | 739e6a84aa9ccacf54db3da6c1e0777cb86ebea5 (diff) |
arm: Fix stored PC value when handling exceptions
ARM processors save the PC value in the Link Register when they handle
and exception, but they store it with an added offset (depending on the
exception type). In order to make crashes easier to read and correctly
support more complicated handlers in libpayload, this patch adjusts the
saved PC value on exception entry to correct for that offset.
(Note: The value that we now store is what ARM calls the "preferred
return address". For most exceptions this is the faulting instruction,
but for software interrupts (SWI) it is the instruction after that. This
is the way most programs like GDB expect the stored PC address to work,
so let's leave it at that.)
Numbers taken from the Architecture Reference Manual at the end of
section B1.8.3.
BRANCH=none
BUG=chrome-os-partner:18390
TEST=Provoked a data abort and an undefined instruction in both coreboot
and depthcharge, confirmed that the PC address was spot on.
Original-Change-Id: Ia958a7edfcd4aa5e04c20148140a6148586935ba
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/199844
Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
Original-Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
(cherry picked from commit 4a914d36bb181d090f75b1414158846d40dc9bac)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: Ib63ca973d5f037a879b4d4d258a4983160b67dd6
Reviewed-on: http://review.coreboot.org/7992
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Diffstat (limited to 'payloads/libpayload/arch')
-rw-r--r-- | payloads/libpayload/arch/arm/exception_asm.S | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/payloads/libpayload/arch/arm/exception_asm.S b/payloads/libpayload/arch/arm/exception_asm.S index 974d1724b5..7b722cb86f 100644 --- a/payloads/libpayload/arch/arm/exception_asm.S +++ b/payloads/libpayload/arch/arm/exception_asm.S @@ -45,25 +45,44 @@ exception_table: 1: mov sp, $0 b exception_common + +/* Undefined Instruction (CAREFUL: the PC offset is specific to thumb mode!) */ 2: + sub lr, lr, $2 mov sp, $1 b exception_common + +/* Software Interrupt (no PC offset necessary) */ 3: mov sp, $2 b exception_common + +/* Prefetch Abort */ 4: + sub lr, lr, $4 mov sp, $3 b exception_common + +/* Data Abort */ 5: + sub lr, lr, $8 mov sp, $4 b exception_common + +/* (not used) */ 6: mov sp, $5 b exception_common + +/* Interrupt */ 7: + sub lr, lr, $4 mov sp, $6 b exception_common + +/* Fast Interrupt */ 8: + sub lr, lr, $4 mov sp, $7 b exception_common |