1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6
7 //#include "debug_api.h"
8
9 #define REG_NAME_WIDTH 7
10
11 typedef struct
12 {
13 /* saved in assembler */
14 int R0;
15 int R1;
16 int R2;
17 int R3;
18 int R4;
19 int R5;
20 int R6;
21 int R7;
22 int R8;
23 int R9;
24 int R10;
25 int R11;
26 int R12;
27 int LR; // Link Register (LR)
28 int PC; // Program Counter (PC)
29 int xPSR; // Program Status Registers
30 int SP; // Stack Pointer
31 int MSP; // Main stack pointer
32 int PSP; // Process stack pointer
33 int EXC_RETURN; // Exception Return
34 int EXC_NUMBER; // Exception Num
35 int PRIMASK; // Interrupt Mask
36 int FAULTMASK; // Interrupt Mask
37 int BASEPRI; // Interrupt Mask
38 } PANIC_CONTEXT;
39
40 typedef struct
41 {
42 int CFSR;
43 int HFSR;
44 int MMFAR;
45 int BFAR;
46 int AFSR;
47 } FAULT_REGS;
48
49 #if DEBUG_PANIC_CONTEXT_IN_STACK > 0
50 PANIC_CONTEXT g_panic_contex;
51 #endif
52
panicGetCtx(void * context,char ** pPC,char ** pLR,int ** pSP)53 void panicGetCtx(void *context, char **pPC, char **pLR, int **pSP)
54 {
55 PANIC_CONTEXT *arm_context = (PANIC_CONTEXT *)context;
56
57 *pSP = (int *)arm_context->SP;
58 *pPC = (char *)arm_context->PC;
59 *pLR = (char *)arm_context->LR;
60 }
61
panicShowRegs(void * context,int (* print_func)(const char * fmt,...))62 void panicShowRegs(void *context, int (*print_func)(const char *fmt, ...))
63 {
64 int x;
65 int *regs = (int *)context;
66 char s_panic_regs[REG_NAME_WIDTH + 14];
67 FAULT_REGS stFregs;
68 /* PANIC_CONTEXT */
69 char s_panic_ctx[] = "R0 "
70 "R1 "
71 "R2 "
72 "R3 "
73 "R4 "
74 "R5 "
75 "R6 "
76 "R7 "
77 "R8 "
78 "R9 "
79 "R10 "
80 "R11 "
81 "R12 "
82 "LR "
83 "PC "
84 "xPSR "
85 "SP "
86 "MSP "
87 "PSP "
88 "EXC_RET"
89 "EXC_NUM"
90 "PRIMASK"
91 "FLTMASK"
92 "BASEPRI";
93 /* FAULT_REGS */
94 char s_panic_reg[] = "CFSR "
95 "HFSR "
96 "MMFAR "
97 "BFAR "
98 "AFSR ";
99
100 if (regs == NULL) {
101 return;
102 }
103
104 print_func("========== Regs info ==========\r\n");
105
106 /* show PANIC_CONTEXT */
107 for (x = 0; x < sizeof(s_panic_ctx) / REG_NAME_WIDTH; x++) {
108 memcpy(&s_panic_regs[0], &s_panic_ctx[x * REG_NAME_WIDTH],
109 REG_NAME_WIDTH);
110 memcpy(&s_panic_regs[REG_NAME_WIDTH], " 0x", 3);
111 k_int2str(regs[x], &s_panic_regs[REG_NAME_WIDTH + 3]);
112 s_panic_regs[REG_NAME_WIDTH + 11] = '\r';
113 s_panic_regs[REG_NAME_WIDTH + 12] = '\n';
114 s_panic_regs[REG_NAME_WIDTH + 13] = 0;
115 print_func(s_panic_regs);
116 }
117
118 /* show FAULT_REGS */
119 stFregs.CFSR = (*((volatile int *)(0xE000ED28)));
120 stFregs.HFSR = (*((volatile int *)(0xE000ED2C)));
121 stFregs.MMFAR = (*((volatile int *)(0xE000ED34)));
122 stFregs.BFAR = (*((volatile int *)(0xE000ED38)));
123 stFregs.AFSR = (*((volatile int *)(0xE000ED3C)));
124 for (x = 0; x < sizeof(stFregs) / sizeof(int); x++) {
125 memcpy(&s_panic_regs[0], &s_panic_reg[x * REG_NAME_WIDTH],
126 REG_NAME_WIDTH);
127 memcpy(&s_panic_regs[REG_NAME_WIDTH], " 0x", 3);
128 k_int2str(((int *)(&stFregs))[x], &s_panic_regs[REG_NAME_WIDTH + 3]);
129 s_panic_regs[REG_NAME_WIDTH + 11] = '\r';
130 s_panic_regs[REG_NAME_WIDTH + 12] = '\n';
131 s_panic_regs[REG_NAME_WIDTH + 13] = 0;
132 print_func(s_panic_regs);
133 }
134 }
135
136 #if (RHINO_CONFIG_CLI_AS_NMI > 0)
panicNmiInputFilter(uint8_t ch)137 void panicNmiInputFilter(uint8_t ch)
138 {
139 static int check_cnt = 0; /* for '$#@!' */
140
141 if ( ch == '$' && check_cnt == 0) {
142 check_cnt++;
143 }
144 else if ( ch == '#' && check_cnt == 1) {
145 check_cnt++;
146 }
147 else if ( ch == '@' && check_cnt == 2) {
148 check_cnt++;
149 }
150 else if ( ch == '!' && check_cnt == 3) {
151 panicNmiFlagSet();
152 __asm__ __volatile__("udf":::"memory");
153 }
154 else {
155 check_cnt = 0;
156 }
157 }
158 #else
panicNmiInputFilter(uint8_t ch)159 void panicNmiInputFilter(uint8_t ch){}
160 #endif
161
162