• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <string.h>
16 #include <stdint.h>
17 #include "boot.h"
18 #include "bk_arch.h"
19 #include "bk_uart.h"
20 #include <components/log.h>
21 #include <common/bk_assert.h>
22 
23 #define STACK_DUMP_MEMORY 0
24 #define STACK_CALLBACK_BUF_SIZE 32
25 
26 extern char __executable_start;
27 extern char __etext;
28 extern char _itcm_ema_start, _itcm_ema_end;
29 
addr_is_in_flash_txt(uint32_t addr)30 static int addr_is_in_flash_txt(uint32_t addr)
31 {
32     return ((addr > 0x100) && (addr < (uint32_t)&__etext));
33 }
34 
addr_is_in_itcm_txt(uint32_t addr)35 static int addr_is_in_itcm_txt(uint32_t addr)
36 {
37     return ((addr > (uint32_t)&_itcm_ema_start) && (addr < (uint32_t)&_itcm_ema_end));
38 }
39 
code_addr_is_valid(uint32_t addr)40 static int code_addr_is_valid(uint32_t addr)
41 {
42     return (addr_is_in_flash_txt(addr) || addr_is_in_itcm_txt(addr));
43 }
44 
stack_mem_dump(uint32_t stack_top,uint32_t stack_bottom)45 void stack_mem_dump(uint32_t stack_top, uint32_t stack_bottom)
46 {
47     unsigned char *data;
48     uint32_t cnt = 0;
49     uint32_t sp = stack_top;
50     uint32_t fp = stack_bottom;
51 
52     BK_DUMP_OUT(">>>>stack mem dump begin, stack_top=%08x, stack end=%08x\r\n", stack_top, stack_bottom);
53     for (;  sp < fp; sp += sizeof(size_t)) {
54         data = ((unsigned char *) sp);
55 
56         if ((cnt++ & 0x7) == 0) {
57             BK_DUMP_OUT("\r\n");
58         }
59 
60         BK_DUMP_OUT("%02x %02x %02x %02x ", data[0], data[1], data[2], data[3]);
61     }
62     BK_DUMP_OUT("\r\n");
63     BK_DUMP_OUT("<<<<stack mem dump end. stack_top=%08x, stack end=%08x\r\n", stack_top, stack_bottom);
64     BK_DUMP_OUT("\r\n");
65 }
66 
67 
68 /* The stack is grow from bottom to top
69  *
70  *   | . | <- bottom, (big address) (x8 fp)
71  *   | . |
72  *   | . |
73  *   |   | <- top (x2 sp)
74  *   |   |
75  *   |   |
76  *   |   | <- minimum_addr = (bottom - stack_size)
77  *
78  * */
arch_parse_stack_backtrace(const char * str_type,uint32_t stack_top,uint32_t stack_bottom,uint32_t stack_size,bool thumb_mode)79 void arch_parse_stack_backtrace(const char *str_type, uint32_t stack_top, uint32_t stack_bottom,
80                            uint32_t stack_size, bool thumb_mode)
81 {
82     uint32_t call_stack_buf[STACK_CALLBACK_BUF_SIZE] = {0};
83     uint32_t stack_minimum = stack_bottom - stack_size;
84     uint32_t pc;
85     int call_stack_index = 0;
86     uint32_t init_stack_top = stack_top;
87 
88 #if STACK_DUMP_MEMORY
89     stack_mem_dump(stack_top, stack_bottom);
90 #endif
91     for (; stack_top < stack_bottom && (call_stack_index < STACK_CALLBACK_BUF_SIZE); stack_top += sizeof(size_t)) {
92         pc = *((uint32_t *) stack_top);
93 
94         if (code_addr_is_valid(pc)) {
95             if (pc & 1)
96                 pc = pc - 1;
97 
98             call_stack_buf[call_stack_index] = pc;
99             call_stack_index++;
100         }
101     }
102 
103     if (call_stack_index > 0) {
104         int index;
105 
106         BK_DUMP_OUT("%-16s   [0x%-6x ~ 0x%-6x]   0x%-6x   %-4d   %-8d   ",
107                   str_type, stack_minimum, stack_bottom, init_stack_top, stack_size, init_stack_top < stack_minimum);
108 
109         for (index = 0; index < call_stack_index; index++)
110             BK_DUMP_OUT("%lx ", call_stack_buf[index]);
111         BK_DUMP_OUT("\r\n");
112     } else if (init_stack_top < stack_minimum) {
113         BK_DUMP_OUT("%-16s   [0x%-6x ~ 0x%-6x]   0x%-6x   %-4d   %-8d   ",
114                   str_type, stack_minimum, stack_bottom, init_stack_top, stack_size, init_stack_top < stack_minimum);
115     }
116 }
117 
118 
119