atf_ramdump.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. #include <arch/arm/mmu.h>
  2. #include <debug.h>
  3. #include <dev/aee_platform_debug.h>
  4. #include <libfdt.h>
  5. #ifdef MTK_SMC_ID_MGMT
  6. #include <mtk_secure_api.h>
  7. #endif
  8. #include <arch/ops.h>
  9. #include <platform/boot_mode.h>
  10. #include <platform/mt_typedefs.h>
  11. #include <platform/plat_atf_dbg_info.h>
  12. #include <sys/types.h>
  13. #ifdef MBLOCK_LIB_SUPPORT
  14. #include <mblock.h>
  15. #endif
  16. /* default support ATF, define an empty function in ARMv7 chip family */
  17. #pragma weak atf_log_init
  18. #ifndef MTK_SMC_ID_MGMT
  19. #define MTK_SIP_LK_DUMP_ATF_LOG_INFO_AARCH32 0x8200010A
  20. #endif
  21. #define ATF_CRASH_MAGIC_NO 0xdead1abf
  22. #define ATF_LAST_LOG_MAGIC_NO 0x41544641
  23. #define ATF_DUMP_DONE_MAGIC_NO 0xd07ed07e
  24. #define ATF_SMC_UNK 0xffffffff
  25. /* each 8 bytes, support 16 types */
  26. #define ATF_OP_ID_GET_FOOTPRINT_BUF_INFO (0x0)
  27. #define MAX_FOOTPRINT_TYPE_STRING_SIZE 8
  28. #define MAX_SUPPORTED_FOOTPRINT_TYPE 16
  29. #define MAX_CORE_COUNT 32
  30. #define FOOTPRINT_MAGIC_NUM 0xCA7FF007
  31. #define ATF_RET_SUCCESS 0
  32. #define ATF_RET_UNKNOWN -1
  33. struct footprint_header {
  34. uint32_t size;
  35. uint32_t magic;
  36. };
  37. struct footprint_package{
  38. struct footprint_header header;
  39. /* 4 bytes alignment */
  40. uint8_t name_string[MAX_FOOTPRINT_TYPE_STRING_SIZE]; /* 8 */
  41. uint32_t footprint[MAX_CORE_COUNT]; /* 16*/
  42. };
  43. #define INFO_LOG(fmt, args...) do {dprintf(INFO, fmt, ##args);} while (0)
  44. #define ALWAYS_LOG(fmt, args...) do {dprintf(ALWAYS, fmt, ##args);} while (0)
  45. extern BOOT_ARGUMENT *g_boot_arg;
  46. static u64 atf_ramdump_addr;
  47. static u32 atf_ramdump_size;
  48. static uint32_t atf_log_buf_addr;
  49. static uint32_t atf_log_buf_size;
  50. static uint32_t atf_crash_flag_addr;
  51. static uintptr_t atf_footprint_addr;
  52. static uint32_t atf_footprint_buf_size;
  53. static void get_atf_ramdump_memory(void)
  54. {
  55. #if (defined(MTK_SMC_ID_MGMT) && !defined(MTK_DIS_ATF_RAM_DUMP))
  56. uint32_t address_hi, address_lo;
  57. address_hi = mt_secure_call_ret3(MTK_SIP_RAM_DUMP_ADDR, 0, 0, 0, 0,
  58. &address_lo, &atf_ramdump_size);
  59. ALWAYS_LOG("atf ram dump address hi:0x%x, adress lo:0x%x, size: %x\n",
  60. address_hi, address_lo, atf_ramdump_size);
  61. atf_ramdump_addr = (((u64)address_hi & 0xFFFFFFFF) << 32) |
  62. ((u64)address_lo & 0xFFFFFFFF);
  63. ALWAYS_LOG("atf ram dump address:0x%llx, size: %x\n",
  64. atf_ramdump_addr, atf_ramdump_size);
  65. #else
  66. atf_ramdump_size = 0;
  67. atf_ramdump_addr = 0;
  68. ALWAYS_LOG("Do not support atf-ramdump-memory, atf_ramdump_addr=0x%llx!\n",
  69. atf_ramdump_addr);
  70. #endif
  71. }
  72. static uint32_t save_atf_log(u64 offset, int *len, CALLBACK dev_write)
  73. {
  74. uint32_t datasize = 0;
  75. #ifdef MTK_3LEVEL_PAGETABLE
  76. /* ATF log is located in DRAM, we must allocate it first */
  77. arch_mmu_map(ROUNDDOWN((uint64_t)atf_log_buf_addr, PAGE_SIZE), ROUNDDOWN((uint32_t)atf_log_buf_addr, PAGE_SIZE),
  78. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA, ROUNDUP(atf_log_buf_size, PAGE_SIZE));
  79. #endif
  80. *len = atf_log_buf_size;
  81. datasize = dev_write((void *)atf_log_buf_addr, *len);
  82. /* Clear ATF crash flag */
  83. *(uint32_t *)atf_crash_flag_addr = ATF_DUMP_DONE_MAGIC_NO;
  84. arch_clean_cache_range((addr_t)atf_crash_flag_addr, sizeof(uint32_t));
  85. dprintf(INFO, "ATF: dev_write:%u, atf_log_buf_addr:0x%x, atf_log_buf_size:%u, crash_flag:0x%x\n", datasize, atf_log_buf_addr, atf_log_buf_size, *(uint32_t *)atf_crash_flag_addr);
  86. return datasize;
  87. }
  88. static uint32_t save_atf_footprint(u64 offset, int *len, CALLBACK dev_write)
  89. {
  90. uint32_t datasize = 0;
  91. uint32_t i = 0;
  92. uint64_t footprint_map_addr;
  93. uint64_t footprint_map_size;
  94. uint64_t temp_offset;
  95. uint32_t local_strlen = 0;
  96. int n = 0;
  97. char *ptr_footprint_buf_start = 0;
  98. /* for pointer of footprint buffer address */
  99. char *ptr_footprint_buf_pointer = 0;
  100. struct footprint_package *ptr_fp_pkg, *ptr_next_fp_pkg;
  101. /* allocate temp buffer to parcking footprint data */
  102. ptr_footprint_buf_start = malloc(atf_footprint_buf_size);
  103. if (!ptr_footprint_buf_start) {
  104. dprintf(CRITICAL, "%s : malloc failure for size 0x%x\n", __func__, atf_footprint_buf_size);
  105. return datasize;
  106. }
  107. if (atf_footprint_addr > 0) {
  108. ptr_fp_pkg = (struct footprint_package *)(intptr_t)atf_footprint_addr;
  109. /* round down */
  110. temp_offset = (uint64_t)(atf_footprint_addr & (PAGE_SIZE -1));
  111. if (temp_offset > 0)
  112. footprint_map_addr = (atf_footprint_addr - temp_offset); /* round down */
  113. else
  114. footprint_map_addr = atf_footprint_addr;
  115. /* round up */
  116. temp_offset = (atf_footprint_buf_size & (PAGE_SIZE -1));
  117. if (temp_offset > 0)
  118. footprint_map_size = (atf_footprint_buf_size - temp_offset) + PAGE_SIZE;
  119. else
  120. footprint_map_size = atf_footprint_buf_size;
  121. #ifdef MTK_3LEVEL_PAGETABLE
  122. /* ATF log is located in DRAM, we must allocate it first */
  123. arch_mmu_map(footprint_map_addr, footprint_map_addr,
  124. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA,
  125. footprint_map_size);
  126. #endif
  127. /* clean whole buffer */
  128. memset((void *)ptr_footprint_buf_start,
  129. 0x0,
  130. atf_footprint_buf_size);
  131. /* traverse footprint_package*/
  132. ptr_footprint_buf_pointer = ptr_footprint_buf_start;
  133. while (ptr_fp_pkg->header.magic == FOOTPRINT_MAGIC_NUM) {
  134. /* cast to void * for byte count */
  135. ptr_next_fp_pkg = (struct footprint_package *)
  136. ((void *)ptr_fp_pkg + ptr_fp_pkg->header.size);
  137. /* format the value to buffer */
  138. local_strlen = strlen((char *)&ptr_fp_pkg->name_string[0]);
  139. if (local_strlen > 0 &&
  140. local_strlen < MAX_FOOTPRINT_TYPE_STRING_SIZE) {
  141. n = sprintf(ptr_footprint_buf_pointer, "%s:",
  142. &ptr_fp_pkg->name_string[0]);
  143. if (n < 0) {
  144. dprintf(CRITICAL, "ATF: sprintf unknown ERROR.\n");
  145. }
  146. /* string and = */
  147. ptr_footprint_buf_pointer += strlen(ptr_footprint_buf_pointer);
  148. /* traverse footprint value*/
  149. i = 0;
  150. while ((uint32_t)&ptr_fp_pkg->footprint[i] < (uint32_t)ptr_next_fp_pkg) {
  151. /* print comma */
  152. if ((uint32_t)&ptr_fp_pkg->footprint[i+1] < (uint32_t)ptr_next_fp_pkg) {
  153. n = sprintf(ptr_footprint_buf_pointer, "[%d]=0x%8x,", i,
  154. ptr_fp_pkg->footprint[i]);
  155. if (n < 0) {
  156. dprintf(CRITICAL, "ATF: sprintf unknown ERROR.\n");
  157. }
  158. } else {
  159. n = sprintf(ptr_footprint_buf_pointer, "[%d]=0x%8x\n", i,
  160. ptr_fp_pkg->footprint[i]);
  161. if (n < 0) {
  162. dprintf(CRITICAL, "ATF: sprintf unknown ERROR.\n");
  163. }
  164. }
  165. /* int and ,*/
  166. ptr_footprint_buf_pointer += strlen(ptr_footprint_buf_pointer);
  167. i++;
  168. }
  169. } /* if (0< local_strlen < MAX_FOOTPRINT_TYPE_STRING_SIZE) */
  170. /* point to next footprint_package*/
  171. ptr_fp_pkg = ptr_next_fp_pkg;
  172. } /* while (ptr_fp_pkg->header.magic == FOOTPRINT_MAGIC_NUM) */
  173. /* flush and invalidate memory */
  174. arch_sync_cache_range((addr_t)ptr_footprint_buf_start, atf_footprint_buf_size);
  175. /* scratch whole memory and write it into db file */
  176. *len = atf_footprint_buf_size;
  177. datasize = dev_write((void *)ptr_footprint_buf_start, *len);
  178. dprintf(CRITICAL, "ATF: footprint dev_write:%u\n", datasize);
  179. } /* End of if (atf_footprint_addr > 0) { */
  180. /* free memory */
  181. free(ptr_footprint_buf_start);
  182. return datasize;
  183. }
  184. static uint32_t save_atf_rdump(u64 offset, int *len, CALLBACK dev_write)
  185. {
  186. uint32_t datasize = 0;
  187. u64 local_atf_ramdump_addr;
  188. u64 local_atf_ramdump_size;
  189. local_atf_ramdump_addr = atf_ramdump_addr;
  190. local_atf_ramdump_size = atf_ramdump_size;
  191. #ifdef MTK_3LEVEL_PAGETABLE
  192. /* ATF log is located in DRAM, we must allocate it first */
  193. arch_mmu_map(ROUNDDOWN((uint64_t)local_atf_ramdump_addr, PAGE_SIZE),
  194. ROUNDDOWN((uint32_t)local_atf_ramdump_addr, PAGE_SIZE),
  195. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA,
  196. ROUNDUP(local_atf_ramdump_size, PAGE_SIZE));
  197. #endif
  198. *len = local_atf_ramdump_size;
  199. datasize = dev_write((void *)(uint32_t)local_atf_ramdump_addr, *len);
  200. dprintf(CRITICAL, "ATF: dev_write:%u, local_atf_ramdump_addr:0x%llx, local_atf_ramdump_size:0x%llx\n",
  201. datasize, local_atf_ramdump_addr, local_atf_ramdump_size);
  202. return datasize;
  203. }
  204. void atf_log_init(void)
  205. {
  206. uint32_t smc_id = 0;
  207. uint32_t atf_footprint_hi_addr = 0;
  208. uint32_t atf_footprint_low_addr = 0;
  209. plat_atf_log_get = NULL;
  210. plat_atf_crash_get = NULL;
  211. plat_atf_rdump_get = save_atf_rdump;
  212. plat_atf_footprint_log_get = NULL;//save_atf_footprint;
  213. /* reserve ramdump memory and pass to ATF*/
  214. get_atf_ramdump_memory();
  215. #ifdef MTK_SMC_ID_MGMT
  216. smc_id = MTK_SIP_LK_DUMP_ATF_LOG_INFO;
  217. atf_log_buf_addr = mt_secure_call_ret3(smc_id, 0, 0, 0, 0,
  218. &atf_log_buf_size, &atf_crash_flag_addr);
  219. smc_id = MTK_SIP_BL_ATF_CONTROL_AARCH32;
  220. atf_footprint_hi_addr = mt_secure_call_ret3(smc_id, 0, 0, 0, 0,
  221. &atf_footprint_low_addr,
  222. &atf_footprint_buf_size);
  223. /* atf_footprint_hi_addr may return -1 */
  224. if (atf_footprint_hi_addr == ATF_SMC_UNK) {
  225. dprintf(CRITICAL, "atf_footprint_hi_addr=0x%x(ATF_SMC_UNK)\n",
  226. atf_footprint_hi_addr);
  227. atf_footprint_addr = 0;
  228. atf_footprint_buf_size = 0;
  229. } else { /* Get footprint addr */
  230. atf_footprint_addr = (uintptr_t)atf_footprint_low_addr;
  231. }
  232. #else
  233. smc_id = MTK_SIP_LK_DUMP_ATF_LOG_INFO_AARCH32;
  234. __asm__ volatile("mov r0, %[smcid]\n"
  235. "smc #0x0\n"
  236. "mov %[addr], r0\n"
  237. "mov %[size], r1\n"
  238. "mov %[type], r2\n"
  239. :[addr]"=r"(atf_log_buf_addr), [size]"=r"(atf_log_buf_size),
  240. [type]"=r"(atf_crash_flag_addr):[smcid]"r"(smc_id):"cc",
  241. "r0", "r1" ,"r2", "r3");
  242. atf_footprint_addr = 0;
  243. atf_footprint_buf_size = 0;
  244. #endif
  245. if(atf_log_buf_addr == ATF_SMC_UNK) {
  246. dprintf(CRITICAL, "LK Dump: atf_log_init not supported\n");
  247. } else {
  248. plat_atf_rdump_get = save_atf_rdump;
  249. #ifdef MTK_3LEVEL_PAGETABLE
  250. arch_mmu_map(ROUNDDOWN((uint64_t)atf_crash_flag_addr, PAGE_SIZE),
  251. ROUNDDOWN((uint32_t)atf_crash_flag_addr, PAGE_SIZE),
  252. MMU_MEMORY_TYPE_NORMAL_WRITE_BACK | MMU_MEMORY_AP_P_RW_U_NA,
  253. PAGE_SIZE);
  254. #endif
  255. /* backward compatible for legacy chips */
  256. if (atf_footprint_addr == 0)
  257. plat_atf_footprint_log_get = NULL;
  258. else
  259. plat_atf_footprint_log_get = save_atf_footprint;
  260. if(ATF_CRASH_MAGIC_NO == *(uint32_t *)atf_crash_flag_addr){
  261. dprintf(CRITICAL, "ATF: CRASH BUFF\n");
  262. plat_atf_crash_get = save_atf_log;
  263. } else if(ATF_LAST_LOG_MAGIC_NO == *(uint32_t *)atf_crash_flag_addr){
  264. dprintf(CRITICAL, "ATF: LAST BUFF\n");
  265. plat_atf_log_get = save_atf_log;
  266. } else {
  267. dprintf(CRITICAL, "ATF: RAW BUFF\n");
  268. plat_atf_raw_log_get = save_atf_log;
  269. /* if raw data, do not dump footprint */
  270. plat_atf_footprint_log_get = NULL;
  271. }
  272. dprintf(CRITICAL, "atf_log_buf_addr:0x%x, atf_log_buf_size:%u, atf_crash_flag addr:0x%x, atf_log_type:0x%x\n",
  273. atf_log_buf_addr, atf_log_buf_size, atf_crash_flag_addr,
  274. *(uint32_t *)atf_crash_flag_addr);
  275. dprintf(CRITICAL, "plat_atf_log_get:%p, plat_atf_crash_get:%p\n",
  276. plat_atf_log_get, plat_atf_crash_get);
  277. }
  278. }