You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.7 KiB
142 lines
3.7 KiB
/* |
|
* Copyright (c) 2016 Intel Corporation |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <zephyr/kernel.h> |
|
#include <zephyr/arch/cpu.h> |
|
#include <zephyr/kernel_structs.h> |
|
#include <inttypes.h> |
|
#include <zephyr/logging/log.h> |
|
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); |
|
|
|
FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, |
|
const z_arch_esf_t *esf) |
|
{ |
|
if (esf != NULL) { |
|
/* Subtract 4 from EA since we added 4 earlier so that the |
|
* faulting instruction isn't retried. |
|
* |
|
* TODO: Only caller-saved registers get saved upon exception |
|
* entry. We may want to introduce a config option to save and |
|
* dump all registers, at the expense of some stack space. |
|
*/ |
|
LOG_ERR("Faulting instruction: 0x%08x", esf->instr - 4); |
|
LOG_ERR(" r1: 0x%08x r2: 0x%08x r3: 0x%08x r4: 0x%08x", |
|
esf->r1, esf->r2, esf->r3, esf->r4); |
|
LOG_ERR(" r5: 0x%08x r6: 0x%08x r7: 0x%08x r8: 0x%08x", |
|
esf->r5, esf->r6, esf->r7, esf->r8); |
|
LOG_ERR(" r9: 0x%08x r10: 0x%08x r11: 0x%08x r12: 0x%08x", |
|
esf->r9, esf->r10, esf->r11, esf->r12); |
|
LOG_ERR(" r13: 0x%08x r14: 0x%08x r15: 0x%08x ra: 0x%08x", |
|
esf->r13, esf->r14, esf->r15, esf->ra); |
|
LOG_ERR("estatus: %08x", esf->estatus); |
|
} |
|
|
|
z_fatal_error(reason, esf); |
|
CODE_UNREACHABLE; |
|
} |
|
|
|
#if defined(CONFIG_EXTRA_EXCEPTION_INFO) && \ |
|
(defined(CONFIG_PRINTK) || defined(CONFIG_LOG)) \ |
|
&& defined(ALT_CPU_HAS_EXTRA_EXCEPTION_INFO) |
|
static char *cause_str(uint32_t cause_code) |
|
{ |
|
switch (cause_code) { |
|
case 0: |
|
return "reset"; |
|
case 1: |
|
return "processor-only reset request"; |
|
case 2: |
|
return "interrupt"; |
|
case 3: |
|
return "trap"; |
|
case 4: |
|
return "unimplemented instruction"; |
|
case 5: |
|
return "illegal instruction"; |
|
case 6: |
|
return "misaligned data address"; |
|
case 7: |
|
return "misaligned destination address"; |
|
case 8: |
|
return "division error"; |
|
case 9: |
|
return "supervisor-only instruction address"; |
|
case 10: |
|
return "supervisor-only instruction"; |
|
case 11: |
|
return "supervisor-only data address"; |
|
case 12: |
|
return "TLB miss"; |
|
case 13: |
|
return "TLB permission violation (execute)"; |
|
case 14: |
|
return "TLB permission violation (read)"; |
|
case 15: |
|
return "TLB permission violation (write)"; |
|
case 16: |
|
return "MPU region violation (instruction)"; |
|
case 17: |
|
return "MPU region violation (data)"; |
|
case 18: |
|
return "ECC TLB error"; |
|
case 19: |
|
return "ECC fetch error (instruction)"; |
|
case 20: |
|
return "ECC register file error"; |
|
case 21: |
|
return "ECC data error"; |
|
case 22: |
|
return "ECC data cache writeback error"; |
|
case 23: |
|
return "bus instruction fetch error"; |
|
case 24: |
|
return "bus data region violation"; |
|
default: |
|
return "unknown"; |
|
} |
|
} |
|
#endif |
|
|
|
FUNC_NORETURN void _Fault(const z_arch_esf_t *esf) |
|
{ |
|
#if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) |
|
/* Unfortunately, completely unavailable on Nios II/e cores */ |
|
#ifdef ALT_CPU_HAS_EXTRA_EXCEPTION_INFO |
|
uint32_t exc_reg, badaddr_reg, eccftl; |
|
enum nios2_exception_cause cause; |
|
|
|
exc_reg = z_nios2_creg_read(NIOS2_CR_EXCEPTION); |
|
|
|
/* Bit 31 indicates potentially fatal ECC error */ |
|
eccftl = (exc_reg & NIOS2_EXCEPTION_REG_ECCFTL_MASK) != 0U; |
|
|
|
/* Bits 2-6 contain the cause code */ |
|
cause = (exc_reg & NIOS2_EXCEPTION_REG_CAUSE_MASK) |
|
>> NIOS2_EXCEPTION_REG_CAUSE_OFST; |
|
|
|
LOG_ERR("Exception cause: %d ECCFTL: 0x%x", cause, eccftl); |
|
#if CONFIG_EXTRA_EXCEPTION_INFO |
|
LOG_ERR("reason: %s", cause_str(cause)); |
|
#endif |
|
if (BIT(cause) & NIOS2_BADADDR_CAUSE_MASK) { |
|
badaddr_reg = z_nios2_creg_read(NIOS2_CR_BADADDR); |
|
LOG_ERR("Badaddr: 0x%x", badaddr_reg); |
|
} |
|
#endif /* ALT_CPU_HAS_EXTRA_EXCEPTION_INFO */ |
|
#endif /* CONFIG_PRINTK || CONFIG_LOG */ |
|
|
|
z_nios2_fatal_error(K_ERR_CPU_EXCEPTION, esf); |
|
} |
|
|
|
#ifdef ALT_CPU_HAS_DEBUG_STUB |
|
FUNC_NORETURN void arch_system_halt(unsigned int reason) |
|
{ |
|
ARG_UNUSED(reason); |
|
|
|
z_nios2_break(); |
|
CODE_UNREACHABLE; |
|
} |
|
#endif
|
|
|