From cf2dfa8985d502eef7446061e989a43d2b473f14 Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Mon, 27 Dec 2021 21:47:09 +0800 Subject: [PATCH] arch/arm/assert: move the arm_assert to common code Signed-off-by: chao.an --- arch/arm/src/arm/arm_assert.c | 509 ---------------- arch/arm/src/armv6-m/arm_assert.c | 397 ------------ arch/arm/src/armv7-a/arm_assert.c | 568 ------------------ arch/arm/src/armv7-m/arm_assert.c | 528 ---------------- arch/arm/src/armv7-r/arm_assert.c | 534 ---------------- arch/arm/src/{armv8-m => common}/arm_assert.c | 222 ++++--- 6 files changed, 106 insertions(+), 2652 deletions(-) delete mode 100644 arch/arm/src/arm/arm_assert.c delete mode 100644 arch/arm/src/armv6-m/arm_assert.c delete mode 100644 arch/arm/src/armv7-a/arm_assert.c delete mode 100644 arch/arm/src/armv7-m/arm_assert.c delete mode 100644 arch/arm/src/armv7-r/arm_assert.c rename arch/arm/src/{armv8-m => common}/arm_assert.c (76%) diff --git a/arch/arm/src/arm/arm_assert.c b/arch/arm/src/arm/arm_assert.c deleted file mode 100644 index c542acaa84..0000000000 --- a/arch/arm/src/arm/arm_assert.c +++ /dev/null @@ -1,509 +0,0 @@ -/**************************************************************************** - * arch/arm/src/arm/arm_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 - -#include "arm_arch.h" -#include "sched/sched.h" -#include "arm_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 Data - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void arm_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: arm_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void arm_registerdump(void) -{ - volatile uint32_t *regs = CURRENT_REGS; - - /* Are user registers available from interrupt processing? */ - - if (regs == NULL) - { - /* No.. capture user registers by hand */ - - arm_saveusercontext(s_last_regs); - regs = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("R0: %08x R1: %08x R2: %08x R3: %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); - _alert("R4: %08x R5: %08x R6: %08x " -#ifdef CONFIG_ARM_THUMB - "FP: %08x\n", -#else - "R7: %08x\n", -#endif - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08x SB: %08x SL: %08x " -#ifdef CONFIG_ARM_THUMB - "R11: %08x\n", -#else - " FP: %08x\n", -#endif - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); - _alert("IP: %08x SP: %08x LR: %08x PC: %08x\n", - regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); - - _alert("CPSR: %08x\n", regs[REG_CPSR]); -} -#endif - -/**************************************************************************** - * Name: arm_dump_task - ****************************************************************************/ - -static void arm_dump_task(FAR struct tcb_s *tcb, FAR 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: arm_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void arm_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: arm_showtasks - ****************************************************************************/ - -static inline 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_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 > 7 - _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 & ~7) -# ifdef CONFIG_STACK_COLORATION - , 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: assert_tracecallback - ****************************************************************************/ - -#ifdef CONFIG_ARCH_USBDUMP -static int usbtrace_syslog(FAR 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(FAR struct usbtrace_s *trace, FAR void *arg) -{ - usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); - return 0; -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_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) */ - - arm_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 */ - - _alert("Interrupt Stack\n", sp); - arm_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - arm_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("User sp: %08x\n", sp); - } - - /* Show user stack info */ - - _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) - { - arm_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - arm_stackdump(ustackbase, ustackbase + ustacksize); - } - - /* Dump the state of all tasks (if available) */ - - arm_showtasks(); - -#ifdef CONFIG_ARCH_USBDUMP - /* Dump USB trace data */ - - usbtrace_enumerate(assert_tracecallback, NULL); -#endif -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Name: _up_assert - ****************************************************************************/ - -static void _up_assert(void) -{ - /* Flush any buffered SYSLOG data */ - - syslog_flush(); - - /* Are we in an interrupt handler or the idle task? */ - - if (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 - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - - /* Flush any buffered SYSLOG data (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 - - up_dumpstate(); - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - -#ifdef CONFIG_BOARD_CRASHDUMP - board_crashdump(up_getsp(), running_task(), filename, lineno); -#endif - - _up_assert(); -} diff --git a/arch/arm/src/armv6-m/arm_assert.c b/arch/arm/src/armv6-m/arm_assert.c deleted file mode 100644 index 70bb9a906d..0000000000 --- a/arch/arm/src/armv6-m/arm_assert.c +++ /dev/null @@ -1,397 +0,0 @@ -/**************************************************************************** - * arch/arm/src/armv6-m/arm_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 "arm_arch.h" -#include "sched/sched.h" -#include "arm_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 Data - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void arm_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: arm_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void arm_registerdump(FAR volatile uint32_t *regs) -{ - /* Are user registers available from interrupt processing? */ - - if (regs == NULL) - { - /* No.. capture user registers by hand */ - - arm_saveusercontext(s_last_regs); - regs = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("R0: %08x R1: %08x R2: %08x R3: %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); - _alert("R4: %08x R5: %08x R6: %08x FP: %08x\n", - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08x SB: %08x SL: %08x R11: %08x\n", - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); - _alert("IP: %08x SP: %08x LR: %08x PC: %08x\n", - 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 -} -#else -# define arm_registerdump(regs) -#endif - -/**************************************************************************** - * Name: up_taskdump - ****************************************************************************/ - -#if defined(CONFIG_STACK_COLORATION) || defined(CONFIG_SCHED_BACKTRACE) -static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg) -{ - /* Dump interesting properties of this task */ - - _alert( -#if CONFIG_TASK_NAME_SIZE > 0 - "%s: " -#endif - "PID=%d " -#ifdef CONFIG_STACK_COLORATION - "Stack Used=%lu of %lu\n", -#else - "Stack=%lu\n", -#endif -#if CONFIG_TASK_NAME_SIZE > 0 - tcb->name, -#endif - tcb->pid, -#ifdef CONFIG_STACK_COLORATION - (unsigned long)up_check_tcbstack(tcb), -#endif - (unsigned long)tcb->adj_stack_size); - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(tcb->pid); -#endif - - /* Dump the registers */ - - arm_registerdump(tcb->xcp.regs); -} - -/**************************************************************************** - * Name: up_showtasks - ****************************************************************************/ - -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: assert_tracecallback - ****************************************************************************/ - -#ifdef CONFIG_ARCH_USBDUMP -static int usbtrace_syslog(FAR 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(FAR struct usbtrace_s *trace, FAR void *arg) -{ - usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); - return 0; -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_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 - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the registers (if available) */ - - arm_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 > 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 */ - - arm_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - arm_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) - { - arm_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within allocated stack\n"); - arm_stackdump(ustackbase, ustackbase + ustacksize); - } - - /* Dump the state of all tasks (if available) */ - - up_showtasks(); - -#ifdef CONFIG_ARCH_USBDUMP - /* Dump USB trace data */ - - usbtrace_enumerate(assert_tracecallback, NULL); -#endif -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Name: _up_assert - ****************************************************************************/ - -static void _up_assert(void) -{ - /* Flush any buffered SYSLOG data */ - - syslog_flush(); - - /* Are we in an interrupt handler or the idle task? */ - - if (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 - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - - /* Flush any buffered SYSLOG data (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 - - up_dumpstate(); - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - -#ifdef CONFIG_BOARD_CRASHDUMP - board_crashdump(up_getsp(), running_task(), filename, lineno); -#endif - - _up_assert(); -} diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c deleted file mode 100644 index a87828cc98..0000000000 --- a/arch/arm/src/armv7-a/arm_assert.c +++ /dev/null @@ -1,568 +0,0 @@ -/**************************************************************************** - * arch/arm/src/armv7-a/arm_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 "sched/sched.h" -#include "irq/irq.h" - -#include "arm_arch.h" -#include "arm_internal.h" -#include "chip.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 Data - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void arm_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: arm_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void arm_registerdump(FAR volatile uint32_t *regs) -{ - /* Are user registers available from interrupt processing? */ - - if (regs == NULL) - { - /* No.. capture user registers by hand */ - - arm_saveusercontext(s_last_regs); - regs = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("R0: %08x R1: %08x R2: %08x R3: %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); - _alert("R4: %08x R5: %08x R6: %08x " -#ifdef CONFIG_ARM_THUMB - "FP: %08x\n", -#else - "R7: %08x\n", -#endif - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08x SB: %08x SL: %08x " -#ifdef CONFIG_ARM_THUMB - "R11: %08x\n", -#else - " FP: %08x\n", -#endif - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); - _alert("IP: %08x SP: %08x LR: %08x PC: %08x\n", - regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); - - _alert("CPSR: %08x\n", regs[REG_CPSR]); -} -#else -# define arm_registerdump(regs) -#endif - -/**************************************************************************** - * Name: arm_dump_task - ****************************************************************************/ - -static void arm_dump_task(FAR struct tcb_s *tcb, FAR 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: arm_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void arm_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: arm_showtasks - ****************************************************************************/ - -static inline 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_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 > 7 - _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 & ~7) -# ifdef CONFIG_STACK_COLORATION - , 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: assert_tracecallback - ****************************************************************************/ - -#ifdef CONFIG_ARCH_USBDUMP -static int usbtrace_syslog(FAR 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(FAR struct usbtrace_s *trace, FAR void *arg) -{ - usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); - return 0; -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) -{ - FAR struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - uint32_t istackbase; - uint32_t istacksize; -#endif -#ifdef CONFIG_ARCH_KERNEL_STACK - uint32_t kstackbase = 0; -#endif - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the CPU registers (if available) */ - - arm_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; - - _alert("Current sp: %08x\n", sp); - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - /* Get the limits on the interrupt stack memory */ - -#ifdef CONFIG_SMP - istackbase = (uint32_t)arm_intstack_alloc(); -#else - istackbase = (uint32_t)&g_intstackalloc; -#endif - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7); - - /* Show interrupt stack info */ - - _alert("Interrupt stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); -#endif - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); - -#ifdef CONFIG_ARCH_KERNEL_STACK - /* Does this thread have a kernel stack allocated? */ - - if (rtcb->xcp.kstack) - { - kstackbase = (uint32_t)rtcb->xcp.kstack; - - _alert("Kernel stack:\n"); - _alert(" base: %08x\n", kstackbase); - _alert(" size: %08x\n", CONFIG_ARCH_KERNEL_STACKSIZE); - } -#endif - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - /* Does the current stack pointer lie within the interrupt stack? */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - _alert("Interrupt Stack\n", sp); - arm_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - arm_stackdump(istackbase, istackbase + istacksize); - } -#endif - - /* 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("User sp: %08x\n", sp); - } - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - _alert("User Stack\n", sp); - arm_stackdump(sp, ustackbase + ustacksize); - } - -#ifdef CONFIG_ARCH_KERNEL_STACK - /* Dump the user stack if the stack pointer lies within the allocated - * kernel stack memory. - */ - - else if (sp >= kstackbase && - sp < kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE) - { - _alert("Kernel Stack\n", sp); - arm_stackdump(sp, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); - } -#endif - else - { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - arm_stackdump(ustackbase, ustackbase + ustacksize); -#ifdef CONFIG_ARCH_KERNEL_STACK - arm_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); -#endif - } - -#ifdef CONFIG_SMP - /* Show the CPU number */ - - _alert("CPU%d:\n", up_cpu_index()); -#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 -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Name: _up_assert - ****************************************************************************/ - -static void _up_assert(void) -{ - /* Flush any buffered SYSLOG data */ - - syslog_flush(); - - /* Are we in an interrupt handler or the idle task? */ - - if (CURRENT_REGS || running_task()->flink == NULL) - { - /* Disable interrupts on this CPU */ - - up_irq_save(); - - for (; ; ) - { -#ifdef CONFIG_SMP - /* Try (again) to stop activity on other CPUs */ - - spin_trylock(&g_cpu_irqlock); -#endif - -#if CONFIG_BOARD_RESET_ON_ASSERT >= 1 - board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE); -#endif -#ifdef CONFIG_ARCH_LEDS - /* FLASH LEDs a 2Hz */ - - 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 - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - - /* Flush any buffered SYSLOG data (prior to the assertion) */ - - syslog_flush(); - -#ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 - _alert("Assertion failed CPU%d at file:%s line: %d task: %s\n", - up_cpu_index(), filename, lineno, running_task()->name); -#else - _alert("Assertion failed CPU%d at file:%s line: %d\n", - up_cpu_index(), filename, lineno); -#endif -#else -#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 -#endif - - up_dumpstate(); - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - -#ifdef CONFIG_BOARD_CRASHDUMP - board_crashdump(up_getsp(), running_task(), filename, lineno); -#endif - - _up_assert(); -} diff --git a/arch/arm/src/armv7-m/arm_assert.c b/arch/arm/src/armv7-m/arm_assert.c deleted file mode 100644 index 5030bdea95..0000000000 --- a/arch/arm/src/armv7-m/arm_assert.c +++ /dev/null @@ -1,528 +0,0 @@ -/**************************************************************************** - * arch/arm/src/armv7-m/arm_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 "sched/sched.h" -#include "irq/irq.h" - -#include "arm_arch.h" -#include "arm_internal.h" -#include "chip.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 Data - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void arm_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: arm_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void arm_registerdump(FAR volatile uint32_t *regs) -{ - /* Are user registers available from interrupt processing? */ - - if (regs == NULL) - { - /* No.. capture user registers by hand */ - - arm_saveusercontext(s_last_regs); - regs = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("R0: %08x R1: %08x R2: %08x R3: %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); - _alert("R4: %08x R5: %08x R6: %08x FP: %08x\n", - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08x SB: %08x SL: %08x R11: %08x\n", - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); - _alert("IP: %08x SP: %08x LR: %08x PC: %08x\n", - regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); - -#ifdef CONFIG_ARMV7M_USEBASEPRI - _alert("xPSR: %08x BASEPRI: %08x CONTROL: %08x\n", - regs[REG_XPSR], regs[REG_BASEPRI], getcontrol()); -#else - _alert("xPSR: %08x PRIMASK: %08x CONTROL: %08x\n", - regs[REG_XPSR], regs[REG_PRIMASK], getcontrol()); -#endif - -#ifdef CONFIG_BUILD_PROTECTED - _alert("EXC_RETURN: %08x\n", regs[REG_EXC_RETURN]); -#endif -} -#endif - -/**************************************************************************** - * Name: up_taskdump - ****************************************************************************/ - -static void up_dump_task(FAR struct tcb_s *tcb, FAR 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: up_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void up_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: up_showtasks - ****************************************************************************/ - -static inline void up_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_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 > 7 - _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 & ~7) -# ifdef CONFIG_STACK_COLORATION - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') -# endif - ); -#endif - - nxsched_foreach(up_dump_task, NULL); -#ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(up_dump_backtrace, NULL); -#endif -} - -/**************************************************************************** - * Name: assert_tracecallback - ****************************************************************************/ - -#ifdef CONFIG_ARCH_USBDUMP -static int usbtrace_syslog(FAR 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(FAR struct usbtrace_s *trace, FAR void *arg) -{ - usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); - return 0; -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) -{ - FAR struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - uint32_t istackbase; - uint32_t istacksize; -#endif - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the registers (if available) */ - - arm_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; - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - /* Get the limits on the interrupt stack memory */ - -#ifdef CONFIG_SMP - istackbase = (uint32_t)arm_intstack_alloc(); -#else - istackbase = (uint32_t)&g_intstackalloc; -#endif - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7); - - /* 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 */ - - arm_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - arm_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); -#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) - { - arm_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - arm_stackdump(ustackbase, ustackbase + ustacksize); - } - -#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(); - -#ifdef CONFIG_ARCH_USBDUMP - /* Dump USB trace data */ - - usbtrace_enumerate(assert_tracecallback, NULL); -#endif -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Name: _up_assert - ****************************************************************************/ - -static void _up_assert(void) -{ - /* Flush any buffered SYSLOG data */ - - syslog_flush(); - - /* Are we in an interrupt handler or the idle task? */ - - if (CURRENT_REGS || (running_task())->flink == NULL) - { - up_irq_save(); - for (; ; ) - { -#ifdef CONFIG_SMP - /* Try (again) to stop activity on other CPUs */ - - spin_trylock(&g_cpu_irqlock); -#endif - -#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 - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - - /* Flush any buffered SYSLOG data (prior to the assertion) */ - - syslog_flush(); - -#ifdef CONFIG_SMP -#if CONFIG_TASK_NAME_SIZE > 0 - _alert("Assertion failed CPU%d at file:%s line: %d task: %s\n", - up_cpu_index(), filename, lineno, running_task()->name); -#else - _alert("Assertion failed CPU%d at file:%s line: %d\n", - up_cpu_index(), filename, lineno); -#endif -#else -#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 -#endif - - up_dumpstate(); - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - -#ifdef CONFIG_BOARD_CRASHDUMP - board_crashdump(up_getsp(), running_task(), filename, lineno); -#endif - - _up_assert(); -} diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c deleted file mode 100644 index 77bb59e979..0000000000 --- a/arch/arm/src/armv7-r/arm_assert.c +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** - * arch/arm/src/armv7-r/arm_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 "arm_arch.h" -#include "sched/sched.h" -#include "arm_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 Data - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_stackdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void arm_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: arm_registerdump - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static inline void arm_registerdump(FAR volatile uint32_t *regs) -{ - /* Are user registers available from interrupt processing? */ - - if (regs == NULL) - { - /* No.. capture user registers by hand */ - - arm_saveusercontext(s_last_regs); - regs = s_last_regs; - } - - /* Dump the interrupt registers */ - - _alert("R0: %08x R1: %08x R2: %08x R3: %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); - _alert("R4: %08x R5: %08x R6: %08x " -#ifdef CONFIG_ARM_THUMB - "FP: %08x\n", -#else - "R7: %08x\n", -#endif - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - _alert("R8: %08x SB: %08x SL: %08x " -#ifdef CONFIG_ARM_THUMB - "R11: %08x\n", -#else - " FP: %08x\n", -#endif - regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); - _alert("IP: %08x SP: %08x LR: %08x PC: %08x\n", - regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); - - _alert("CPSR: %08x\n", regs[REG_CPSR]); -} -#else -# define arm_registerdump(regs) -#endif - -/**************************************************************************** - * Name: arm_dump_task - ****************************************************************************/ - -static void arm_dump_task(FAR struct tcb_s *tcb, FAR 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: arm_dump_backtrace - ****************************************************************************/ - -#ifdef CONFIG_SCHED_BACKTRACE -static void arm_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) -{ - /* Show back trace */ - - sched_dumpstack(tcb->pid); -} -#endif - -/**************************************************************************** - * Name: arm_showtasks - ****************************************************************************/ - -static inline 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_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 > 7 - _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 & ~7) -# ifdef CONFIG_STACK_COLORATION - , 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: assert_tracecallback - ****************************************************************************/ - -#ifdef CONFIG_ARCH_USBDUMP -static int usbtrace_syslog(FAR 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(FAR struct usbtrace_s *trace, FAR void *arg) -{ - usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); - return 0; -} -#endif - -/**************************************************************************** - * Name: up_dumpstate - ****************************************************************************/ - -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) -{ - FAR struct tcb_s *rtcb = running_task(); - uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - uint32_t istackbase; - uint32_t istacksize; -#endif -#ifdef CONFIG_ARCH_KERNEL_STACK - uint32_t kstackbase = 0; -#endif - - /* Show back trace */ - -#ifdef CONFIG_SCHED_BACKTRACE - sched_dumpstack(rtcb->pid); -#endif - - /* Dump the registers (if available) */ - - arm_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; - - _alert("Current sp: %08x\n", sp); - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - /* Get the limits on the interrupt stack memory */ - - istackbase = (uint32_t)&g_intstackalloc; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7); - - /* Show interrupt stack info */ - - _alert("Interrupt stack:\n"); - _alert(" base: %08x\n", istackbase); - _alert(" size: %08x\n", istacksize); -#endif - - /* Show user stack info */ - - _alert("User stack:\n"); - _alert(" base: %08x\n", ustackbase); - _alert(" size: %08x\n", ustacksize); - -#ifdef CONFIG_ARCH_KERNEL_STACK - /* Does this thread have a kernel stack allocated? */ - - if (rtcb->xcp.kstack) - { - kstackbase = (uint32_t)rtcb->xcp.kstack; - - _alert("Kernel stack:\n"); - _alert(" base: %08x\n", kstackbase); - _alert(" size: %08x\n", CONFIG_ARCH_KERNEL_STACKSIZE); - } -#endif - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - /* Does the current stack pointer lie within the interrupt stack? */ - - if (sp >= istackbase && sp < istackbase + istacksize) - { - /* Yes.. dump the interrupt stack */ - - _alert("Interrupt Stack\n", sp); - arm_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - arm_stackdump(istackbase, istackbase + istacksize); - } -#endif - - /* 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("User sp: %08x\n", sp); - } - - /* Dump the user stack if the stack pointer lies within the allocated user - * stack memory. - */ - - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - _alert("User Stack\n", sp); - arm_stackdump(sp, ustackbase + ustacksize); - } - -#ifdef CONFIG_ARCH_KERNEL_STACK - /* Dump the user stack if the stack pointer lies within the allocated - * kernel stack memory. - */ - - else if (sp >= kstackbase && - sp < kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE) - { - _alert("Kernel Stack\n", sp); - arm_stackdump(sp, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); - } -#endif - else - { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - arm_stackdump(ustackbase, ustackbase + ustacksize); -#ifdef CONFIG_ARCH_KERNEL_STACK - arm_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE); -#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 -} -#else -# define up_dumpstate() -#endif - -/**************************************************************************** - * Name: _up_assert - ****************************************************************************/ - -static void _up_assert(void) -{ - /* Flush any buffered SYSLOG data */ - - syslog_flush(); - - /* Are we in an interrupt handler or the idle task? */ - - if (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 - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_assert - ****************************************************************************/ - -void up_assert(const char *filename, int lineno) -{ - board_autoled_on(LED_ASSERTION); - - /* Flush any buffered SYSLOG data (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 - - up_dumpstate(); - - /* Flush any buffered SYSLOG data (from the above) */ - - syslog_flush(); - -#ifdef CONFIG_BOARD_CRASHDUMP - board_crashdump(up_getsp(), running_task(), filename, lineno); -#endif - - _up_assert(); -} diff --git a/arch/arm/src/armv8-m/arm_assert.c b/arch/arm/src/common/arm_assert.c similarity index 76% rename from arch/arm/src/armv8-m/arm_assert.c rename to arch/arm/src/common/arm_assert.c index 7f9b4a48ce..6c1abb768c 100644 --- a/arch/arm/src/armv8-m/arm_assert.c +++ b/arch/arm/src/common/arm_assert.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv8-m/arm_assert.c + * arch/arm/src/common/arm_assert.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -64,7 +64,6 @@ #ifdef CONFIG_ARCH_STACKDUMP static uint32_t s_last_regs[XCPTCONTEXT_REGS]; -#endif /**************************************************************************** * Private Functions @@ -74,7 +73,6 @@ static uint32_t s_last_regs[XCPTCONTEXT_REGS]; * Name: arm_stackdump ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP static void arm_stackdump(uint32_t sp, uint32_t stack_top) { uint32_t stack; @@ -91,14 +89,12 @@ static void arm_stackdump(uint32_t sp, uint32_t stack_top) ptr[4], ptr[5], ptr[6], ptr[7]); } } -#endif /**************************************************************************** * Name: arm_registerdump ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP -static inline void arm_registerdump(FAR volatile uint32_t *regs) +static void arm_registerdump(FAR volatile uint32_t *regs) { /* Are user registers available from interrupt processing? */ @@ -114,32 +110,40 @@ static inline void arm_registerdump(FAR volatile uint32_t *regs) _alert("R0: %08x R1: %08x R2: %08x R3: %08x\n", regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3]); +#ifdef CONFIG_ARM_THUMB _alert("R4: %08x R5: %08x R6: %08x FP: %08x\n", regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); _alert("R8: %08x SB: %08x SL: %08x R11: %08x\n", regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); +#else + _alert("R4: %08x R5: %08x R6: %08x R7: %08x\n", + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + _alert("R8: %08x SB: %08x SL: %08x FP: %08x\n", + regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11]); +#endif _alert("IP: %08x SP: %08x LR: %08x PC: %08x\n", regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); -#ifdef CONFIG_ARMV8M_USEBASEPRI +#if defined(REG_BASEPRI) _alert("xPSR: %08x BASEPRI: %08x CONTROL: %08x\n", regs[REG_XPSR], regs[REG_BASEPRI], getcontrol()); -#else +#elif defined(REG_PRIMASK) _alert("xPSR: %08x PRIMASK: %08x CONTROL: %08x\n", regs[REG_XPSR], regs[REG_PRIMASK], getcontrol()); +#elif defined(REG_CPSR) + _alert("CPSR: %08x\n", regs[REG_CPSR]); #endif -#ifdef CONFIG_BUILD_PROTECTED +#ifdef REG_EXC_RETURN _alert("EXC_RETURN: %08x\n", regs[REG_EXC_RETURN]); #endif } -#endif /**************************************************************************** - * Name: up_taskdump + * Name: arm_dump_task ****************************************************************************/ -static void up_dump_task(FAR struct tcb_s *tcb, FAR void *arg) +static void arm_dump_task(FAR struct tcb_s *tcb, FAR void *arg) { #ifdef CONFIG_STACK_COLORATION uint32_t stack_filled = 0; @@ -199,24 +203,24 @@ static void up_dump_task(FAR struct tcb_s *tcb, FAR void *arg) #endif (unsigned long)tcb->adj_stack_size #ifdef CONFIG_STACK_COLORATION - , stack_filled / 10, stack_filled % 10, - (stack_filled >= 10 * 80 ? '!' : ' ') + , stack_filled / 10, stack_filled % 10, + (stack_filled >= 10 * 80 ? '!' : ' ') #endif #ifdef CONFIG_SCHED_CPULOAD - , intpart, fracpart + , intpart, fracpart #endif #if CONFIG_TASK_NAME_SIZE > 0 - , tcb->name + , tcb->name #endif ); } /**************************************************************************** - * Name: up_dump_backtrace + * Name: arm_dump_backtrace ****************************************************************************/ #ifdef CONFIG_SCHED_BACKTRACE -static void up_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) +static void arm_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) { /* Show back trace */ @@ -225,10 +229,10 @@ static void up_dump_backtrace(FAR struct tcb_s *tcb, FAR void *arg) #endif /**************************************************************************** - * Name: up_showtasks + * Name: arm_showtasks ****************************************************************************/ -static inline void up_showtasks(void) +static void arm_showtasks(void) { #if CONFIG_ARCH_INTERRUPTSTACK > 7 # ifdef CONFIG_STACK_COLORATION @@ -290,9 +294,9 @@ static inline void up_showtasks(void) ); #endif - nxsched_foreach(up_dump_task, NULL); + nxsched_foreach(arm_dump_task, NULL); #ifdef CONFIG_SCHED_BACKTRACE - nxsched_foreach(up_dump_backtrace, NULL); + nxsched_foreach(arm_dump_backtrace, NULL); #endif } @@ -321,20 +325,42 @@ static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) #endif /**************************************************************************** - * Name: up_dumpstate + * Name: arm_dump_stack ****************************************************************************/ -#ifdef CONFIG_ARCH_STACKDUMP -static void up_dumpstate(void) +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: %08x\n", sp); + _alert(" base: %08x\n", base); + _alert(" size: %08x\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) + { + arm_stackdump(base, top); + } + } +} + +/**************************************************************************** + * Name: arm_dumpstate + ****************************************************************************/ + +static void arm_dumpstate(void) { FAR struct tcb_s *rtcb = running_task(); uint32_t sp = up_getsp(); - uint32_t ustackbase; - uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - uint32_t istackbase; - uint32_t istacksize; -#endif /* Show back trace */ @@ -346,87 +372,46 @@ static void up_dumpstate(void) arm_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; + /* Dump the irq stack */ #if CONFIG_ARCH_INTERRUPTSTACK > 7 - /* Get the limits on the interrupt stack memory */ - -#ifdef CONFIG_SMP - istackbase = (uint32_t)arm_intstack_alloc(); -#else - istackbase = (uint32_t)&g_intstackalloc; -#endif - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7); - - /* 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 */ - - arm_stackdump(sp, istackbase + istacksize); - } - else if (CURRENT_REGS) - { - _alert("ERROR: Stack pointer is not within the interrupt stack\n"); - arm_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). - */ + 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]; - _alert("sp: %08x\n", sp); } - - _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. - */ + /* Dump the user stack */ - if (sp >= ustackbase && sp < ustackbase + ustacksize) - { - arm_stackdump(sp, ustackbase + ustacksize); - } - else - { - _alert("ERROR: Stack pointer is not within the allocated stack\n"); - arm_stackdump(ustackbase, ustackbase + ustacksize); - } + 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_SMP - /* Show the CPU number */ - - _alert("CPU%d:\n", up_cpu_index()); +#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) */ - up_showtasks(); + arm_showtasks(); #ifdef CONFIG_ARCH_USBDUMP /* Dump USB trace data */ @@ -434,15 +419,13 @@ static void up_dumpstate(void) usbtrace_enumerate(assert_tracecallback, NULL); #endif } -#else -# define up_dumpstate() -#endif +#endif /* CONFIG_ARCH_STACKDUMP */ /**************************************************************************** - * Name: _up_assert + * Name: arm_assert ****************************************************************************/ -static void _up_assert(void) +static void arm_assert(void) { /* Flush any buffered SYSLOG data */ @@ -452,7 +435,10 @@ static void _up_assert(void) if (CURRENT_REGS || (running_task())->flink == NULL) { + /* Disable interrupts on this CPU */ + up_irq_save(); + for (; ; ) { #ifdef CONFIG_SMP @@ -465,6 +451,8 @@ static void _up_assert(void) board_reset(CONFIG_BOARD_ASSERT_RESET_VALUE); #endif #ifdef CONFIG_ARCH_LEDS + /* FLASH LEDs a 2Hz */ + board_autoled_on(LED_PANIC); up_mdelay(250); board_autoled_off(LED_PANIC); @@ -496,25 +484,27 @@ void up_assert(const char *filename, int lineno) syslog_flush(); + _alert("Assertion failed " #ifdef CONFIG_SMP + "CPU%d " +#endif + "at file:%s line: %d" #if CONFIG_TASK_NAME_SIZE > 0 - _alert("Assertion failed CPU%d at file:%s line: %d task: %s\n", - up_cpu_index(), filename, lineno, running_task()->name); -#else - _alert("Assertion failed CPU%d at file:%s line: %d\n", - up_cpu_index(), filename, lineno); + " task: %s" #endif -#else + "\n", +#ifdef CONFIG_SMP + up_cpu_index(), +#endif + filename, lineno #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 + , running_task()->name #endif + ); - up_dumpstate(); +#ifdef CONFIG_ARCH_STACKDUMP + arm_dumpstate(); +#endif /* Flush any buffered SYSLOG data (from the above) */ @@ -524,5 +514,5 @@ void up_assert(const char *filename, int lineno) board_crashdump(up_getsp(), running_task(), filename, lineno); #endif - _up_assert(); + arm_assert(); }