ESP8266 ILI9341 display support code with printf sources, wire-frame viewer and custom fonts  1.0
ESP8266ILI9341DisplayProject
cal_dex.c
Go to the documentation of this file.
1 
7 #define CAL_DEX_VERSION "0.1"
8 #define CAL_DEX_DUMP_FORMAT "0.1"
9 
10 //extern void output_redirect(const char *str);
11 //#define c_puts output_redirect
12 
13 extern void* __real__xtos_set_exception_handler(int exno, void (*exhandler)());
14 
15 extern char* system_get_sdk_version();
16 
17 typedef struct
18 {
19  int epc1;
20  int ps;
21  int sar;
22  int xx1;
23  int a0;
24  int a2;
25  int a3;
26  int a4;
27  int a5;
28  int a6;
29  int a7;
30  int a8;
31  int a9;
32  int a10;
33  int a11;
34  int a12;
35  int a13;
36  int a14;
37  int a15;
38  int exccause;
39 } ex_regs;
40 
41 /* use some link symbols to get a kind of firmware fingerprint */
42 extern char _text_start;
43 extern char _text_end;
44 extern char _rodata_start;
45 extern char _rodata_end;
46 extern char _data_start;
47 extern char _data_end;
48 extern char _bss_start;
49 extern char _bss_end;
50 
51 static void (*orighandler)(int code);
52 static void cal_dex_handler(int exccause, ex_regs regs);
53 
54 #define L(x) (((unsigned int)(x)) & 0xFFFF)
55 
56 // did not work reliably for me (cal101)
57 #define USE_ETS_PRINTF 1
58 
59 #if USE_ETS_PRINTF
60 #define c_puts(a) cal_tprintf(a)
61 extern void ets_uart_printf(char* fmt, ...);
62 //#define cal_tprintf printf
63 #define cal_tprintf printf
64 #else
65 static char TINYBUF[120];
66 
67 #define cal_tprintfOFF(fmt,...) do { \
68 ets_vsprintf(TINYBUF, fmt, __VA_ARGS__); \
69 c_puts(TINYBUF); \
70 } while(0)
71 #define P4X(s,n) c_puts(s); print4x(n);
72 #define P8X(s,n) c_puts(s); print8x((int)(n));
73 #endif
74 
75 #if !USE_ETS_PRINTF
76 // quick and dirty print hex bytes to avoid printf.
78 void print8x(unsigned int n)
79 {
80  int i = 0;
81  for (i = 0; i < 8; i++)
82  {
83  int nib = n & 0xf;
84  TINYBUF[7-i] = (nib < 10) ? '0' + nib : 'a' - 10 + nib;
85  n = n>>4;
86  }
87  TINYBUF[8] = 0;
88  c_puts(TINYBUF);
89 }
90 
91 
93 void print4x(unsigned int n)
94 {
95  int i = 0;
96  for (i = 0; i < 4; i++)
97  {
98  int nib = n & 0xf;
99  TINYBUF[3-i] = (nib < 10) ? '0' + nib : 'a' - 10 + nib;
100  n = n>>4;
101  }
102  TINYBUF[4] = 0;
103  c_puts(TINYBUF);
104 }
105 
106 
107 MEMSPACE
108 void print2d(unsigned int n)
109 {
110  int i = 0;
111  for (i = 0; i < 2; i++)
112  {
113  int nib = n % 10;
114  TINYBUF[1-i] = '0' + nib;
115  n = n / 10;
116  }
117  TINYBUF[2] = 0;
118  c_puts(TINYBUF);
119 }
120 #endif
121 
122 #define NUM 8
123 
124 // TODO: could use TINYBUF per line
125 //__attribute__((noinline))
126 void cal_dex_dump_hex(int* p, int cnt)
127 {
128  int i;
129  for (i = 0; i < cnt; i++)
130  {
131 #if USE_ETS_PRINTF
132  if (i % NUM == 0)
133  {
134  printf("%08x ", (int )(p + i));
135  }
136  printf(" %08x", p[i]);
137 #else
138  if (i % NUM == 0)
139  {
140  print8x((int )(p + i));
141  c_puts(" ");
142  }
143  c_puts(" ");
144  print8x(p[i]);
145 #endif
146  if ((i + 1) % NUM == 0)
147  {
148  c_puts("\n");
149  }
150  }
151 }
152 
153 
154 int stackok(int* sp)
155 {
156  int i = (unsigned int) sp;
157  return (i > 0x3fffc000) && (i < 0x40000000) && ((i & 3) == 0);
158 }
159 
160 
161 //__attribute__((noinline))
162 void cal_dex_dump_stack(int* sp)
163 {
164  int* p = sp - 8;
165  if (stackok(p))
166  {
167  int n = (0x40000000 - (unsigned int)p);
168  if (n > 512)
169  {
170  n = 512;
171  }
172 #if defined(cal_tprintf)
173  cal_tprintf("Stack: (%08x)\n", sp);
174 #else
175  c_puts("Stack (");
176  print8x((unsigned int)sp);
177  c_puts(")\n");
178 #endif
179  cal_dex_dump_hex(p, n / 4);
180  }
181  else
182  {
183 #if defined(cal_tprintf)
184  cal_tprintf("Stack pointer may be corrupt: %08x\n", sp);
185 #else
186  c_puts("Stack pointer may be corrupt: ");
187  print8x((unsigned int)sp);
188  c_puts("\n");
189 #endif
190  }
191 }
192 
193 
194 static int get_excvaddr()
195 {
196  int v;
197  asm volatile (
198  "rsr.excvaddr %0\n\t"
199  : "=r" (v)
200  );
201  return v;
202 }
203 
204 
205 static int get_depc()
206 {
207  int v;
208  asm volatile (
209  "rsr.depc %0\n\t"
210  : "=r" (v)
211  );
212  return v;
213 }
214 
215 
216 //__attribute__((noinline))
217 void cal_dex_dump(int* sp)
218 {
219  ex_regs *regs = (ex_regs*) sp;
220 // stack pointer at exception place
221  int* ex_sp = (sp + 256 / 4);
222  int* p = ex_sp - 8;
223  int usestack = stackok(p);
224 
225  c_puts("cal_dex " CAL_DEX_VERSION ", dump " CAL_DEX_DUMP_FORMAT "\n");
226 #if defined(cal_tprintf)
227  cal_tprintf("Fatal Exception: %04x (%d), sp %08x\n", regs->exccause,
228  regs->exccause, sp);
229 #else
230  c_puts("Fatal Exception: ");
231  print4x(regs->exccause);
232  c_puts(" (");
233  print2d(regs->exccause);
234  c_puts("), sp ");
235  print8x((int)sp);
236  c_puts("\n");
237 #endif
238  c_puts("SDK Version: ");
240  c_puts("\n");
241  if (usestack)
242  {
243  int excvaddr = get_excvaddr();
244  int depc = get_depc();
245 #if defined(cal_tprintf)
246  cal_tprintf(
247  "Fingerprint: 1/xh=%08x,t=%04x-%04x,d=%04x-%04x,b=%04x-%04x,ro=%04x-%04x\n",
248  cal_dex_handler, L(&_text_start), L(&_text_end),
249  L(&_data_start), L(&_data_end), L(&_bss_start), L(&_bss_end),
250  L(&_rodata_start), L(&_rodata_end));
251  cal_tprintf(
252  " epc1: %08x ps: %08x sar: %08x exccause: %08x unk1: %08x\n",
253  regs->epc1, regs->ps, regs->sar, regs->exccause, regs->xx1);
254 // a1 is stack at exception
255  cal_tprintf(" a0 : %08x a1 : %08x a2 : %08x a3 : %08x\n",
256  regs->a0, (int )ex_sp, regs->a2, regs->a3);
257  cal_tprintf(" a4 : %08x a5 : %08x a6 : %08x a7 : %08x\n",
258  regs->a4, regs->a5, regs->a6, regs->a7);
259  cal_tprintf(" a8 : %08x a9 : %08x a10: %08x a11: %08x\n",
260  regs->a8, regs->a9, regs->a10, regs->a11);
261  cal_tprintf(" a12: %08x a13: %08x a14: %08x a15: %08x\n",
262  regs->a12, regs->a13, regs->a14, regs->a15);
263 #else
264  c_puts("Fingerprint: 1/");
265  P8X("xh=", cal_dex_handler);
266  P4X(",t=", L(&_text_start)); P4X("-", L(&_text_end));
267  P4X(",d=", L(&_data_start)); P4X("-", L(&_data_end));
268  P4X(",b=", L(&_bss_start)); P4X("-", L(&_bss_end));
269  P4X(",ro=", L(&_rodata_start)); P4X("-", L(&_rodata_end));
270  c_puts("\n");
271  P8X(" epc1: ", regs->epc1); P8X(" exccause: ", regs->exccause); P8X(" excvaddr: ", excvaddr);
272  P8X(" depc: ", depc);
273  c_puts("\n");
274  P8X(" ps : ", regs->ps); P8X(" sar : ", regs->sar); P8X(" unk1 : ", regs->xx1);
275  c_puts("\n");
276 // a1 is stack at exception
277  P8X(" a0 : ", regs->a0);
278  P8X(" a1 : ", (int )ex_sp);
279  P8X(" a2 : ", regs->a2);
280  P8X(" a3 : ", regs->a3);
281  c_puts("\n");
282  P8X(" a4 : ", regs->a4);
283  P8X(" a5 : ", regs->a5);
284  P8X(" a6 : ", regs->a6);
285  P8X(" a7 : ", regs->a7);
286  c_puts("\n");
287  P8X(" a8 : ", regs->a8);
288  P8X(" a9 : ", regs->a9);
289  P8X(" a10: ", regs->a10);
290  P8X(" a11: ", regs->a11);
291  c_puts("\n");
292  P8X(" a12: ", regs->a12);
293  P8X(" a13: ", regs->a13);
294  P8X(" a14: ", regs->a14);
295  P8X(" a15: ", regs->a15);
296  c_puts("\n");
297 #endif
299  }
300  else
301  {
302 #if defined(cal_tprintf)
303  cal_tprintf("Stack pointer may be corrupted: %08x\n", sp);
304 #else
305  c_puts("Stack pointer may be corrupted: ");
306  print8x((int)sp);
307  c_puts("\n");
308 #endif
309  }
310 }
311 
312 
313 // TODO: parameter passing to orighandler is most probably wrong
314 /*
315 
316  __attribute__((interrupt,exception,exception_handler,isr,noreturn)) static void cal_dex_handler(ex_regs regs) {
317  int* p = __builtin_frame_address(0);
318  cal_dex_dump(p, &regs);
319  //orighandler(regs.exccause);
320  asm("jmp %0" :: "p" (orighandler));
321  }
322  */
323 
324 /*
325  * a2 contains exception cause, current stack contains register dump.
326  * a3 and a4 may be used because they are not used by standard handler.
327  */
328 //__attribute__((noinline))
329 void cal_dex_handler(int exccause, ex_regs regs)
330 {
331  asm volatile (
332  "addi a1, a1, -16\n\t"
333  "s32i.n a0, a1, 12\n\t"
334  );
335  asm volatile (
336  "addi a2, a1, 16\n\t"
337  "mov a0, %0\n\t"
338  "callx0 a0\n\t"
339  :: "r" (cal_dex_dump)
340  );
341  asm volatile (
342  "mov a2, %1\n\t"
343  "mov a3, %0\n\t"
344  "l32i a0, a1, 12\n\t"
345  "addi a1, a1, 16\n\t"
346  "jx a3\n\t"
347  :: "r" (orighandler), "r" (exccause)
348  );
349 }
350 
351 
359 void* __wrap__xtos_set_exception_handler(int exno, void (*exhandler)())
360 {
361 //int* sp = __builtin_frame_address(0);
362  void *res = 0;
363  if (exhandler != 0)
364  {
365  if (orighandler == 0)
366  {
367  orighandler = exhandler;
368  res = __real__xtos_set_exception_handler(exno, exhandler);
369  }
370  else
371  {
372  if (orighandler != exhandler)
373  {
374  c_puts(
375  "__wrap__xtos_set_exception_handler: unexpected handler!");
376  res = __real__xtos_set_exception_handler(exno, exhandler);
377  }
378  else
379  {
380 //c_puts("installed exception_handler\n");
382  }
383  }
384  }
385  else
386  {
387  void* p = __real__xtos_set_exception_handler(exno, exhandler);
388  if (p == cal_dex_handler)
389  {
390  res = orighandler;
391  }
392  else
393  {
394  res = p;
395  }
396  }
397  if (exno == 29)
398  {
399 // provoke error
400 //*((int*)(0x1020)) = 0xdeadbeaf;
401 //cal_dex_dump_stack((int*) sp);
402  }
403  return res;
404 }
405 
int a8
Definition: cal_dex.c:30
static int get_depc()
Definition: cal_dex.c:205
char _bss_end
#define CAL_DEX_VERSION
Definition: cal_dex.c:7
int a3
Definition: cal_dex.c:25
int exccause
Definition: cal_dex.c:38
int sar
Definition: cal_dex.c:21
int epc1
Definition: cal_dex.c:19
int a6
Definition: cal_dex.c:28
#define cal_tprintf
Definition: cal_dex.c:63
char _data_end
void cal_dex_dump_stack(int *sp)
Definition: cal_dex.c:162
#define c_puts(a)
Definition: cal_dex.c:60
char _rodata_start
int a15
Definition: cal_dex.c:37
int ps
Definition: cal_dex.c:20
int stackok(int *sp)
Definition: cal_dex.c:154
char _data_start
int a12
Definition: cal_dex.c:34
void ets_uart_printf(char *fmt,...)
char _bss_start
void * __real__xtos_set_exception_handler(int exno, void(*exhandler)())
int xx1
Definition: cal_dex.c:22
static void(* orighandler)(int code)
Definition: cal_dex.c:51
int a10
Definition: cal_dex.c:32
int a5
Definition: cal_dex.c:27
int a13
Definition: cal_dex.c:35
int a0
Definition: cal_dex.c:23
static int get_excvaddr()
Definition: cal_dex.c:194
char _text_start
static void cal_dex_handler(int exccause, ex_regs regs)
Definition: cal_dex.c:329
char * system_get_sdk_version()
#define MEMSPACE
Definition: cpu.h:25
void * __wrap__xtos_set_exception_handler(int exno, void(*exhandler)())
Definition: cal_dex.c:359
MEMSPACE int printf(const char *format,...)
int a4
Definition: cal_dex.c:26
int a14
Definition: cal_dex.c:36
#define NUM
Definition: cal_dex.c:122
int a11
Definition: cal_dex.c:33
char _text_end
#define L(x)
Definition: cal_dex.c:54
char _rodata_end
int a2
Definition: cal_dex.c:24
int a9
Definition: cal_dex.c:31
void cal_dex_dump(int *sp)
Definition: cal_dex.c:217
void cal_dex_dump_hex(int *p, int cnt)
Definition: cal_dex.c:126
#define CAL_DEX_DUMP_FORMAT
Definition: cal_dex.c:8
int a7
Definition: cal_dex.c:29