File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <bsp/vectors.h>
0021
0022 #include <rtems/score/thread.h>
0023 #include <rtems/score/threaddispatch.h>
0024
0025 #include <inttypes.h>
0026
0027 #ifndef __SPE__
0028 #define GET_GPR(gpr) (gpr)
0029 #else
0030 #define GET_GPR(gpr) ((uintptr_t) ((gpr) >> 32))
0031 #endif
0032
0033
0034
0035
0036 typedef struct LRFrameRec_ {
0037 struct LRFrameRec_ *frameLink;
0038 unsigned long *lr;
0039 } LRFrameRec, *LRFrame;
0040
0041 #define STACK_CLAMP 50
0042
0043 static uint32_t ppc_exc_get_DAR_dflt(void)
0044 {
0045 uint32_t val;
0046 if (ppc_cpu_is_60x()) {
0047 PPC_SPECIAL_PURPOSE_REGISTER(PPC_DAR, val);
0048 return val;
0049 } else {
0050 switch (ppc_cpu_is_bookE()) {
0051 default:
0052 break;
0053 case PPC_BOOKE_STD:
0054 case PPC_BOOKE_E500:
0055 PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_DEAR, val);
0056 return val;
0057 case PPC_BOOKE_405:
0058 PPC_SPECIAL_PURPOSE_REGISTER(PPC405_DEAR, val);
0059 return val;
0060 }
0061 }
0062 return 0xdeadbeef;
0063 }
0064
0065 uint32_t (*ppc_exc_get_DAR)(void) = ppc_exc_get_DAR_dflt;
0066
0067 void BSP_printStackTrace(const BSP_Exception_frame *excPtr)
0068 {
0069 LRFrame f;
0070 int i;
0071 LRFrame sp;
0072 void *lr;
0073
0074 printk("Stack Trace: \n ");
0075 if (excPtr) {
0076 printk("IP: 0x%08" PRIxPTR ", ", excPtr->EXC_SRR0);
0077 sp = (LRFrame) GET_GPR(excPtr->GPR1);
0078 lr = (void *) excPtr->EXC_LR;
0079 } else {
0080
0081 __asm__ __volatile__("mr %0, 1":"=r"(sp));
0082 lr = (LRFrame) ppc_link_register();
0083 }
0084 printk("LR: 0x%08" PRIxPTR "\n", (uintptr_t) lr);
0085 for (f = (LRFrame) sp, i = 0; f->frameLink && i < STACK_CLAMP; f = f->frameLink) {
0086 printk("--^ 0x%08" PRIxPTR "", (uintptr_t) (f->frameLink->lr));
0087 if (!(++i % 5))
0088 printk("\n");
0089 }
0090 if (i >= STACK_CLAMP) {
0091 printk("Too many stack frames (stack possibly corrupted), giving up...\n");
0092 } else {
0093 if (i % 5)
0094 printk("\n");
0095 }
0096 }
0097
0098 void _CPU_Exception_frame_print(const CPU_Exception_frame *excPtr)
0099 {
0100 const Thread_Control *executing = _Thread_Executing;
0101 bool synch = (int) excPtr->_EXC_number >= 0;
0102 unsigned n = excPtr->_EXC_number & 0x7fff;
0103
0104 printk("exception vector %d (0x%x)\n", n, n);
0105 printk(" next PC or address of fault = 0x%08" PRIxPTR "\n", excPtr->EXC_SRR0);
0106 printk(" saved MSR = 0x%08" PRIxPTR "\n", excPtr->EXC_SRR1);
0107
0108
0109 printk(
0110 " context = %s, ISR nest level = %" PRIu32 "\n",
0111 _ISR_Nest_level == 0 ? "task" : "interrupt",
0112 _ISR_Nest_level
0113 );
0114 printk(
0115 " thread dispatch disable level = %" PRIu32 "\n",
0116 _Thread_Dispatch_disable_level
0117 );
0118
0119
0120
0121 printk(" R0 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR0));
0122 if (synch) {
0123 printk(" R1 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR1));
0124 printk(" R2 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR2));
0125 } else {
0126 printk(" ");
0127 printk(" ");
0128 }
0129 printk(" R3 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR3));
0130 printk(" R4 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR4));
0131 printk(" R5 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR5));
0132 printk(" R6 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR6));
0133 printk(" R7 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR7));
0134 printk(" R8 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR8));
0135 printk(" R9 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR9));
0136 printk(" R10 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR10));
0137 printk(" R11 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR11));
0138 printk(" R12 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR12));
0139 if (synch) {
0140 printk(" R13 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR13));
0141 printk(" R14 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR14));
0142 printk(" R15 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR15));
0143 printk(" R16 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR16));
0144 printk(" R17 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR17));
0145 printk(" R18 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR18));
0146 printk(" R19 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR19));
0147 printk(" R20 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR20));
0148 printk(" R21 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR21));
0149 printk(" R22 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR22));
0150 printk(" R23 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR23));
0151 printk(" R24 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR24));
0152 printk(" R25 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR25));
0153 printk(" R26 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR26));
0154 printk(" R27 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR27));
0155 printk(" R28 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR28));
0156 printk(" R29 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR29));
0157 printk(" R30 = 0x%08" PRIxPTR "", GET_GPR(excPtr->GPR30));
0158 printk(" R31 = 0x%08" PRIxPTR "\n", GET_GPR(excPtr->GPR31));
0159 } else {
0160 printk("\n");
0161 }
0162 printk(" CR = 0x%08" PRIx32 "\n", excPtr->EXC_CR);
0163 printk(" CTR = 0x%08" PRIxPTR "\n", excPtr->EXC_CTR);
0164 printk(" XER = 0x%08" PRIx32 "\n", excPtr->EXC_XER);
0165 printk(" LR = 0x%08" PRIxPTR "\n", excPtr->EXC_LR);
0166
0167
0168
0169
0170
0171
0172
0173 if (ppc_exc_get_DAR != NULL) {
0174 char* reg = ppc_cpu_is_60x() ? " DAR" : "DEAR";
0175 printk(" %s = 0x%08" PRIx32 "\n", reg, ppc_exc_get_DAR());
0176 }
0177 if (ppc_cpu_is_bookE()) {
0178 uint32_t esr, mcsr;
0179 if (ppc_cpu_is_bookE() == PPC_BOOKE_405) {
0180 PPC_SPECIAL_PURPOSE_REGISTER(PPC405_ESR, esr);
0181 PPC_SPECIAL_PURPOSE_REGISTER(PPC405_MCSR, mcsr);
0182 } else {
0183 PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_ESR, esr);
0184 PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_MCSR, mcsr);
0185 }
0186 printk(" ESR = 0x%08x\n", esr);
0187 printk(" MCSR = 0x%08x\n", mcsr);
0188 }
0189
0190 #ifdef PPC_MULTILIB_ALTIVEC
0191 {
0192 unsigned char *v = (unsigned char *) &excPtr->V0;
0193 int i;
0194 int j;
0195
0196 printk(" VSCR = 0x%08" PRIx32 "\n", excPtr->VSCR);
0197 printk("VRSAVE = 0x%08" PRIx32 "\n", excPtr->VRSAVE);
0198
0199 for (i = 0; i < 32; ++i) {
0200 printk(" V%02i = 0x", i);
0201
0202 for (j = 0; j < 16; ++j) {
0203 printk("%02x", v[j]);
0204 }
0205
0206 printk("\n");
0207
0208 v += 16;
0209 }
0210 }
0211 #endif
0212
0213 #ifdef PPC_MULTILIB_FPU
0214 {
0215 uint64_t *f = (uint64_t *) &excPtr->F0;
0216 int i;
0217
0218 printk("FPSCR = 0x%08" PRIu64 "\n", excPtr->FPSCR);
0219
0220 for (i = 0; i < 32; ++i) {
0221 printk(" F%02i = 0x%016" PRIu64 "\n", i, f[i]);
0222 }
0223 }
0224 #endif
0225
0226 if (executing != NULL) {
0227 const char *name = (const char *) &executing->Object.name;
0228
0229 printk(
0230 " executing thread ID = 0x%08" PRIx32 ", name = %c%c%c%c\n",
0231 executing->Object.id,
0232 name [0],
0233 name [1],
0234 name [2],
0235 name [3]
0236 );
0237 } else {
0238 printk(" executing thread pointer is NULL");
0239 }
0240
0241 BSP_printStackTrace(excPtr);
0242 }