Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:23

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreCPUAArch64
0007  *
0008  * @brief Implementation of _CPU_Exception_frame_print.
0009  *
0010  * This file implements _CPU_Exception_frame_print for use in fatal output.
0011  * It dumps all standard integer and floating point registers as well as some
0012  * of the more important system registers.
0013  */
0014 
0015 /*
0016  * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
0017  * Written by Kinsey Moore <kinsey.moore@oarcorp.com>
0018  *
0019  * Redistribution and use in source and binary forms, with or without
0020  * modification, are permitted provided that the following conditions
0021  * are met:
0022  * 1. Redistributions of source code must retain the above copyright
0023  *    notice, this list of conditions and the following disclaimer.
0024  * 2. Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the distribution.
0027  *
0028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0029  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0031  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0032  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0033  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0034  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0036  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0037  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0038  * POSSIBILITY OF SUCH DAMAGE.
0039  */
0040 
0041 #ifdef HAVE_CONFIG_H
0042 #include "config.h"
0043 #endif
0044 
0045 #include <inttypes.h>
0046 
0047 #include <rtems/score/cpu.h>
0048 #include <rtems/dev/io.h>
0049 #include <rtems/bspIo.h>
0050 
0051 typedef struct {
0052     char *s;
0053     size_t n;
0054 } String_Context;
0055 
0056 static void _CPU_Put_char( int c, void *arg )
0057 {
0058   String_Context *sctx = arg;
0059   size_t n = sctx->n;
0060 
0061   if (n > 0) {
0062     char *s = sctx->s;
0063     *s = (char) c;
0064     sctx->s = s + 1;
0065     sctx->n = n - 1;
0066   }
0067 }
0068 
0069 static void _CPU_Binary_sprintf(
0070   char *s,
0071   size_t maxlen,
0072   uint32_t num_bits,
0073   uint32_t value
0074 )
0075 {
0076   String_Context sctx;
0077   uint32_t mask;
0078 
0079   sctx.s = s;
0080   sctx.n = maxlen;
0081 
0082   mask = 1 << (num_bits - 1);
0083 
0084   while ( mask != 0 ) {
0085     _IO_Printf( _CPU_Put_char, &sctx, "%d", (value & mask ? 1 : 0) );
0086     mask >>= 1;
0087   }
0088 
0089   s[num_bits] = '\0';
0090 }
0091 
0092 static const char* _CPU_Exception_class_to_string( uint16_t exception_class )
0093 {
0094   /* The 80 character limit is intentionally ignored for these strings. */
0095   switch ( exception_class ) {
0096     case 0x01:
0097       return "Trapped WFI or WFE instruction";
0098     case 0x03:
0099       return "Trapped MCR or MRC access with (coproc==0b1111)";
0100     case 0x04:
0101       return "Trapped MCRR or MRRC access with (coproc==0b1111)";
0102     case 0x05:
0103       return "Trapped MCR or MRC access with (coproc==0b1110)";
0104     case 0x06:
0105       return "Trapped LDC or STC access";
0106     case 0x0c:
0107       return "Trapped MRRC access with (coproc==0b1110)";
0108     case 0x0e:
0109       return "Illegal Execution state";
0110     case 0x18:
0111       return "Trapped MSR, MRS, or System instruction";
0112     case 0x20:
0113       return "Instruction Abort from a lower Exception level";
0114     case 0x21:
0115       return "Instruction Abort taken without a change in Exception level";
0116     case 0x22:
0117       return "PC alignment fault";
0118     case 0x24:
0119       return "Data Abort from a lower Exception level";
0120     case 0x25:
0121       return "Data Abort taken without a change in Exception level";
0122     case 0x26:
0123       return "SP alignment fault";
0124     case 0x30:
0125       return "Breakpoint exception from a lower Exception level";
0126     case 0x31:
0127       return "Breakpoint exception taken without a change in Exception level";
0128     case 0x32:
0129       return "Software Step exception from a lower Exception level";
0130     case 0x33:
0131       return "Software Step exception taken without a change in Exception level";
0132     case 0x34:
0133       return "Watchpoint exception from a lower Exception level";
0134     case 0x35:
0135       return "Watchpoint exception taken without a change in Exception level";
0136     case 0x38:
0137       return "BKPT instruction execution in AArch32 state";
0138     case 0x3c:
0139       return "BRK instruction execution in AArch64 state";
0140     default:
0141       return "Unknown";
0142   }
0143 }
0144 
0145 void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
0146 {
0147   uint32_t ec;
0148   uint32_t il;
0149   uint32_t iss;
0150   char     ec_str[7];
0151   char     iss_str[26];
0152   int      i;
0153   const uint128_t *qx;
0154 
0155   printk(
0156     "\n"
0157     "X0   = 0x%016" PRIx64  " X17  = 0x%016" PRIx64 "\n"
0158     "X1   = 0x%016" PRIx64  " X18  = 0x%016" PRIx64 "\n"
0159     "X2   = 0x%016" PRIx64  " X19  = 0x%016" PRIx64 "\n"
0160     "X3   = 0x%016" PRIx64  " X20  = 0x%016" PRIx64 "\n"
0161     "X4   = 0x%016" PRIx64  " X21  = 0x%016" PRIx64 "\n"
0162     "X5   = 0x%016" PRIx64  " X22  = 0x%016" PRIx64 "\n"
0163     "X6   = 0x%016" PRIx64  " X23  = 0x%016" PRIx64 "\n"
0164     "X7   = 0x%016" PRIx64  " X24  = 0x%016" PRIx64 "\n"
0165     "X8   = 0x%016" PRIx64  " X25  = 0x%016" PRIx64 "\n"
0166     "X9   = 0x%016" PRIx64  " X26  = 0x%016" PRIx64 "\n"
0167     "X10  = 0x%016" PRIx64  " X27  = 0x%016" PRIx64 "\n"
0168     "X11  = 0x%016" PRIx64  " X28  = 0x%016" PRIx64 "\n"
0169     "X12  = 0x%016" PRIx64  " FP   = 0x%016" PRIx64 "\n"
0170     "X13  = 0x%016" PRIx64  " LR   = 0x%016" PRIxPTR "\n"
0171     "X14  = 0x%016" PRIx64  " SP   = 0x%016" PRIxPTR "\n"
0172     "X15  = 0x%016" PRIx64  " PC   = 0x%016" PRIxPTR "\n"
0173     "X16  = 0x%016" PRIx64  " DAIF = 0x%016" PRIx64 "\n"
0174     "VEC  = 0x%016" PRIxPTR " CPSR = 0x%016" PRIx64 "\n",
0175     frame->register_x0, frame->register_x17,
0176     frame->register_x1, frame->register_x18,
0177     frame->register_x2, frame->register_x19,
0178     frame->register_x3, frame->register_x20,
0179     frame->register_x4, frame->register_x21,
0180     frame->register_x5, frame->register_x22,
0181     frame->register_x6, frame->register_x23,
0182     frame->register_x7, frame->register_x24,
0183     frame->register_x8, frame->register_x25,
0184     frame->register_x9, frame->register_x26,
0185     frame->register_x10, frame->register_x27,
0186     frame->register_x11, frame->register_x28,
0187     frame->register_x12, frame->register_fp,
0188     frame->register_x13, (intptr_t) frame->register_lr,
0189     frame->register_x14, (intptr_t) frame->register_sp,
0190     frame->register_x15, (intptr_t) frame->register_pc,
0191     frame->register_x16, frame->register_daif,
0192     (intptr_t) frame->vector, frame->register_cpsr
0193   );
0194 
0195   ec = frame->register_syndrome >> 26 & 0x3f;
0196   il = frame->register_syndrome >> 25 & 0x1;
0197   iss = frame->register_syndrome & 0x1ffffff;
0198 
0199   _CPU_Binary_sprintf( ec_str, sizeof( ec_str ), sizeof( ec_str ) - 1, ec );
0200   _CPU_Binary_sprintf( iss_str, sizeof( iss_str ), sizeof( iss_str ) - 1, iss );
0201 
0202   printk(
0203     "ESR  = EC: 0b%s" " IL: 0b%d" " ISS: 0b%s" "\n"
0204     "       %s\n",
0205     ec_str, il, iss_str, _CPU_Exception_class_to_string( ec )
0206   );
0207 
0208   printk( "FAR  = 0x%016" PRIx64 "\n", frame->register_fault_address );
0209 
0210   qx = &frame->register_q0;
0211 
0212   printk(
0213     "FPCR = 0x%016" PRIx64 " FPSR = 0x%016" PRIx64 "\n",
0214     frame->register_fpcr, frame->register_fpsr
0215   );
0216 
0217   for ( i = 0 ; i < 32 ; ++i ) {
0218     uint64_t low = (uint64_t) qx[i];
0219     uint64_t high = (uint64_t) (qx[i] >> 64);
0220 
0221     printk( "Q%02i  = 0x%016" PRIx64 "%016" PRIx64 "\n", i, high, low );
0222   }
0223 }