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