xtensa: mmu: do not fault for known exceptions
There are known exceptions which are not fatal, and we need to handle them properly by returning to the fixup addresses as indicated. This adds the code necessary in the exception handler for this situation. Signed-off-by: Daniel Leung <daniel.leung@intel.com> Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
parent
bc0656a92e
commit
e9c449a737
2 changed files with 34 additions and 12 deletions
|
@ -121,14 +121,6 @@ void z_xtensa_fatal_error(unsigned int reason, const z_arch_esf_t *esf)
|
|||
z_fatal_error(reason, esf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_EXC_DECLARE(z_xtensa_user_string_nlen);
|
||||
|
||||
static const struct z_exc_handle exceptions[] = {
|
||||
Z_EXC_HANDLE(z_xtensa_user_string_nlen)
|
||||
};
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
#ifdef XT_SIMULATOR
|
||||
void exit(int return_code)
|
||||
{
|
||||
|
|
|
@ -15,11 +15,20 @@
|
|||
#include <zephyr/logging/log.h>
|
||||
#include <offsets.h>
|
||||
#include <zsr.h>
|
||||
#include <zephyr/arch/common/exc_handle.h>
|
||||
|
||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
||||
|
||||
extern char xtensa_arch_except_epc[];
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_EXC_DECLARE(z_xtensa_user_string_nlen);
|
||||
|
||||
static const struct z_exc_handle exceptions[] = {
|
||||
Z_EXC_HANDLE(z_xtensa_user_string_nlen)
|
||||
};
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
void *xtensa_init_stack(struct k_thread *thread, int *stack_top,
|
||||
void (*entry)(void *, void *, void *),
|
||||
void *arg1, void *arg2, void *arg3)
|
||||
|
@ -335,6 +344,21 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
|||
ps = bsa->ps;
|
||||
pc = (void *)bsa->pc;
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* If the faulting address is from one of the known
|
||||
* exceptions that should not be fatal, return to
|
||||
* the fixup address.
|
||||
*/
|
||||
for (int i = 0; i < ARRAY_SIZE(exceptions); i++) {
|
||||
if ((pc >= exceptions[i].start) &&
|
||||
(pc < exceptions[i].end)) {
|
||||
bsa->pc = (uintptr_t)exceptions[i].fixup;
|
||||
|
||||
goto fixup_out;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
__asm__ volatile("rsr.excvaddr %0" : "=r"(vaddr));
|
||||
|
||||
/* Default for exception */
|
||||
|
@ -397,10 +421,6 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
|||
is_fatal_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_dblexc) {
|
||||
__asm__ volatile("wsr.depc %0" : : "r"(0));
|
||||
}
|
||||
#endif /* CONFIG_XTENSA_MMU */
|
||||
|
||||
if (is_dblexc || is_fatal_error) {
|
||||
|
@ -432,6 +452,16 @@ void *xtensa_excint1_c(int *interrupted_stack)
|
|||
_current_cpu->nested = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XTENSA_MMU
|
||||
#ifdef CONFIG_USERSPACE
|
||||
fixup_out:
|
||||
#endif
|
||||
if (is_dblexc) {
|
||||
__asm__ volatile("wsr.depc %0" : : "r"(0));
|
||||
}
|
||||
#endif /* CONFIG_XTENSA_MMU */
|
||||
|
||||
|
||||
return return_to(interrupted_stack);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue