source: rtems/cpukit/score/cpu/arm/arm-exception-frame-print.c

Last change on this file was 0e4e9dd4, checked in by Karel Gardas <karel@…>, on 03/15/23 at 18:15:51

score/arm: improve printed exception information for Cortex-Mx CPUs

Sponsored-By: Precidata

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreCPUARM
7 *
8 * @brief This source file contains the implementation of
9 *   _CPU_Exception_frame_print().
10 */
11
12/*
13 * Copyright (C) 2012, 2013 embedded brains GmbH & Co. KG
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifdef HAVE_CONFIG_H
38#include "config.h"
39#endif
40
41#include <inttypes.h>
42
43#include <rtems/score/cpu.h>
44#if defined(ARM_MULTILIB_ARCH_V7M)
45#include <rtems/score/armv7m.h>
46#endif
47#include <rtems/bspIo.h>
48
49static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
50{
51#ifdef ARM_MULTILIB_VFP
52  if ( vfp_context != NULL ) {
53    const uint64_t *dx = &vfp_context->register_d0;
54    int i;
55
56    printk(
57      "FPEXC = 0x%08" PRIx32 "\nFPSCR = 0x%08" PRIx32 "\n",
58      vfp_context->register_fpexc,
59      vfp_context->register_fpscr
60    );
61
62#if defined(ARM_MULTILIB_VFP_D32)
63    int regcount = 32;
64#elif defined(ARM_MULTILIB_VFP_D16)
65    int regcount = 16;
66#else
67    int regcount = 0;
68#endif
69    for ( i = 0; i < regcount; ++i ) {
70      uint32_t low = (uint32_t) dx[i];
71      uint32_t high = (uint32_t) (dx[i] >> 32);
72
73      printk( "D%02i = 0x%08" PRIx32 "%08" PRIx32 "\n", i, high, low );
74    }
75  }
76#endif
77}
78
79static void _ARM_Cortex_M_fault_info_print( void )
80{
81#if defined(ARM_MULTILIB_ARCH_V7M)
82  /*
83   * prints content of additional debugging registers
84   * available on Cortex-Mx where x > 0 cores.
85   */
86  uint32_t cfsr = _ARMV7M_SCB->cfsr;
87  uint8_t mmfsr = ARMV7M_SCB_CFSR_MMFSR_GET( cfsr );
88  uint8_t bfsr = ( ARMV7M_SCB_CFSR_BFSR_GET( cfsr ) >> 8 );
89  uint16_t ufsr = ( ARMV7M_SCB_CFSR_UFSR_GET( cfsr ) >> 16 );
90  uint32_t hfsr = _ARMV7M_SCB->hfsr;
91  if ( mmfsr > 0 ) {
92    printk( "MMFSR= 0x%08" PRIx32 " (memory fault)\n", mmfsr );
93    if ( ( mmfsr & 0x1 ) != 0 ) {
94      printk( "  IACCVIOL   : 1  (instruction access violation)\n" );
95    }
96    if ( ( mmfsr & 0x2 ) != 0 ) {
97      printk( "  DACCVIOL   : 1  (data access violation)\n" );
98    }
99    if ( (mmfsr & 0x8 ) != 0 ) {
100      printk(
101        "  MUNSTKERR  : 1  (fault on unstacking on exception return)\n"
102      );
103    }
104    if ( ( mmfsr & 0x10 ) != 0 ) {
105      printk( "  MSTKERR    : 1  (fault on stacking on exception entry)\n" );
106    }
107    if ( (mmfsr & 0x20 ) != 0 ) {
108      printk( "  MLSPERR    : 1  (fault during lazy FP stack preservation)\n" );
109    }
110    if ( (mmfsr & 0x80 ) != 0 ) {
111      printk(
112        "  MMFARVALID : 1 -> 0x%08" PRIx32 " (error address)\n",
113        _ARMV7M_SCB->mmfar
114      );
115    }
116    else {
117      printk( "  MMFARVALID : 0  (undetermined error address)\n" );
118    }
119  }
120  if ( bfsr > 0 ) {
121    printk( "BFSR = 0x%08" PRIx32 " (bus fault)\n", bfsr );
122    if ( ( bfsr & 0x1 ) != 0 ) {
123      printk( "  IBUSERR    : 1  (instruction fetch error)\n" );
124    }
125    if ( (bfsr & 0x2 ) != 0 ) {
126      printk(
127        "  PRECISERR  : 1  (data bus error with known exact location)\n"
128      );
129    }
130    if ( ( bfsr & 0x4) != 0 ) {
131      printk(
132        "  IMPRECISERR: 1  (data bus error without known exact location)\n"
133      );
134    }
135    if ( (bfsr & 0x8 ) != 0 ) {
136      printk(
137        "  UNSTKERR   : 1  (fault on unstacking on exception return)\n"
138      );
139    }
140    if ( ( bfsr & 0x10 ) != 0 ) {
141      printk( "  STKERR     : 1  (fault on stacking on exception entry)\n" );
142    }
143    if ( ( bfsr & 0x20 ) != 0 ) {
144      printk( "  LSPERR     : 1  (fault during lazy FP stack preservation)\n" );
145    }
146    if ( (bfsr & 0x80 ) != 0 ) {
147      printk(
148        "  BFARVALID  : 1 -> 0x%08" PRIx32 "  (error address)\n",
149        _ARMV7M_SCB->bfar
150      );
151    }
152    else {
153      printk( "  BFARVALID  : 0  (undetermined error address)\n" );
154    }
155  }
156  if ( ufsr > 0 ) {
157    printk( "UFSR = 0x%08" PRIx32 " (usage fault)\n", ufsr);
158    if ( (ufsr & 0x1 ) != 0 ) {
159      printk( "  UNDEFINSTR : 1  (undefined instruction issued)\n");
160    }
161    if ( (ufsr & 0x2 ) != 0 ) {
162      printk(
163        "  INVSTATE   : 1"
164        "  (invalid instruction state"
165        " (Thumb not set in EPSR or invalid IT state in EPSR))\n"
166      );
167    }
168    if ( (ufsr & 0x4 ) != 0 ) {
169      printk( "  INVPC      : 1  (integrity check failure on EXC_RETURN)\n" );
170    }
171    if ( (ufsr & 0x8 ) != 0 ) {
172      printk(
173        "  NOCP       : 1"
174        "  (coprocessor instruction issued"
175        " but coprocessor disabled or non existent)\n"
176      );
177    }
178    if ( ( ufsr & 0x100) != 0 ) {
179      printk( "  UNALIGNED  : 1  (unaligned access operation occurred)\n" );
180    }
181    if ( ( ufsr & 0x200) != 0 ) {
182      printk( "  DIVBYZERO  : 1  (division by zero)" );
183    }
184  }
185  if ( (hfsr & (
186    ARMV7M_SCB_HFSR_VECTTBL_MASK
187    | ARMV7M_SCB_HFSR_DEBUGEVT_MASK
188    | ARMV7M_SCB_HFSR_FORCED_MASK
189    ) ) != 0 ) {
190    printk( "HFSR = 0x%08" PRIx32 " (hard fault)\n", hfsr );
191    if ( (hfsr & ARMV7M_SCB_HFSR_VECTTBL_MASK ) != 0 ) {
192      printk(
193        "  VECTTBL    : 1  (error in address located in vector table)\n"
194      );
195    }
196    if ( (hfsr & ARMV7M_SCB_HFSR_FORCED_MASK ) != 0 ) {
197      printk(
198        "  FORCED     : 1  (configurable fault escalated to hard fault)\n"
199      );
200    }
201    if ( (hfsr & ARMV7M_SCB_HFSR_DEBUGEVT_MASK ) != 0 ) {
202      printk(
203        "  DEBUGEVT   : 1  (debug event occurred with debug system disabled)\n"
204      );
205    }
206  }
207#endif
208}
209void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
210{
211  printk(
212    "\n"
213    "R0   = 0x%08" PRIx32 " R8  = 0x%08" PRIx32 "\n"
214    "R1   = 0x%08" PRIx32 " R9  = 0x%08" PRIx32 "\n"
215    "R2   = 0x%08" PRIx32 " R10 = 0x%08" PRIx32 "\n"
216    "R3   = 0x%08" PRIx32 " R11 = 0x%08" PRIx32 "\n"
217    "R4   = 0x%08" PRIx32 " R12 = 0x%08" PRIx32 "\n"
218    "R5   = 0x%08" PRIx32 " SP  = 0x%08" PRIx32 "\n"
219    "R6   = 0x%08" PRIx32 " LR  = 0x%08" PRIxPTR "\n"
220    "R7   = 0x%08" PRIx32 " PC  = 0x%08" PRIxPTR "\n"
221#if defined(ARM_MULTILIB_ARCH_V4)
222    "CPSR = 0x%08" PRIx32 " "
223#elif defined(ARM_MULTILIB_ARCH_V7M)
224    "XPSR = 0x%08" PRIx32 " "
225#endif
226    "VEC = 0x%08" PRIxPTR "\n",
227    frame->register_r0,
228    frame->register_r8,
229    frame->register_r1,
230    frame->register_r9,
231    frame->register_r2,
232    frame->register_r10,
233    frame->register_r3,
234    frame->register_r11,
235    frame->register_r4,
236    frame->register_r12,
237    frame->register_r5,
238    frame->register_sp,
239    frame->register_r6,
240    (intptr_t) frame->register_lr,
241    frame->register_r7,
242    (intptr_t) frame->register_pc,
243#if defined(ARM_MULTILIB_ARCH_V4)
244    frame->register_cpsr,
245#elif defined(ARM_MULTILIB_ARCH_V7M)
246    frame->register_xpsr,
247#endif
248    (intptr_t) frame->vector
249  );
250
251  _ARM_VFP_context_print( frame->vfp_context );
252  _ARM_Cortex_M_fault_info_print();
253}
Note: See TracBrowser for help on using the repository browser.