From 453a1a7332cdd93a6b06b58cce93d9a558b04cfd Mon Sep 17 00:00:00 2001 From: zhangyuan21 Date: Wed, 14 Dec 2022 09:58:38 +0800 Subject: [PATCH] arch: move stack and task dump to common code Signed-off-by: zhangyuan21 --- arch/arm/src/armv7-a/arm_cpustart.c | 31 +- arch/arm/src/common/Make.defs | 2 +- arch/arm/src/common/arm_assert.c | 368 +--------------- arch/arm/src/common/arm_checkstack.c | 7 +- arch/arm/src/common/arm_getintstack.c | 49 +++ arch/arm/src/common/arm_internal.h | 2 + arch/arm/src/common/arm_registerdump.c | 98 +++++ arch/arm/src/nrf52/nrf52_sdc.c | 4 +- arch/arm64/src/common/Make.defs | 1 + arch/arm64/src/common/arm64_assert.c | 401 +----------------- arch/arm64/src/common/arm64_checkstack.c | 7 +- arch/arm64/src/common/arm64_getintstack.c | 48 +++ arch/arm64/src/common/arm64_internal.h | 2 + arch/arm64/src/common/arm64_registerdump.c | 103 +++++ arch/avr/src/at32uc3/Make.defs | 7 +- arch/avr/src/at90usb/Make.defs | 5 +- arch/avr/src/atmega/Make.defs | 5 +- arch/avr/src/avr/avr_dumpstate.c | 220 ---------- arch/avr/src/avr/avr_registerdump.c | 101 +++++ arch/avr/src/avr32/avr_dumpstate.c | 191 --------- .../src/avr32/avr_registerdump.c} | 68 ++- arch/avr/src/common/avr_assert.c | 4 +- arch/avr/src/common/avr_getintstack.c | 44 ++ arch/avr/src/common/avr_internal.h | 6 +- arch/ceva/src/common/ceva_assert.c | 194 +-------- arch/ceva/src/common/ceva_getintstack.c | 44 ++ arch/ceva/src/common/ceva_internal.h | 2 + arch/ceva/src/common/ceva_registerdump.c | 63 +++ arch/hc/src/common/hc_getintstack.c | 44 ++ arch/hc/src/common/hc_internal.h | 2 + arch/hc/src/m9s12/Make.defs | 4 +- arch/hc/src/m9s12/m9s12_assert.c | 159 +------ arch/hc/src/m9s12/m9s12_registerdump.c | 78 ++++ arch/mips/src/common/mips_getintstack.c | 44 ++ arch/mips/src/common/mips_internal.h | 6 +- arch/mips/src/mips32/mips_assert.c | 4 +- arch/mips/src/mips32/mips_dumpstate.c | 211 --------- arch/mips/src/mips32/mips_registerdump.c | 99 +++++ arch/mips/src/mips32/mips_swint0.c | 34 +- arch/mips/src/pic32mx/Make.defs | 5 +- arch/mips/src/pic32mz/Make.defs | 5 +- arch/misoc/src/lm32/Make.defs | 2 +- arch/misoc/src/lm32/lm32.h | 2 +- arch/misoc/src/lm32/lm32_assert.c | 4 +- arch/misoc/src/lm32/lm32_dumpstate.c | 197 --------- arch/misoc/src/lm32/lm32_registerdump.c | 88 ++++ arch/misoc/src/lm32/lm32_swint.c | 37 +- arch/misoc/src/minerva/Make.defs | 2 +- arch/misoc/src/minerva/minerva.h | 2 +- arch/misoc/src/minerva/minerva_assert.c | 4 +- arch/misoc/src/minerva/minerva_dumpstate.c | 199 --------- arch/misoc/src/minerva/minerva_registerdump.c | 87 ++++ arch/misoc/src/minerva/minerva_swint.c | 37 +- arch/or1k/src/common/or1k_assert.c | 202 +-------- arch/or1k/src/common/or1k_getintstack.c | 44 ++ arch/or1k/src/common/or1k_internal.h | 2 + arch/or1k/src/common/or1k_registerdump.c | 69 +++ arch/or1k/src/mor1kx/Make.defs | 2 + arch/renesas/src/common/renesas_assert.c | 25 +- arch/renesas/src/common/renesas_getintstack.c | 44 ++ arch/renesas/src/common/renesas_internal.h | 15 +- arch/renesas/src/m16c/Make.defs | 5 +- arch/renesas/src/m16c/chip.h | 9 - arch/renesas/src/m16c/m16c_dumpstate.c | 215 ---------- .../src/m16c/m16c_registerdump.c} | 87 ++-- arch/renesas/src/rx65n/Make.defs | 5 +- arch/renesas/src/rx65n/rx65n_dumpstate.c | 215 ---------- arch/renesas/src/rx65n/rx65n_registerdump.c | 78 ++++ arch/renesas/src/sh1/Make.defs | 4 +- arch/renesas/src/sh1/chip.h | 9 - arch/renesas/src/sh1/sh1_dumpstate.c | 195 --------- arch/renesas/src/sh1/sh1_registerdump.c | 70 +++ arch/risc-v/src/common/Make.defs | 2 +- arch/risc-v/src/common/riscv_assert.c | 349 +-------------- arch/risc-v/src/common/riscv_getintstack.c | 44 ++ arch/risc-v/src/common/riscv_internal.h | 2 + arch/risc-v/src/common/riscv_registerdump.c | 89 ++++ arch/risc-v/src/common/riscv_swint.c | 41 +- arch/sim/src/sim/sim_assert.c | 12 +- arch/sparc/src/common/Make.defs | 2 +- arch/sparc/src/common/sparc_assert.c | 4 +- arch/sparc/src/common/sparc_getintstack.c | 44 ++ arch/sparc/src/common/sparc_internal.h | 6 +- arch/sparc/src/sparc_v8/Make.defs | 8 +- arch/sparc/src/sparc_v8/sparc_v8_dumpstate.c | 216 ---------- .../src/sparc_v8/sparc_v8_registerdump.c | 75 ++++ arch/sparc/src/sparc_v8/sparc_v8_swint1.c | 14 +- arch/x86/src/common/x86_assert.c | 122 +----- arch/x86/src/common/x86_getintstack.c | 44 ++ arch/x86/src/i486/i486_regdump.c | 9 + arch/x86/src/qemu/Make.defs | 2 +- arch/x86_64/src/common/x86_64_assert.c | 126 +----- arch/x86_64/src/common/x86_64_getintstack.c | 44 ++ arch/x86_64/src/intel64/Make.defs | 2 +- arch/x86_64/src/intel64/intel64_regdump.c | 9 + arch/xtensa/src/common/Make.defs | 6 +- arch/xtensa/src/common/xtensa.h | 6 +- arch/xtensa/src/common/xtensa_assert.c | 39 +- arch/xtensa/src/common/xtensa_checkstack.c | 6 +- arch/xtensa/src/common/xtensa_dumpstate.c | 397 ----------------- arch/xtensa/src/common/xtensa_getintstack.c | 48 +++ arch/xtensa/src/common/xtensa_registerdump.c | 78 ++++ arch/xtensa/src/common/xtensa_swint.c | 22 +- arch/xtensa/src/esp32/esp32_cpustart.c | 21 +- arch/z16/src/common/z16_assert.c | 23 +- arch/z16/src/common/z16_internal.h | 8 +- arch/z16/src/common/z16_registerdump.c | 40 +- arch/z16/src/z16f/Make.defs | 3 +- arch/z80/src/common/z80_assert.c | 3 +- arch/z80/src/common/z80_internal.h | 2 - arch/z80/src/ez80/Make.defs | 4 - arch/z80/src/ez80/ez80_registerdump.c | 10 + arch/z80/src/z180/z180_registerdump.c | 12 +- arch/z80/src/z8/z8_registerdump.c | 10 + arch/z80/src/z80/z80_registerdump.c | 12 +- include/nuttx/arch.h | 19 +- sched/misc/assert.c | 314 +++++++++++++- 117 files changed, 2447 insertions(+), 4630 deletions(-) create mode 100644 arch/arm/src/common/arm_getintstack.c create mode 100644 arch/arm/src/common/arm_registerdump.c create mode 100644 arch/arm64/src/common/arm64_getintstack.c create mode 100644 arch/arm64/src/common/arm64_registerdump.c delete mode 100644 arch/avr/src/avr/avr_dumpstate.c create mode 100644 arch/avr/src/avr/avr_registerdump.c delete mode 100644 arch/avr/src/avr32/avr_dumpstate.c rename arch/{z80/src/common/z80_stackdump.c => avr/src/avr32/avr_registerdump.c} (55%) create mode 100644 arch/avr/src/common/avr_getintstack.c create mode 100644 arch/ceva/src/common/ceva_getintstack.c create mode 100644 arch/ceva/src/common/ceva_registerdump.c create mode 100644 arch/hc/src/common/hc_getintstack.c create mode 100644 arch/hc/src/m9s12/m9s12_registerdump.c create mode 100644 arch/mips/src/common/mips_getintstack.c delete mode 100644 arch/mips/src/mips32/mips_dumpstate.c create mode 100644 arch/mips/src/mips32/mips_registerdump.c delete mode 100644 arch/misoc/src/lm32/lm32_dumpstate.c create mode 100644 arch/misoc/src/lm32/lm32_registerdump.c delete mode 100644 arch/misoc/src/minerva/minerva_dumpstate.c create mode 100644 arch/misoc/src/minerva/minerva_registerdump.c create mode 100644 arch/or1k/src/common/or1k_getintstack.c create mode 100644 arch/or1k/src/common/or1k_registerdump.c create mode 100644 arch/renesas/src/common/renesas_getintstack.c delete mode 100644 arch/renesas/src/m16c/m16c_dumpstate.c rename arch/{z16/src/common/z16_stackdump.c => renesas/src/m16c/m16c_registerdump.c} (55%) delete mode 100644 arch/renesas/src/rx65n/rx65n_dumpstate.c create mode 100644 arch/renesas/src/rx65n/rx65n_registerdump.c delete mode 100644 arch/renesas/src/sh1/sh1_dumpstate.c create mode 100644 arch/renesas/src/sh1/sh1_registerdump.c create mode 100644 arch/risc-v/src/common/riscv_getintstack.c create mode 100644 arch/risc-v/src/common/riscv_registerdump.c create mode 100644 arch/sparc/src/common/sparc_getintstack.c delete mode 100644 arch/sparc/src/sparc_v8/sparc_v8_dumpstate.c create mode 100644 arch/sparc/src/sparc_v8/sparc_v8_registerdump.c create mode 100644 arch/x86/src/common/x86_getintstack.c create mode 100644 arch/x86_64/src/common/x86_64_getintstack.c delete mode 100644 arch/xtensa/src/common/xtensa_dumpstate.c create mode 100644 arch/xtensa/src/common/xtensa_getintstack.c create mode 100644 arch/xtensa/src/common/xtensa_registerdump.c diff --git a/arch/arm/src/armv7-a/arm_cpustart.c b/arch/arm/src/armv7-a/arm_cpustart.c index 27a9905fa8f..e77d408a115 100644 --- a/arch/arm/src/armv7-a/arm_cpustart.c +++ b/arch/arm/src/armv7-a/arm_cpustart.c @@ -43,33 +43,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: arm_registerdump - ****************************************************************************/ - -#if 0 /* Was useful in solving some startup problems */ -static inline void arm_registerdump(struct tcb_s *tcb) -{ - int regndx; - - _info("CPU%d:\n", up_cpu_index()); - - /* Dump the startup registers */ - - for (regndx = REG_R0; regndx <= REG_R15; regndx += 8) - { - uint32_t *ptr = (uint32_t *)&tcb->xcp.regs[regndx]; - _info("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regndx, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } - - _info("CPSR: %08x\n", tcb->xcp.regs[REG_CPSR]); -} -#else -# define arm_registerdump(tcb) -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -108,7 +81,9 @@ int arm_start_handler(int irq, void *context, void *arg) /* Dump registers so that we can see what is going to happen on return */ - arm_registerdump(tcb); +#if 0 + arm_registerdump(tcb->xcp.regs); +#endif /* Then switch contexts. This instantiates the exception context of the * tcb at the head of the assigned task list. In this case, this should diff --git a/arch/arm/src/common/Make.defs b/arch/arm/src/common/Make.defs index 2b7d1cb015f..a90af8c3ad5 100644 --- a/arch/arm/src/common/Make.defs +++ b/arch/arm/src/common/Make.defs @@ -26,7 +26,7 @@ CMN_CSRCS += arm_initialize.c arm_lowputs.c CMN_CSRCS += arm_modifyreg16.c arm_modifyreg32.c CMN_CSRCS += arm_modifyreg8.c arm_nputs.c CMN_CSRCS += arm_releasestack.c arm_saveusercontext.c -CMN_CSRCS += arm_stackframe.c +CMN_CSRCS += arm_stackframe.c arm_registerdump.c arm_getintstack.c CMN_CSRCS += arm_vfork.c arm_switchcontext.c arm_usestack.c ifneq ($(CONFIG_ALARM_ARCH),y) diff --git a/arch/arm/src/common/arm_assert.c b/arch/arm/src/common/arm_assert.c index 9f1ee948852..01498fe232f 100644 --- a/arch/arm/src/common/arm_assert.c +++ b/arch/arm/src/common/arm_assert.c @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -37,8 +36,6 @@ #include "sched/sched.h" #include "arm_internal.h" -#ifdef CONFIG_ARCH_STACKDUMP - /**************************************************************************** * Private Data ****************************************************************************/ @@ -46,300 +43,18 @@ static uint8_t s_last_regs[XCPTCONTEXT_SIZE]; /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: arm_stackdump + * Name: up_assert ****************************************************************************/ -static void arm_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08" PRIx32 ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 "\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: arm_registerdump - ****************************************************************************/ - -static void arm_registerdump(volatile uint32_t *regs) -{ - /* Dump the interrupt registers */ - - _alert("R0: %08" PRIx32 " R1: %08" PRIx32 - " R2: %08" PRIx32 " R3: %08" PRIx32 "\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); -#ifdef CONFIG_ARM_THUMB - _alert("R4: %08" PRIx32 " R5: %08" PRIx32 - " R6: %08" PRIx32 " FP: %08" PRIx32 "\n", - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08" PRIx32 " SB: %08" PRIx32 - " SL: %08" PRIx32 " R11: %08" PRIx32 "\n", - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); -#else - _alert("R4: %08" PRIx32 " R5: %08" PRIx32 - " R6: %08" PRIx32 " R7: %08" PRIx32 "\n", - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08" PRIx32 " SB: %08" PRIx32 - " SL: %08" PRIx32 " FP: %08" PRIx32 "\n", - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); -#endif - _alert("IP: %08" PRIx32 " SP: %08" PRIx32 - " LR: %08" PRIx32 " PC: %08" PRIx32 "\n", - regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); - -#if defined(REG_BASEPRI) - _alert("xPSR: %08" PRIx32 " BASEPRI: %08" PRIx32 - " CONTROL: %08" PRIx32 "\n", - regs[REG_XPSR], regs[REG_BASEPRI], getcontrol()); -#elif defined(REG_PRIMASK) - _alert("xPSR: %08" PRIx32 " PRIMASK: %08" PRIx32 - " CONTROL: %08" PRIx32 "\n", - regs[REG_XPSR], regs[REG_PRIMASK], getcontrol()); -#elif defined(REG_CPSR) - _alert("CPSR: %08" PRIx32 "\n", regs[REG_CPSR]); -#endif - -#ifdef REG_EXC_RETURN - _alert("EXC_RETURN: %08" PRIx32 "\n", regs[REG_EXC_RETURN]); -#endif -} - -/**************************************************************************** - * Name: arm_dump_task - ****************************************************************************/ - -static void arm_dump_task(struct tcb_s *tcb, void *arg) -{ - char args[64] = ""; -#ifdef CONFIG_STACK_COLORATION - uint32_t stack_filled = 0; - uint32_t stack_used; -#endif -#ifdef CONFIG_SCHED_CPULOAD - struct cpuload_s cpuload; - uint32_t fracpart; - uint32_t intpart; - uint32_t tmp; - - clock_cpuload(tcb->pid, &cpuload); - - if (cpuload.total > 0) - { - tmp = (1000 * cpuload.active) / cpuload.total; - intpart = tmp / 10; - fracpart = tmp - 10 * intpart; - } - else - { - intpart = 0; - fracpart = 0; - } -#endif - -#ifdef CONFIG_STACK_COLORATION - stack_used = up_check_tcbstack(tcb); - if (tcb->adj_stack_size > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * stack_used / tcb->adj_stack_size; - } -#endif - -#ifndef CONFIG_DISABLE_PTHREAD - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) - { - struct pthread_tcb_s *ptcb = (struct pthread_tcb_s *)tcb; - - snprintf(args, sizeof(args), " %p", ptcb->arg); - } - else -#endif - { - char **argv = tcb->group->tg_info->argv + 1; - size_t npos = 0; - - while (*argv != NULL && npos < sizeof(args)) - { - npos += snprintf(args + npos, sizeof(args) - npos, " %s", *argv++); - } - } - - /* Dump interesting properties of this task */ - - _alert(" %4d %4d" -#ifdef CONFIG_SMP - " %4d" -#endif - " %7lu" -#ifdef CONFIG_STACK_COLORATION - " %7lu %3" PRId32 ".%1" PRId32 "%%%c" -#endif -#ifdef CONFIG_SCHED_CPULOAD - " %3" PRId32 ".%01" PRId32 "%%" -#endif - " %s%s\n" - , tcb->pid, tcb->sched_priority -#ifdef CONFIG_SMP - , tcb->cpu -#endif - , (unsigned long)tcb->adj_stack_size -#ifdef CONFIG_STACK_COLORATION - , (unsigned long)up_check_tcbstack(tcb) - , stack_filled / 10, stack_filled % 10 - , (stack_filled >= 10 * 80 ? '!' : ' ') -#endif -#ifdef CONFIG_SCHED_CPULOAD - , intpart, fracpart -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - , tcb->name -#else - , "" -#endif - , args - ); -} - -/**************************************************************************** - * Name: arm_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void arm_dump_backtrace(struct tcb_s *tcb, void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: arm_showtasks - ****************************************************************************/ - -static void arm_showtasks(void) -{ -#if CONFIG_ARCH_INTERRUPTSTACK > 7 -# ifdef CONFIG_STACK_COLORATION - uint32_t stack_used = up_check_intstack(); - uint32_t stack_filled = 0; - - if ((CONFIG_ARCH_INTERRUPTSTACK & ~7) > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * - stack_used / (CONFIG_ARCH_INTERRUPTSTACK & ~7); - } -# endif -#endif - - /* Dump interesting properties of each task in the crash environment */ - - _alert(" PID PRI" -#ifdef CONFIG_SMP - " CPU" -#endif - " STACK" -#ifdef CONFIG_STACK_COLORATION - " USED FILLED " -#endif -#ifdef CONFIG_SCHED_CPULOAD - " CPU" -#endif - " COMMAND\n"); - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - _alert(" ---- ----" -# ifdef CONFIG_SMP - " ----" -# endif - " %7u" -# ifdef CONFIG_STACK_COLORATION - " %7" PRId32 " %3" PRId32 ".%1" PRId32 "%%%c" -# endif -# ifdef CONFIG_SCHED_CPULOAD - " ----" -# endif - " irq\n" - , (CONFIG_ARCH_INTERRUPTSTACK & ~7) -# ifdef CONFIG_STACK_COLORATION - , stack_used - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') -# endif - ); -#endif - - nxsched_foreach(arm_dump_task, NULL); -#ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(arm_dump_backtrace, NULL); -#endif -} - -/**************************************************************************** - * Name: arm_dump_stack - ****************************************************************************/ - -static void arm_dump_stack(const char *tag, uint32_t sp, - uint32_t base, uint32_t size, bool force) -{ - uint32_t top = base + size; - - _alert("%s Stack:\n", tag); - _alert("sp: %08" PRIx32 "\n", sp); - _alert(" base: %08" PRIx32 "\n", base); - _alert(" size: %08" PRIx32 "\n", size); - - if (sp >= base && sp < top) - { - arm_stackdump(sp, top); - } - else - { - _alert("ERROR: %s Stack pointer is not within the stack\n", tag); - if (force) - { -#ifdef CONFIG_STACK_COLORATION - uint32_t remain; - - remain = size - arm_stack_check((void *)(uintptr_t)base, size); - base += remain; - size -= remain; -#endif - -#if CONFIG_ARCH_STACKDUMP_MAX_LENGTH > 0 - if (size > CONFIG_ARCH_STACKDUMP_MAX_LENGTH) - { - size = CONFIG_ARCH_STACKDUMP_MAX_LENGTH; - } -#endif - - arm_stackdump(base, base + size); - } - } -} - -/**************************************************************************** - * Name: arm_dumpstate - ****************************************************************************/ - -static void arm_dumpstate(void) +void up_assert(void) { struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); + + board_autoled_on(LED_ASSERTION); /* Update the xcp context */ @@ -353,78 +68,7 @@ static void arm_dumpstate(void) rtcb->xcp.regs = (uint32_t *)s_last_regs; } - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the registers */ + /* Dump the interrupt registers */ arm_registerdump(rtcb->xcp.regs); - - /* Dump the irq stack */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - arm_dump_stack("IRQ", sp, -# ifdef CONFIG_SMP - (uint32_t)arm_intstack_alloc(), -# else - (uint32_t)g_intstackalloc, -# endif - (CONFIG_ARCH_INTERRUPTSTACK & ~7), - !!CURRENT_REGS); - - if (CURRENT_REGS) - { - sp = CURRENT_REGS[REG_R13]; - } -#endif - - /* Dump the user stack */ - - arm_dump_stack("User", sp, - (uint32_t)rtcb->stack_base_ptr, - (uint32_t)rtcb->adj_stack_size, -#ifdef CONFIG_ARCH_KERNEL_STACK - false -#else - true -#endif - ); - -#ifdef CONFIG_ARCH_KERNEL_STACK - arm_dump_stack("Kernel", sp, - (uint32_t)rtcb->xcp.kstack, - CONFIG_ARCH_KERNEL_STACKSIZE, - false); -#endif - - /* Dump the state of all tasks (if available) */ - - arm_showtasks(); - -#ifdef CONFIG_ARCH_USBDUMP - /* Dump USB trace data */ - - usbtrace_enumerate(assert_tracecallback, NULL); -#endif -} -#endif /* CONFIG_ARCH_STACKDUMP */ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - -#ifdef CONFIG_ARCH_STACKDUMP - arm_dumpstate(); -#endif } diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c index 97ac16f5ca5..96c0ebd5d1a 100644 --- a/arch/arm/src/common/arm_checkstack.c +++ b/arch/arm/src/common/arm_checkstack.c @@ -242,13 +242,8 @@ ssize_t up_check_stack_remain(void) #if CONFIG_ARCH_INTERRUPTSTACK > 3 size_t up_check_intstack(void) { -#ifdef CONFIG_SMP - return arm_stack_check((void *)arm_intstack_alloc(), + return arm_stack_check((void *)up_get_intstackbase(), STACK_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)); -#else - return arm_stack_check(g_intstackalloc, - STACK_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)); -#endif } size_t up_check_intstack_remain(void) diff --git a/arch/arm/src/common/arm_getintstack.c b/arch/arm/src/common/arm_getintstack.c new file mode 100644 index 00000000000..b2617d79fe6 --- /dev/null +++ b/arch/arm/src/common/arm_getintstack.c @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/arm/src/common/arm_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ +#ifdef CONFIG_SMP + return arm_intstack_alloc(); +#else + return (uintptr_t)g_intstackalloc; +#endif +} +#endif + diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h index a1dbcfb9040..f46abb6b89e 100644 --- a/arch/arm/src/common/arm_internal.h +++ b/arch/arm/src/common/arm_internal.h @@ -480,6 +480,8 @@ size_t arm_stack_check(void *stackbase, size_t nbytes); void arm_stack_color(void *stackbase, size_t nbytes); #endif +void arm_registerdump(volatile uint32_t *regs); + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/arm/src/common/arm_registerdump.c b/arch/arm/src/common/arm_registerdump.c new file mode 100644 index 00000000000..99c2632fe6e --- /dev/null +++ b/arch/arm/src/common/arm_registerdump.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/arm/src/common/arm_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "arm_internal.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_SP]; +} + +/**************************************************************************** + * Name: arm_registerdump + ****************************************************************************/ + +void arm_registerdump(volatile uint32_t *regs) +{ + /* Dump the interrupt registers */ + + _alert("R0: %08" PRIx32 " R1: %08" PRIx32 + " R2: %08" PRIx32 " R3: %08" PRIx32 "\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); +#ifdef CONFIG_ARM_THUMB + _alert("R4: %08" PRIx32 " R5: %08" PRIx32 + " R6: %08" PRIx32 " FP: %08" PRIx32 "\n", + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + _alert("R8: %08" PRIx32 " SB: %08" PRIx32 + " SL: %08" PRIx32 " R11: %08" PRIx32 "\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); +#else + _alert("R4: %08" PRIx32 " R5: %08" PRIx32 + " R6: %08" PRIx32 " R7: %08" PRIx32 "\n", + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + _alert("R8: %08" PRIx32 " SB: %08" PRIx32 + " SL: %08" PRIx32 " FP: %08" PRIx32 "\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); +#endif + _alert("IP: %08" PRIx32 " SP: %08" PRIx32 + " LR: %08" PRIx32 " PC: %08" PRIx32 "\n", + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); + +#if defined(REG_BASEPRI) + _alert("xPSR: %08" PRIx32 " BASEPRI: %08" PRIx32 + " CONTROL: %08" PRIx32 "\n", + regs[REG_XPSR], regs[REG_BASEPRI], getcontrol()); +#elif defined(REG_PRIMASK) + _alert("xPSR: %08" PRIx32 " PRIMASK: %08" PRIx32 + " CONTROL: %08" PRIx32 "\n", + regs[REG_XPSR], regs[REG_PRIMASK], getcontrol()); +#elif defined(REG_CPSR) + _alert("CPSR: %08" PRIx32 "\n", regs[REG_CPSR]); +#endif + +#ifdef REG_EXC_RETURN + _alert("EXC_RETURN: %08" PRIx32 "\n", regs[REG_EXC_RETURN]); +#endif +} diff --git a/arch/arm/src/nrf52/nrf52_sdc.c b/arch/arm/src/nrf52/nrf52_sdc.c index c48a92379d7..cdf3d994885 100644 --- a/arch/arm/src/nrf52/nrf52_sdc.c +++ b/arch/arm/src/nrf52/nrf52_sdc.c @@ -238,7 +238,7 @@ static int bt_hci_send(struct bt_driver_s *btdev, static void sdc_fault_handler(const char *file, const uint32_t line) { _alert("SoftDevice Controller Fault\n"); - up_assert(file, line); + _assert(file, line); } /**************************************************************************** @@ -248,7 +248,7 @@ static void sdc_fault_handler(const char *file, const uint32_t line) static void mpsl_assert_handler(const char *const file, const uint32_t line) { _alert("MPSL assertion failed\n"); - up_assert(file, line); + _assert(file, line); } /**************************************************************************** diff --git a/arch/arm64/src/common/Make.defs b/arch/arm64/src/common/Make.defs index c11dc11f671..bf731b424ed 100644 --- a/arch/arm64/src/common/Make.defs +++ b/arch/arm64/src/common/Make.defs @@ -48,6 +48,7 @@ CMN_CSRCS += arm64_createstack.c arm64_releasestack.c arm64_stackframe.c arm64_u CMN_CSRCS += arm64_task_sched.c arm64_exit.c arm64_vfork.c arm64_switchcontext.c CMN_CSRCS += arm64_assert.c arm64_schedulesigaction.c arm64_backtrace.c CMN_CSRCS += arm64_sigdeliver.c arm64_systemreset.c +CMN_CSRCS += arm64_getintstack.c arm64_registerdump.c # Common C source files ( hardware BSP ) CMN_CSRCS += arm64_mmu.c arm64_arch_timer.c arm64_cache.c diff --git a/arch/arm64/src/common/arm64_assert.c b/arch/arm64/src/common/arm64_assert.c index b7c73460129..1a14e98e02a 100644 --- a/arch/arm64/src/common/arm64_assert.c +++ b/arch/arm64/src/common/arm64_assert.c @@ -39,384 +39,14 @@ #endif /**************************************************************************** - * Name: arm_registerdump + * Public Functions ****************************************************************************/ -static void arm64_registerdump(struct regs_context * regs) -{ - _alert("stack = %p\n", regs); - _alert("x0: 0x%-16"PRIx64" x1: 0x%"PRIx64"\n", - regs->regs[REG_X0], regs->regs[REG_X1]); - _alert("x2: 0x%-16"PRIx64" x3: 0x%"PRIx64"\n", - regs->regs[REG_X2], regs->regs[REG_X3]); - _alert("x4: 0x%-16"PRIx64" x5: 0x%"PRIx64"\n", - regs->regs[REG_X4], regs->regs[REG_X5]); - _alert("x6: 0x%-16"PRIx64" x7: 0x%"PRIx64"\n", - regs->regs[REG_X6], regs->regs[REG_X7]); - _alert("x8: 0x%-16"PRIx64" x9: 0x%"PRIx64"\n", - regs->regs[REG_X8], regs->regs[REG_X9]); - _alert("x10: 0x%-16"PRIx64" x11: 0x%"PRIx64"\n", - regs->regs[REG_X10], regs->regs[REG_X11]); - _alert("x12: 0x%-16"PRIx64" x13: 0x%"PRIx64"\n", - regs->regs[REG_X12], regs->regs[REG_X13]); - _alert("x14: 0x%-16"PRIx64" x15: 0x%"PRIx64"\n", - regs->regs[REG_X14], regs->regs[REG_X15]); - _alert("x16: 0x%-16"PRIx64" x17: 0x%"PRIx64"\n", - regs->regs[REG_X16], regs->regs[REG_X17]); - _alert("x18: 0x%-16"PRIx64" x19: 0x%"PRIx64"\n", - regs->regs[REG_X18], regs->regs[REG_X19]); - _alert("x20: 0x%-16"PRIx64" x21: 0x%"PRIx64"\n", - regs->regs[REG_X20], regs->regs[REG_X21]); - _alert("x22: 0x%-16"PRIx64" x23: 0x%"PRIx64"\n", - regs->regs[REG_X22], regs->regs[REG_X23]); - _alert("x24: 0x%-16"PRIx64" x25: 0x%"PRIx64"\n", - regs->regs[REG_X24], regs->regs[REG_X25]); - _alert("x26: 0x%-16"PRIx64" x27: 0x%"PRIx64"\n", - regs->regs[REG_X26], regs->regs[REG_X27]); - _alert("x28: 0x%-16"PRIx64" x29: 0x%"PRIx64"\n", - regs->regs[REG_X28], regs->regs[REG_X29]); - _alert("x30: 0x%-16"PRIx64"\n", regs->regs[REG_X30]); - - _alert("\n"); - _alert("STATUS Registers:\n"); - _alert("SPSR: 0x%-16"PRIx64"\n", regs->spsr); - _alert("ELR: 0x%-16"PRIx64"\n", regs->elr); - _alert("SP_EL0: 0x%-16"PRIx64"\n", regs->sp_el0); - _alert("SP_ELX: 0x%-16"PRIx64"\n", regs->sp_elx); - _alert("TPIDR_EL0: 0x%-16"PRIx64"\n", regs->tpidr_el0); - _alert("TPIDR_EL1: 0x%-16"PRIx64"\n", regs->tpidr_el1); - _alert("EXE_DEPTH: 0x%-16"PRIx64"\n", regs->exe_depth); -} - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_stackdump - ****************************************************************************/ - -static void arm64_stackdump(uint64_t sp, uint64_t stack_top) -{ - uint64_t stack; - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 64) - { - uint64_t *ptr = (uint64_t *)stack; - _alert("%08" PRIx64 ": %08" PRIx64 " %08" PRIx64 " %08" PRIx64 - " %08" PRIx64 " %08" PRIx64 " %08" PRIx64 " %08" PRIx64 - " %08" PRIx64 "\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: arm_dump_task - ****************************************************************************/ - -static void arm64_dump_task(struct tcb_s *tcb, void *arg) -{ - char args[64] = ""; -#ifdef CONFIG_STACK_COLORATION - uint64_t stack_filled = 0; - uint64_t stack_used; -#endif -#ifdef CONFIG_SCHED_CPULOAD - struct cpuload_s cpuload; - uint64_t fracpart; - uint64_t intpart; - uint64_t tmp; - - clock_cpuload(tcb->pid, &cpuload); - - if (cpuload.total > 0) - { - tmp = (1000 * cpuload.active) / cpuload.total; - intpart = tmp / 10; - fracpart = tmp - 10 * intpart; - } - else - { - intpart = 0; - fracpart = 0; - } -#endif - -#ifdef CONFIG_STACK_COLORATION - stack_used = up_check_tcbstack(tcb); - if (tcb->adj_stack_size > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * stack_used / tcb->adj_stack_size; - } -#endif - -#ifndef CONFIG_DISABLE_PTHREAD - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) - { - struct pthread_tcb_s *ptcb = (struct pthread_tcb_s *)tcb; - - snprintf(args, sizeof(args), "%p ", ptcb->arg); - } - else -#endif - { - char **argv = tcb->group->tg_info->argv + 1; - size_t npos = 0; - - while (*argv != NULL && npos < sizeof(args)) - { - npos += snprintf(args + npos, sizeof(args) - npos, " %s", *argv++); - } - } - - /* Dump interesting properties of this task */ - - _alert(" %4d %4d" -#ifdef CONFIG_SMP - " %4d" -#endif -#ifdef CONFIG_STACK_COLORATION - " %7lu" -#endif - " %7lu" -#ifdef CONFIG_STACK_COLORATION - " %3" PRId64 ".%1" PRId64 "%%%c" -#endif -#ifdef CONFIG_SCHED_CPULOAD - " %3" PRId64 ".%01" PRId64 "%%" -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - " %s %s\n", -#else - " %s\n", -#endif - tcb->pid, tcb->sched_priority, -#ifdef CONFIG_SMP - tcb->cpu, -#endif -#ifdef CONFIG_STACK_COLORATION - (unsigned long)up_check_tcbstack(tcb), -#endif - (unsigned long)tcb->adj_stack_size -#ifdef CONFIG_STACK_COLORATION - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') -#endif -#ifdef CONFIG_SCHED_CPULOAD - , intpart, fracpart -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - , tcb->name -#else - , "" -#endif - , args - ); -} - -/**************************************************************************** - * Name: arm_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void arm64_dump_backtrace(struct tcb_s *tcb, void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: arm_showtasks - ****************************************************************************/ - -static void arm64_showtasks(void) -{ -#if CONFIG_ARCH_INTERRUPTSTACK > 15 -# ifdef CONFIG_STACK_COLORATION - uint64_t stack_used = up_check_intstack(); - uint64_t stack_filled = 0; - - if ((CONFIG_ARCH_INTERRUPTSTACK & ~15) > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * - stack_used / (CONFIG_ARCH_INTERRUPTSTACK & ~15); - } -# endif -#endif - - /* Dump interesting properties of each task in the crash environment */ - - _alert(" PID PRI" -#ifdef CONFIG_SMP - " CPU" -#endif -#ifdef CONFIG_STACK_COLORATION - " USED" -#endif - " STACK" -#ifdef CONFIG_STACK_COLORATION - " FILLED " -#endif -#ifdef CONFIG_SCHED_CPULOAD - " CPU" -#endif - " COMMAND\n"); - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - _alert(" ---- ----" -# ifdef CONFIG_SMP - " ----" -# endif -# ifdef CONFIG_STACK_COLORATION - " %7lu" -# endif - " %7lu" -# ifdef CONFIG_STACK_COLORATION - " %3" PRId64 ".%1" PRId64 "%%%c" -# endif -# ifdef CONFIG_SCHED_CPULOAD - " ----" -# endif -# if CONFIG_TASK_NAME_SIZE > 0 - " irq" -# endif - "\n" -# ifdef CONFIG_STACK_COLORATION - , (unsigned long)stack_used -# endif - , (unsigned long)(CONFIG_ARCH_INTERRUPTSTACK & ~15) -# ifdef CONFIG_STACK_COLORATION - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') -# endif - ); -#endif - - nxsched_foreach(arm64_dump_task, NULL); -#ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(arm64_dump_backtrace, NULL); -#endif -} - -/**************************************************************************** - * Name: arm_dump_stack - ****************************************************************************/ - -static void arm64_dump_stack(const char *tag, uint64_t sp, - uint64_t base, uint64_t size, bool force) -{ - uint64_t top = base + size; - - _alert("%s Stack:\n", tag); - _alert("sp: %08" PRIx64 "\n", sp); - _alert(" base: %08" PRIx64 "\n", base); - _alert(" size: %08" PRIx64 "\n", size); - - if (sp >= base && sp < top) - { - arm64_stackdump(sp, top); - } - else - { - _alert("ERROR: %s Stack pointer is not within the stack\n", tag); - - if (force) - { - arm64_stackdump(base, top); - } - } -} - -/**************************************************************************** - * Name: arm64_dumpstate_assert (for assert) - ****************************************************************************/ - -static void arm64_dumpstate_assert(void) -{ - struct tcb_s *rtcb = (struct tcb_s *)arch_get_current_tcb(); - uint64_t sp = up_getsp(); - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Update the xcp context */ - - if (CURRENT_REGS) - { - /* in interrupt */ - - rtcb->xcp.regs = (uint64_t *)CURRENT_REGS; - } - else - { - up_saveusercontext(rtcb->xcp.regs); - } - - /* Dump the registers */ - - arm64_registerdump((struct regs_context *)rtcb->xcp.regs); - - /* Dump the irq stack */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - arm64_dump_stack("IRQ", sp, -# ifdef CONFIG_SMP - (uint64_t)arm64_intstack_alloc(), -# else - (uint64_t)&g_interrupt_stack, -# endif - (CONFIG_ARCH_INTERRUPTSTACK & ~15), - !!CURRENT_REGS); - - if (CURRENT_REGS) - { - sp = CURRENT_REGS[REG_X13]; - } -#endif - - /* Dump the user stack */ - - arm64_dump_stack("User", sp, - (uint64_t)rtcb->stack_base_ptr, - (uint64_t)rtcb->adj_stack_size, -#ifdef CONFIG_ARCH_KERNEL_STACK - false -#else - true -#endif - ); - -#ifdef CONFIG_ARCH_KERNEL_STACK - arm64_dump_stack("Kernel", sp, - (uint64_t)rtcb->xcp.kstack, - CONFIG_ARCH_KERNEL_STACKSIZE, - false); -#endif - - /* Dump the state of all tasks (if available) */ - - arm64_showtasks(); -} - -#endif /* CONFIG_ARCH_STACKDUMP */ - /**************************************************************************** * Name: arm64_dump_fatal ****************************************************************************/ -void arm64_dump_fatal(struct regs_context * regs) +void arm64_dump_fatal(struct regs_context *regs) { #ifdef CONFIG_SCHED_BACKTRACE struct tcb_s *rtcb = (struct tcb_s *)regs->tpidr_el1; @@ -444,17 +74,28 @@ void up_mdelay(unsigned int milliseconds) } } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { -#ifdef CONFIG_ARCH_STACKDUMP - arm64_dumpstate_assert(); -#endif + struct tcb_s *rtcb = (struct tcb_s *)arch_get_current_tcb(); + + /* Update the xcp context */ + + if (CURRENT_REGS) + { + /* in interrupt */ + + rtcb->xcp.regs = (uint64_t *)CURRENT_REGS; + } + else + { + up_saveusercontext(rtcb->xcp.regs); + } + + /* Dump the registers */ + + arm64_registerdump((struct regs_context *)rtcb->xcp.regs); } diff --git a/arch/arm64/src/common/arm64_checkstack.c b/arch/arm64/src/common/arm64_checkstack.c index 6940b5644d3..705954aaaa2 100644 --- a/arch/arm64/src/common/arm64_checkstack.c +++ b/arch/arm64/src/common/arm64_checkstack.c @@ -219,13 +219,8 @@ ssize_t up_check_stack_remain(void) #if CONFIG_ARCH_INTERRUPTSTACK > 7 size_t up_check_intstack(void) { -#ifdef CONFIG_SMP - return arm64_stack_check((void *)arm64_intstack_alloc(), + return arm64_stack_check((void *)up_get_intstackbase(), STACK_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)); -#else - return arm64_stack_check((void *)&g_interrupt_stack, - STACK_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)); -#endif } size_t up_check_intstack_remain(void) diff --git a/arch/arm64/src/common/arm64_getintstack.c b/arch/arm64/src/common/arm64_getintstack.c new file mode 100644 index 00000000000..8da53fc19e6 --- /dev/null +++ b/arch/arm64/src/common/arm64_getintstack.c @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/arm64/src/common/arm64_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "arm64_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 +uintptr_t up_get_intstackbase(void) +{ +#ifdef CONFIG_SMP + return arm64_intstack_alloc(); +#else + return (uintptr_t)g_interrupt_stack; +#endif +} +#endif diff --git a/arch/arm64/src/common/arm64_internal.h b/arch/arm64/src/common/arm64_internal.h index 1b4d3af8e8f..211a3f175bd 100644 --- a/arch/arm64/src/common/arm64_internal.h +++ b/arch/arm64/src/common/arm64_internal.h @@ -347,6 +347,8 @@ size_t arm64_stack_check(void *stackbase, size_t nbytes); void arm64_stack_color(void *stackbase, size_t nbytes); #endif +void arm64_registerdump(struct regs_context * regs); + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/arm64/src/common/arm64_registerdump.c b/arch/arm64/src/common/arm64_registerdump.c new file mode 100644 index 00000000000..b7973adff8d --- /dev/null +++ b/arch/arm64/src/common/arm64_registerdump.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/arm64/src/common/arm64_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "arm64_arch.h" +#include "arm64_internal.h" +#include "chip.h" + +#ifdef CONFIG_ARCH_FPU +#include "arm64_fpu.h" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_X13]; +} + +/**************************************************************************** + * Name: arm64_registerdump + ****************************************************************************/ + +void arm64_registerdump(struct regs_context * regs) +{ + _alert("stack = %p\n", regs); + _alert("x0: 0x%-16"PRIx64" x1: 0x%"PRIx64"\n", + regs->regs[REG_X0], regs->regs[REG_X1]); + _alert("x2: 0x%-16"PRIx64" x3: 0x%"PRIx64"\n", + regs->regs[REG_X2], regs->regs[REG_X3]); + _alert("x4: 0x%-16"PRIx64" x5: 0x%"PRIx64"\n", + regs->regs[REG_X4], regs->regs[REG_X5]); + _alert("x6: 0x%-16"PRIx64" x7: 0x%"PRIx64"\n", + regs->regs[REG_X6], regs->regs[REG_X7]); + _alert("x8: 0x%-16"PRIx64" x9: 0x%"PRIx64"\n", + regs->regs[REG_X8], regs->regs[REG_X9]); + _alert("x10: 0x%-16"PRIx64" x11: 0x%"PRIx64"\n", + regs->regs[REG_X10], regs->regs[REG_X11]); + _alert("x12: 0x%-16"PRIx64" x13: 0x%"PRIx64"\n", + regs->regs[REG_X12], regs->regs[REG_X13]); + _alert("x14: 0x%-16"PRIx64" x15: 0x%"PRIx64"\n", + regs->regs[REG_X14], regs->regs[REG_X15]); + _alert("x16: 0x%-16"PRIx64" x17: 0x%"PRIx64"\n", + regs->regs[REG_X16], regs->regs[REG_X17]); + _alert("x18: 0x%-16"PRIx64" x19: 0x%"PRIx64"\n", + regs->regs[REG_X18], regs->regs[REG_X19]); + _alert("x20: 0x%-16"PRIx64" x21: 0x%"PRIx64"\n", + regs->regs[REG_X20], regs->regs[REG_X21]); + _alert("x22: 0x%-16"PRIx64" x23: 0x%"PRIx64"\n", + regs->regs[REG_X22], regs->regs[REG_X23]); + _alert("x24: 0x%-16"PRIx64" x25: 0x%"PRIx64"\n", + regs->regs[REG_X24], regs->regs[REG_X25]); + _alert("x26: 0x%-16"PRIx64" x27: 0x%"PRIx64"\n", + regs->regs[REG_X26], regs->regs[REG_X27]); + _alert("x28: 0x%-16"PRIx64" x29: 0x%"PRIx64"\n", + regs->regs[REG_X28], regs->regs[REG_X29]); + _alert("x30: 0x%-16"PRIx64"\n", regs->regs[REG_X30]); + + _alert("\n"); + _alert("STATUS Registers:\n"); + _alert("SPSR: 0x%-16"PRIx64"\n", regs->spsr); + _alert("ELR: 0x%-16"PRIx64"\n", regs->elr); + _alert("SP_EL0: 0x%-16"PRIx64"\n", regs->sp_el0); + _alert("SP_ELX: 0x%-16"PRIx64"\n", regs->sp_elx); + _alert("TPIDR_EL0: 0x%-16"PRIx64"\n", regs->tpidr_el0); + _alert("TPIDR_EL1: 0x%-16"PRIx64"\n", regs->tpidr_el1); + _alert("EXE_DEPTH: 0x%-16"PRIx64"\n", regs->exe_depth); +} diff --git a/arch/avr/src/at32uc3/Make.defs b/arch/avr/src/at32uc3/Make.defs index 3e80086a4f4..deeb192d5a1 100644 --- a/arch/avr/src/at32uc3/Make.defs +++ b/arch/avr/src/at32uc3/Make.defs @@ -31,12 +31,7 @@ CMN_CSRCS += avr_initialize.c avr_initialstate.c CMN_CSRCS += avr_modifyreg8.c avr_modifyreg16.c avr_modifyreg32.c avr_releasestack.c CMN_CSRCS += avr_schedulesigaction.c avr_sigdeliver.c avr_stackframe.c CMN_CSRCS += avr_switchcontext.c avr_usestack.c avr_doirq.c avr_nputs.c - -# Configuration-dependent common files - -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += avr_dumpstate.c -endif +CMN_CSRCS += avr_registerdump.c avr_getintstack.c # Required AT32UC3 files diff --git a/arch/avr/src/at90usb/Make.defs b/arch/avr/src/at90usb/Make.defs index 49e36ba8737..5d04bc37115 100644 --- a/arch/avr/src/at90usb/Make.defs +++ b/arch/avr/src/at90usb/Make.defs @@ -32,13 +32,10 @@ CMN_CSRCS += avr_mdelay.c avr_modifyreg8.c avr_modifyreg16.c avr_modifyreg32.c CMN_CSRCS += avr_nputs.c avr_releasestack.c CMN_CSRCS += avr_schedulesigaction.c avr_sigdeliver.c CMN_CSRCS += avr_stackframe.c avr_udelay.c avr_switchcontext.c avr_usestack.c +CMN_CSRCS += avr_registerdump.c avr_getintstack.c # Configuration-dependent common files -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += avr_dumpstate.c -endif - ifeq ($(CONFIG_AVR_SPI),y) CMN_CSRCS += avr_spi.c endif diff --git a/arch/avr/src/atmega/Make.defs b/arch/avr/src/atmega/Make.defs index 31c9b0ef86a..9b0131957f3 100644 --- a/arch/avr/src/atmega/Make.defs +++ b/arch/avr/src/atmega/Make.defs @@ -32,13 +32,10 @@ CMN_CSRCS += avr_mdelay.c avr_modifyreg8.c avr_modifyreg16.c avr_modifyreg32.c CMN_CSRCS += avr_nputs.c avr_releasestack.c CMN_CSRCS += avr_schedulesigaction.c avr_sigdeliver.c CMN_CSRCS += avr_stackframe.c avr_udelay.c avr_switchcontext.c avr_usestack.c +CMN_CSRCS += avr_registerdump.c avr_getintstack.c # Configuration-dependent common files -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += avr_dumpstate.c -endif - ifeq ($(CONFIG_AVR_SPI),y) CMN_CSRCS += avr_spi.c endif diff --git a/arch/avr/src/avr/avr_dumpstate.c b/arch/avr/src/avr/avr_dumpstate.c deleted file mode 100644 index fce35f03691..00000000000 --- a/arch/avr/src/avr/avr_dumpstate.c +++ /dev/null @@ -1,220 +0,0 @@ -/**************************************************************************** - * arch/avr/src/avr/avr_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sched/sched.h" -#include "avr_internal.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: avr_stackdump - ****************************************************************************/ - -static void avr_stackdump(uint16_t sp, uint16_t stack_top) -{ - uint16_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x7; stack < (stack_top & ~0x7); stack += 8) - { - uint8_t *ptr = (uint8_t *)stack; - _alert("%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: avr_registerdump - ****************************************************************************/ - -static inline void avr_registerdump(void) -{ - /* Are user registers available from interrupt processing? */ - - if (g_current_regs) - { - _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", - 0, - g_current_regs[REG_R0], g_current_regs[REG_R1], - g_current_regs[REG_R2], g_current_regs[REG_R3], - g_current_regs[REG_R4], g_current_regs[REG_R5], - g_current_regs[REG_R6], g_current_regs[REG_R7]); - - _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", - 8, - g_current_regs[REG_R8], g_current_regs[REG_R9], - g_current_regs[REG_R10], g_current_regs[REG_R11], - g_current_regs[REG_R12], g_current_regs[REG_R13], - g_current_regs[REG_R14], g_current_regs[REG_R15]); - - _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", - 16, - g_current_regs[REG_R16], g_current_regs[REG_R17], - g_current_regs[REG_R18], g_current_regs[REG_R19], - g_current_regs[REG_R20], g_current_regs[REG_R21], - g_current_regs[REG_R22], g_current_regs[REG_R23]); - - _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", - 24, - g_current_regs[REG_R24], g_current_regs[REG_R25], - g_current_regs[REG_R26], g_current_regs[REG_R27], - g_current_regs[REG_R28], g_current_regs[REG_R29], - g_current_regs[REG_R30], g_current_regs[REG_R31]); - -#if !defined(REG_PC2) - _alert("PC: %02x%02x SP: %02x%02x SREG: %02x\n", - g_current_regs[REG_PC0], g_current_regs[REG_PC1], - g_current_regs[REG_SPH], g_current_regs[REG_SPL], - g_current_regs[REG_SREG]); -#else - _alert("PC: %02x%02x%02x SP: %02x%02x SREG: %02x\n", - g_current_regs[REG_PC0], g_current_regs[REG_PC1], - g_current_regs[REG_PC2], g_current_regs[REG_SPH], - g_current_regs[REG_SPL], g_current_regs[REG_SREG]); -#endif - } -} - -/**************************************************************************** - * Name: _up_assert - ****************************************************************************/ - -/**************************************************************************** - * Name: avr_dumpstate - ****************************************************************************/ - -void avr_dumpstate(void) -{ - FAR struct tcb_s *rtcb = running_task(); - uint16_t sp = up_getsp(); - uint16_t ustackbase; - uint16_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 0 - uint16_t istackbase; - uint16_t istacksize; -#endif - - /* Dump the registers (if available) */ - - avr_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint16_t)rtcb->stack_base_ptr; - ustacksize = (uint16_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 0 - istackbase = (uint16_t)g_intstackalloc; - istacksize = CONFIG_ARCH_INTERRUPTSTACK; - - /* Show interrupt stack info */ - - _alert("sp: %04x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %04x\n", istackbase); - _alert(" size: %04x\n", istacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_intstack()); -#endif - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - avr_stackdump(sp, istackbase + istacksize); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - avr_stackdump(istackbase, istackbase + istacksize); - } - - /* Extract the user stack pointer if we are in an interrupt handler. - * If we are not in an interrupt handler. Then sp is the user stack - * pointer (and the above range check should have failed). - */ - - if (g_current_regs) - { - sp = g_current_regs[REG_R13]; - _alert("sp: %04x\n", sp); - } - - _alert("User stack:\n"); - _alert(" base: %04x\n", ustackbase); - _alert(" size: %04x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_tcbstack(rtcb)); -#endif -#else - _alert("sp: %04x\n", sp); - _alert("stack base: %04x\n", ustackbase); - _alert("stack size: %04x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert("stack used: %08x\n", up_check_tcbstack(rtcb)); -#endif -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - avr_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - avr_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/avr/src/avr/avr_registerdump.c b/arch/avr/src/avr/avr_registerdump.c new file mode 100644 index 00000000000..9410dd99e08 --- /dev/null +++ b/arch/avr/src/avr/avr_registerdump.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * arch/avr/src/avr/avr_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "avr_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_R13]; +} + +/**************************************************************************** + * Name: avr_registerdump + ****************************************************************************/ + +void avr_registerdump(volatile uint8_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + if (regs) + { + _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 0, + regs[REG_R0], regs[REG_R1], + regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], + regs[REG_R6], regs[REG_R7]); + + _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 8, + regs[REG_R8], regs[REG_R9], + regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], + regs[REG_R14], regs[REG_R15]); + + _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 16, + regs[REG_R16], regs[REG_R17], + regs[REG_R18], regs[REG_R19], + regs[REG_R20], regs[REG_R21], + regs[REG_R22], regs[REG_R23]); + + _alert("R%02d: %02x %02x %02x %02x %02x %02x %02x %02x\n", + 24, + regs[REG_R24], regs[REG_R25], + regs[REG_R26], regs[REG_R27], + regs[REG_R28], regs[REG_R29], + regs[REG_R30], regs[REG_R31]); + +#if !defined(REG_PC2) + _alert("PC: %02x%02x SP: %02x%02x SREG: %02x\n", + regs[REG_PC0], regs[REG_PC1], + regs[REG_SPH], regs[REG_SPL], + regs[REG_SREG]); +#else + _alert("PC: %02x%02x%02x SP: %02x%02x SREG: %02x\n", + regs[REG_PC0], regs[REG_PC1], + regs[REG_PC2], regs[REG_SPH], + regs[REG_SPL], regs[REG_SREG]); +#endif + } +} + diff --git a/arch/avr/src/avr32/avr_dumpstate.c b/arch/avr/src/avr32/avr_dumpstate.c deleted file mode 100644 index b422733cf5a..00000000000 --- a/arch/avr/src/avr32/avr_dumpstate.c +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** - * arch/avr/src/avr32/avr_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sched/sched.h" -#include "avr_internal.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: avr_stackdump - ****************************************************************************/ - -static void avr_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: avr_registerdump - ****************************************************************************/ - -static inline void avr_registerdump(void) -{ - /* Are user registers available from interrupt processing? */ - - if (g_current_regs) - { - _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", - 0, - g_current_regs[REG_R0], g_current_regs[REG_R1], - g_current_regs[REG_R2], g_current_regs[REG_R3], - g_current_regs[REG_R4], g_current_regs[REG_R5], - g_current_regs[REG_R6], g_current_regs[REG_R7]); - - _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", - 8, - g_current_regs[REG_R8], g_current_regs[REG_R9], - g_current_regs[REG_R10], g_current_regs[REG_R11], - g_current_regs[REG_R12], g_current_regs[REG_R13], - g_current_regs[REG_R14], g_current_regs[REG_R15]); - - _alert("SR: %08x\n", g_current_regs[REG_SR]); - } -} - -/**************************************************************************** - * Name: avr_dumpstate - ****************************************************************************/ - -void avr_dumpstate(void) -{ - FAR struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - avr_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_intstack()); -#endif - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - avr_stackdump(sp, istackbase + istacksize); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - avr_stackdump(istackbase, istackbase + istacksize); - } - - /* Extract the user stack pointer if we are in an interrupt handler. - * If we are not in an interrupt handler. Then sp is the user stack - * pointer (and the above range check should have failed). - */ - - if (g_current_regs) - { - sp = g_current_regs[REG_R13]; - _alert("sp: %08x\n", sp); - } - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_tcbstack(rtcb)); -#endif -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert("stack used: %08x\n", up_check_tcbstack(rtcb)); -#endif -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - avr_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - avr_stackdump(ustackbase, ustackbase + ustacksize); - } -} -#endif diff --git a/arch/z80/src/common/z80_stackdump.c b/arch/avr/src/avr32/avr_registerdump.c similarity index 55% rename from arch/z80/src/common/z80_stackdump.c rename to arch/avr/src/avr32/avr_registerdump.c index 8a5b74edd6f..9fc5da1a31f 100644 --- a/arch/z80/src/common/z80_stackdump.c +++ b/arch/avr/src/avr32/avr_registerdump.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/z80/src/common/z80_stackdump.c + * arch/avr/src/avr32/avr_registerdump.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,59 +25,53 @@ #include #include +#include +#include #include -#include "sched/sched.h" -#include "z80_internal.h" +#include +#include -#ifdef CONFIG_ARCH_STACKDUMP +#include "avr_internal.h" /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: z80_stackdump + * Name: up_getusrsp ****************************************************************************/ -void z80_stackdump(void) +uintptr_t up_getusrsp(void) { - FAR struct tcb_s *rtcb = running_task(); - uintptr_t sp = up_getsp(); - uintptr_t stack_base = (uintptr_t)rtcb->stack_base_ptr; - uintptr_t stack_size = (uintptr_t)rtcb->adj_stack_size; - uintptr_t stack; - uintptr_t stack_top; + return g_current_regs[REG_R13]; +} - _alert("stack_base: %06x\n", stack_base); - _alert("stack_size: %06x\n", stack_size); - _alert("sp: %06x\n", sp); +/**************************************************************************** + * Name: avr_registerdump + ****************************************************************************/ - if (sp >= stack_base && sp < stack_base + stack_size) +void avr_registerdump(volatile uint32_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + if (regs) { - stack = sp; - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - stack = stack_base; - } + _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + 0, + regs[REG_R0], regs[REG_R1], + regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], + regs[REG_R6], regs[REG_R7]); - stack_top = stack_base + stack_size; + _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + 8, + regs[REG_R8], regs[REG_R9], + regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], + regs[REG_R14], regs[REG_R15]); - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = stack & ~(8 * sizeof(chipreg_t) - 1); - stack < (stack_top & ~(8 * sizeof(chipreg_t) - 1)); - stack += 8 * sizeof(chipreg_t)) - { - FAR chipreg_t *ptr = (FAR chipreg_t *)stack; - _alert("%06x: %06x %06x %06x %06x %06x %06x %06x %06x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); + _alert("SR: %08x\n", regs[REG_SR]); } } -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/avr/src/common/avr_assert.c b/arch/avr/src/common/avr_assert.c index a23dce264eb..a10f0f61ee3 100644 --- a/arch/avr/src/common/avr_assert.c +++ b/arch/avr/src/common/avr_assert.c @@ -37,8 +37,8 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { board_autoled_on(LED_ASSERTION); - avr_dumpstate(); + avr_registerdump(g_current_regs); } diff --git a/arch/avr/src/common/avr_getintstack.c b/arch/avr/src/common/avr_getintstack.c new file mode 100644 index 00000000000..8baceec9ddc --- /dev/null +++ b/arch/avr/src/common/avr_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/avr/src/common/avr_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "avr_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/avr/src/common/avr_internal.h b/arch/avr/src/common/avr_internal.h index 2d79bf6b69b..2a0ad930584 100644 --- a/arch/avr/src/common/avr_internal.h +++ b/arch/avr/src/common/avr_internal.h @@ -119,7 +119,11 @@ void weak_function avr_dma_initialize(void); void avr_sigdeliver(void); void avr_lowputc(char ch); void avr_lowputs(const char *str); -void avr_dumpstate(void); +#ifdef CONFIG_ARCH_FAMILY_AVR32 +void avr_registerdump(volatile uint32_t *regs); +#else +void avr_registerdump(volatile uint8_t *regs); +#endif /* Defined in common/avr_allocateheap.c or chip/xxx_allocateheap.c */ diff --git a/arch/ceva/src/common/ceva_assert.c b/arch/ceva/src/common/ceva_assert.c index daf304a6f67..92d523ab088 100644 --- a/arch/ceva/src/common/ceva_assert.c +++ b/arch/ceva/src/common/ceva_assert.c @@ -35,80 +35,19 @@ * Private Data ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: up_stackdump + * Name: up_assert ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP -static void up_stackdump(uint32_t sp, uint32_t stack_base) -{ - uint32_t stack; - - for (stack = sp; stack < stack_base; stack += 8 * sizeof(uint32_t)) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} -#else -# define up_stackdump(sp, stack_base) -#endif - -/**************************************************************************** - * Name: up_taskdump - ****************************************************************************/ - -#ifdef CONFIG_STACK_COLORATION -static void up_taskdump(struct tcb_s *tcb, void *arg) -{ - /* Dump interesting properties of this task */ - -#if CONFIG_TASK_NAME_SIZE > 0 - _alert("%s: PID=%d Stack Used=%lu of %lu\n", - tcb->name, tcb->pid, up_check_tcbstack(tcb), - tcb->adj_stack_size); -#else - _alert("PID: %d Stack Used=%lu of %lu\n", - tcb->pid, up_check_tcbstack(tcb), - tcb->adj_stack_size); -#endif -} -#endif - -/**************************************************************************** - * Name: up_showtasks - ****************************************************************************/ - -#ifdef CONFIG_STACK_COLORATION -static inline void up_showtasks(void) -{ - /* Dump interesting properties of each task in the crash environment */ - - sched_foreach(up_taskdump, NULL); -} -#else -# define up_showtasks() -#endif - -/**************************************************************************** - * Name: up_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void up_registerdump(void) +void up_assert(void) { volatile uint32_t *regs = CURRENT_REGS; - int rx; /* Are user registers available from interrupt processing? */ @@ -120,130 +59,5 @@ static inline void up_registerdump(void) regs = s_last_regs; } - /* Dump the interrupt registers */ - - for (rx = 0; rx < XCPTCONTEXT_REGS; rx += 8) - { - _alert("R%03d: %08x %08x %08x %08x %08x %08x %08x %08x\n", - rx, regs[rx], regs[rx + 1], regs[rx + 2], regs[rx + 3], - regs[rx + 4], regs[rx + 5], regs[rx + 6], regs[rx + 7]); - } -} -#else -# define up_registerdump() -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; - uint32_t istackbase; - uint32_t istacksize; - - /* Dump the registers (if available) */ - - up_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - - istackbase = (uint32_t)g_intstackbase; - istacksize = g_intstackbase - g_intstackalloc; - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_intstack()); -#endif - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp <= istackbase && sp > istackbase - istacksize) - { - /* Yes.. dump the interrupt stack */ - - up_stackdump(sp, istackbase); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - up_stackdump(istackbase - istacksize, istackbase); - } - - /* Extract the user stack pointer if we are in an interrupt handler. - * If we are not in an interrupt handler. Then sp is the user stack - * pointer (and the above range check should have failed). - */ - - if (CURRENT_REGS) - { - sp = (uint32_t)CURRENT_REGS; - } - - /* Show user stack info */ - - _alert("sp: %08x\n", sp); - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_tcbstack(rtcb)); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp > ustackbase || sp <= ustackbase - ustacksize) - { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); - } - else - { - up_stackdump(sp, ustackbase); - } - -#ifdef CONFIG_SMP - /* Show the CPU number */ - - _alert("CPU%d:\n", up_cpu_index()); -#endif - - /* Dump the state of all tasks (if available) */ - - up_showtasks(); -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const uint8_t *filename, int lineno) -{ - up_dumpstate(); + ceva_registerdump(regs); } diff --git a/arch/ceva/src/common/ceva_getintstack.c b/arch/ceva/src/common/ceva_getintstack.c new file mode 100644 index 00000000000..5b7ffd25f5c --- /dev/null +++ b/arch/ceva/src/common/ceva_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/ceva/src/common/ceva_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "ceva_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/ceva/src/common/ceva_internal.h b/arch/ceva/src/common/ceva_internal.h index 8a2de7647ee..f7fefc0885e 100644 --- a/arch/ceva/src/common/ceva_internal.h +++ b/arch/ceva/src/common/ceva_internal.h @@ -305,6 +305,8 @@ size_t ceva_stack_check(uintptr_t alloc, size_t size); void ceva_stack_color(void *stackbase, size_t nbytes); #endif +void ceva_registerdump(volatile uint32_t *regs); + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/ceva/src/common/ceva_registerdump.c b/arch/ceva/src/common/ceva_registerdump.c new file mode 100644 index 00000000000..a301f7a32cd --- /dev/null +++ b/arch/ceva/src/common/ceva_registerdump.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/ceva/src/common/ceva_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "ceva_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_SP]; +} + +/**************************************************************************** + * Name: ceva_registerdump + ****************************************************************************/ + +void ceva_registerdump(volatile uint32_t *regs) +{ + int rx; + + /* Dump the interrupt registers */ + + for (rx = 0; rx < XCPTCONTEXT_REGS; rx += 8) + { + _alert("R%03d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + rx, regs[rx], regs[rx + 1], regs[rx + 2], regs[rx + 3], + regs[rx + 4], regs[rx + 5], regs[rx + 6], regs[rx + 7]); + } +} diff --git a/arch/hc/src/common/hc_getintstack.c b/arch/hc/src/common/hc_getintstack.c new file mode 100644 index 00000000000..b3d30b2859a --- /dev/null +++ b/arch/hc/src/common/hc_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/hc/src/common/hc_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "hc_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/hc/src/common/hc_internal.h b/arch/hc/src/common/hc_internal.h index a493daccda4..62fee6d98ea 100644 --- a/arch/hc/src/common/hc_internal.h +++ b/arch/hc/src/common/hc_internal.h @@ -195,6 +195,8 @@ void hc_usbuninitialize(void); # define hc_usbuninitialize() #endif +void hc_registerdump(volatile uint8_t *regs); + #endif /* __ASSEMBLY__ */ #endif /* __ARCH_HC_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/hc/src/m9s12/Make.defs b/arch/hc/src/m9s12/Make.defs index a44a733613d..3d22989579a 100644 --- a/arch/hc/src/m9s12/Make.defs +++ b/arch/hc/src/m9s12/Make.defs @@ -23,12 +23,12 @@ HEAD_ASRC = m9s12_vectors.S CMN_CSRCS = hc_allocateheap.c hc_copystate.c hc_createstack.c CMN_CSRCS += hc_doirq.c hc_exit.c hc_idle.c hc_initialize.c CMN_CSRCS += hc_mdelay.c hc_modifyreg16.c hc_modifyreg32.c hc_modifyreg8.c -CMN_CSRCS += hc_nputs.c hc_releasestack.c +CMN_CSRCS += hc_nputs.c hc_releasestack.c hc_getintstack.c CMN_CSRCS += hc_stackframe.c hc_udelay.c hc_switchcontext.c hc_usestack.c CHIP_ASRCS = m9s12_start.S m9s12_lowputc.S m9s12_saveusercontext.S CHIP_CSRCS = m9s12_assert.c m9s12_gpio.c m9s12_gpioirq.c m9s12_initialstate.c -CHIP_CSRCS += m9s12_irq.c m9s12_serial.c +CHIP_CSRCS += m9s12_irq.c m9s12_serial.c m9s12_registerdump.c ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += m9s12_timerisr.c diff --git a/arch/hc/src/m9s12/m9s12_assert.c b/arch/hc/src/m9s12/m9s12_assert.c index 4afe9297abc..e7cf5b9e538 100644 --- a/arch/hc/src/m9s12/m9s12_assert.c +++ b/arch/hc/src/m9s12/m9s12_assert.c @@ -40,42 +40,22 @@ * Private Data ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP static uint8_t s_last_regs[XCPTCONTEXT_REGS]; -#endif /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: hc_stackdump + * Name: up_assert ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP -static void hc_stackdump(uint16_t sp, uint16_t stack_top) -{ - uint16_t stack; - - for (stack = sp & ~0x7; stack < (stack_top & ~0x7); stack += 8) - { - uint8_t *ptr = (uint8_t *)stack; - _alert("%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} -#endif - -/**************************************************************************** - * Name: hc_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void hc_registerdump(void) +void up_assert(void) { volatile uint8_t *regs = g_current_regs; + board_autoled_on(LED_ASSERTION); + /* Are user registers available from interrupt processing? */ if (regs == NULL) @@ -86,132 +66,5 @@ static inline void hc_registerdump(void) regs = s_last_regs; } - _alert("A:%02x B:%02x X:%02x%02x Y:%02x%02x PC:%02x%02x CCR:%02x\n", - regs[REG_A], regs[REG_B], regs[REG_XH], regs[REG_XL], - regs[REG_YH], regs[REG_YL], regs[REG_PCH], regs[REG_PCL], - regs[REG_CCR]); - _alert("SP:%02x%02x FRAME:%02x%02x TMP:%02x%02x Z:%02x%02x XY:%02x\n", - regs[REG_SPH], regs[REG_SPL], regs[REG_FRAMEH], regs[REG_FRAMEL], - regs[REG_TMPL], regs[REG_TMPH], regs[REG_ZL], regs[REG_ZH], - regs[REG_XY], regs[REG_XY + 1]); - -#if CONFIG_HCS12_MSOFTREGS > 2 -# error "Need to save more registers" -#elif CONFIG_HCS12_MSOFTREGS == 2 - _alert("SOFTREGS: %02x%02x :%02x%02x\n", - regs[REG_SOFTREG1], regs[REG_SOFTREG1 + 1], - regs[REG_SOFTREG2], regs[REG_SOFTREG2 + 1]); -#elif CONFIG_HCS12_MSOFTREGS == 1 - _alert("SOFTREGS: %02x%02x\n", - regs[REG_SOFTREG1], regs[REG_SOFTREG1 + 1]); -#endif - -#ifndef CONFIG_HCS12_NONBANKED - _alert("PPAGE: %02x\n", regs[REG_PPAGE]); -#endif -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) -{ - FAR struct tcb_s *rtcb = running_task(); - uint16_t sp = up_getsp(); - uint16_t ustackbase; - uint16_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint16_t istackbase; - uint16_t istacksize; -#endif - - /* Dump the registers (if available) */ - - hc_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint16_t)rtcb->stack_base_ptr; - ustacksize = (uint16_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint16_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %04x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %04x\n", istackbase); - _alert(" size: %04x\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - hc_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %04x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - hc_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %04x\n", ustackbase); - _alert(" size: %04x\n", ustacksize); -#else - _alert("sp: %04x\n", sp); - _alert("stack base: %04x\n", ustackbase); - _alert("stack size: %04x\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - hc_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - hc_stackdump(ustackbase, ustackbase + ustacksize); - } -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - up_dumpstate(); + hc_registerdump(regs); } diff --git a/arch/hc/src/m9s12/m9s12_registerdump.c b/arch/hc/src/m9s12/m9s12_registerdump.c new file mode 100644 index 00000000000..332e9fcd15d --- /dev/null +++ b/arch/hc/src/m9s12/m9s12_registerdump.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/hc/src/m9s12/m9s12_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "hc_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + uint8_t *ptr = (uint8_t *)g_current_regs; + return (uintptr_t)(ptr[REG_SPH] << 8 | ptr[REG_SPL]); +} + +/**************************************************************************** + * Name: hc_registerdump + ****************************************************************************/ + +void hc_registerdump(volatile uint8_t *regs) +{ + _alert("A:%02x B:%02x X:%02x%02x Y:%02x%02x PC:%02x%02x CCR:%02x\n", + regs[REG_A], regs[REG_B], regs[REG_XH], regs[REG_XL], + regs[REG_YH], regs[REG_YL], regs[REG_PCH], regs[REG_PCL], + regs[REG_CCR]); + _alert("SP:%02x%02x FRAME:%02x%02x TMP:%02x%02x Z:%02x%02x XY:%02x\n", + regs[REG_SPH], regs[REG_SPL], regs[REG_FRAMEH], regs[REG_FRAMEL], + regs[REG_TMPL], regs[REG_TMPH], regs[REG_ZL], regs[REG_ZH], + regs[REG_XY], regs[REG_XY + 1]); + +#if CONFIG_HCS12_MSOFTREGS > 2 +# error "Need to save more registers" +#elif CONFIG_HCS12_MSOFTREGS == 2 + _alert("SOFTREGS: %02x%02x :%02x%02x\n", + regs[REG_SOFTREG1], regs[REG_SOFTREG1 + 1], + regs[REG_SOFTREG2], regs[REG_SOFTREG2 + 1]); +#elif CONFIG_HCS12_MSOFTREGS == 1 + _alert("SOFTREGS: %02x%02x\n", + regs[REG_SOFTREG1], regs[REG_SOFTREG1 + 1]); +#endif + +#ifndef CONFIG_HCS12_NONBANKED + _alert("PPAGE: %02x\n", regs[REG_PPAGE]); +#endif +} diff --git a/arch/mips/src/common/mips_getintstack.c b/arch/mips/src/common/mips_getintstack.c new file mode 100644 index 00000000000..435f36c2a97 --- /dev/null +++ b/arch/mips/src/common/mips_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/mips/src/common/mips_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "mips_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/mips/src/common/mips_internal.h b/arch/mips/src/common/mips_internal.h index 612d9fd2031..badf12cad3e 100644 --- a/arch/mips/src/common/mips_internal.h +++ b/arch/mips/src/common/mips_internal.h @@ -178,11 +178,7 @@ void mips_lowputs(const char *str); /* Debug */ -#ifdef CONFIG_ARCH_STACKDUMP -void mips_dumpstate(void); -#else -# define mips_dumpstate() -#endif +void mips_registerdump(volatile uint32_t *regs); /* Common MIPS32 functions defined in arch/mips/src/MIPS32 */ diff --git a/arch/mips/src/mips32/mips_assert.c b/arch/mips/src/mips32/mips_assert.c index 1e9ec7fe921..7f9f72b34dd 100644 --- a/arch/mips/src/mips32/mips_assert.c +++ b/arch/mips/src/mips32/mips_assert.c @@ -38,8 +38,8 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { board_autoled_on(LED_ASSERTION); - mips_dumpstate(); + mips_registerdump(CURRENT_REGS); } diff --git a/arch/mips/src/mips32/mips_dumpstate.c b/arch/mips/src/mips32/mips_dumpstate.c deleted file mode 100644 index 55b683e3375..00000000000 --- a/arch/mips/src/mips32/mips_dumpstate.c +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** - * arch/mips/src/mips32/mips_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sched/sched.h" -#include "mips_internal.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: mips_stackdump - ****************************************************************************/ - -static void mips_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08" PRIx32 ": %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: mips_registerdump - ****************************************************************************/ - -static inline void mips_registerdump(void) -{ - /* Are user registers available from interrupt processing? */ - - if (CURRENT_REGS) - { - _alert("MFLO:%08" PRIx32 " MFHI:%08" PRIx32 - " EPC:%08" PRIx32 " STATUS:%08" PRIx32 "\n", - CURRENT_REGS[REG_MFLO], CURRENT_REGS[REG_MFHI], - CURRENT_REGS[REG_EPC], CURRENT_REGS[REG_STATUS]); - _alert("AT:%08" PRIx32 " V0:%08" PRIx32 " V1:%08" PRIx32 - " A0:%08" PRIx32 " A1:%08" PRIx32 " A2:%08" PRIx32 - " A3:%08" PRIx32 "\n", - CURRENT_REGS[REG_AT], CURRENT_REGS[REG_V0], - CURRENT_REGS[REG_V1], CURRENT_REGS[REG_A0], - CURRENT_REGS[REG_A1], CURRENT_REGS[REG_A2], - CURRENT_REGS[REG_A3]); - _alert("T0:%08" PRIx32 " T1:%08" PRIx32 " T2:%08" PRIx32 - " T3:%08" PRIx32 " T4:%08" PRIx32 " T5:%08" PRIx32 - " T6:%08" PRIx32 " T7:%08" PRIx32 "\n", - CURRENT_REGS[REG_T0], CURRENT_REGS[REG_T1], - CURRENT_REGS[REG_T2], CURRENT_REGS[REG_T3], - CURRENT_REGS[REG_T4], CURRENT_REGS[REG_T5], - CURRENT_REGS[REG_T6], CURRENT_REGS[REG_T7]); - _alert("S0:%08" PRIx32 " S1:%08" PRIx32 " S2:%08" PRIx32 - " S3:%08" PRIx32 " S4:%08" PRIx32 " S5:%08" PRIx32 - " S6:%08" PRIx32 " S7:%08" PRIx32 "\n", - CURRENT_REGS[REG_S0], CURRENT_REGS[REG_S1], - CURRENT_REGS[REG_S2], CURRENT_REGS[REG_S3], - CURRENT_REGS[REG_S4], CURRENT_REGS[REG_S5], - CURRENT_REGS[REG_S6], CURRENT_REGS[REG_S7]); -#ifdef MIPS32_SAVE_GP - _alert("T8:%08" PRIx32 " T9:%08" PRIx32 " GP:%08" PRIx32 - " SP:%08" PRIx32 " FP:%08" PRIx32 " RA:%08" PRIx32 "\n", - CURRENT_REGS[REG_T8], CURRENT_REGS[REG_T9], - CURRENT_REGS[REG_GP], CURRENT_REGS[REG_SP], - CURRENT_REGS[REG_FP], CURRENT_REGS[REG_RA]); -#else - _alert("T8:%08" PRIx32 " T9:%08" PRIx32 " SP:%08" PRIx32 - " FP:%08" PRIx32 " RA:%08" PRIx32 "\n", - CURRENT_REGS[REG_T8], CURRENT_REGS[REG_T9], - CURRENT_REGS[REG_SP], CURRENT_REGS[REG_FP], - CURRENT_REGS[REG_RA]); -#endif - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: mips_dumpstate - ****************************************************************************/ - -void mips_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - mips_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08" PRIx32 "\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08" PRIx32 "\n", istackbase); - _alert(" size: %08" PRIx32 "\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - mips_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %08" PRIx32 "\n", sp); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - mips_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08" PRIx32 "\n", ustackbase); - _alert(" size: %08" PRIx32 "\n", ustacksize); -#else - _alert("sp: %08" PRIx32 "\n", sp); - _alert("stack base: %08" PRIx32 "\n", ustackbase); - _alert("stack size: %08" PRIx32 "\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - mips_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - mips_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/mips/src/mips32/mips_registerdump.c b/arch/mips/src/mips32/mips_registerdump.c new file mode 100644 index 00000000000..9ce3fa7ee17 --- /dev/null +++ b/arch/mips/src/mips32/mips_registerdump.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/mips/src/mips32/mips_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "mips_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_SP]; +} + +/**************************************************************************** + * Name: mips_registerdump + ****************************************************************************/ + +void mips_registerdump(volatile uint32_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + if (regs) + { + _alert("MFLO:%08" PRIx32 " MFHI:%08" PRIx32 + " EPC:%08" PRIx32 " STATUS:%08" PRIx32 "\n", + regs[REG_MFLO], regs[REG_MFHI], + regs[REG_EPC], regs[REG_STATUS]); + _alert("AT:%08" PRIx32 " V0:%08" PRIx32 " V1:%08" PRIx32 + " A0:%08" PRIx32 " A1:%08" PRIx32 " A2:%08" PRIx32 + " A3:%08" PRIx32 "\n", + regs[REG_AT], regs[REG_V0], + regs[REG_V1], regs[REG_A0], + regs[REG_A1], regs[REG_A2], + regs[REG_A3]); + _alert("T0:%08" PRIx32 " T1:%08" PRIx32 " T2:%08" PRIx32 + " T3:%08" PRIx32 " T4:%08" PRIx32 " T5:%08" PRIx32 + " T6:%08" PRIx32 " T7:%08" PRIx32 "\n", + regs[REG_T0], regs[REG_T1], + regs[REG_T2], regs[REG_T3], + regs[REG_T4], regs[REG_T5], + regs[REG_T6], regs[REG_T7]); + _alert("S0:%08" PRIx32 " S1:%08" PRIx32 " S2:%08" PRIx32 + " S3:%08" PRIx32 " S4:%08" PRIx32 " S5:%08" PRIx32 + " S6:%08" PRIx32 " S7:%08" PRIx32 "\n", + regs[REG_S0], regs[REG_S1], + regs[REG_S2], regs[REG_S3], + regs[REG_S4], regs[REG_S5], + regs[REG_S6], regs[REG_S7]); +#ifdef MIPS32_SAVE_GP + _alert("T8:%08" PRIx32 " T9:%08" PRIx32 " GP:%08" PRIx32 + " SP:%08" PRIx32 " FP:%08" PRIx32 " RA:%08" PRIx32 "\n", + regs[REG_T8], regs[REG_T9], + regs[REG_GP], regs[REG_SP], + regs[REG_FP], regs[REG_RA]); +#else + _alert("T8:%08" PRIx32 " T9:%08" PRIx32 " SP:%08" PRIx32 + " FP:%08" PRIx32 " RA:%08" PRIx32 "\n", + regs[REG_T8], regs[REG_T9], + regs[REG_SP], regs[REG_FP], + regs[REG_RA]); +#endif + } +} diff --git a/arch/mips/src/mips32/mips_swint0.c b/arch/mips/src/mips32/mips_swint0.c index 0c2bb58688b..6d15e610002 100644 --- a/arch/mips/src/mips32/mips_swint0.c +++ b/arch/mips/src/mips32/mips_swint0.c @@ -43,38 +43,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: mips_registerdump - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_SYSCALL_INFO -static void mips_registerdump(const uint32_t *regs) -{ - svcinfo("MFLO:%08x MFHI:%08x EPC:%08x STATUS:%08x\n", - regs[REG_MFLO], regs[REG_MFHI], regs[REG_EPC], regs[REG_STATUS]); - svcinfo("AT:%08x V0:%08x V1:%08x A0:%08x A1:%08x A2:%08x A3:%08x\n", - regs[REG_AT], regs[REG_V0], regs[REG_V1], regs[REG_A0], - regs[REG_A1], regs[REG_A2], regs[REG_A3]); - svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x " - "T4:%08x T5:%08x T6:%08x T7:%08x\n", - regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], - regs[REG_T4], regs[REG_T5], regs[REG_T6], regs[REG_T7]); - svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x " - "S4:%08x S5:%08x S6:%08x S7:%08x\n", - regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], - regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); -#ifdef MIPS32_SAVE_GP - svcinfo("T8:%08x T9:%08x GP:%08x SP:%08x FP:%08x RA:%08x\n", - regs[REG_T8], regs[REG_T9], regs[REG_GP], regs[REG_SP], - regs[REG_FP], regs[REG_RA]); -#else - svcinfo("T8:%08x T9:%08x SP:%08x FP:%08x RA:%08x\n", - regs[REG_T8], regs[REG_T9], regs[REG_SP], regs[REG_FP], - regs[REG_RA]); -#endif -} -#endif - /**************************************************************************** * Name: dispatch_syscall * @@ -288,7 +256,7 @@ int mips_swint0(int irq, void *context, void *arg) if (regs != CURRENT_REGS) { svcinfo("SWInt Return: Context switch!\n"); - mips_registerdump((const uint32_t *)CURRENT_REGS); + mips_registerdump(CURRENT_REGS); } else { diff --git a/arch/mips/src/pic32mx/Make.defs b/arch/mips/src/pic32mx/Make.defs index 9981e23ee53..fc6d74044d8 100644 --- a/arch/mips/src/pic32mx/Make.defs +++ b/arch/mips/src/pic32mx/Make.defs @@ -33,6 +33,7 @@ CMN_CSRCS += mips_nputs.c mips_releasestack.c CMN_CSRCS += mips_schedulesigaction.c mips_sigdeliver.c CMN_CSRCS += mips_stackframe.c mips_swint0.c mips_udelay.c mips_switchcontext.c CMN_CSRCS += mips_usestack.c mips_vfork.c +CMN_CSRCS += mips_registerdump.c mips_getintstack.c # Configuration dependent common files @@ -50,10 +51,6 @@ CMN_CSRCS += mips_etherstub.c endif endif -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += mips_dumpstate.c -endif - # Required PIC32MX files CHIP_CSRCS = pic32mx_irq.c pic32mx_decodeirq.c pic32mx_exception.c diff --git a/arch/mips/src/pic32mz/Make.defs b/arch/mips/src/pic32mz/Make.defs index 00d015d05e8..348a3b942a0 100644 --- a/arch/mips/src/pic32mz/Make.defs +++ b/arch/mips/src/pic32mz/Make.defs @@ -33,6 +33,7 @@ CMN_CSRCS += mips_nputs.c mips_releasestack.c CMN_CSRCS += mips_schedulesigaction.c mips_sigdeliver.c CMN_CSRCS += mips_stackframe.c mips_swint0.c mips_udelay.c mips_switchcontext.c CMN_CSRCS += mips_usestack.c mips_vfork.c +CMN_CSRCS += mips_registerdump.c mips_getintstack.c # Configuration dependent common files @@ -50,10 +51,6 @@ CMN_CSRCS += mips_etherstub.c endif endif -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += mips_dumpstate.c -endif - # Required PIC32MZ files CHIP_CSRCS = pic32mz_lowinit.c pic32mz_exception.c pic32mz_decodeirq.c diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index 88e4e60f9bc..234549f451c 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -29,7 +29,7 @@ CHIP_ASRCS = lm32_syscall.S CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_decodeirq.c -CHIP_CSRCS += lm32_doirq.c lm32_dumpstate.c lm32_exit.c lm32_idle.c +CHIP_CSRCS += lm32_doirq.c lm32_registerdump.c lm32_exit.c lm32_idle.c CHIP_CSRCS += lm32_initialstate.c lm32_irq.c CHIP_CSRCS += lm32_releasestack.c lm32_stackframe.c lm32_swint.c CHIP_CSRCS += lm32_switchcontext.c diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index e9552a043c5..395799c2d31 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -128,7 +128,7 @@ void lm32_flush_icache(void); /* Debug ********************************************************************/ -void lm32_dumpstate(void); +void lm32_registerdump(volatile uint32_t *regs); #endif /* __ASSEMBLY__ */ #endif /* __ARCH_MISOC_SRC_LM32_LM32_H */ diff --git a/arch/misoc/src/lm32/lm32_assert.c b/arch/misoc/src/lm32/lm32_assert.c index f5705298851..7b934061c8b 100644 --- a/arch/misoc/src/lm32/lm32_assert.c +++ b/arch/misoc/src/lm32/lm32_assert.c @@ -38,8 +38,8 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { board_autoled_on(LED_ASSERTION); - lm32_dumpstate(); + lm32_registerdump(g_current_regs); } diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c deleted file mode 100644 index 64d167e13d4..00000000000 --- a/arch/misoc/src/lm32/lm32_dumpstate.c +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** - * arch/misoc/src/lm32/lm32_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sched/sched.h" -#include "lm32.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: lm32_stackdump - ****************************************************************************/ - -static void lm32_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: lm32_registerdump - ****************************************************************************/ - -static inline void lm32_registerdump(void) -{ - /* Are user registers available from interrupt processing? */ - - if (g_current_regs) - { - _alert("EPC:%08x\n", - g_current_regs[REG_EPC]); - _alert(" X0:%08x A0:%08x A1:%08x A2:%08x " - " A3:%08x A4:%08x A5:%08x A6:%08x\n", - g_current_regs[REG_X0_NDX], g_current_regs[REG_X1_NDX], - g_current_regs[REG_X2_NDX], g_current_regs[REG_X3_NDX], - g_current_regs[REG_X4_NDX], g_current_regs[REG_X5_NDX], - g_current_regs[REG_X6_NDX], g_current_regs[REG_X7_NDX]); - _alert(" A7:%08x X9:%08x X10:%08x X11:%08x " - "X12:%08x X13:%08x X14:%08x X15:%08x\n", - g_current_regs[REG_X8_NDX], g_current_regs[REG_X9_NDX], - g_current_regs[REG_X10_NDX], g_current_regs[REG_X11_NDX], - g_current_regs[REG_X12_NDX], g_current_regs[REG_X13_NDX], - g_current_regs[REG_X14_NDX], g_current_regs[REG_X15_NDX]); - _alert("X16:%08x X17:%08x X18:%08x X19:%08x " - "X20:%08x X21:%08x X22:%08x X23:%08x\n", - g_current_regs[REG_X16_NDX], g_current_regs[REG_X17_NDX], - g_current_regs[REG_X18_NDX], g_current_regs[REG_X19_NDX], - g_current_regs[REG_X20_NDX], g_current_regs[REG_X21_NDX], - g_current_regs[REG_X22_NDX], g_current_regs[REG_X23_NDX]); - _alert("X24:%08x X25:%08x GP:%08x FP:%08x " - " SP:%08x RA:%08x EA:%08x BA:%08x\n", - g_current_regs[REG_X24_NDX], g_current_regs[REG_X25_NDX], - g_current_regs[REG_X26_NDX], g_current_regs[REG_X27_NDX], - g_current_regs[REG_X28_NDX], g_current_regs[REG_X29_NDX], - g_current_regs[REG_X30_NDX], g_current_regs[REG_X31_NDX]); - _alert(" IE:%08x\n", g_current_regs[REG_X32_NDX]); - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: lm32_dumpstate - ****************************************************************************/ - -void lm32_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - lm32_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - lm32_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %08x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - lm32_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - lm32_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - lm32_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/misoc/src/lm32/lm32_registerdump.c b/arch/misoc/src/lm32/lm32_registerdump.c new file mode 100644 index 00000000000..7e5e34b7088 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_registerdump.c @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_SP]; +} + +/**************************************************************************** + * Name: lm32_registerdump + ****************************************************************************/ + +void lm32_registerdump(volatile uint32_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + if (regs) + { + _alert("EPC:%08x\n", + regs[REG_EPC]); + _alert(" X0:%08x A0:%08x A1:%08x A2:%08x " + " A3:%08x A4:%08x A5:%08x A6:%08x\n", + regs[REG_X0_NDX], regs[REG_X1_NDX], + regs[REG_X2_NDX], regs[REG_X3_NDX], + regs[REG_X4_NDX], regs[REG_X5_NDX], + regs[REG_X6_NDX], regs[REG_X7_NDX]); + _alert(" A7:%08x X9:%08x X10:%08x X11:%08x " + "X12:%08x X13:%08x X14:%08x X15:%08x\n", + regs[REG_X8_NDX], regs[REG_X9_NDX], + regs[REG_X10_NDX], regs[REG_X11_NDX], + regs[REG_X12_NDX], regs[REG_X13_NDX], + regs[REG_X14_NDX], regs[REG_X15_NDX]); + _alert("X16:%08x X17:%08x X18:%08x X19:%08x " + "X20:%08x X21:%08x X22:%08x X23:%08x\n", + regs[REG_X16_NDX], regs[REG_X17_NDX], + regs[REG_X18_NDX], regs[REG_X19_NDX], + regs[REG_X20_NDX], regs[REG_X21_NDX], + regs[REG_X22_NDX], regs[REG_X23_NDX]); + _alert("X24:%08x X25:%08x GP:%08x FP:%08x " + " SP:%08x RA:%08x EA:%08x BA:%08x\n", + regs[REG_X24_NDX], regs[REG_X25_NDX], + regs[REG_X26_NDX], regs[REG_X27_NDX], + regs[REG_X28_NDX], regs[REG_X29_NDX], + regs[REG_X30_NDX], regs[REG_X31_NDX]); + _alert(" IE:%08x\n", regs[REG_X32_NDX]); + } +} + diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index e80f79dc14c..353caa23f37 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -40,41 +40,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: lm32_registerdump - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_SYSCALL_INFO -static void lm32_registerdump(const uint32_t *regs) -{ -#if 0 - svcinfo("EPC:%08x\n", - regs[REG_EPC]); - svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x " - "A4:%08x A5:%08x A6:%08x A7:%08x\n", - regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3], - regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); - svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n", - regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], - regs[REG_T4], regs[REG_T5], regs[REG_T6]); - svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x " - "S4:%08x S5:%08x S6:%08x S7:%08x\n", - regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], - regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); - svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n", - regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); -#ifdef LM3232_SAVE_GP - svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n", - regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], - regs[REG_RA]); -#else - svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n", - regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); -#endif -#endif -} -#endif - /**************************************************************************** * Name: dispatch_syscall * @@ -289,7 +254,7 @@ int lm32_swint(int irq, void *context, void *arg) if (regs != g_current_regs) { svcinfo("SWInt Return: Context switch!\n"); - lm32_registerdump((const uint32_t *)g_current_regs); + lm32_registerdump(g_current_regs); } else { diff --git a/arch/misoc/src/minerva/Make.defs b/arch/misoc/src/minerva/Make.defs index a8c3f3bc25e..9a409ee6b1a 100644 --- a/arch/misoc/src/minerva/Make.defs +++ b/arch/misoc/src/minerva/Make.defs @@ -29,7 +29,7 @@ CHIP_ASRCS = minerva_syscall.S CHIP_CSRCS = minerva_allocateheap.c minerva_assert.c CHIP_CSRCS += minerva_copystate.c minerva_createstack.c minerva_decodeirq.c -CHIP_CSRCS += minerva_doirq.c minerva_dumpstate.c minerva_exit.c minerva_idle.c +CHIP_CSRCS += minerva_doirq.c minerva_registerdump.c minerva_exit.c minerva_idle.c CHIP_CSRCS += minerva_initialstate.c minerva_irq.c CHIP_CSRCS += minerva_releasestack.c minerva_stackframe.c minerva_swint.c CHIP_CSRCS += minerva_switchcontext.c diff --git a/arch/misoc/src/minerva/minerva.h b/arch/misoc/src/minerva/minerva.h index 5def3d49e2d..20b8124c4e2 100644 --- a/arch/misoc/src/minerva/minerva.h +++ b/arch/misoc/src/minerva/minerva.h @@ -127,7 +127,7 @@ void minerva_flush_icache(void); /* Debug ********************************************************************/ -void minerva_dumpstate(void); +void mineva_registerdump(volatile uint32_t *regs); #endif /* __ASSEMBLY__ */ #endif /* __ARCH_MISOC_SRC_MINERVA_MINERVA_H */ diff --git a/arch/misoc/src/minerva/minerva_assert.c b/arch/misoc/src/minerva/minerva_assert.c index e427abe9196..86ade9ba5f3 100644 --- a/arch/misoc/src/minerva/minerva_assert.c +++ b/arch/misoc/src/minerva/minerva_assert.c @@ -38,8 +38,8 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { board_autoled_on(LED_ASSERTION); - minerva_dumpstate(); + mineva_registerdump(g_current_regs); } diff --git a/arch/misoc/src/minerva/minerva_dumpstate.c b/arch/misoc/src/minerva/minerva_dumpstate.c deleted file mode 100644 index 2b4809f88e9..00000000000 --- a/arch/misoc/src/minerva/minerva_dumpstate.c +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** - * arch/misoc/src/minerva/minerva_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sched/sched.h" -#include "minerva.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: mineva_stackdump - ****************************************************************************/ - -static void mineva_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: mineva_registerdump - ****************************************************************************/ - -static inline void mineva_registerdump(void) -{ - /* Are user registers available from interrupt processing? */ - - if (g_current_regs) - { - _alert("EPC:%08x\n", g_current_regs[REG_CSR_MEPC]); - _alert(" X0:%08x A0:%08x A1:%08x A2:%08x " - " A3:%08x A4:%08x A5:%08x A6:%08x\n", - g_current_regs[REG_X0_NDX], g_current_regs[REG_X1_NDX], - g_current_regs[REG_X2_NDX], g_current_regs[REG_X3_NDX], - g_current_regs[REG_X4_NDX], g_current_regs[REG_X5_NDX], - g_current_regs[REG_X6_NDX], g_current_regs[REG_X7_NDX]); - _alert(" A7:%08x X9:%08x X10:%08x X11:%08x " - "X12:%08x X13:%08x X14:%08x X15:%08x\n", - g_current_regs[REG_X8_NDX], g_current_regs[REG_X9_NDX], - g_current_regs[REG_X10_NDX], g_current_regs[REG_X11_NDX], - g_current_regs[REG_X12_NDX], g_current_regs[REG_X13_NDX], - g_current_regs[REG_X14_NDX], g_current_regs[REG_X15_NDX]); - _alert("X16:%08x X17:%08x X18:%08x X19:%08x" - "X20:%08x X21:%08x X22:%08x X23:%08x\n", - g_current_regs[REG_X16_NDX], g_current_regs[REG_X17_NDX], - g_current_regs[REG_X18_NDX], g_current_regs[REG_X19_NDX], - g_current_regs[REG_X20_NDX], g_current_regs[REG_X21_NDX], - g_current_regs[REG_X22_NDX], g_current_regs[REG_X23_NDX]); - _alert("X24:%08x X25:%08x GP:%08x FP:%08x " - " SP:%08x RA:%08x EA:%08x BA:%08x\n", - g_current_regs[REG_X24_NDX], g_current_regs[REG_X25_NDX], - g_current_regs[REG_X26_NDX], g_current_regs[REG_X27_NDX], - g_current_regs[REG_X28_NDX], g_current_regs[REG_X29_NDX], - g_current_regs[REG_X30_NDX], g_current_regs[REG_X31_NDX]); - _alert(" IE:%08x\n", g_current_regs[REG_CSR_MSTATUS]); - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: minerva_dumpstate - ****************************************************************************/ - -void minerva_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - mineva_registerdump(); - - /* Get the limits on the user stack memory NOTE: You cannot use the PID to - * determine if this is an IDLE task. In the SMP case, there may be - * multiple IDLE tasks with different PIDs. The only consistent way to - * test for the IDLE task is to check it is at the end of the list (flink - * == NULL) - */ - - ustackbase = (uint32_t) rtcb->stack_base_ptr; - ustacksize = (uint32_t) rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); - - /* Does the current stack pointer lie within the interrupt stack? */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - mineva_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie at the base of the - * interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %08x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - mineva_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - mineva_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - mineva_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/misoc/src/minerva/minerva_registerdump.c b/arch/misoc/src/minerva/minerva_registerdump.c new file mode 100644 index 00000000000..98a95998da3 --- /dev/null +++ b/arch/misoc/src/minerva/minerva_registerdump.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/misoc/src/minerva/minerva_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "minerva.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_X2]; +} + +/**************************************************************************** + * Name: mineva_registerdump + ****************************************************************************/ + +void mineva_registerdump(volatile uint32_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + if (regs) + { + _alert("EPC:%08x\n", regs[REG_CSR_MEPC]); + _alert(" X0:%08x A0:%08x A1:%08x A2:%08x " + " A3:%08x A4:%08x A5:%08x A6:%08x\n", + regs[REG_X0_NDX], regs[REG_X1_NDX], + regs[REG_X2_NDX], regs[REG_X3_NDX], + regs[REG_X4_NDX], regs[REG_X5_NDX], + regs[REG_X6_NDX], regs[REG_X7_NDX]); + _alert(" A7:%08x X9:%08x X10:%08x X11:%08x " + "X12:%08x X13:%08x X14:%08x X15:%08x\n", + regs[REG_X8_NDX], regs[REG_X9_NDX], + regs[REG_X10_NDX], regs[REG_X11_NDX], + regs[REG_X12_NDX], regs[REG_X13_NDX], + regs[REG_X14_NDX], regs[REG_X15_NDX]); + _alert("X16:%08x X17:%08x X18:%08x X19:%08x" + "X20:%08x X21:%08x X22:%08x X23:%08x\n", + regs[REG_X16_NDX], regs[REG_X17_NDX], + regs[REG_X18_NDX], regs[REG_X19_NDX], + regs[REG_X20_NDX], regs[REG_X21_NDX], + regs[REG_X22_NDX], regs[REG_X23_NDX]); + _alert("X24:%08x X25:%08x GP:%08x FP:%08x " + " SP:%08x RA:%08x EA:%08x BA:%08x\n", + regs[REG_X24_NDX], regs[REG_X25_NDX], + regs[REG_X26_NDX], regs[REG_X27_NDX], + regs[REG_X28_NDX], regs[REG_X29_NDX], + regs[REG_X30_NDX], regs[REG_X31_NDX]); + _alert(" IE:%08x\n", regs[REG_CSR_MSTATUS]); + } +} + diff --git a/arch/misoc/src/minerva/minerva_swint.c b/arch/misoc/src/minerva/minerva_swint.c index 66f03330f5e..d46f2dca0ba 100644 --- a/arch/misoc/src/minerva/minerva_swint.c +++ b/arch/misoc/src/minerva/minerva_swint.c @@ -40,41 +40,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: minerva_registerdump - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_SYSCALL_INFO -static void minerva_registerdump(const uint32_t * regs) -{ -#if 0 - svcinfo("EPC:%08x\n", regs[REG_CSR_MEPC]); - svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x " - "A4:%08x A5:%08x A6:%08x A7:%08x\n", - regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3], - regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); - svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x " - "T4:%08x T5:%08x T6:%08x\n", - regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], - regs[REG_T4], regs[REG_T5], regs[REG_T6]); - svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x " - "S4:%08x S5:%08x S6:%08x S7:%08x\n", - regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], - regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); - svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n", - regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); -#ifdef MINERVA32_SAVE_GP - svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n", - regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], - regs[REG_RA]); -#else - svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n", - regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); -#endif -#endif -} -#endif - /**************************************************************************** * Name: dispatch_syscall * @@ -265,7 +230,7 @@ int minerva_swint(int irq, void *context, void *arg) if (regs != g_current_regs) { svcinfo("SWInt Return: Context switch!\n"); - minerva_registerdump((const uint32_t *)g_current_regs); + minerva_registerdump(g_current_regs); } else { diff --git a/arch/or1k/src/common/or1k_assert.c b/arch/or1k/src/common/or1k_assert.c index 068a8f97639..88824d1c057 100644 --- a/arch/or1k/src/common/or1k_assert.c +++ b/arch/or1k/src/common/or1k_assert.c @@ -40,78 +40,22 @@ * Private Data ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: or1k_stackdump + * Name: up_assert ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP -static void or1k_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} -#endif - -/**************************************************************************** - * Name: up_taskdump - ****************************************************************************/ - -#ifdef CONFIG_STACK_COLORATION -static void up_taskdump(struct tcb_s *tcb, void *arg) -{ - /* Dump interesting properties of this task */ - -#if CONFIG_TASK_NAME_SIZE > 0 - _alert("%s: PID=%d Stack Used=%lu of %lu\n", - tcb->name, tcb->pid, (unsigned long)up_check_tcbstack(tcb), - (unsigned long)tcb->adj_stack_size); -#else - _alert("PID: %d Stack Used=%lu of %lu\n", - tcb->pid, (unsigned long)up_check_tcbstack(tcb), - (unsigned long)tcb->adj_stack_size); -#endif -} -#endif - -/**************************************************************************** - * Name: up_showtasks - ****************************************************************************/ - -#ifdef CONFIG_STACK_COLORATION -static inline void up_showtasks(void) -{ - /* Dump interesting properties of each task in the crash environment */ - - nxsched_foreach(up_taskdump, NULL); -} -#else -# define up_showtasks() -#endif - -/**************************************************************************** - * Name: or1k_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void or1k_registerdump(void) +void up_assert(void) { volatile uint32_t *regs = CURRENT_REGS; + board_autoled_on(LED_ASSERTION); + /* Are user registers available from interrupt processing? */ if (regs == NULL) @@ -122,139 +66,5 @@ static inline void or1k_registerdump(void) regs = s_last_regs; } - /* Dump the interrupt registers */ - - _alert("R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], - regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); -#ifdef CONFIG_BUILD_PROTECTED - _alert("xPSR: %08x PRIMASK: %08x EXEC_RETURN: %08x\n", - regs[REG_XPSR], regs[REG_PRIMASK], regs[REG_EXC_RETURN]); -#else - _alert("xPSR: %08x PRIMASK: %08x\n", - regs[REG_XPSR], regs[REG_PRIMASK]); -#endif -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - or1k_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_intstack()); -#endif - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - or1k_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - or1k_stackdump(istackbase, istackbase + istacksize); - } - - /* Extract the user stack pointer if we are in an interrupt handler. - * If we are not in an interrupt handler. Then sp is the user stack - * pointer (and the above range check should have failed). - */ - - if (CURRENT_REGS) - { - sp = CURRENT_REGS[REG_R13]; - _alert("sp: %08x\n", sp); - } - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_tcbstack(rtcb)); -#endif -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert("stack used: %08x\n", up_check_tcbstack(rtcb)); -#endif -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - or1k_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - or1k_stackdump(ustackbase, ustackbase + ustacksize); - } - - /* Dump the state of all tasks (if available) */ - - up_showtasks(); -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - up_dumpstate(); + or1k_registerdump(regs); } diff --git a/arch/or1k/src/common/or1k_getintstack.c b/arch/or1k/src/common/or1k_getintstack.c new file mode 100644 index 00000000000..dcfcf16075f --- /dev/null +++ b/arch/or1k/src/common/or1k_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/or1k/src/common/or1k_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "or1k_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/or1k/src/common/or1k_internal.h b/arch/or1k/src/common/or1k_internal.h index 6ea0c9fb2ef..925ca1d57b9 100644 --- a/arch/or1k/src/common/or1k_internal.h +++ b/arch/or1k/src/common/or1k_internal.h @@ -323,6 +323,8 @@ size_t or1k_stack_check(uintptr_t alloc, size_t size); void or1k_stack_color(void *stackbase, size_t nbytes); #endif +void or1k_registerdump(volatile uint32_t *regs); + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/or1k/src/common/or1k_registerdump.c b/arch/or1k/src/common/or1k_registerdump.c new file mode 100644 index 00000000000..14a6263966c --- /dev/null +++ b/arch/or1k/src/common/or1k_registerdump.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * arch/or1k/src/common/or1k_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "or1k_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_R13]; +} + +/**************************************************************************** + * Name: or1k_registerdump + ****************************************************************************/ + +void or1k_registerdump(volatile uint32_t *regs) +{ + /* Dump the interrupt registers */ + + _alert("R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + _alert("R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); +#ifdef CONFIG_BUILD_PROTECTED + _alert("xPSR: %08x PRIMASK: %08x EXEC_RETURN: %08x\n", + regs[REG_XPSR], regs[REG_PRIMASK], regs[REG_EXC_RETURN]); +#else + _alert("xPSR: %08x PRIMASK: %08x\n", + regs[REG_XPSR], regs[REG_PRIMASK]); +#endif +} diff --git a/arch/or1k/src/mor1kx/Make.defs b/arch/or1k/src/mor1kx/Make.defs index 59fe0e0906d..0e217ccbebf 100644 --- a/arch/or1k/src/mor1kx/Make.defs +++ b/arch/or1k/src/mor1kx/Make.defs @@ -32,6 +32,8 @@ CMN_CSRCS = or1k_initialize.c \ or1k_switchcontext.c \ or1k_schedulesigaction.c \ or1k_copyfullstate.c \ + or1k_registerdump.c \ + or1k_getintstack.c \ or1k_assert.c \ or1k_exit.c \ or1k_udelay.c \ diff --git a/arch/renesas/src/common/renesas_assert.c b/arch/renesas/src/common/renesas_assert.c index 919b3cb884e..28b8b66db94 100644 --- a/arch/renesas/src/common/renesas_assert.c +++ b/arch/renesas/src/common/renesas_assert.c @@ -25,10 +25,18 @@ #include #include +#include +#include #include #include "renesas_internal.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static uint32_t s_last_regs[XCPTCONTEXT_REGS]; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -37,8 +45,21 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { + volatile uint32_t *regs = g_current_regs; + board_autoled_on(LED_ASSERTION); - renesas_dumpstate(); + + /* Are user registers available from interrupt processing? */ + + if (regs == NULL) + { + /* No.. capture user registers by hand */ + + up_saveusercontext(s_last_regs); + regs = s_last_regs; + } + + renesas_registerdump(regs); } diff --git a/arch/renesas/src/common/renesas_getintstack.c b/arch/renesas/src/common/renesas_getintstack.c new file mode 100644 index 00000000000..0e384a588cc --- /dev/null +++ b/arch/renesas/src/common/renesas_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/renesas/src/common/renesas_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "renesas_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/renesas/src/common/renesas_internal.h b/arch/renesas/src/common/renesas_internal.h index 270b6745825..472edc4639c 100644 --- a/arch/renesas/src/common/renesas_internal.h +++ b/arch/renesas/src/common/renesas_internal.h @@ -118,6 +118,15 @@ typedef void (*up_vector_t)(void); extern uint32_t g_idle_topstack; #endif +/* Address of the saved user stack pointer */ + +#ifndef __ASSEMBLY__ +# if CONFIG_ARCH_INTERRUPTSTACK > 3 + extern uint8_t g_intstackalloc[]; + extern uint8_t g_intstacktop[]; +# endif +#endif + /**************************************************************************** * Inline Functions ****************************************************************************/ @@ -193,11 +202,7 @@ void renesas_usbuninitialize(void); /* Defined in chip-specific logic */ -#ifdef CONFIG_ARCH_STACKDUMP -void renesas_dumpstate(void); -#else -# define renesas_dumpstate() -#endif +void renesas_registerdump(volatile uint32_t *regs); #endif /* __ASSEMBLY__ */ #endif /* ___ARCH_RENESAS_SRC_COMMON_UP_INTERNAL_H */ diff --git a/arch/renesas/src/m16c/Make.defs b/arch/renesas/src/m16c/Make.defs index 8246e83dbab..264d2d10872 100644 --- a/arch/renesas/src/m16c/Make.defs +++ b/arch/renesas/src/m16c/Make.defs @@ -22,13 +22,14 @@ HEAD_ASRC = m16c_head.S CMN_CSRCS = renesas_allocateheap.c renesas_assert.c CMN_CSRCS += renesas_createstack.c renesas_doirq.c renesas_exit.c renesas_idle.c renesas_initialize.c -CMN_CSRCS += renesas_lowputs.c renesas_mdelay.c renesas_nputs.c renesas_releasestack.c +CMN_CSRCS += renesas_lowputs.c renesas_mdelay.c renesas_nputs.c +CMN_CSRCS += renesas_releasestack.c renesas_getintstack.c CMN_CSRCS += renesas_stackframe.c renesas_udelay.c renesas_switchcontext.c renesas_usestack.c CHIP_ASRCS = m16c_vectors.S CHIP_CSRCS = m16c_initialstate.c m16c_copystate.c m16c_lowputc.c m16c_irq.c CHIP_CSRCS += m16c_schedulesigaction.c m16c_sigdeliver.c -CHIP_CSRCS += m16c_serial.c m16c_dumpstate.c +CHIP_CSRCS += m16c_serial.c m16c_registerdump.c ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += m16c_timerisr.c diff --git a/arch/renesas/src/m16c/chip.h b/arch/renesas/src/m16c/chip.h index 1ed92f665a1..1772cf06f52 100644 --- a/arch/renesas/src/m16c/chip.h +++ b/arch/renesas/src/m16c/chip.h @@ -253,15 +253,6 @@ extern uint32_t g_enronly; /* Start of relocated read-only data in FLASH * #endif extern uint32_t g_svarvect; /* Start of variable vectors */ -/* Address of the saved user stack pointer */ - -#ifndef __ASSEMBLY__ -# if CONFIG_ARCH_INTERRUPTSTACK > 3 - extern uint8_t g_intstackalloc[]; - extern uint8_t g_intstacktop[]; -# endif -#endif - #endif /* __ASSEMBLY__ */ #endif /* __ARCH_RENESAS_SRC_M16C_CHIP_H */ diff --git a/arch/renesas/src/m16c/m16c_dumpstate.c b/arch/renesas/src/m16c/m16c_dumpstate.c deleted file mode 100644 index 7e5c2848642..00000000000 --- a/arch/renesas/src/m16c/m16c_dumpstate.c +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** - * arch/renesas/src/m16c/m16c_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include - -#include "renesas_internal.h" -#include "sched/sched.h" -#include "chip.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static uint8_t s_last_regs[XCPTCONTEXT_REGS]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: m16c_getusersp - ****************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 -static inline uint16_t m16c_getusersp(void) -{ - uint8_t *ptr = (uint8_t *) g_current_regs; - return (uint16_t)ptr[REG_SP] << 8 | ptr[REG_SP + 1]; -} -#endif - -/**************************************************************************** - * Name: m16c_stackdump - ****************************************************************************/ - -static void m16c_stackdump(uint16_t sp, uint16_t stack_top) -{ - uint16_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x7; stack < (stack_top & ~0x7); stack += 8) - { - uint8_t *ptr = (uint8_t *)stack; - _alert("%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: m16c_registerdump - ****************************************************************************/ - -static inline void m16c_registerdump(void) -{ - volatile uint8_t *ptr = (uint8_t *)g_current_regs; - - /* Are user registers available from interrupt processing? */ - - if (ptr == NULL) - { - /* No.. capture user registers by hand */ - - up_saveusercontext((uint32_t *)s_last_regs); - ptr = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("PC: %02x%02x%02x FLG: %02x00%02x FB: %02x%02x SB: %02x%02x " - "SP: %02x%02x\n", - ptr[REG_FLGPCHI] & 0xff, ptr[REG_PC], ptr[REG_PC + 1], - ptr[REG_FLGPCHI] >> 8, ptr[REG_FLG], - ptr[REG_FB], ptr[REG_FB + 1], - ptr[REG_SB], ptr[REG_SB + 1], - ptr[REG_SP], ptr[REG_SP + 1]); - - _alert("R0: %02x%02x R1: %02x%02x R2: %02x%02x A0: %02x%02x " - "A1: %02x%02x\n", - ptr[REG_R0], ptr[REG_R0 + 1], ptr[REG_R1], ptr[REG_R1 + 1], - ptr[REG_R2], ptr[REG_R2 + 1], ptr[REG_R3], ptr[REG_R3 + 1], - ptr[REG_A0], ptr[REG_A0 + 1], ptr[REG_A1], ptr[REG_A1 + 1]); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: renesas_dumpstate - ****************************************************************************/ - -void renesas_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint16_t sp = up_getsp(); - uint16_t ustackbase; - uint16_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint16_t istackbase; - uint16_t istacksize; -#endif - - /* Dump the registers (if available) */ - - m16c_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint16_t)rtcb->stack_base_ptr; - ustacksize = (uint16_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory. - * The near RAM memory map is as follows: - * - * 0x00400 - DATA Size: Determined by linker - * BSS Size: Determined by linker - * Interrupt stack Size: CONFIG_ARCH_INTERRUPTSTACK - * Idle stack Size: CONFIG_IDLETHREAD_STACKSIZE - * Heap Size: Everything remaining - * 0x00bff - (end+1) - */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = g_enbss; - istacksize = CONFIG_ARCH_INTERRUPTSTACK; - - /* Show interrupt stack info */ - - _alert("sp: %04x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %04x\n", istackbase); - _alert(" size: %04x\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - m16c_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer from the register area */ - - sp = m16c_getusersp(); - _alert("sp: %04x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - m16c_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %04x\n", ustackbase); - _alert(" size: %04x\n", ustacksize); -#else - _alert("sp: %04x\n", sp); - _alert("stack base: %04x\n", ustackbase); - _alert("stack size: %04x\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - m16c_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - m16c_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z16/src/common/z16_stackdump.c b/arch/renesas/src/m16c/m16c_registerdump.c similarity index 55% rename from arch/z16/src/common/z16_stackdump.c rename to arch/renesas/src/m16c/m16c_registerdump.c index 49431ca60c3..5566fc2e53e 100644 --- a/arch/z16/src/common/z16_stackdump.c +++ b/arch/renesas/src/m16c/m16c_registerdump.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/z16/src/common/z16_stackdump.c + * arch/renesas/src/m16c/m16c_registerdump.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -23,68 +23,51 @@ ****************************************************************************/ #include -#include +#include #include +#include +#include + +#include "renesas_internal.h" #include "chip.h" -#include "sched/sched.h" -#include "z16_internal.h" - -#ifdef CONFIG_ARCH_STACKDUMP /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: up_getsp + * Name: up_getusrsp ****************************************************************************/ -/* To be provided */ - -/**************************************************************************** - * Name: z16_stackdump - ****************************************************************************/ - -void z16_stackdump(void) +uintptr_t up_getusrsp(void) { - FAR struct tcb_s *rtcb = running_task(); - chipreg_t sp = up_getsp(); - chipreg_t stack_base = (chipreg_t)rtcb->stack_base_ptr; - chipreg_t stack_size = (chipreg_t)rtcb->adj_stack_size; - chipreg_t stack; - chipreg_t stack_top; - - _alert("stack_base: %08x\n", stack_base); - _alert("stack_size: %08x\n", stack_size); - _alert("sp: %08x\n", sp); - - if (sp >= stack_base && sp < stack_base + stack_size) - { - stack = sp; - } - else - { - _err("ERROR: Stack pointer is not within allocated stack\n"); - stack = stack_base; - } - - stack_top = stack_base + stack_size; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = stack & ~(8 * sizeof(chipreg_t) - 1); - stack < (stack_top & ~(8 * sizeof(chipreg_t) - 1)); - stack += 8 * sizeof(chipreg_t)) - { - chipreg_t *ptr = (chipreg_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } + uint8_t *ptr = (uint8_t *) g_current_regs; + return (uintptr_t)(ptr[REG_SP] << 8 | ptr[REG_SP + 1]); } -#endif /* CONFIG_ARCH_STACKDUMP */ +/**************************************************************************** + * Name: renesas_registerdump + ****************************************************************************/ + +void renesas_registerdump(volatile uint32_t *regs) +{ + uint8_t *ptr = (uint8_t *)regs; + + /* Dump the interrupt registers */ + + _alert("PC: %02x%02x%02x FLG: %02x00%02x FB: %02x%02x SB: %02x%02x " + "SP: %02x%02x\n", + ptr[REG_FLGPCHI] & 0xff, ptr[REG_PC], ptr[REG_PC + 1], + ptr[REG_FLGPCHI] >> 8, ptr[REG_FLG], + ptr[REG_FB], ptr[REG_FB + 1], + ptr[REG_SB], ptr[REG_SB + 1], + ptr[REG_SP], ptr[REG_SP + 1]); + + _alert("R0: %02x%02x R1: %02x%02x R2: %02x%02x A0: %02x%02x " + "A1: %02x%02x\n", + ptr[REG_R0], ptr[REG_R0 + 1], ptr[REG_R1], ptr[REG_R1 + 1], + ptr[REG_R2], ptr[REG_R2 + 1], ptr[REG_R3], ptr[REG_R3 + 1], + ptr[REG_A0], ptr[REG_A0 + 1], ptr[REG_A1], ptr[REG_A1 + 1]); +} diff --git a/arch/renesas/src/rx65n/Make.defs b/arch/renesas/src/rx65n/Make.defs index 6b5e2c41eea..6ffd59f1113 100644 --- a/arch/renesas/src/rx65n/Make.defs +++ b/arch/renesas/src/rx65n/Make.defs @@ -22,14 +22,15 @@ HEAD_ASRC = rx65n_head.S CMN_CSRCS = renesas_allocateheap.c renesas_assert.c CMN_CSRCS += renesas_createstack.c renesas_doirq.c renesas_exit.c renesas_idle.c renesas_initialize.c -CMN_CSRCS += renesas_lowputs.c renesas_mdelay.c renesas_nputs.c renesas_releasestack.c +CMN_CSRCS += renesas_lowputs.c renesas_mdelay.c renesas_nputs.c +CMN_CSRCS += renesas_releasestack.c renesas_getintstack.c CMN_CSRCS += renesas_stackframe.c renesas_udelay.c renesas_switchcontext.c renesas_usestack.c CHIP_ASRCS = rx65n_vector.S CHIP_CSRCS = rx65n_lowputc.c rx65n_serial.c rx65n_copystate.c rx65n_irq.c CHIP_CSRCS += rx65n_schedulesigaction.c rx65n_sigdeliver.c rx65n_initialstate.c CHIP_CSRCS += rx65n_hardware_setup.c rx65n_port.c rx65n_sci.c -CHIP_CSRCS += rx65n_cgc.c rx65n_dumpstate.c rx65n_vector_table.c +CHIP_CSRCS += rx65n_cgc.c rx65n_registerdump.c rx65n_vector_table.c CHIP_CSRCS += rx65n_timerisr.c rx65n_sbram.c ifeq ($(CONFIG_RX65N_EMAC),y) diff --git a/arch/renesas/src/rx65n/rx65n_dumpstate.c b/arch/renesas/src/rx65n/rx65n_dumpstate.c deleted file mode 100644 index b8509398c49..00000000000 --- a/arch/renesas/src/rx65n/rx65n_dumpstate.c +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** - * arch/renesas/src/rx65n/rx65n_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include -#include -#include - -#include "renesas_internal.h" -#include "sched/sched.h" -#include "chip.h" -#include "arch/rx65n/irq.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: rx65n_getusersp - ****************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 -static inline uint16_t rx65n_getusersp(void) -{ - uint8_t *ptr = (uint8_t *) g_current_regs; - return (uint16_t)ptr[REG_SP] << 8 | ptr[REG_SP + 1]; /* check */ -} -#endif - -/**************************************************************************** - * Name: rx65n_stackdump - ****************************************************************************/ - -static void rx65n_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08" PRIxPTR ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 "\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: rx65n_registerdump - ****************************************************************************/ - -static inline void rx65n_registerdump(void) -{ - volatile uint32_t *ptr = g_current_regs; - - /* Are user registers available from interrupt processing? */ - - if (ptr == NULL) - { - /* No.. capture user registers by hand */ - - up_saveusercontext(s_last_regs); - ptr = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("PC: %08" PRIx32 " PSW=%08" PRIx32 "\n", - ptr[REG_PC], ptr[REG_PSW]); - - _alert("FPSW: %08" PRIx32 " ACC0LO: %08" PRIx32 " ACC0HI: %08" PRIx32 - " ACC0GU: %08" PRIx32 "ACC1LO: %08" PRIx32 " ACC1HI: %08" PRIx32 - " ACC1GU: %08" PRIx32 "\n", - ptr[REG_FPSW], ptr[REG_ACC0LO], ptr[REG_ACC0HI], - ptr[REG_ACC0GU], ptr[REG_ACC1LO], - ptr[REG_ACC1HI], ptr[REG_ACC1GU]); - - _alert("R%d:%08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", 0, - ptr[REG_R1], ptr[REG_R2], ptr[REG_R3], - ptr[REG_R4], ptr[REG_R5], ptr[REG_R6], ptr[REG_R7]); - - _alert("R%d: %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", 8, - ptr[REG_R8], ptr[REG_R9], ptr[REG_R10], ptr[REG_R11], - ptr[REG_R12], ptr[REG_R13], ptr[REG_R14], ptr[REG_R15]); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: renesas_dumpstate - ****************************************************************************/ - -void renesas_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - rx65n_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = ebss; /* check how to declare ebss, as of now declared in chip.h */ - - istacksize = CONFIG_ARCH_INTERRUPTSTACK & ~3; - - /* Show interrupt stack info */ - - _alert("sp: %08" PRIx32 "\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08" PRIx32 "\n", istackbase); - _alert(" size: %08" PRIx32 "\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - rx65n_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer from the register area */ - - sp = rx65n_getusersp(); - _alert("sp: %08" PRIx32 "\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - rx65n_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08" PRIx32 "\n", ustackbase); - _alert(" size: %08" PRIx32 "\n", ustacksize); -#else - _alert("sp: %08" PRIx32 "\n", sp); - _alert("stack base: %08" PRIx32 "\n", ustackbase); - _alert("stack size: %08" PRIx32 "\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - rx65n_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - rx65n_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/renesas/src/rx65n/rx65n_registerdump.c b/arch/renesas/src/rx65n/rx65n_registerdump.c new file mode 100644 index 00000000000..a816bd6ebf7 --- /dev/null +++ b/arch/renesas/src/rx65n/rx65n_registerdump.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/renesas/src/rx65n/rx65n_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "renesas_internal.h" +#include "chip.h" +#include "arch/rx65n/irq.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_SP]; +} + +/**************************************************************************** + * Name: rx65n_registerdump + ****************************************************************************/ + +void renesas_registerdump(volatile uint32_t *regs) +{ + /* Dump the interrupt registers */ + + _alert("PC: %08" PRIx32 " PSW=%08" PRIx32 "\n", + regs[REG_PC], regs[REG_PSW]); + + _alert("FPSW: %08" PRIx32 " ACC0LO: %08" PRIx32 " ACC0HI: %08" PRIx32 + " ACC0GU: %08" PRIx32 "ACC1LO: %08" PRIx32 " ACC1HI: %08" PRIx32 + " ACC1GU: %08" PRIx32 "\n", + regs[REG_FPSW], regs[REG_ACC0LO], regs[REG_ACC0HI], + regs[REG_ACC0GU], regs[REG_ACC1LO], + regs[REG_ACC1HI], regs[REG_ACC1GU]); + + _alert("R%d:%08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 + " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", 0, + regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + + _alert("R%d: %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 + " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n", 8, + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); +} diff --git a/arch/renesas/src/sh1/Make.defs b/arch/renesas/src/sh1/Make.defs index aef46d38761..7cc7a929193 100644 --- a/arch/renesas/src/sh1/Make.defs +++ b/arch/renesas/src/sh1/Make.defs @@ -24,13 +24,13 @@ CMN_CSRCS = renesas_allocateheap.c renesas_assert.c CMN_CSRCS += renesas_createstack.c renesas_doirq.c renesas_exit.c renesas_idle.c renesas_initialize.c CMN_CSRCS += renesas_initialstate.c renesas_lowputs.c CMN_CSRCS += renesas_mdelay.c renesas_nputs.c renesas_releasestack.c -CMN_CSRCS += renesas_stackframe.c renesas_udelay.c +CMN_CSRCS += renesas_stackframe.c renesas_udelay.c renesas_getintstack.c CMN_CSRCS += sh1_schedulesigaction.c sh1_sigdeliver.c CMN_CSRCS += renesas_switchcontext.c renesas_usestack.c CHIP_ASRCS = sh1_vector.S sh1_saveusercontext.S CHIP_CSRCS = sh1_lowputc.c sh1_irq.c sh1_serial.c sh1_initialstate.c -CHIP_CSRCS += sh1_copystate.c sh1_dumpstate.c +CHIP_CSRCS += sh1_copystate.c sh1_registerdump.c ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += sh1_timerisr.c diff --git a/arch/renesas/src/sh1/chip.h b/arch/renesas/src/sh1/chip.h index 1a092a889bf..b180db0464c 100644 --- a/arch/renesas/src/sh1/chip.h +++ b/arch/renesas/src/sh1/chip.h @@ -44,15 +44,6 @@ * Public Data ************************************************************************************/ -/* Address of the saved user stack pointer */ - -#ifndef __ASSEMBLY__ -# if CONFIG_ARCH_INTERRUPTSTACK > 3 - extern uint8_t g_intstackalloc[]; - extern uint8_t g_intstacktop[]; -# endif -#endif - /************************************************************************************ * Public Functions Prototypes ************************************************************************************/ diff --git a/arch/renesas/src/sh1/sh1_dumpstate.c b/arch/renesas/src/sh1/sh1_dumpstate.c deleted file mode 100644 index 2276dc140b2..00000000000 --- a/arch/renesas/src/sh1/sh1_dumpstate.c +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** - * arch/renesas/src/sh1/sh1_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include - -#include -#include -#include - -#include "renesas_internal.h" -#include "sched/sched.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: sh1_stackdump - ****************************************************************************/ - -static void sh1_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: sh1_registerdump - ****************************************************************************/ - -static inline void sh1_registerdump(void) -{ - volatile uint32_t *ptr = g_current_regs; - - /* Are user registers available from interrupt processing? */ - - if (ptr == NULL) - { - /* No.. capture user registers by hand */ - - up_saveusercontext(s_last_regs); - regs = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("PC: %08x SR=%08x\n", - ptr[REG_PC], ptr[REG_SR]); - - _alert("PR: %08x GBR: %08x MACH: %08x MACL: %08x\n", - ptr[REG_PR], ptr[REG_GBR], ptr[REG_MACH], ptr[REG_MACL]); - - _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", 0, - ptr[REG_R0], ptr[REG_R1], ptr[REG_R2], ptr[REG_R3], - ptr[REG_R4], ptr[REG_R5], ptr[REG_R6], ptr[REG_R7]); - - _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", 8, - ptr[REG_R8], ptr[REG_R9], ptr[REG_R10], ptr[REG_R11], - ptr[REG_R12], ptr[REG_R13], ptr[REG_R14], ptr[REG_R15]); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: renesas_dumpstate - ****************************************************************************/ - -void renesas_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ - - sh1_registerdump(); - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - sh1_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %08x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - sh1_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - sh1_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - sh1_stackdump(ustackbase, ustackbase + ustacksize); - } -} - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/renesas/src/sh1/sh1_registerdump.c b/arch/renesas/src/sh1/sh1_registerdump.c new file mode 100644 index 00000000000..888d6a75c54 --- /dev/null +++ b/arch/renesas/src/sh1/sh1_registerdump.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/renesas/src/sh1/sh1_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "renesas_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_SP]; +} + +/**************************************************************************** + * Name: renesas_registerdump + ****************************************************************************/ + +void renesas_registerdump(volatile uint32_t *regs) +{ + /* Dump the interrupt registers */ + + _alert("PC: %08x SR=%08x\n", + regs[REG_PC], regs[REG_SR]); + + _alert("PR: %08x GBR: %08x MACH: %08x MACL: %08x\n", + regs[REG_PR], regs[REG_GBR], regs[REG_MACH], regs[REG_MACL]); + + _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", 0, + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + + _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", 8, + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], + regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); +} + diff --git a/arch/risc-v/src/common/Make.defs b/arch/risc-v/src/common/Make.defs index d809039d68d..19517ec0e68 100644 --- a/arch/risc-v/src/common/Make.defs +++ b/arch/risc-v/src/common/Make.defs @@ -34,7 +34,7 @@ CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c CMN_CSRCS += riscv_sigdeliver.c riscv_switchcontext.c riscv_usestack.c CMN_CSRCS += riscv_idle.c riscv_tcbinfo.c riscv_cpuidlestack.c CMN_CSRCS += riscv_exception.c riscv_getnewintctx.c riscv_doirq.c -CMN_CSRCS += riscv_saveusercontext.c +CMN_CSRCS += riscv_saveusercontext.c riscv_getintstack.c riscv_registerdump.c ifneq ($(CONFIG_ALARM_ARCH),y) ifneq ($(CONFIG_TIMER_ARCH),y) diff --git a/arch/risc-v/src/common/riscv_assert.c b/arch/risc-v/src/common/riscv_assert.c index b684fc1419e..cd8a1dfac54 100644 --- a/arch/risc-v/src/common/riscv_assert.c +++ b/arch/risc-v/src/common/riscv_assert.c @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -41,8 +40,6 @@ * Private Functions ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP - /**************************************************************************** * Private Data ****************************************************************************/ @@ -50,295 +47,18 @@ static uint8_t s_last_regs[XCPTCONTEXT_SIZE]; /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: riscv_stackdump + * Name: up_assert ****************************************************************************/ -static void riscv_stackdump(uintptr_t sp, uintptr_t stack_top) -{ - uintptr_t stack; - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%" PRIxREG ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 "\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: riscv_registerdump - ****************************************************************************/ - -static inline void riscv_registerdump(volatile uintptr_t *regs) -{ - /* Are user registers available from interrupt processing? */ - - _alert("EPC: %" PRIxREG "\n", regs[REG_EPC]); - _alert("A0: %" PRIxREG " A1: %" PRIxREG " A2: %" PRIxREG - " A3: %" PRIxREG "\n", - regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3]); - _alert("A4: %" PRIxREG " A5: %" PRIxREG " A6: %" PRIxREG - " A7: %" PRIxREG "\n", - regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); - _alert("T0: %" PRIxREG " T1: %" PRIxREG " T2: %" PRIxREG - " T3: %" PRIxREG "\n", - regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3]); - _alert("T4: %" PRIxREG " T5: %" PRIxREG " T6: %" PRIxREG "\n", - regs[REG_T4], regs[REG_T5], regs[REG_T6]); - _alert("S0: %" PRIxREG " S1: %" PRIxREG " S2: %" PRIxREG - " S3: %" PRIxREG "\n", - regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3]); - _alert("S4: %" PRIxREG " S5: %" PRIxREG " S6: %" PRIxREG - " S7: %" PRIxREG "\n", - regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); - _alert("S8: %" PRIxREG " S9: %" PRIxREG " S10: %" PRIxREG - " S11: %" PRIxREG "\n", - regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); -#ifdef RISCV_SAVE_GP - _alert("GP: %" PRIxREG " SP: %" PRIxREG " FP: %" PRIxREG - " TP: %" PRIxREG " RA: %" PRIxREG "\n", - regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], - regs[REG_RA]); -#else - _alert("SP: %" PRIxREG " FP: %" PRIxREG " TP: %" PRIxREG - " RA: %" PRIxREG "\n", - regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); -#endif -} - -/**************************************************************************** - * Name: riscv_dump_task - ****************************************************************************/ - -static void riscv_dump_task(struct tcb_s *tcb, void *arg) -{ - char args[64] = ""; -#ifdef CONFIG_STACK_COLORATION - uint32_t stack_filled = 0; - uint32_t stack_used; -#endif -#ifdef CONFIG_SCHED_CPULOAD - struct cpuload_s cpuload; - uint32_t fracpart; - uint32_t intpart; - uint32_t tmp; - - clock_cpuload(tcb->pid, &cpuload); - - if (cpuload.total > 0) - { - tmp = (1000 * cpuload.active) / cpuload.total; - intpart = tmp / 10; - fracpart = tmp - 10 * intpart; - } - else - { - intpart = 0; - fracpart = 0; - } -#endif - -#ifdef CONFIG_STACK_COLORATION - stack_used = up_check_tcbstack(tcb); - if (tcb->adj_stack_size > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * stack_used / tcb->adj_stack_size; - } -#endif - -#ifndef CONFIG_DISABLE_PTHREAD - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) - { - struct pthread_tcb_s *ptcb = (struct pthread_tcb_s *)tcb; - - snprintf(args, sizeof(args), " %p", ptcb->arg); - } - else -#endif - { - char **argv = tcb->group->tg_info->argv + 1; - size_t npos = 0; - - while (*argv != NULL && npos < sizeof(args)) - { - npos += snprintf(args + npos, sizeof(args) - npos, " %s", *argv++); - } - } - - /* Dump interesting properties of this task */ - - _alert(" %4d %4d" -#ifdef CONFIG_SMP - " %4d" -#endif - " %7lu" -#ifdef CONFIG_STACK_COLORATION - " %7lu %3" PRId32 ".%1" PRId32 "%%%c" -#endif -#ifdef CONFIG_SCHED_CPULOAD - " %3" PRId32 ".%01" PRId32 "%%" -#endif - " %s%s\n" - , tcb->pid, tcb->sched_priority -#ifdef CONFIG_SMP - , tcb->cpu -#endif - , (unsigned long)tcb->adj_stack_size -#ifdef CONFIG_STACK_COLORATION - , (unsigned long)up_check_tcbstack(tcb) - , stack_filled / 10, stack_filled % 10 - , (stack_filled >= 10 * 80 ? '!' : ' ') -#endif -#ifdef CONFIG_SCHED_CPULOAD - , intpart, fracpart -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - , tcb->name -#else - , "" -#endif - , args - ); -} - -/**************************************************************************** - * Name: riscv_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void riscv_dump_backtrace(struct tcb_s *tcb, void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: riscv_showtasks - ****************************************************************************/ - -static inline void riscv_showtasks(void) -{ -#if CONFIG_ARCH_INTERRUPTSTACK > 15 -# ifdef CONFIG_STACK_COLORATION - uint32_t stack_used = up_check_intstack(); - uint32_t stack_filled = 0; - - if ((CONFIG_ARCH_INTERRUPTSTACK & ~15) > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * - stack_used / (CONFIG_ARCH_INTERRUPTSTACK & ~15); - } -# endif -#endif - - /* Dump interesting properties of each task in the crash environment */ - - _alert(" PID PRI" -#ifdef CONFIG_SMP - " CPU" -#endif - " STACK" -#ifdef CONFIG_STACK_COLORATION - " USED FILLED " -#endif -#ifdef CONFIG_SCHED_CPULOAD - " CPU" -#endif - " COMMAND\n"); - -#if CONFIG_ARCH_INTERRUPTSTACK > 15 - _alert(" ---- ----" -# ifdef CONFIG_SMP - " ----" -# endif - " %7u" -# ifdef CONFIG_STACK_COLORATION - " %7" PRId32 " %3" PRId32 ".%1" PRId32 "%%%c" -# endif -# ifdef CONFIG_SCHED_CPULOAD - " ----" -# endif - " irq\n" - , (CONFIG_ARCH_INTERRUPTSTACK & ~15) -# ifdef CONFIG_STACK_COLORATION - , stack_used - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') -# endif - ); -#endif - - nxsched_foreach(riscv_dump_task, NULL); -#ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(riscv_dump_backtrace, NULL); -#endif -} - -/**************************************************************************** - * Name: riscv_dump_stack - ****************************************************************************/ - -static void riscv_dump_stack(const char *tag, uintptr_t sp, - uintptr_t base, uint32_t size, bool force) -{ - uintptr_t top = base + size; - - _alert("%s Stack:\n", tag); - _alert("sp: %08" PRIxPTR "\n", sp); - _alert(" base: %08" PRIxPTR "\n", base); - _alert(" size: %08" PRIx32 "\n", size); - - if (sp >= base && sp < top) - { - riscv_stackdump(sp, top); - } - else - { - _alert("ERROR: %s Stack pointer is not within the stack\n", tag); - - if (force) - { -#ifdef CONFIG_STACK_COLORATION - uint32_t remain; - - remain = size - riscv_stack_check((uintptr_t)base, size); - base += remain; - size -= remain; -#endif - -#if CONFIG_ARCH_STACKDUMP_MAX_LENGTH > 0 - if (size > CONFIG_ARCH_STACKDUMP_MAX_LENGTH) - { - size = CONFIG_ARCH_STACKDUMP_MAX_LENGTH; - } -#endif - - riscv_stackdump(base, base + size); - } - } -} - -/**************************************************************************** - * Name: riscv_dumpstate - ****************************************************************************/ - -static void riscv_dumpstate(void) +void up_assert(void) { struct tcb_s *rtcb = running_task(); - uintptr_t sp = up_getsp(); + + board_autoled_on(LED_ASSERTION); /* Update the xcp context */ @@ -352,64 +72,5 @@ static void riscv_dumpstate(void) rtcb->xcp.regs = (uintptr_t *)s_last_regs; } - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the registers (if available) */ - riscv_registerdump(rtcb->xcp.regs); - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 15 - riscv_dump_stack("IRQ", sp, - (uintptr_t)g_intstackalloc, - (CONFIG_ARCH_INTERRUPTSTACK & ~15), - !!CURRENT_REGS); - if (CURRENT_REGS) - { - sp = CURRENT_REGS[REG_SP]; - } -#endif - - riscv_dump_stack("User", sp, - (uintptr_t)rtcb->stack_base_ptr, - (uint32_t)rtcb->adj_stack_size, -#ifdef CONFIG_ARCH_KERNEL_STACK - false -#else - true -#endif - ); - -#ifdef CONFIG_ARCH_KERNEL_STACK - riscv_dump_stack("Kernel", sp, - (uintptr_t)rtcb->xcp.kstack, - CONFIG_ARCH_KERNEL_STACKSIZE, - false); -#endif -} -#else -# define riscv_dumpstate() -#endif /* CONFIG_ARCH_STACKDUMP */ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - riscv_dumpstate(); - - /* Dump the state of all tasks (if available) */ - - riscv_showtasks(); } diff --git a/arch/risc-v/src/common/riscv_getintstack.c b/arch/risc-v/src/common/riscv_getintstack.c new file mode 100644 index 00000000000..9222f21a112 --- /dev/null +++ b/arch/risc-v/src/common/riscv_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/risc-v/src/common/riscv_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index fbfa3f12fa6..a7aa3608386 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -277,6 +277,8 @@ size_t riscv_stack_check(uintptr_t alloc, size_t size); void riscv_stack_color(void *stackbase, size_t nbytes); #endif +void riscv_registerdump(volatile uintptr_t *regs); + #ifdef CONFIG_SMP void riscv_cpu_boot(int cpu); int riscv_pause_handler(int irq, void *c, void *arg); diff --git a/arch/risc-v/src/common/riscv_registerdump.c b/arch/risc-v/src/common/riscv_registerdump.c new file mode 100644 index 00000000000..63648284063 --- /dev/null +++ b/arch/risc-v/src/common/riscv_registerdump.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * arch/risc-v/src/common/riscv_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_SP]; +} + +/**************************************************************************** + * Name: riscv_registerdump + ****************************************************************************/ + +void riscv_registerdump(volatile uintptr_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + _alert("EPC: %" PRIxREG "\n", regs[REG_EPC]); + _alert("A0: %" PRIxREG " A1: %" PRIxREG " A2: %" PRIxREG + " A3: %" PRIxREG "\n", + regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3]); + _alert("A4: %" PRIxREG " A5: %" PRIxREG " A6: %" PRIxREG + " A7: %" PRIxREG "\n", + regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); + _alert("T0: %" PRIxREG " T1: %" PRIxREG " T2: %" PRIxREG + " T3: %" PRIxREG "\n", + regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3]); + _alert("T4: %" PRIxREG " T5: %" PRIxREG " T6: %" PRIxREG "\n", + regs[REG_T4], regs[REG_T5], regs[REG_T6]); + _alert("S0: %" PRIxREG " S1: %" PRIxREG " S2: %" PRIxREG + " S3: %" PRIxREG "\n", + regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3]); + _alert("S4: %" PRIxREG " S5: %" PRIxREG " S6: %" PRIxREG + " S7: %" PRIxREG "\n", + regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); + _alert("S8: %" PRIxREG " S9: %" PRIxREG " S10: %" PRIxREG + " S11: %" PRIxREG "\n", + regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); +#ifdef RISCV_SAVE_GP + _alert("GP: %" PRIxREG " SP: %" PRIxREG " FP: %" PRIxREG + " TP: %" PRIxREG " RA: %" PRIxREG "\n", + regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], + regs[REG_RA]); +#else + _alert("SP: %" PRIxREG " FP: %" PRIxREG " TP: %" PRIxREG + " RA: %" PRIxREG "\n", + regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); +#endif +} + diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c index bd84a35ca6f..a66f1330673 100644 --- a/arch/risc-v/src/common/riscv_swint.c +++ b/arch/risc-v/src/common/riscv_swint.c @@ -52,45 +52,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: riscv_registerdump - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_SYSCALL_INFO -static void riscv_registerdump(const uintptr_t *regs) -{ - svcinfo("EPC: %" PRIxREG "\n", - regs[REG_EPC]); - svcinfo("A0: %" PRIxREG " A1: %" PRIxREG " A2: %" PRIxREG " A3: %" PRIxREG - " A4: %" PRIxREG " A5: %" PRIxREG " A6: %" PRIxREG " A7: %" PRIxREG - "\n", - regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3], - regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); - svcinfo("T0: %" PRIxREG " T1: %" PRIxREG " T2: %" PRIxREG " T3: %" PRIxREG - " T4: %" PRIxREG " T5: %" PRIxREG " T6: %" PRIxREG "\n", - regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], - regs[REG_T4], regs[REG_T5], regs[REG_T6]); - svcinfo("S0: %" PRIxREG " S1: %" PRIxREG " S2: %" PRIxREG " S3: %" PRIxREG - " S4: %" PRIxREG " S5: %" PRIxREG " S6: %" PRIxREG " S7: %" PRIxREG - "\n", - regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], - regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); - svcinfo("S8: %" PRIxREG " S9: %" PRIxREG " S10: %"PRIxREG - " S11: %" PRIxREG "\n", - regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); -#ifdef RISCV_SAVE_GP - svcinfo("GP: %" PRIxREG " SP: %" PRIxREG " FP: %" PRIxREG - " TP: %" PRIxREG " RA: %" PRIxREG "\n", - regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], - regs[REG_RA]); -#else - svcinfo("SP: %" PRIxREG " FP: %" PRIxREG " TP: %" PRIxREG " RA: %" PRIxREG - "\n", - regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); -#endif -} -#endif - /**************************************************************************** * Name: dispatch_syscall * @@ -552,7 +513,7 @@ int riscv_swint(int irq, void *context, void *arg) if (regs != CURRENT_REGS) { svcinfo("SWInt Return: Context switch!\n"); - riscv_registerdump((const uintptr_t *)CURRENT_REGS); + riscv_registerdump(CURRENT_REGS); } else { diff --git a/arch/sim/src/sim/sim_assert.c b/arch/sim/src/sim/sim_assert.c index fb498918f38..9105feab373 100644 --- a/arch/sim/src/sim/sim_assert.c +++ b/arch/sim/src/sim/sim_assert.c @@ -71,20 +71,10 @@ * ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { struct tcb_s *rtcb = running_task(); - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - if (CURRENT_REGS || is_idle_task(rtcb)) { /* Exit the simulation */ diff --git a/arch/sparc/src/common/Make.defs b/arch/sparc/src/common/Make.defs index 3bcae0ca91c..cf320a245ac 100644 --- a/arch/sparc/src/common/Make.defs +++ b/arch/sparc/src/common/Make.defs @@ -24,7 +24,7 @@ CMN_CSRCS += sparc_allocateheap.c sparc_assert.c CMN_CSRCS += sparc_createstack.c sparc_exit.c sparc_idle.c sparc_initialize.c CMN_CSRCS += sparc_lowputs.c sparc_mdelay.c CMN_CSRCS += sparc_modifyreg8.c sparc_modifyreg16.c sparc_modifyreg32.c -CMN_CSRCS += sparc_nputs.c sparc_releasestack.c +CMN_CSRCS += sparc_nputs.c sparc_releasestack.c sparc_getintstack.c CMN_CSRCS += sparc_stackframe.c sparc_udelay.c sparc_usestack.c # Configuration-dependent common files diff --git a/arch/sparc/src/common/sparc_assert.c b/arch/sparc/src/common/sparc_assert.c index c86e8e587ba..e146904c8c1 100644 --- a/arch/sparc/src/common/sparc_assert.c +++ b/arch/sparc/src/common/sparc_assert.c @@ -34,7 +34,7 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { - sparc_dumpstate(); + sparc_registerdump(CURRENT_REGS); } diff --git a/arch/sparc/src/common/sparc_getintstack.c b/arch/sparc/src/common/sparc_getintstack.c new file mode 100644 index 00000000000..55c258b6f2f --- /dev/null +++ b/arch/sparc/src/common/sparc_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/sparc/src/common/sparc_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "sparc_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)sparc_intstack_alloc(); +} +#endif diff --git a/arch/sparc/src/common/sparc_internal.h b/arch/sparc/src/common/sparc_internal.h index 7a49a8396e9..4ed19b8d73c 100644 --- a/arch/sparc/src/common/sparc_internal.h +++ b/arch/sparc/src/common/sparc_internal.h @@ -185,11 +185,7 @@ void sparc_lowputs(const char *str); /* Debug */ -#ifdef CONFIG_ARCH_STACKDUMP -void sparc_dumpstate(void); -#else -# define sparc_dumpstate() -#endif +void sparc_registerdump(volatile uint32_t *regs); /* Software interrupt 0 handler */ diff --git a/arch/sparc/src/sparc_v8/Make.defs b/arch/sparc/src/sparc_v8/Make.defs index c064913d499..d37bb41b564 100644 --- a/arch/sparc/src/sparc_v8/Make.defs +++ b/arch/sparc/src/sparc_v8/Make.defs @@ -27,10 +27,4 @@ CMN_CSRCS += sparc_v8_copystate.c sparc_v8_doirq.c CMN_CSRCS += sparc_v8_initialstate.c sparc_v8_irq.c CMN_CSRCS += sparc_v8_schedulesigaction.c CMN_CSRCS += sparc_v8_sigdeliver.c sparc_v8_swint1.c sparc_v8_systemreset.c -CMN_CSRCS += sparc_v8_switchcontext.c - -# Configuration-dependent common files - -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += sparc_v8_dumpstate.c -endif +CMN_CSRCS += sparc_v8_switchcontext.c sparc_v8_registerdump.c diff --git a/arch/sparc/src/sparc_v8/sparc_v8_dumpstate.c b/arch/sparc/src/sparc_v8/sparc_v8_dumpstate.c deleted file mode 100644 index bc1e498823e..00000000000 --- a/arch/sparc/src/sparc_v8/sparc_v8_dumpstate.c +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** - * arch/sparc/src/sparc_v8/sparc_v8_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "sched/sched.h" -#include "sparc_internal.h" - -#ifdef CONFIG_ARCH_STACKDUMP - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_stackdump - ****************************************************************************/ - -static void up_stackdump(uint32_t sp, uint32_t stack_base) -{ - uint32_t stack ; - - for (stack = sp & ~0x1f; stack < stack_base; stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: up_registerdump - ****************************************************************************/ - -static inline void up_registerdump(void) -{ - uint32_t *regs = (uint32_t *)CURRENT_REGS; /* Don't need volatile here */ - - /* Are user registers available from interrupt processing? */ - - if (regs) - { - _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", - 0, - regs[REG_R16], regs[REG_R17], - regs[REG_R18], regs[REG_R19], - regs[REG_R20], regs[REG_R21], - regs[REG_R22], regs[REG_R23]); - - _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", - 8, - regs[REG_R24], regs[REG_R25], - regs[REG_R26], regs[REG_R27], - regs[REG_R28], regs[REG_R29], - regs[REG_R30], regs[REG_R31]); - - _alert("SR: %08x\n", regs[REG_R14]); - } -} - -/**************************************************************************** - * Name: sparc_dumpstate - ****************************************************************************/ - -void sparc_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - -#ifdef CONFIG_SMP - /* Show the CPU number */ - - _alert("CPU%d:\n", up_cpu_index()); -#endif - - /* Dump the registers (if available) */ - - up_registerdump(); - - /* Get the limits on the user stack memory */ - - if (rtcb->pid == IDLE_PROCESS_ID) /* Check for CPU0 IDLE thread */ - { - ustackbase = g_idle_topstack - 4; - ustacksize = CONFIG_IDLETHREAD_STACKSIZE; - } - else - { - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - } - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)sparc_intstack_alloc(); - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_intstack()); -#endif - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp <= istackbase && sp > istackbase - istacksize) - { - /* Yes.. dump the interrupt stack */ - - up_stackdump(sp, istackbase); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - up_stackdump(istackbase - istacksize, istackbase); - } - - /* Extract the user stack pointer if we are in an interrupt handler. - * If we are not in an interrupt handler. Then sp is the user stack - * pointer (and the above range check should have failed). - */ - - if (CURRENT_REGS) - { - sp = CURRENT_REGS[REG_I6]; - _alert("sp: %08x\n", sp); - } - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08x\n", up_check_tcbstack(rtcb)); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp <= ustackbase && sp > ustackbase - ustacksize) - { - up_stackdump(sp, ustackbase); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); - } -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#ifdef CONFIG_STACK_COLORATION - _alert("stack used: %08x\n", up_check_tcbstack(rtcb)); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp > ustackbase || sp <= ustackbase - ustacksize) - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - up_stackdump(ustackbase - ustacksize, ustackbase); - } - else - { - up_stackdump(sp, ustackbase); - } -#endif -} -#endif diff --git a/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c b/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c new file mode 100644 index 00000000000..df77801ad99 --- /dev/null +++ b/arch/sparc/src/sparc_v8/sparc_v8_registerdump.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * arch/sparc/src/sparc_v8/sparc_v8_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "sparc_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_I6]; +} + +/**************************************************************************** + * Name: sparc_registerdump + ****************************************************************************/ + +void sparc_registerdump(volatile uint32_t *regs) +{ + /* Are user registers available from interrupt processing? */ + + if (regs) + { + _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + 0, + regs[REG_R16], regs[REG_R17], + regs[REG_R18], regs[REG_R19], + regs[REG_R20], regs[REG_R21], + regs[REG_R22], regs[REG_R23]); + + _alert("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n", + 8, + regs[REG_R24], regs[REG_R25], + regs[REG_R26], regs[REG_R27], + regs[REG_R28], regs[REG_R29], + regs[REG_R30], regs[REG_R31]); + + _alert("SR: %08x\n", regs[REG_R14]); + } +} diff --git a/arch/sparc/src/sparc_v8/sparc_v8_swint1.c b/arch/sparc/src/sparc_v8/sparc_v8_swint1.c index 4e35b55318e..9d6b0650ded 100644 --- a/arch/sparc/src/sparc_v8/sparc_v8_swint1.c +++ b/arch/sparc/src/sparc_v8/sparc_v8_swint1.c @@ -40,18 +40,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: up_registerdump - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_SYSCALL_INFO -static void up_registerdump(const uint32_t *regs) -{ -} -#else -# define up_registerdump(regs) -#endif - /**************************************************************************** * Name: dispatch_syscall * @@ -229,7 +217,7 @@ int sparc_swint1(int irq, void *context, void *arg) if (regs != CURRENT_REGS) { svcinfo("SWInt Return: Context switch!\n"); - up_registerdump((const uint32_t *)CURRENT_REGS); + up_registerdump(CURRENT_REGS); } else { diff --git a/arch/x86/src/common/x86_assert.c b/arch/x86/src/common/x86_assert.c index 982515353b8..c7a631e27c1 100644 --- a/arch/x86/src/common/x86_assert.c +++ b/arch/x86/src/common/x86_assert.c @@ -40,50 +40,19 @@ * Private Data ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: x86_stackdump + * Name: up_assert ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP -static void x86_stackdump(uint32_t sp, uint32_t stack_top) +void up_assert(void) { - uint32_t stack; - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} -#endif - -/**************************************************************************** - * Name: x86_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void x86_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Dump the registers (if available) */ + board_autoled_on(LED_ASSERTION); if (g_current_regs != NULL) { @@ -96,87 +65,4 @@ static void x86_dumpstate(void) up_saveusercontext(s_last_regs); x86_registerdump(s_last_regs); } - - /* Get the limits on the user stack memory */ - - ustackbase = (uint32_t)rtcb->stack_base_ptr; - ustacksize = (uint32_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint32_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %08x\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - x86_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %08x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - x86_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); -#else - _alert("sp: %08x\n", sp); - _alert("stack base: %08x\n", ustackbase); - _alert("stack size: %08x\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - x86_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - x86_stackdump(ustackbase, ustackbase + ustacksize); - } -} -#else -# define x86_dumpstate() -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - x86_dumpstate(); } diff --git a/arch/x86/src/common/x86_getintstack.c b/arch/x86/src/common/x86_getintstack.c new file mode 100644 index 00000000000..03167b6b348 --- /dev/null +++ b/arch/x86/src/common/x86_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/x86/src/common/x86_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "x86_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/x86/src/i486/i486_regdump.c b/arch/x86/src/i486/i486_regdump.c index 70ff9f652fd..f73bfc66844 100644 --- a/arch/x86/src/i486/i486_regdump.c +++ b/arch/x86/src/i486/i486_regdump.c @@ -33,6 +33,15 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_ESP]; +} + /**************************************************************************** * Name: x86_registerdump ****************************************************************************/ diff --git a/arch/x86/src/qemu/Make.defs b/arch/x86/src/qemu/Make.defs index 6ac2df0ab82..e2dc8960a5a 100644 --- a/arch/x86/src/qemu/Make.defs +++ b/arch/x86/src/qemu/Make.defs @@ -30,7 +30,7 @@ CMN_CSRCS += i486_createstack.c i486_initialstate.c CMN_CSRCS += x86_allocateheap.c x86_assert.c x86_copystate.c CMN_CSRCS += x86_exit.c x86_initialize.c x86_mdelay.c x86_udelay.c CMN_CSRCS += x86_modifyreg8.c x86_modifyreg16.c x86_modifyreg32.c -CMN_CSRCS += x86_nputs.c x86_switchcontext.c +CMN_CSRCS += x86_nputs.c x86_switchcontext.c x86_getintstack.c CMN_CSRCS += i486_irq.c i486_regdump.c i486_releasestack.c CMN_CSRCS += i486_savestate.c i486_sigdeliver.c CMN_CSRCS += i486_schedulesigaction.c i486_stackframe.c diff --git a/arch/x86_64/src/common/x86_64_assert.c b/arch/x86_64/src/common/x86_64_assert.c index e6602dc6cbb..b551aa65526 100644 --- a/arch/x86_64/src/common/x86_64_assert.c +++ b/arch/x86_64/src/common/x86_64_assert.c @@ -35,124 +35,6 @@ #include "sched/sched.h" #include "x86_64_internal.h" -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: x86_64_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void x86_64_stackdump(uint64_t sp, uint64_t stack_top) -{ - uint64_t stack; - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%016" PRIx64 ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 - " %08" PRIx32 "\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} -#endif - -/**************************************************************************** - * Name: x86_64_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void x86_64_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint64_t sp = up_getsp(); - uint64_t ustackbase; - uint64_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - uint64_t istackbase; - uint64_t istacksize; -#endif - - /* Get the limits on the user stack memory */ - - ustackbase = (uint64_t)rtcb->stack_base_ptr; - ustacksize = (uint64_t)rtcb->adj_stack_size; - - /* Get the limits on the interrupt stack memory */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - istackbase = (uint64_t)g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - - /* Show interrupt stack info */ - - _alert("sp: %016" PRIx64 "\n", sp); - _alert("IRQ stack:\n"); - _alert(" base: %016" PRIx64 "\n", istackbase); - _alert(" size: %016" PRIx64 "\n", istacksize); - - /* Does the current stack pointer lie within the interrupt - * stack? - */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - x86_64_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = g_intstacktop; - _alert("sp: %016" PRIx64 "\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - x86_64_stackdump(istackbase, istackbase + istacksize); - } - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %016" PRIx64 "\n", ustackbase); - _alert(" size: %016" PRIx64 "\n", ustacksize); -#else - _alert("sp: %016" PRIx64 "\n", sp); - _alert("stack base: %016" PRIx64 "\n", ustackbase); - _alert("stack size: %016" PRIx64 "\n", ustacksize); -#endif - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - x86_64_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - x86_64_stackdump(ustackbase, ustackbase + ustacksize); - } - - /* Then dump the registers (if available) */ - - if (g_current_regs != NULL) - { - x86_64_registerdump((uint64_t *)g_current_regs); - } -} -#else -# define x86_64_dumpstate() -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -161,8 +43,12 @@ static void x86_64_dumpstate(void) * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { board_autoled_on(LED_ASSERTION); - x86_64_dumpstate(); + + if (g_current_regs != NULL) + { + x86_64_registerdump((uint64_t *)g_current_regs); + } } diff --git a/arch/x86_64/src/common/x86_64_getintstack.c b/arch/x86_64/src/common/x86_64_getintstack.c new file mode 100644 index 00000000000..85469a72c81 --- /dev/null +++ b/arch/x86_64/src/common/x86_64_getintstack.c @@ -0,0 +1,44 @@ +/**************************************************************************** + * arch/x86_64/src/common/x86_64_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "x86_64_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ + return (uintptr_t)g_intstackalloc; +} +#endif diff --git a/arch/x86_64/src/intel64/Make.defs b/arch/x86_64/src/intel64/Make.defs index 918dec6153b..411181f0b2e 100644 --- a/arch/x86_64/src/intel64/Make.defs +++ b/arch/x86_64/src/intel64/Make.defs @@ -23,7 +23,7 @@ CMN_CSRCS += x86_64_allocateheap.c x86_64_assert.c x86_64_copystate.c CMN_CSRCS += x86_64_mdelay.c x86_64_udelay.c x86_64_exit.c x86_64_initialize.c CMN_CSRCS += x86_64_modifyreg8.c x86_64_modifyreg16.c x86_64_modifyreg32.c x86_64_nputs.c -CMN_CSRCS += x86_64_switchcontext.c +CMN_CSRCS += x86_64_switchcontext.c x86_64_getintstack.c CMN_CSRCS += intel64_restore_auxstate.c intel64_createstack.c intel64_initialstate.c CMN_CSRCS += intel64_regdump.c intel64_releasestack.c intel64_map_region.c CMN_CSRCS += intel64_savestate.c intel64_sigdeliver.c diff --git a/arch/x86_64/src/intel64/intel64_regdump.c b/arch/x86_64/src/intel64/intel64_regdump.c index f6836372e74..64ff453e19d 100644 --- a/arch/x86_64/src/intel64/intel64_regdump.c +++ b/arch/x86_64/src/intel64/intel64_regdump.c @@ -34,6 +34,15 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_RSP]; +} + /**************************************************************************** * Name: x86_64_registerdump ****************************************************************************/ diff --git a/arch/xtensa/src/common/Make.defs b/arch/xtensa/src/common/Make.defs index 374ea8f6e15..9776a26645b 100644 --- a/arch/xtensa/src/common/Make.defs +++ b/arch/xtensa/src/common/Make.defs @@ -36,7 +36,7 @@ CMN_CSRCS += xtensa_nputs.c xtensa_releasestack.c CMN_CSRCS += xtensa_schedsigaction.c CMN_CSRCS += xtensa_sigdeliver.c xtensa_stackframe.c xtensa_udelay.c CMN_CSRCS += xtensa_switchcontext.c xtensa_usestack.c xtensa_swint.c -CMN_CSRCS += xtensa_saveusercontext.c +CMN_CSRCS += xtensa_saveusercontext.c xtensa_getintstack.c xtensa_registerdump.c # Configuration-dependent common Xtensa files @@ -44,10 +44,6 @@ ifeq ($(CONFIG_DEBUG_TCBINFO),y) CMN_CSRCS += xtensa_tcbinfo.c endif -ifeq ($(CONFIG_DEBUG_ALERT),y) - CMN_CSRCS += xtensa_dumpstate.c -endif - ifeq ($(CONFIG_ARCH_FPU),y) CMN_CSRCS += xtensa_fpucmp.c endif diff --git a/arch/xtensa/src/common/xtensa.h b/arch/xtensa/src/common/xtensa.h index 820707bf11f..7f28fed94b2 100644 --- a/arch/xtensa/src/common/xtensa.h +++ b/arch/xtensa/src/common/xtensa.h @@ -216,11 +216,7 @@ void xtensa_lowputs(const char *str); /* Debug */ -#ifdef CONFIG_ARCH_STACKDUMP -void xtensa_dumpstate(void); -#else -# define xtensa_dumpstate() -#endif +void xtensa_registerdump(uintptr_t *regs); /* Common XTENSA functions */ diff --git a/arch/xtensa/src/common/xtensa_assert.c b/arch/xtensa/src/common/xtensa_assert.c index 6034cdc9ae1..002d071d8ba 100644 --- a/arch/xtensa/src/common/xtensa_assert.c +++ b/arch/xtensa/src/common/xtensa_assert.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -37,19 +38,10 @@ #include "xtensa.h" /**************************************************************************** - * Private Functions + * Private Data ****************************************************************************/ -/**************************************************************************** - * Name: xtensa_assert - ****************************************************************************/ - -static void xtensa_assert(void) -{ - /* Dump the processor state */ - - xtensa_dumpstate(); -} +static uint8_t s_last_regs[XCPTCONTEXT_SIZE]; /**************************************************************************** * Public Functions @@ -59,10 +51,27 @@ static void xtensa_assert(void) * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { + struct tcb_s *rtcb = running_task(); + board_autoled_on(LED_ASSERTION); - xtensa_assert(); + + /* Update the xcp context */ + + if (CURRENT_REGS) + { + rtcb->xcp.regs = (uint32_t *)CURRENT_REGS; + } + else + { + up_saveusercontext(s_last_regs); + rtcb->xcp.regs = (uint32_t *)s_last_regs; + } + + /* Dump the registers (if available) */ + + xtensa_registerdump(rtcb->xcp.regs); } /**************************************************************************** @@ -105,7 +114,7 @@ void xtensa_panic(int xptcode, uint32_t *regs) _alert("Unhandled Exception %d\n", xptcode); #endif - xtensa_assert(); /* Should not return */ + PANIC(); /* Should not return */ for (; ; ); } @@ -208,6 +217,6 @@ void xtensa_user_panic(int exccause, uint32_t *regs) _alert("User Exception: EXCCAUSE=%04x\n", exccause); #endif - xtensa_assert(); /* Should not return */ + PANIC(); /* Should not return */ for (; ; ); } diff --git a/arch/xtensa/src/common/xtensa_checkstack.c b/arch/xtensa/src/common/xtensa_checkstack.c index a5e1cba71a9..8d4614d8ebc 100644 --- a/arch/xtensa/src/common/xtensa_checkstack.c +++ b/arch/xtensa/src/common/xtensa_checkstack.c @@ -180,11 +180,7 @@ ssize_t up_check_stack_remain(void) #if CONFIG_ARCH_INTERRUPTSTACK > 15 size_t up_check_intstack(void) { -#ifdef CONFIG_SMP - return xtensa_stack_check(xtensa_intstack_alloc(), INTSTACK_SIZE); -#else - return xtensa_stack_check((uintptr_t)g_intstackalloc, INTSTACK_SIZE); -#endif + return xtensa_stack_check(up_get_intstackbase(), INTSTACK_SIZE); } size_t up_check_intstack_remain(void) diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c deleted file mode 100644 index 7b35aeaf30d..00000000000 --- a/arch/xtensa/src/common/xtensa_dumpstate.c +++ /dev/null @@ -1,397 +0,0 @@ -/**************************************************************************** - * arch/xtensa/src/common/xtensa_dumpstate.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "sched/sched.h" -#include "xtensa.h" - -#ifdef CONFIG_DEBUG_ALERT - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static uint8_t s_last_regs[XCPTCONTEXT_SIZE]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: xtensa_dump_task - ****************************************************************************/ - -static void xtensa_dump_task(struct tcb_s *tcb, void *arg) -{ - char args[64] = ""; -#ifdef CONFIG_STACK_COLORATION - uint32_t stack_filled = 0; - uint32_t stack_used; -#endif -#ifdef CONFIG_SCHED_CPULOAD - struct cpuload_s cpuload; - uint32_t fracpart; - uint32_t intpart; - uint32_t tmp; - - clock_cpuload(tcb->pid, &cpuload); - - if (cpuload.total > 0) - { - tmp = (1000 * cpuload.active) / cpuload.total; - intpart = tmp / 10; - fracpart = tmp - 10 * intpart; - } - else - { - intpart = 0; - fracpart = 0; - } -#endif - -#ifdef CONFIG_STACK_COLORATION - stack_used = up_check_tcbstack(tcb); - if (tcb->adj_stack_size > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * stack_used / tcb->adj_stack_size; - } -#endif - -#ifndef CONFIG_DISABLE_PTHREAD - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) - { - struct pthread_tcb_s *ptcb = (struct pthread_tcb_s *)tcb; - - snprintf(args, sizeof(args), " %p", ptcb->arg); - } - else -#endif - { - char **argv = tcb->group->tg_info->argv + 1; - size_t npos = 0; - - while (*argv != NULL && npos < sizeof(args)) - { - npos += snprintf(args + npos, sizeof(args) - npos, " %s", *argv++); - } - } - - /* Dump interesting properties of this task */ - - _alert(" %4d %4d" -#ifdef CONFIG_SMP - " %4d" -#endif - " %7lu" -#ifdef CONFIG_STACK_COLORATION - " %7lu %3" PRId32 ".%1" PRId32 "%%%c" -#endif -#ifdef CONFIG_SCHED_CPULOAD - " %3" PRId32 ".%01" PRId32 "%%" -#endif - " %s%s\n" - , tcb->pid, tcb->sched_priority -#ifdef CONFIG_SMP - , tcb->cpu -#endif - , (unsigned long)tcb->adj_stack_size -#ifdef CONFIG_STACK_COLORATION - , (unsigned long)up_check_tcbstack(tcb) - , stack_filled / 10, stack_filled % 10 - , (stack_filled >= 10 * 80 ? '!' : ' ') -#endif -#ifdef CONFIG_SCHED_CPULOAD - , intpart, fracpart -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - , tcb->name -#else - , "" -#endif - , args - ); -} - -/**************************************************************************** - * Name: xtensa_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void xtensa_dump_backtrace(struct tcb_s *tcb, void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: xtensa_showtasks - ****************************************************************************/ - -static inline void xtensa_showtasks(void) -{ -#if CONFIG_ARCH_INTERRUPTSTACK > 15 -# ifdef CONFIG_STACK_COLORATION - uint32_t stack_used = up_check_intstack(); - uint32_t stack_filled = 0; - - if ((CONFIG_ARCH_INTERRUPTSTACK & ~15) > 0 && stack_used > 0) - { - /* Use fixed-point math with one decimal place */ - - stack_filled = 10 * 100 * - stack_used / (CONFIG_ARCH_INTERRUPTSTACK & ~15); - } -# endif -#endif - - /* Dump interesting properties of each task in the crash environment */ - - _alert(" PID PRI" -#ifdef CONFIG_SMP - " CPU" -#endif - " STACK" -#ifdef CONFIG_STACK_COLORATION - " USED FILLED " -#endif -#ifdef CONFIG_SCHED_CPULOAD - " CPU" -#endif - " COMMAND\n"); - -#if CONFIG_ARCH_INTERRUPTSTACK > 15 - _alert(" ---- ----" -# ifdef CONFIG_SMP - " ----" -# endif - " %7u" -# ifdef CONFIG_STACK_COLORATION - " %7" PRId32 " %3" PRId32 ".%1" PRId32 "%%%c" -# endif -# ifdef CONFIG_SCHED_CPULOAD - " ----" -# endif - " irq\n" - , (CONFIG_ARCH_INTERRUPTSTACK & ~15) -# ifdef CONFIG_STACK_COLORATION - , stack_used - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') -# endif - ); -#endif - - nxsched_foreach(xtensa_dump_task, NULL); -#ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(xtensa_dump_backtrace, NULL); -#endif -} - -/**************************************************************************** - * Name: xtensa_stackdump - ****************************************************************************/ - -static void xtensa_stackdump(uint32_t sp, uint32_t stack_top) -{ - uint32_t stack; - - /* Flush any buffered SYSLOG data to avoid overwrite */ - - syslog_flush(); - - for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) - { - uint32_t *ptr = (uint32_t *)stack; - _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", - stack, ptr[0], ptr[1], ptr[2], ptr[3], - ptr[4], ptr[5], ptr[6], ptr[7]); - } -} - -/**************************************************************************** - * Name: xtensa_registerdump - ****************************************************************************/ - -static inline void xtensa_registerdump(uintptr_t *regs) -{ - _alert(" PC: %08lx PS: %08lx\n", - (unsigned long)regs[REG_PC], (unsigned long)regs[REG_PS]); - _alert(" A0: %08lx A1: %08lx A2: %08lx A3: %08lx\n", - (unsigned long)regs[REG_A0], (unsigned long)regs[REG_A1], - (unsigned long)regs[REG_A2], (unsigned long)regs[REG_A3]); - _alert(" A4: %08lx A5: %08lx A6: %08lx A7: %08lx\n", - (unsigned long)regs[REG_A4], (unsigned long)regs[REG_A5], - (unsigned long)regs[REG_A6], (unsigned long)regs[REG_A7]); - _alert(" A8: %08lx A9: %08lx A10: %08lx A11: %08lx\n", - (unsigned long)regs[REG_A8], (unsigned long)regs[REG_A9], - (unsigned long)regs[REG_A10], (unsigned long)regs[REG_A11]); - _alert(" A12: %08lx A13: %08lx A14: %08lx A15: %08lx\n", - (unsigned long)regs[REG_A12], (unsigned long)regs[REG_A13], - (unsigned long)regs[REG_A14], (unsigned long)regs[REG_A15]); - _alert(" SAR: %08lx CAUSE: %08lx VADDR: %08lx\n", - (unsigned long)regs[REG_SAR], (unsigned long)regs[REG_EXCCAUSE], - (unsigned long)regs[REG_EXCVADDR]); -#if XCHAL_HAVE_LOOPS != 0 - _alert(" LBEG: %08lx LEND: %08lx LCNT: %08lx\n", - (unsigned long)regs[REG_LBEG], (unsigned long)regs[REG_LEND], - (unsigned long)regs[REG_LCOUNT]); -#endif -} - -/**************************************************************************** - * Name: xtensa_dump_stack - ****************************************************************************/ - -static void xtensa_dump_stack(const char *tag, uint32_t sp, - uint32_t base, uint32_t size, bool force) -{ - uint32_t top = base + size; -#ifdef CONFIG_STACK_COLORATION - uint32_t used = xtensa_stack_check((uintptr_t)base, size); -#endif - - _alert("%s Stack:\n", tag); - _alert("sp: %08" PRIx32 "\n", sp); - _alert(" base: %08" PRIx32 "\n", base); - _alert(" size: %08" PRIx32 "\n", size); -#ifdef CONFIG_STACK_COLORATION - _alert(" used: %08" PRIx32 "\n", used); -#endif - - if (sp >= base && sp < top) - { - xtensa_stackdump(sp, top); - } - else - { - _alert("ERROR: %s Stack pointer is not within the stack\n", tag); - - if (force) - { -#ifdef CONFIG_STACK_COLORATION - base += size - used; - size = used; -#endif - -#if CONFIG_ARCH_STACKDUMP_MAX_LENGTH > 0 - if (size > CONFIG_ARCH_STACKDUMP_MAX_LENGTH) - { - size = CONFIG_ARCH_STACKDUMP_MAX_LENGTH; - } -#endif - - xtensa_stackdump(base, base + size); - } - } -} - -/**************************************************************************** - * Name: xtensa_dumpstate - ****************************************************************************/ - -void xtensa_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - -#ifdef CONFIG_SMP - /* Show the CPU number */ - - _alert("CPU%d:\n", up_cpu_index()); -#endif - - /* Update the xcp context */ - - if (CURRENT_REGS) - { - rtcb->xcp.regs = (uint32_t *)CURRENT_REGS; - } - else - { - up_saveusercontext(s_last_regs); - rtcb->xcp.regs = (uint32_t *)s_last_regs; - } - - /* Dump the registers (if available) */ - - xtensa_registerdump(rtcb->xcp.regs); - - /* Dump the backtrace */ - -#if defined(CONFIG_XTENSA_DUMPBT_ON_ASSERT) && \ - defined(CONFIG_SCHED_BACKTRACE) - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the irq stack */ - -#if CONFIG_ARCH_INTERRUPTSTACK > 15 - xtensa_dump_stack("IRQ", sp, -# ifdef CONFIG_SMP - (uint32_t)xtensa_intstack_alloc(), -# else - (uint32_t)g_intstackalloc, -# endif - INTSTACK_SIZE, - !!CURRENT_REGS); - - if (CURRENT_REGS) - { - sp = CURRENT_REGS[REG_A1]; - } -#endif - - /* Dump the user stack */ - - xtensa_dump_stack("User", sp, - (uint32_t)rtcb->stack_base_ptr, - (uint32_t)rtcb->adj_stack_size, - true); - - /* Dump the state of all tasks (if available) */ - - xtensa_showtasks(); -} - -#endif /* CONFIG_DEBUG_ALERT */ diff --git a/arch/xtensa/src/common/xtensa_getintstack.c b/arch/xtensa/src/common/xtensa_getintstack.c new file mode 100644 index 00000000000..eb64149ddd7 --- /dev/null +++ b/arch/xtensa/src/common/xtensa_getintstack.c @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/xtensa/src/common/xtensa_getintstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "xtensa.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_get_intstackbase + ****************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void) +{ +#ifdef CONFIG_SMP + return (uintptr_t)xtensa_intstack_alloc(); +#else + return (uintptr_t)g_intstackalloc; +#endif +} +#endif diff --git a/arch/xtensa/src/common/xtensa_registerdump.c b/arch/xtensa/src/common/xtensa_registerdump.c new file mode 100644 index 00000000000..4470141fd59 --- /dev/null +++ b/arch/xtensa/src/common/xtensa_registerdump.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * arch/xtensa/src/common/xtensa_registerdump.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "xtensa.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + return CURRENT_REGS[REG_A1]; +} + +/**************************************************************************** + * Name: xtensa_registerdump + ****************************************************************************/ + +void xtensa_registerdump(uintptr_t *regs) +{ + _alert(" PC: %08lx PS: %08lx\n", + (unsigned long)regs[REG_PC], (unsigned long)regs[REG_PS]); + _alert(" A0: %08lx A1: %08lx A2: %08lx A3: %08lx\n", + (unsigned long)regs[REG_A0], (unsigned long)regs[REG_A1], + (unsigned long)regs[REG_A2], (unsigned long)regs[REG_A3]); + _alert(" A4: %08lx A5: %08lx A6: %08lx A7: %08lx\n", + (unsigned long)regs[REG_A4], (unsigned long)regs[REG_A5], + (unsigned long)regs[REG_A6], (unsigned long)regs[REG_A7]); + _alert(" A8: %08lx A9: %08lx A10: %08lx A11: %08lx\n", + (unsigned long)regs[REG_A8], (unsigned long)regs[REG_A9], + (unsigned long)regs[REG_A10], (unsigned long)regs[REG_A11]); + _alert(" A12: %08lx A13: %08lx A14: %08lx A15: %08lx\n", + (unsigned long)regs[REG_A12], (unsigned long)regs[REG_A13], + (unsigned long)regs[REG_A14], (unsigned long)regs[REG_A15]); + _alert(" SAR: %08lx CAUSE: %08lx VADDR: %08lx\n", + (unsigned long)regs[REG_SAR], (unsigned long)regs[REG_EXCCAUSE], + (unsigned long)regs[REG_EXCVADDR]); +#if XCHAL_HAVE_LOOPS != 0 + _alert(" LBEG: %08lx LEND: %08lx LCNT: %08lx\n", + (unsigned long)regs[REG_LBEG], (unsigned long)regs[REG_LEND], + (unsigned long)regs[REG_LCOUNT]); +#endif +} + diff --git a/arch/xtensa/src/common/xtensa_swint.c b/arch/xtensa/src/common/xtensa_swint.c index 1f56639ff60..3ae0c5bbb81 100644 --- a/arch/xtensa/src/common/xtensa_swint.c +++ b/arch/xtensa/src/common/xtensa_swint.c @@ -40,26 +40,6 @@ * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: xtensa_registerdump - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_SYSCALL_INFO -static void xtensa_registerdump(const uintptr_t *regs) -{ - svcinfo(" A0: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3], - regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); - svcinfo(" A8: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regs[REG_A8], regs[REG_A9], regs[REG_A10], regs[REG_A11], - regs[REG_A12], regs[REG_A13], regs[REG_A14], regs[REG_A15]); - svcinfo(" PC: %08x PS: %08x\n", regs[REG_PC], regs[REG_PS]); -#ifdef CONFIG_BUILD_PROTECTED - svcinfo(" INT_CTX: %08x\n", regs[REG_INT_CTX]); -#endif -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -451,7 +431,7 @@ int xtensa_swint(int irq, void *context, void *arg) if (regs != CURRENT_REGS) { svcinfo("SYSCALL Return: Context switch!\n"); - xtensa_registerdump((const uintptr_t *)CURRENT_REGS); + xtensa_registerdump(CURRENT_REGS); } else { diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c index 1935142b853..7d69c6c191d 100644 --- a/arch/xtensa/src/esp32/esp32_cpustart.c +++ b/arch/xtensa/src/esp32/esp32_cpustart.c @@ -65,23 +65,6 @@ extern void ets_set_appcpu_boot_addr(uint32_t start); * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: xtensa_registerdump - ****************************************************************************/ - -#if 0 /* Was useful in solving some startup problems */ -static inline void xtensa_registerdump(struct tcb_s *tcb) -{ - _info("CPU%d:\n", up_cpu_index()); - - /* Dump the startup registers */ - - /* To be provided */ -} -#else -# define xtensa_registerdump(tcb) -#endif - /**************************************************************************** * Name: xtensa_attach_fromcpu0_interrupt ****************************************************************************/ @@ -182,7 +165,9 @@ void IRAM_ATTR xtensa_appcpu_start(void) /* Dump registers so that we can see what is going to happen on return */ - xtensa_registerdump(tcb); +#if 0 + xtensa_registerdump(tcb->xcp.regs); +#endif #ifdef CONFIG_ESP32_GPIO_IRQ /* Initialize GPIO interrupt support */ diff --git a/arch/z16/src/common/z16_assert.c b/arch/z16/src/common/z16_assert.c index 0554c17fcd6..1064e55e636 100644 --- a/arch/z16/src/common/z16_assert.c +++ b/arch/z16/src/common/z16_assert.c @@ -24,8 +24,17 @@ #include +#include +#include + #include "z16_internal.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static chipreg_t s_last_regs[XCPTCONTEXT_REGS]; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -34,9 +43,17 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { + FAR volatile uint32_t *regs32 = (FAR volatile uint32_t *)g_current_regs; + board_autoled_on(LED_ASSERTION); - z16_registerdump(); - z16_stackdump(); + + if (regs32 == NULL) + { + up_saveusercontext(s_last_regs); + regs32 = (FAR volatile uint32_t *)s_last_regs; + } + + z16_registerdump(regs32); } diff --git a/arch/z16/src/common/z16_internal.h b/arch/z16/src/common/z16_internal.h index 5b13b934bb4..ffe81aaade8 100644 --- a/arch/z16/src/common/z16_internal.h +++ b/arch/z16/src/common/z16_internal.h @@ -157,13 +157,7 @@ void z16_netinitialize(void); /* Dump stack and registers */ -#ifdef CONFIG_ARCH_STACKDUMP -void z16_stackdump(void); -void z16_registerdump(void); -#else -# define z16_stackdump() -# define z16_registerdump() -#endif +void z16_registerdump(FAR volatile uint32_t *regs); #endif /* __ASSEMBLY__ */ diff --git a/arch/z16/src/common/z16_registerdump.c b/arch/z16/src/common/z16_registerdump.c index 8c85dfc3ffe..56d0c38b138 100644 --- a/arch/z16/src/common/z16_registerdump.c +++ b/arch/z16/src/common/z16_registerdump.c @@ -27,49 +27,37 @@ #include #include -#include -#include - #include "z16_internal.h" -#ifdef CONFIG_ARCH_STACKDUMP - /**************************************************************************** - * Private Data + * Public Functions ****************************************************************************/ -static chipreg_t s_last_regs[XCPTCONTEXT_REGS]; - /**************************************************************************** - * Private Functions + * Name: up_getusrsp ****************************************************************************/ +uintptr_t up_getusrsp(void) +{ + return g_current_regs[REG_SP]; +} + /**************************************************************************** * Name: z16_registerdump ****************************************************************************/ -void z16_registerdump(void) +void z16_registerdump(FAR volatile uint32_t *regs) { #ifdef CONFIG_DEBUG_INFO - FAR volatile uint32_t *regs32 = (FAR volatile uint32_t *)g_current_regs; - - if (regs32 == NULL) - { - up_saveusercontext(s_last_regs); - regs32 = (FAR volatile uint32_t *)s_last_regs; - } - _alert("R0 :%08x R1 :%08x R2 :%08x R3 :%08x " "R4 :%08x R5 :%08x R6 :%08x R7 :%08x\n" - regs32[REG_R0 / 2], regs32[REG_R1 / 2], regs32[REG_R2 / 2], - regs32[REG_R3 / 2], regs32[REG_R4 / 2], regs32[REG_R5 / 2], - regs32[REG_R6 / 2], regs32[REG_R7 / 2]); + regs[REG_R0 / 2], regs[REG_R1 / 2], regs[REG_R2 / 2], + regs[REG_R3 / 2], regs[REG_R4 / 2], regs[REG_R5 / 2], + regs[REG_R6 / 2], regs[REG_R7 / 2]); _alert("R8 :%08x R9 :%08x R10:%08x R11:%08x R12:%08x R13:%08x\n" - regs32[REG_R8 / 2], regs32[REG_R9 / 2], regs32[REG_R10 / 2], - regs3[REG_R11 / 2], regs32[REG_R12 / 2], regs32[REG_R13 / 2]); + regs[REG_R8 / 2], regs[REG_R9 / 2], regs[REG_R10 / 2], + regs3[REG_R11 / 2], regs[REG_R12 / 2], regs[REG_R13 / 2]); _alert("FP :%08x SP :%08x FLG:%04x\n" - regs32[REG_R14 / 2], regs32[REG_R15 / 2], regs32[REG_FLAGS]); + regs[REG_R14 / 2], regs[REG_R15 / 2], regs[REG_FLAGS]); #endif } - -#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/z16/src/z16f/Make.defs b/arch/z16/src/z16f/Make.defs index 6e18725e653..0e7a089360b 100644 --- a/arch/z16/src/z16f/Make.defs +++ b/arch/z16/src/z16f/Make.defs @@ -21,8 +21,7 @@ HEAD_SSRC = z16f_head.S CMN_CSRCS = z16_allocateheap.c z16_initialize.c z16_schedulesigaction.c -CMN_CSRCS += z16_assert.c z16_initialstate.c z16_sigdeliver.c -CMN_CSRCS += z16_stackdump.c z16_copystate.c +CMN_CSRCS += z16_assert.c z16_initialstate.c z16_sigdeliver.c z16_copystate.c CMN_CSRCS += z16_mdelay.c z16_udelay.c z16_createstack.c z16_registerdump.c CMN_CSRCS += z16_switchcontext.c z16_doirq.c z16_usestack.c CMN_CSRCS += z16_exit.c z16_releasestack.c z16_stackframe.c z16_idle.c diff --git a/arch/z80/src/common/z80_assert.c b/arch/z80/src/common/z80_assert.c index b9b10691577..eae6bf03184 100644 --- a/arch/z80/src/common/z80_assert.c +++ b/arch/z80/src/common/z80_assert.c @@ -34,8 +34,7 @@ * Name: up_assert ****************************************************************************/ -void up_assert(const char *filename, int lineno) +void up_assert(void) { Z80_REGISTER_DUMP(); - z80_stackdump(); } diff --git a/arch/z80/src/common/z80_internal.h b/arch/z80/src/common/z80_internal.h index e4c3cbaae8d..566b1a6f3cb 100644 --- a/arch/z80/src/common/z80_internal.h +++ b/arch/z80/src/common/z80_internal.h @@ -146,10 +146,8 @@ int z80_multicastfilter(FAR struct net_driver_s *dev, FAR uint8_t *mac, /* Dump stack and registers */ #ifdef CONFIG_ARCH_STACKDUMP -void z80_stackdump(void); # define Z80_REGISTER_DUMP() _REGISTER_DUMP() #else -# define z80_stackdump() # define Z80_REGISTER_DUMP() #endif diff --git a/arch/z80/src/ez80/Make.defs b/arch/z80/src/ez80/Make.defs index 355aae67438..00e19b1daaf 100644 --- a/arch/z80/src/ez80/Make.defs +++ b/arch/z80/src/ez80/Make.defs @@ -25,10 +25,6 @@ CMN_CSRCS += z80_idle.c z80_assert.c z80_doirq.c CMN_CSRCS += z80_mdelay.c z80_stackframe.c z80_udelay.c z80_usestack.c CMN_CSRCS += z80_nputs.c -ifeq ($(CONFIG_ARCH_STACKDUMP),y) -CMN_CSRCS += z80_stackdump.c -endif - CHIP_ASRCS = ez80_startup.asm ez80_io.asm ez80_irqsave.asm CHIP_ASRCS += ez80_irqcommon.asm CHIP_ASRCS += ez80_saveusercontext.asm ez80_restorecontext.asm diff --git a/arch/z80/src/ez80/ez80_registerdump.c b/arch/z80/src/ez80/ez80_registerdump.c index a298b3dea62..184dc57bca7 100644 --- a/arch/z80/src/ez80/ez80_registerdump.c +++ b/arch/z80/src/ez80/ez80_registerdump.c @@ -44,6 +44,16 @@ static chipreg_t s_last_regs[XCPTCONTEXT_REGS]; * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + FAR chipreg_t *regs = g_current_regs; + return regs[XCPT_SP]; +} + /**************************************************************************** * Name: z80_registerdump ****************************************************************************/ diff --git a/arch/z80/src/z180/z180_registerdump.c b/arch/z80/src/z180/z180_registerdump.c index 96610708a57..87f11ab9952 100644 --- a/arch/z80/src/z180/z180_registerdump.c +++ b/arch/z80/src/z180/z180_registerdump.c @@ -41,9 +41,19 @@ static chipreg_t s_last_regs[XCPTCONTEXT_REGS]; /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + FAR chipreg_t *regs = g_current_regs; + return regs[XCPT_SP]; +} + /**************************************************************************** * Name: z180_registerdump ****************************************************************************/ diff --git a/arch/z80/src/z8/z8_registerdump.c b/arch/z80/src/z8/z8_registerdump.c index b4e4aac677a..d5fa77d35bc 100644 --- a/arch/z80/src/z8/z8_registerdump.c +++ b/arch/z80/src/z8/z8_registerdump.c @@ -63,6 +63,16 @@ static inline void z8_dumpstate(chipreg_t sp, chipreg_t pc, uint8_t irqctl, * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + FAR chipreg_t *regs = g_z8irqstate.regs; + return regs[XCPT_SP]; +} + /**************************************************************************** * Name: z8_registerdump ****************************************************************************/ diff --git a/arch/z80/src/z80/z80_registerdump.c b/arch/z80/src/z80/z80_registerdump.c index 5bcfa69f571..05e049b6d63 100644 --- a/arch/z80/src/z80/z80_registerdump.c +++ b/arch/z80/src/z80/z80_registerdump.c @@ -41,9 +41,19 @@ static chipreg_t s_last_regs[XCPTCONTEXT_REGS]; /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_getusrsp + ****************************************************************************/ + +uintptr_t up_getusrsp(void) +{ + FAR chipreg_t *regs = g_current_regs; + return regs[XCPT_SP]; +} + /**************************************************************************** * Name: z80_registerdump ****************************************************************************/ diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index a5171e125ba..7fd4b5a1855 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -430,7 +430,7 @@ void up_exit(int status) noreturn_function; * ****************************************************************************/ -void up_assert(FAR const char *filename, int linenum); +void up_assert(void); #ifdef CONFIG_ARCH_HAVE_BACKTRACE @@ -1757,6 +1757,19 @@ int up_timer_tick_start(clock_t ticks); * The actual implementation may be a MACRO or an inline function. */ +/**************************************************************************** + * Name: up_getusrsp + * + * Input Parameters: + * None + * + * Returned Value: + * User stack pointer. + * + ****************************************************************************/ + +uintptr_t up_getusrsp(void); + /**************************************************************************** * TLS support ****************************************************************************/ @@ -2269,6 +2282,10 @@ size_t up_check_intstack_remain(void); #endif #endif +#if defined(CONFIG_ARCH_INTERRUPTSTACK) && CONFIG_ARCH_INTERRUPTSTACK > 3 +uintptr_t up_get_intstackbase(void); +#endif + /**************************************************************************** * Name: up_rtc_initialize * diff --git a/sched/misc/assert.c b/sched/misc/assert.c index e9865a77387..0ce6f3b8dad 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,12 @@ # define CONFIG_BOARD_RESET_ON_ASSERT 0 #endif +/* Check if an interrupt stack size is configured */ + +#ifndef CONFIG_ARCH_INTERRUPTSTACK +# define CONFIG_ARCH_INTERRUPTSTACK 0 +#endif + /* USB trace dumping */ #ifndef CONFIG_USBDEV_TRACE @@ -80,6 +87,298 @@ static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) } #endif +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Name: stackdump + ****************************************************************************/ + +static void stackdump(uintptr_t sp, uintptr_t stack_top) +{ + uintptr_t stack; + + for (stack = sp & ~0x1f; stack < (stack_top & ~0x1f); stack += 32) + { + FAR uint32_t *ptr = (FAR uint32_t *)stack; + _alert("%" PRIxPTR ": %08" PRIx32 " %08" PRIx32 " %08" PRIx32 + " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 + " %08" PRIx32 "\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +} + +/**************************************************************************** + * Name: dump_stack + ****************************************************************************/ + +static void dump_stack(FAR const char *tag, uintptr_t sp, + uintptr_t base, size_t size, + size_t used, bool force) +{ + uintptr_t top = base + size; + + _alert("%s Stack:\n", tag); + _alert("sp: %08" PRIxPTR "\n", sp); + _alert(" base: %08" PRIxPTR "\n", base); + _alert(" size: %08zu\n", size); + + if (sp >= base && sp < top) + { + stackdump(sp, top); + } + else + { + _alert("ERROR: %s Stack pointer is not within the stack\n", tag); + + if (force) + { +#ifdef CONFIG_STACK_COLORATION + size_t remain = size - used; + + base += remain; + size -= remain; +#endif + +#if CONFIG_ARCH_STACKDUMP_MAX_LENGTH > 0 + if (size > CONFIG_ARCH_STACKDUMP_MAX_LENGTH) + { + size = CONFIG_ARCH_STACKDUMP_MAX_LENGTH; + } +#endif + + stackdump(base, base + size); + } + } +} + +/**************************************************************************** + * Name: showstacks + ****************************************************************************/ + +static void showstacks(void) +{ + FAR struct tcb_s *rtcb = running_task(); + uintptr_t sp = up_getsp(); + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + dump_stack("IRQ", sp, + up_get_intstackbase(), + CONFIG_ARCH_INTERRUPTSTACK, +# ifdef CONFIG_STACK_COLORATION + up_check_intstack(), +# else + 0, +# endif + up_interrupt_context()); + if (up_interrupt_context()) + { + sp = up_getusrsp(); + } +#endif + + dump_stack("User", sp, + (uintptr_t)rtcb->stack_base_ptr, + (size_t)rtcb->adj_stack_size, +#ifdef CONFIG_STACK_COLORATION + up_check_tcbstack(rtcb), +#else + 0, +#endif +#ifdef CONFIG_ARCH_KERNEL_STACK + false +#else + true +#endif + ); + +#ifdef CONFIG_ARCH_KERNEL_STACK + dump_stack("Kernel", sp, + (uintptr_t)rtcb->xcp.kstack, + CONFIG_ARCH_KERNEL_STACKSIZE, +# ifdef CONFIG_STACK_COLORATION + up_check_tcbstack(rtcb), +# else + 0, +# endif + false); +#endif +} + +#endif + +/**************************************************************************** + * Name: dump_task + ****************************************************************************/ + +static void dump_task(struct tcb_s *tcb, void *arg) +{ + char args[64] = ""; +#ifdef CONFIG_STACK_COLORATION + size_t stack_filled = 0; + size_t stack_used; +#endif +#ifdef CONFIG_SCHED_CPULOAD + struct cpuload_s cpuload; + size_t fracpart = 0; + size_t intpart = 0; + size_t tmp; + + clock_cpuload(tcb->pid, &cpuload); + + if (cpuload.total > 0) + { + tmp = (1000 * cpuload.active) / cpuload.total; + intpart = tmp / 10; + fracpart = tmp - 10 * intpart; + } +#endif + +#ifdef CONFIG_STACK_COLORATION + stack_used = up_check_tcbstack(tcb); + if (tcb->adj_stack_size > 0 && stack_used > 0) + { + /* Use fixed-point math with one decimal place */ + + stack_filled = 10 * 100 * stack_used / tcb->adj_stack_size; + } +#endif + +#ifndef CONFIG_DISABLE_PTHREAD + if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) + { + struct pthread_tcb_s *ptcb = (struct pthread_tcb_s *)tcb; + + snprintf(args, sizeof(args), " %p", ptcb->arg); + } + else +#endif + { + char **argv = tcb->group->tg_info->argv + 1; + size_t npos = 0; + + while (*argv != NULL && npos < sizeof(args)) + { + npos += snprintf(args + npos, sizeof(args) - npos, " %s", *argv++); + } + } + + /* Dump interesting properties of this task */ + + _alert(" %4d %4d" +#ifdef CONFIG_SMP + " %4d" +#endif + " %7zu" +#ifdef CONFIG_STACK_COLORATION + " %7zu %3zu.%1zu%%%c" +#endif +#ifdef CONFIG_SCHED_CPULOAD + " %3zu.%01zu%%" +#endif + " %s%s\n" + , tcb->pid, tcb->sched_priority +#ifdef CONFIG_SMP + , tcb->cpu +#endif + , tcb->adj_stack_size +#ifdef CONFIG_STACK_COLORATION + , up_check_tcbstack(tcb) + , stack_filled / 10, stack_filled % 10 + , (stack_filled >= 10 * 80 ? '!' : ' ') +#endif +#ifdef CONFIG_SCHED_CPULOAD + , intpart, fracpart +#endif +#if CONFIG_TASK_NAME_SIZE > 0 + , tcb->name +#else + , "" +#endif + , args + ); +} + +/**************************************************************************** + * Name: dump_backtrace + ****************************************************************************/ + +#ifdef CONFIG_SCHED_BACKTRACE +static void dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) +{ + /* Show back trace */ + + sched_dumpstack(tcb->pid); +} +#endif + +/**************************************************************************** + * Name: showtasks + ****************************************************************************/ + +static void showtasks(void) +{ +#if CONFIG_ARCH_INTERRUPTSTACK > 0 +# ifdef CONFIG_STACK_COLORATION + size_t stack_used = up_check_intstack(); + size_t stack_filled = 0; + + if (stack_used > 0) + { + /* Use fixed-point math with one decimal place */ + + stack_filled = 10 * 100 * + stack_used / CONFIG_ARCH_INTERRUPTSTACK; + } +# endif +#endif + + /* Dump interesting properties of each task in the crash environment */ + + _alert(" PID PRI" +#ifdef CONFIG_SMP + " CPU" +#endif + " STACK" +#ifdef CONFIG_STACK_COLORATION + " USED FILLED " +#endif +#ifdef CONFIG_SCHED_CPULOAD + " CPU" +#endif + " COMMAND\n"); + +#if CONFIG_ARCH_INTERRUPTSTACK > 0 + _alert(" ---- ----" +# ifdef CONFIG_SMP + " ----" +# endif + " %7u" +# ifdef CONFIG_STACK_COLORATION + " %7zu %3zu.%1zu%%%c" +# endif +# ifdef CONFIG_SCHED_CPULOAD + " ----" +# endif + " irq\n" + , CONFIG_ARCH_INTERRUPTSTACK +# ifdef CONFIG_STACK_COLORATION + , stack_used + , stack_filled / 10, stack_filled % 10, + (stack_filled >= 10 * 80 ? '!' : ' ') +# endif + ); +#endif + + nxsched_foreach(dump_task, NULL); + +#ifdef CONFIG_SCHED_BACKTRACE + nxsched_foreach(dump_backtrace, NULL); +#endif +} + /**************************************************************************** * Name: assert_end ****************************************************************************/ @@ -174,7 +473,20 @@ void _assert(FAR const char *filename, int linenum) syslog_flush(); - up_assert(filename, linenum); + /* Show back trace */ + +#ifdef CONFIG_SCHED_BACKTRACE + sched_dumpstack(running_task()->pid); +#endif + + up_assert(); + +#ifdef CONFIG_ARCH_STACKDUMP + showstacks(); +#endif + + showtasks(); + assert_end(); exit(EXIT_FAILURE); }