mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-17 22:28:17 +01:00
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>
73 lines
1.6 KiB
C
73 lines
1.6 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* (C) Copyright 2007 Michal Simek
|
|
*
|
|
* Michal SIMEK <monstr@monstr.eu>
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <hang.h>
|
|
#include <asm/asm.h>
|
|
|
|
void _hw_exception_handler (void)
|
|
{
|
|
int address = 0;
|
|
int state = 0;
|
|
|
|
/* loading address of exception EAR */
|
|
MFS(address, rear);
|
|
/* loading excetpion state register ESR */
|
|
MFS(state, resr);
|
|
printf("Hardware exception at 0x%x address\n", address);
|
|
R17(address);
|
|
|
|
if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) &&
|
|
(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:
|
|
puts("Unaligned data access exception\n");
|
|
break;
|
|
case 0x2:
|
|
puts("Illegal op-code exception\n");
|
|
break;
|
|
case 0x3:
|
|
puts("Instruction bus error exception\n");
|
|
break;
|
|
case 0x4:
|
|
puts("Data bus error exception\n");
|
|
break;
|
|
case 0x5:
|
|
puts("Divide by zero exception\n");
|
|
break;
|
|
case 0x7:
|
|
puts("Priviledged or stack protection violation exception\n");
|
|
break;
|
|
default:
|
|
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);
|
|
hang();
|
|
}
|
|
|
|
#if CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USR_EXCEP)
|
|
void _exception_handler (void)
|
|
{
|
|
puts("User vector_exception\n");
|
|
hang();
|
|
}
|
|
#endif
|