ram_console.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include <string.h>
  2. #include "dram_buffer.h"
  3. #include "ram_console.h"
  4. #define RAM_CONSOLE_SIG (0x43474244) /* DBGC */
  5. #define MOD "RAM_CONSOLE"
  6. struct ram_console_buffer {
  7. u32 sig;
  8. /* for size comptible */
  9. u32 off_pl;
  10. u32 off_lpl; /* last preloader */
  11. u32 sz_pl;
  12. u32 off_lk;
  13. u32 off_llk; /* last lk */
  14. u32 sz_lk;
  15. u32 padding[4]; /* size = 4 * 16 = 64 byte */
  16. u32 off_linux;
  17. u32 off_console;
  18. u32 padding2[3];
  19. };
  20. struct reboot_reason_pl {
  21. u32 wdt_status;
  22. u32 last_func[RAM_CONSOLE_PL_SIZE];
  23. };
  24. struct reboot_reason_kernel {
  25. u32 fiq_step;
  26. u32 exp_type; /* 0xaeedeadX: X=1 (HWT), X=2 (KE), X=3 (nested panic) */
  27. u32 others[0];
  28. };
  29. static struct ram_console_buffer *ram_console = NULL;
  30. static int ram_console_size;
  31. #define ALIGN(x, size) ((x + size - 1) & ~(size - 1))
  32. static void ram_console_fatal(const char *str)
  33. {
  34. print("%s FATAL:%s\n", MOD, str);
  35. while(1)
  36. ;
  37. }
  38. #define bootarg g_dram_buf->bootarg
  39. void ram_console_mblock_reserve(void)
  40. {
  41. u64 addr_res;
  42. addr_res = mblock_reserve_ext(&bootarg.mblock_info, RAM_CONSOLE_DRAM_SIZE, 0x10000/*align*/, (RAM_CONSOLE_DRAM_ADDR + RAM_CONSOLE_DRAM_SIZE), 0, "ram_console");
  43. if (addr_res != RAM_CONSOLE_DRAM_ADDR)
  44. ram_console_fatal("reserve dram memory failed");
  45. addr_res = mblock_reserve_ext(&bootarg.mblock_info, PSTORE_SIZE, 0x10000/*align*/, (PSTORE_ADDR + PSTORE_SIZE), 0, "pstore");
  46. if (addr_res != PSTORE_ADDR)
  47. ram_console_fatal("reserve pstore memory failed");
  48. addr_res = mblock_reserve_ext(&bootarg.mblock_info, MRDUMP_MINI_HEADER_SIZE, 0x10000/*align*/, (MRDUMP_MINI_HEADER_ADDR + MRDUMP_MINI_HEADER_SIZE), 0, "minirdump");
  49. if (addr_res != MRDUMP_MINI_HEADER_ADDR)
  50. ram_console_fatal("reserve minirdump memory failed");
  51. }
  52. void ram_console_init(void)
  53. {
  54. int i;
  55. struct reboot_reason_pl *rr_pl;
  56. ram_console = (struct ram_console_buffer *)RAM_CONSOLE_SRAM_ADDR;
  57. u32 def_type;
  58. def_type = ram_console_def_memory();
  59. if (def_type == RAM_CONSOLE_DEF_SRAM) {
  60. print("%s using SRAM\n", MOD);
  61. ram_console = (struct ram_console_buffer *)RAM_CONSOLE_SRAM_ADDR;
  62. ram_console_size = RAM_CONSOLE_SRAM_SIZE;
  63. } else if (def_type == RAM_CONSOLE_DEF_DRAM) {
  64. print("%s using DRAM\n", MOD);
  65. ram_console = (struct ram_console_buffer *)RAM_CONSOLE_DRAM_ADDR;
  66. ram_console_size = RAM_CONSOLE_DRAM_SIZE;
  67. } else {
  68. print("%s def type:%d\n", MOD, def_type);
  69. ram_console_fatal("[pl] unknown def type");
  70. }
  71. print("%s start: 0x%x, size: 0x%x, sig: 0x%x\n", MOD, ram_console, ram_console_size, ram_console->sig);
  72. if (ram_console->sig == RAM_CONSOLE_SIG && ram_console->sz_pl == sizeof(struct reboot_reason_pl) && ram_console->off_pl + ALIGN(ram_console->sz_pl, 64) == ram_console->off_lpl) {
  73. print("%s preloader last status: ", MOD);
  74. rr_pl = (void*)ram_console + ram_console->off_pl;
  75. for (i = 0; i < RAM_CONSOLE_PL_SIZE; i++) {
  76. print("0x%x ", rr_pl->last_func[i]);
  77. }
  78. print("\n");
  79. memcpy((void *)ram_console + ram_console->off_lpl, (void *)ram_console + ram_console->off_pl, ram_console->sz_pl);
  80. } else {
  81. memset(ram_console, 0, ram_console_size);
  82. ram_console->sig = RAM_CONSOLE_SIG;
  83. ram_console->off_pl = sizeof(struct ram_console_buffer);
  84. ram_console->sz_pl = sizeof(struct reboot_reason_pl);
  85. ram_console->off_lpl = ram_console->off_pl + ALIGN(ram_console->sz_pl, 64);
  86. print("%s init done\n", MOD);
  87. }
  88. }
  89. void ram_console_reboot_reason_save(u32 rgu_status)
  90. {
  91. struct reboot_reason_pl *rr_pl;
  92. if (ram_console) {
  93. rr_pl = (void*)ram_console + ram_console->off_pl;
  94. rr_pl->wdt_status = rgu_status;
  95. print("%s wdt status (0x%x)=0x%x\n", MOD,
  96. rr_pl->wdt_status, rgu_status);
  97. }
  98. }
  99. void ram_console_pl_save(unsigned int val, int index)
  100. {
  101. struct reboot_reason_pl *rr_pl;
  102. if (ram_console) {
  103. rr_pl = (void*)ram_console + ram_console->off_pl;
  104. if (index < RAM_CONSOLE_PL_SIZE)
  105. rr_pl->last_func[index] = val;
  106. }
  107. }
  108. #define RE_BOOT_BY_WDT_SW 2
  109. #define RE_BOOT_NORMAL_BOOT 0
  110. #define RE_BOOT_FULL_PMIC 0x800
  111. bool ram_console_is_abnormal_boot(void)
  112. {
  113. unsigned int fiq_step, wdt_status, exp_type;
  114. if (!ram_console) {
  115. ram_console_init();
  116. }
  117. wdt_status = ((struct reboot_reason_pl*)((void*)ram_console + ram_console->off_pl))->wdt_status;
  118. if (wdt_status != RE_BOOT_NORMAL_BOOT && wdt_status != RE_BOOT_BY_WDT_SW && wdt_status != RE_BOOT_FULL_PMIC) {
  119. print("%s detect abnormal boot wdt_status:0x%x ", MOD, wdt_status);
  120. return true;
  121. }
  122. if (ram_console && ram_console->off_linux && ram_console->off_linux < ram_console_size && ram_console->off_pl < ram_console_size) {
  123. fiq_step = ((struct reboot_reason_kernel*)((void*)ram_console + ram_console->off_linux))->fiq_step;
  124. exp_type = ((struct reboot_reason_kernel*)((void*)ram_console + ram_console->off_linux))->exp_type;
  125. print("%s wdt_status 0x%x, fiq_step 0x%x, exp_type 0x%x\n", MOD, wdt_status, fiq_step, (exp_type ^ 0xaeedead0) < 16 ? exp_type ^ 0xaeedead0 : exp_type);
  126. if (fiq_step != 0 && (exp_type ^ 0xaeedead0) >= 16) {
  127. fiq_step = 0;
  128. ((struct reboot_reason_kernel*)((void*)ram_console + ram_console->off_linux))->fiq_step = fiq_step;
  129. }
  130. if ((fiq_step == 0 && (wdt_status == RE_BOOT_BY_WDT_SW || wdt_status == RE_BOOT_FULL_PMIC)) || (wdt_status == RE_BOOT_NORMAL_BOOT))
  131. return false;
  132. else
  133. return true;
  134. }
  135. return false;
  136. }
  137. u32 ram_console_def_memory(void)
  138. {
  139. if (RAM_CONSOLE_DEF_ADDR == RAM_CONSOLE_SRAM_ADDR)
  140. return RAM_CONSOLE_DEF_SRAM;
  141. else if (RAM_CONSOLE_DEF_ADDR == RAM_CONSOLE_DRAM_ADDR)
  142. return RAM_CONSOLE_DEF_DRAM;
  143. else
  144. return RAM_CONSOLE_DEF_UNKNOWN;
  145. }
  146. void ram_console_sram_addr_size(u32 *addr, int *size)
  147. {
  148. if (addr != NULL)
  149. *addr = RAM_CONSOLE_SRAM_ADDR;
  150. if (size != NULL)
  151. *size = RAM_CONSOLE_SRAM_SIZE;
  152. }
  153. #define SHOW_ARGS(p, a, b, c, d) \
  154. print("RAM_CONSOLE " #a":0x%x, "#b":0x%x, "#c":0x%x, "#d":0x%x\n", (p)->a, (p)->b, (p)->c, (p)->d)
  155. static void ram_console_memory_info_show(struct ram_console_memory_info *memory_info)
  156. {
  157. if (memory_info == NULL) {
  158. print("%s. %s args null\n", MOD, __func__);
  159. return;
  160. }
  161. SHOW_ARGS(memory_info, sram_plat_dbg_info_addr, sram_plat_dbg_info_size, sram_log_store_addr, sram_log_store_size);
  162. SHOW_ARGS(memory_info, mrdump_addr, mrdump_size, dram_addr, dram_size);
  163. SHOW_ARGS(memory_info, pstore_addr, pstore_size, pstore_console_size, pstore_pmsg_size);
  164. SHOW_ARGS(memory_info, mrdump_mini_header_addr, mrdump_mini_header_size, magic1, magic2);
  165. }
  166. u32 ram_console_memory_info_offset(void)
  167. {
  168. #ifdef RAM_CONSOLE_SRAM_SIZE_OVERALL
  169. struct ram_console_memory_info *memory_info;
  170. u32 offset = RAM_CONSOLE_MEMORY_INFO_OFFSET;
  171. print("%s offset:0x%x\n", MOD, offset);
  172. if (offset <= 0 || offset >= RAM_CONSOLE_SRAM_SIZE_OVERALL) {
  173. print("%s. illegal offset\n", MOD);
  174. return 0;
  175. }
  176. memory_info = (struct ram_console_memory_info *)(RAM_CONSOLE_SRAM_ADDR + offset);
  177. memset(memory_info, 0, sizeof(struct ram_console_memory_info));
  178. memory_info->magic1 = MEM_MAGIC1;
  179. memory_info->sram_plat_dbg_info_addr = RAM_CONSOLE_PLAT_DBG_INFO_ADDR;
  180. memory_info->sram_plat_dbg_info_size = RAM_CONSOLE_PLAT_DBG_INFO_SIZE;
  181. memory_info->sram_log_store_addr = RAM_CONSOLE_LOG_STORE_ADDR;
  182. memory_info->sram_log_store_size = RAM_CONSOLE_LOG_STORE_SIZE;
  183. memory_info->mrdump_addr = RAM_CONSOLE_MRDUMP_ADDR;
  184. memory_info->mrdump_size = RAM_CONSOLE_MRDUMP_SIZE;
  185. memory_info->dram_addr = RAM_CONSOLE_DRAM_ADDR;
  186. memory_info->dram_size = RAM_CONSOLE_DRAM_SIZE;
  187. memory_info->pstore_addr = PSTORE_ADDR;
  188. memory_info->pstore_size = PSTORE_SIZE;
  189. memory_info->pstore_console_size = PSTORE_CONSOLE_SIZE;
  190. memory_info->pstore_pmsg_size = PSTORE_PMSG_SIZE;
  191. memory_info->mrdump_mini_header_addr = MRDUMP_MINI_HEADER_ADDR;
  192. memory_info->mrdump_mini_header_size = MRDUMP_MINI_HEADER_SIZE;
  193. memory_info->magic2 = MEM_MAGIC2;
  194. ram_console_memory_info_show(memory_info);
  195. return offset;
  196. #else
  197. return 0;
  198. #endif
  199. }