diff --git a/arch/risc-v/src/rv64gc/riscv_assert.c b/arch/risc-v/src/common/riscv_assert.c similarity index 88% rename from arch/risc-v/src/rv64gc/riscv_assert.c rename to arch/risc-v/src/common/riscv_assert.c index c39cc3d2cfd..9bf7741fbaf 100644 --- a/arch/risc-v/src/rv64gc/riscv_assert.c +++ b/arch/risc-v/src/common/riscv_assert.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/risc-v/src/rv64gc/riscv_assert.c + * arch/risc-v/src/common/riscv_assert.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -57,6 +57,14 @@ # define CONFIG_BOARD_RESET_ON_ASSERT 0 #endif +/* Format output with register width and hex */ + +#ifdef CONFIG_ARCH_RV32 +# define PRIxREG "%08"PRIxPTR +#else +# define PRIxREG "%016"PRIxPTR +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -71,9 +79,9 @@ * Name: riscv_stackdump ****************************************************************************/ -static void riscv_stackdump(uint64_t sp, uintptr_t stack_top) +static void riscv_stackdump(uintptr_t sp, uintptr_t stack_top) { - uint64_t stack; + uintptr_t stack; /* Flush any buffered SYSLOG data to avoid overwrite */ @@ -82,7 +90,7 @@ static void riscv_stackdump(uint64_t sp, uintptr_t stack_top) 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 + _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], @@ -98,35 +106,35 @@ static inline void riscv_registerdump(volatile uintptr_t *regs) { /* Are user registers available from interrupt processing? */ - _alert("EPC:%016" PRIx64 "\n", regs[REG_EPC]); - _alert("A0:%016" PRIx64 " A1:%01" PRIx64 "6 A2:%016" PRIx64 - " A3:%016" PRIx64 "\n", + _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:%016" PRIx64 " A5:%016" PRIx64 "A6:%016" PRIx64 - " A7:%016" PRIx64 "\n", + _alert("A4:" PRIxREG " A5:" PRIxREG "A6:" PRIxREG + " A7:" PRIxREG "\n", regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); - _alert("T0:%016" PRIx64 " T1:%016" PRIx64 " T2:%016" PRIx64 - " T3:%016" PRIx64 "\n", + _alert("T0:" PRIxREG " T1:" PRIxREG " T2:" PRIxREG + " T3:" PRIxREG "\n", regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3]); - _alert("T4:%016" PRIx64 " T5:%016" PRIx64 " T6:%016" PRIx64 "\n", + _alert("T4:" PRIxREG " T5:" PRIxREG " T6:" PRIxREG "\n", regs[REG_T4], regs[REG_T5], regs[REG_T6]); - _alert("S0:%016" PRIx64 " S1:%016" PRIx64 " S2:%016" PRIx64 - " S3:%016" PRIx64 "\n", + _alert("S0:" PRIxREG " S1:" PRIxREG " S2:" PRIxREG + " S3:" PRIxREG "\n", regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3]); - _alert("S4:%016" PRIx64 " S5:%016" PRIx64 " S6:%016" PRIx64 - " S7:%016" PRIx64 "\n", + _alert("S4:" PRIxREG " S5:" PRIxREG " S6:" PRIxREG + " S7:" PRIxREG "\n", regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); - _alert("S8:%016" PRIx64 " S9:%016" PRIx64 " S10:%016" PRIx64 - " S11:%016" PRIx64 "\n", + _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:%016" PRIx64 " SP:%016" PRIx64 " FP:%016" PRIx64 - " TP:%016" PRIx64 " RA:%016" PRIx64 "\n", + _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:%016" PRIx64 " FP:%016" PRIx64 " TP:%016" PRIx64 - " RA:%016" PRIx64 "\n", + _alert("SP:" PRIxREG " FP:" PRIxREG " TP:" PRIxREG + " RA:" PRIxREG "\n", regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); #endif } @@ -299,7 +307,7 @@ static inline void riscv_showtasks(void) static void riscv_dumpstate(void) { struct tcb_s *rtcb = running_task(); - uint64_t sp = up_getsp(); + uintptr_t sp = up_getsp(); uintptr_t ustackbase; uintptr_t ustacksize; #if CONFIG_ARCH_INTERRUPTSTACK > 15 @@ -315,7 +323,7 @@ static void riscv_dumpstate(void) /* Dump the registers (if available) */ - riscv_registerdump(CURRENT_REGS); + riscv_registerdump((volatile uintptr_t *)CURRENT_REGS); /* Get the limits on the user stack memory */ @@ -330,10 +338,10 @@ static void riscv_dumpstate(void) /* Show interrupt stack info */ - _alert("sp: %016" PRIx64 "\n", sp); + _alert("sp: " PRIxREG "\n", sp); _alert("IRQ stack:\n"); - _alert(" base: %016" PRIxPTR "\n", istackbase); - _alert(" size: %016" PRIxPTR "\n", istacksize); + _alert(" base: " PRIxREG "\n", istackbase); + _alert(" size: " PRIxREG "\n", istacksize); /* Does the current stack pointer lie within the interrupt * stack? @@ -348,7 +356,7 @@ static void riscv_dumpstate(void) /* Extract the user stack pointer */ sp = CURRENT_REGS[REG_SP]; - _alert("sp: %016" PRIx64 "\n", sp); + _alert("sp: " PRIxREG "\n", sp); } else if (CURRENT_REGS) { @@ -359,12 +367,12 @@ static void riscv_dumpstate(void) /* Show user stack info */ _alert("User stack:\n"); - _alert(" base: %016" PRIxPTR "\n", ustackbase); - _alert(" size: %016" PRIxPTR "\n", ustacksize); + _alert(" base: " PRIxREG "\n", ustackbase); + _alert(" size: " PRIxREG "\n", ustacksize); #else - _alert("sp: %016" PRIx64 "\n", sp); - _alert("stack base: %016" PRIxPTR "\n", ustackbase); - _alert("stack size: %016" PRIxPTR "\n", ustacksize); + _alert("sp: " PRIxREG "\n", sp); + _alert("stack base: " PRIxREG "\n", ustackbase); + _alert("stack size: " PRIxREG "\n", ustacksize); #endif /* Dump the user stack if the stack pointer lies within the allocated user @@ -386,10 +394,10 @@ static void riscv_dumpstate(void) #endif /* CONFIG_ARCH_STACKDUMP */ /**************************************************************************** - * Name: _up_assert + * Name: riscv_assert ****************************************************************************/ -static void _up_assert(void) +static void riscv_assert(void) { /* Flush any buffered SYSLOG data */ @@ -511,5 +519,5 @@ void up_assert(const char *filename, int lineno) board_crashdump(up_getsp(), running_task(), filename, lineno); #endif - _up_assert(); + riscv_assert(); } diff --git a/arch/risc-v/src/rv32im/riscv_assert.c b/arch/risc-v/src/rv32im/riscv_assert.c deleted file mode 100644 index 115407a2a45..00000000000 --- a/arch/risc-v/src/rv32im/riscv_assert.c +++ /dev/null @@ -1,487 +0,0 @@ -/**************************************************************************** - * arch/risc-v/src/rv32im/riscv_assert.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 "riscv_arch.h" -#include "sched/sched.h" -#include "riscv_internal.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* USB trace dumping */ - -#ifndef CONFIG_USBDEV_TRACE -# undef CONFIG_ARCH_USBDUMP -#endif - -#ifndef CONFIG_BOARD_RESET_ON_ASSERT -# define CONFIG_BOARD_RESET_ON_ASSERT 0 -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: riscv_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void riscv_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]); - } -} -#endif - -/**************************************************************************** - * Name: riscv_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void riscv_registerdump(volatile uint32_t *regs) -{ - /* Are user registers available from interrupt processing? */ - - _alert("EPC:%08x\n", regs[REG_EPC]); - _alert("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]); - _alert("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]); - _alert("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]); - _alert("S8:%08x S9:%08x S10:%08x S11:%08x\n", - regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); -#ifdef RISCV_SAVE_GP - _alert("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 - _alert("SP:%08x FP:%08x TP:%08x RA:%08x\n", - regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); -#endif -} -#else -# define riscv_registerdump(reg) -#endif - -/**************************************************************************** - * Name: riscv_dump_task - ****************************************************************************/ - -static void riscv_dump_task(struct tcb_s *tcb, void *arg) -{ -#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 - - /* Dump interesting properties of this task */ - - _alert(" %4d %4d" -#ifdef CONFIG_STACK_COLORATION - " %7lu" -#endif - " %7lu" -#ifdef CONFIG_STACK_COLORATION - " %3" PRId32 ".%1" PRId32 "%%%c" -#endif -#ifdef CONFIG_SCHED_CPULOAD - " %3" PRId32 ".%01" PRId32 "%%" -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - " %s" -#endif - "\n", - tcb->pid, tcb->sched_priority, -#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 -#endif - ); -} - -/**************************************************************************** - * 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_STACK_COLORATION - " USED" -#endif - " STACK" -#ifdef CONFIG_STACK_COLORATION - " FILLED " -#endif -#ifdef CONFIG_SCHED_CPULOAD - " CPU" -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - " COMMAND" -#endif - "\n"); - -#if CONFIG_ARCH_INTERRUPTSTACK > 15 - _alert(" ---- ----" -# ifdef CONFIG_STACK_COLORATION - " %7lu" -# endif - " %7lu" -# ifdef CONFIG_STACK_COLORATION - " %3" PRId32 ".%1" PRId32 "%%%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(riscv_dump_task, NULL); -#ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(riscv_dump_backtrace, NULL); -#endif -} - -/**************************************************************************** - * Name: riscv_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void riscv_dumpstate(void) -{ - struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 15 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the registers (if available) */ - - riscv_registerdump(CURRENT_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 > 15 - istackbase = (uint32_t)&g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~15); - - /* 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 */ - - riscv_stackdump(sp, istackbase + istacksize); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - - sp = (uint32_t)&g_intstacktop; - _alert("sp: %08x\n", sp); - } - else if (g_current_regs) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - riscv_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) - { - riscv_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - riscv_stackdump(ustackbase, ustackbase + ustacksize); - } -} -#else -# define riscv_dumpstate() -#endif - -/**************************************************************************** - * Name: riscv_assert - ****************************************************************************/ - -static void riscv_assert(void) -{ - /* Flush any buffered SYSLOG data */ - - syslog_flush(); - - /* Are we in an interrupt handler or the idle task? */ - - if (g_current_regs || running_task()->flink == NULL) - { - up_irq_save(); - for (; ; ) - { -#if CONFIG_BOARD_RESET_ON_ASSERT >= 1 - board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE); -#endif -#ifdef CONFIG_ARCH_LEDS - board_autoled_on(LED_PANIC); - up_mdelay(250); - board_autoled_off(LED_PANIC); - up_mdelay(250); -#endif - } - } - else - { -#if CONFIG_BOARD_RESET_ON_ASSERT >= 2 - board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE); -#endif - } -} - -/**************************************************************************** - * Name: assert_tracecallback - ****************************************************************************/ - -#ifdef CONFIG_ARCH_USBDUMP -static int usbtrace_syslog(const char *fmt, ...) -{ - va_list ap; - - /* Let vsyslog do the real work */ - - va_start(ap, fmt); - vsyslog(LOG_EMERG, fmt, ap); - va_end(ap); - return OK; -} - -static int assert_tracecallback(struct usbtrace_s *trace, void *arg) -{ - usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); - return 0; -} -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - - /* Flush any buffered SYSLOG data (from prior to the assertion) */ - - syslog_flush(); - -#if CONFIG_TASK_NAME_SIZE > 0 - _alert("Assertion failed at file:%s line: %d task: %s\n", - filename, lineno, running_task()->name); -#else - _alert("Assertion failed at file:%s line: %d\n", - filename, lineno); -#endif - - riscv_dumpstate(); - - /* Dump the state of all tasks (if available) */ - - riscv_showtasks(); - -#ifdef CONFIG_ARCH_USBDUMP - /* Dump USB trace data */ - - usbtrace_enumerate(assert_tracecallback, NULL); -#endif - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - -#ifdef CONFIG_BOARD_CRASHDUMP - board_crashdump(up_getsp(), running_task(), filename, lineno); -#endif - - riscv_assert(); -}