]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
microblaze: exception: fix return address for delay slot exceptions
authorOvidiu Panait <ovidiu.panait@windriver.com>
Sun, 13 Feb 2022 08:09:22 +0000 (10:09 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 15 Feb 2022 12:11:43 +0000 (13:11 +0100)
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>
arch/microblaze/cpu/exception.c

index 64d5fe4a80c5ef2a3d81299f74b7b21d74c0d16b..f79e465e1fb5faf6d3b55a153176222e3c410cc5 100644 (file)
@@ -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);