summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOvidiu Panait <ovidiu.panait@windriver.com>2022-02-13 10:09:22 +0200
committerMichal Simek <michal.simek@xilinx.com>2022-02-15 13:11:43 +0100
commitee8161f7d182e57ea828f77a6b246c884c70b7cd (patch)
treeaeee6ced6a02ba6d2f266cdaf102d9b7db4758d7
parent7422b411757faa2a01487b43138f29b4fdde3c74 (diff)
microblaze: exception: fix return address for delay slot exceptions
According to the MicroBlaze reference manual (xilinx2021.2/ug984/page-37): """ If an exception is caused by an instruction in a delay slot (that is, ESR[DS]=1), the exception handler should return execution to the address stored in BTR instead of the normal exception return address stored in R17. """ Adjust the code to print the proper return address for delay slot exceptions. Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com> Link: https://lore.kernel.org/r/20220213080925.1548411-4-ovidiu.panait@windriver.com Signed-off-by: Michal Simek <michal.simek@xilinx.com>
-rw-r--r--arch/microblaze/cpu/exception.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c
index 64d5fe4a80c..f79e465e1fb 100644
--- a/arch/microblaze/cpu/exception.c
+++ b/arch/microblaze/cpu/exception.c
@@ -20,11 +20,17 @@ void _hw_exception_handler (void)
MFS(state, resr);
printf("Hardware exception at 0x%x address\n", address);
R17(address);
- printf("Return address from exception 0x%x\n", address);
if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) &&
- (state & 0x1000))
+ (state & 0x1000)) {
+ /*
+ * For exceptions in delay slots, the return address is stored
+ * in the Branch Target Register (BTR), rather than R17.
+ */
+ MFS(address, rbtr);
+
puts("Exception in delay slot\n");
+ }
switch (state & 0x1f) { /* mask on exception cause */
case 0x1:
@@ -49,6 +55,8 @@ void _hw_exception_handler (void)
puts("Undefined cause\n");
break;
}
+
+ printf("Return address from exception 0x%x\n", address);
printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half"));
printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load"));
printf("Register R%x\n", (state & 0x3E) >> 5);