blob: be9495dc66d6d2e1a5eee8ce95ad864b03c5a1a4 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2018 MediaTek Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <arch/ops.h>
25#include <boot_args.h>
26#include <env.h>
27#include <lib/kcmdline.h>
28#include <libfdt.h>
29#include <malloc.h>
30#include <mrdump.h>
31#include <platform.h>
32#include <platform/mtk_wdt.h>
33#include <platform/platform_blx.h>
34#include <printf.h>
35#include <ram_console.h>
36#include <stdarg.h>
37#include <stdint.h>
38#include <stdlib.h>
39#include <string.h>
40#include "aee.h"
41#include "kdump.h"
42
43extern BOOT_ARGUMENT *g_boot_arg;
44extern int kedump_restore_mem(void);
45
46#define MRDUMP_RSV_MEM "mrdump_rsvmem=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x"
47#define MRDUMP_CB_RSV_MEM "mrdump_cb=0x%x,0x%x"
48#define RAM_CONSOLE_RSV_MEM "ram_console_rsvmem=0x%x,0x%x"
49#define MINIDUMP_RSV_MEM "minirdump_rsvmem=0x%x,0x%x"
50#define PSTORE_RSV_MEM "pstore_rsvmem=0x%x,0x%x,0x%x,0x%x"
51
52unsigned int get_reboot_reason(unsigned int boot_reason)
53{
54 unsigned int rc_wdt_status;
55 unsigned int rc_exp_type;
56 unsigned int ret = 0;
57 if (boot_reason == BR_WDT_BY_PASS_PWK) {
58 if (ram_console_get_wdt_status(&rc_wdt_status) && ram_console_get_exp_type(&rc_exp_type)){
59 dprintf(CRITICAL, "rc_wdt_status = %d, rc_exp_type = %d\n", rc_wdt_status, rc_exp_type);
60 switch (rc_exp_type) {
61 case 0:
62 if (rc_wdt_status == 5)
63 ret = REBOOT_REASON_WATCHDOG;
64 break;
65 case AEE_EXP_TYPE_HWT:
66 ret = REBOOT_REASON_WATCHDOG;
67 break;
68 case AEE_EXP_TYPE_DM_VERITY_CORRUPTION:
69 ret = REBOOT_REASON_DM_VERITY_CORRUPTION;
70 break;
71 case AEE_EXP_TYPE_KE:
72 case AEE_EXP_TYPE_NESTED_PANIC:
73 ret = REBOOT_REASON_KERNEL_PANIC;
74 break;
75 default:
76 break;
77 }
78 }
79 }
80 else if (boot_reason == BR_2SEC_REBOOT) {
81 ret = REBOOT_REASON_2S_REBOOT;
82 } else {
83 ret = REBOOT_REASON_REBOOT;
84 }
85 return ret;
86}
87
88static void mrdump_ddr_reserved_mode_control(void)
89{
90 if (g_boot_arg->ddr_reserve_ready != AEE_MRDUMP_DDR_RSV_READY) {
91 kcmdline_append("mrdump_ddrsv=no");
92 dprintf(CRITICAL, "MT-RAMDUMP: DDR reserve mode not ready, skipped (0x%x)\n",
93 g_boot_arg->ddr_reserve_ready);
94 } else
95 kcmdline_append("mrdump_ddrsv=yes");
96}
97
98void mrdump_setup_boot_reason(void)
99{
100 unsigned int boot_reason = 0;
101 unsigned int reboot_reason = 0;
102 char tmpbuf[128];
103 unsigned int len_bootreason=0;
104 const char aee_reboot_reason[][20] = {"reboot", "watchdog", "kernel_panic", "oemerr_2sec_reboot","dmveri_corruption"};
105
106 boot_reason = platform_boot_status();
107 reboot_reason=get_reboot_reason(boot_reason);
108 len_bootreason = strlen(" androidboot.bootreason=") + strlen(aee_reboot_reason[reboot_reason]);
109 snprintf(tmpbuf,len_bootreason,"%s%s", "androidboot.bootreason=",aee_reboot_reason[reboot_reason]);
110 dprintf(CRITICAL, "tmpbuf %s\n", tmpbuf);
111 kcmdline_append(tmpbuf);
112}
113
114void mrdump_append_cmdline(void)
115{
116 mrdump_ddr_reserved_mode_control();
117 /* mrdump control block reserve memory*/
118#ifdef MTK_MRDUMP_SRAM_CB
119 aee_reserve_memory(MRDUMP_CB_RSV_MEM, MRDUMP_CB_ADDR, MRDUMP_CB_SIZE);
120#endif
121
122 /* mrdump reserve memory*/
123 aee_reserve_memory(MRDUMP_RSV_MEM, MEMBASE, AEE_MRDUMP_LK_RSV_SIZE,
124 DRAM_BOOTARG_BASE, DRAM_BOOTARG_SIZE, DRAM_ARENA_BASE,
125 DRAM_ARENA_SIZE, kvaddr_to_paddr((void *)UNCACHED_MEMPOOL_ADDR),
126 UNCACHED_MEMPOOL_SIZE, kvaddr_to_paddr((void *)CACHED_MEMPOOL_ADDR),
127 CACHED_MEMPOOL_SIZE);
128
129 /* ram_console reserve memory*/
130#if RAM_CONSOLE_DRAM_ADDR
131 aee_reserve_memory(RAM_CONSOLE_RSV_MEM, RAM_CONSOLE_DEF_ADDR,
132 RAM_CONSOLE_DEF_SIZE);
133#endif
134
135 /* minidump reserve memory*/
136#if MINIRDUMP_MEM_ADDR
137 aee_reserve_memory(MINIDUMP_RSV_MEM, MINIRDUMP_MEM_ADDR,
138 MINIRDUMP_MEM_SIZE);
139#endif
140
141 /* pstore reserve memory*/
142#if PSTORE_RESERVE_ADDR
143 aee_reserve_memory(PSTORE_RSV_MEM, PSTORE_RESERVE_ADDR, PSTORE_RESERVE_SIZE,
144 PSTORE_CONSOEL_SIZE, PSTORE_PMSG_SIZE);
145#endif
146 mrdump_setup_version();
147 mrdump_setup_boot_reason();
148}
149
150static int kedump_get_bootreason(unsigned int wdt_status)
151{
152 unsigned int g_rgu_status = 0;
153
154 if (wdt_status & MTK_WDT_STATUS_HWWDT_RST) {
155 /* For E1 bug, that SW reset value is 0xC000, we using "==" to check */
156 /* Time out reboot always by pass power key */
157 g_rgu_status = RE_BOOT_BY_WDT_HW;
158 } else if (wdt_status & MTK_WDT_STATUS_SWWDT_RST) {
159 g_rgu_status = RE_BOOT_BY_WDT_SW;
160 } else {
161 g_rgu_status = RE_BOOT_REASON_UNKNOW;
162 }
163
164 if (wdt_status & MTK_WDT_STATUS_IRQWDT_RST) {
165 g_rgu_status |= RE_BOOT_WITH_INTTERUPT;
166 }
167#ifdef MTK_THERMAL_RESET_SUPPORT
168 if (wdt_status & MTK_WDT_STATUS_SPM_THERMAL_RST) {
169 g_rgu_status |= RE_BOOT_BY_SPM_THERMAL;
170 }
171#endif
172 if (wdt_status & MTK_WDT_STATUS_SPMWDT_RST) {
173 g_rgu_status |= RE_BOOT_BY_SPM;
174 }
175 if (wdt_status & MTK_WDT_STATUS_THERMAL_CTL_RST) {
176 g_rgu_status |= RE_BOOT_BY_THERMAL_DIRECT;
177 }
178 if (wdt_status & MTK_WDT_STATUS_DEBUGWDT_RST) {
179 g_rgu_status |= RE_BOOT_BY_DEBUG;
180 }
181 if (wdt_status & MTK_WDT_STATUS_SECURITY_RST) {
182 g_rgu_status |= RE_BOOT_BY_SECURITY;
183 }
184
185#ifdef MTK_PMIC_FULL_RESET
186 if (mtk_wdt_is_pmic_full_reset())
187 g_rgu_status |= RE_BOOT_BY_PMIC_FULL_RST;
188#endif
189 return g_rgu_status;
190}
191
192int kedump_init(void)
193{
194 static int kedump_dumped = 0;
195 unsigned int boot_reason = kedump_get_bootreason(g_boot_arg->boot_reason);
196
197 pl_ram_console_init();
198 ram_console_reboot_reason_save(boot_reason);
199
200 ram_console_init();
201
202 /* this flow should be executed once only */
203 if (kedump_dumped == 0) {
204 kedump_dumped = 1;
205 if (ram_console_is_abnormal_boot())
206 return -1;
207 }
208
209 // for power lost or reboot before KE DB collected scenario
210 kedump_restore_mem();
211 return 0;
212}