blob: 49aeb01cdf003f8ab483384ca3496d6ed7bceca4 [file] [log] [blame]
Bo Lv72d0e902023-01-02 14:27:34 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <common.h>
dongqing.li3d3670e2023-10-17 11:15:45 +08007#include <asm/amlogic/arch/bl31_apis.h>
8#include <asm/amlogic/arch/secure_apb.h>
9#include <amlogic/ramdump.h>
10#include <amlogic/emmc_partitions.h>
Bo Lv72d0e902023-01-02 14:27:34 +000011#include <usb.h>
dongqing.li3d3670e2023-10-17 11:15:45 +080012#include <asm/amlogic/arch/regs.h>
13#include <asm/global_data.h>
14#include <syscon.h>
Bo Lv72d0e902023-01-02 14:27:34 +000015
16#define DEBUG_RAMDUMP 0
17#define AMLOGIC_KERNEL_PANIC 0x0c
18#define AMLOGIC_WATCHDOG_REBOOT 0x0d
Zhongfu Luobef22a72023-12-07 16:30:21 +080019#ifdef CONFIG_USB_STORAGE
dongqing.li3d3670e2023-10-17 11:15:45 +080020static void wait_usb_dev(void);
Zhongfu Luobef22a72023-12-07 16:30:21 +080021#endif
dongqing.li4c9adeb2024-09-14 09:58:20 +000022unsigned long ramdump_base = 0;
23unsigned long ramdump_size = 0;
24
dongqing.li3d3670e2023-10-17 11:15:45 +080025#undef CONFIG_DUMP_COMPRESS_HEAD
Bo Lv72d0e902023-01-02 14:27:34 +000026#ifdef CONFIG_DUMP_COMPRESS_HEAD
27static void dump_info(unsigned int addr, unsigned int size, const char *info)
28{
29 int i = 0;
30
31 printf("\nDUMP %s 0X%08x :", info, addr);
32 for (i = 0; i < size; i += 4) {
33 if (0 == (i % 32))
34 printf("\n[0x%08x] ", addr + i);
35 printf("%08x ", readl(addr + i));
36 }
37 printf("\n\n");
38}
dongqing.li3d3670e2023-10-17 11:15:45 +080039
40int parse_dump_file_v2(const char *base, unsigned long size)
41{
42 struct ram_compress_file_header_v2 *fhead;
43 struct ram_compress_section_header_v2 csh;
44 struct section_info *seg_tbl;
45 unsigned long seg_offset;
46 unsigned int idx;
47 int cnt = 0, csh_size = 0;
48
49 // check ramdump version >= v2.0
50 if ((!strncmp(base, COMPRESS_TAG_HEAD, COMPRESS_TAG_SIZE - 1)) &&
51 (!strncmp(base, COMPRESS_TAG_BL3Z, COMPRESS_TAG_SIZE - 1))) {
52 printf("# Check the crash file head error, exit.\n");
53 return -1;
54 }
55
56 // dump crash section head
57 fhead = (struct ram_compress_file_header_v2 *)base;
58 printf("# total number of segment is %d\n", fhead->section_count);
59 if (fhead->section_count > 10) {
60 printf("# crash file head error. exit.\n");
61 return -1;
62 }
63
64 seg_tbl = malloc(sizeof(struct section_info) * fhead->section_count);
65 printf("# total compress file size is 0x%08lx\n", fhead->file_size);
66 csh_size = sizeof(struct ram_compress_section_header_v2);
67 seg_offset = (unsigned long)fhead + sizeof(struct ram_compress_file_header_v2);
68 printf("# crash file fhead offset is 0x%08lx\n", seg_offset);
69
70 for (cnt = 0; cnt < fhead->section_count; cnt++) {
71 memset(&csh, 0, sizeof(csh));
72 if (seg_offset > ((unsigned long)base + size))
73 continue;
74
75 memcpy((void *)&csh, (char *)seg_offset, sizeof(csh));
76 if (csh.section_index > fhead->section_count) {
77 printf("csh.section_index(%d) > fhead->section_count(%d), error, exit.\n",
78 csh.section_index, fhead->section_count);
79 return -1;
80 }
81
82 if (csh.compress_type == RAM_COMPRESS_ERROR ||
83 csh.compress_type > RAM_COMPRESS_MAX)
84 continue;
85
86 idx = csh.section_index - 1;
87 seg_tbl[idx].offset = seg_offset + sizeof(csh);
88 seg_tbl[idx].type = csh.compress_type;
89 seg_tbl[idx].raw_size = csh.raw_size;
90 seg_tbl[idx].zip_size = csh.zip_size;
91 seg_tbl[idx].val = csh.set_value;
92 seg_offset += csh.zip_size;
93 }
94
95 // dump section table
96 printf("\n-----------------------------------------------------------\n");
97 printf("idx offset type orig size zip size val\n");
98 printf("-----------------------------------------------------------\n");
99 for (cnt = 0; cnt < fhead->section_count; cnt++) {
100 if (seg_tbl[cnt].type == RAM_COMPRESS_ERROR ||
101 seg_tbl[cnt].type > RAM_COMPRESS_MAX)
102 continue;
103 printf(" %2d, 0x%08lx, %2u, 0x%08lx, 0x%08lx, 0x%02x\n",
104 cnt + 1, seg_tbl[cnt].offset,
105 seg_tbl[cnt].type, seg_tbl[cnt].raw_size,
106 seg_tbl[cnt].zip_size, seg_tbl[cnt].val);
107 }
108 printf("-----------------------------------------------------------\n");
109
110 // printf section table
111 for (cnt = 0; cnt < fhead->section_count; cnt++) {
112 if (seg_tbl[cnt].type == RAM_COMPRESS_ERROR ||
113 seg_tbl[cnt].type > RAM_COMPRESS_MAX)
114 continue;
115 dump_info((unsigned int)seg_tbl[cnt].offset - csh_size, csh_size, "crash section head");
116 }
117
118 return 0;
119}
Bo Lv72d0e902023-01-02 14:27:34 +0000120#endif
121
dongqing.li4c9adeb2024-09-14 09:58:20 +0000122static int compare_memory_regions(unsigned int *addr1,
123 unsigned int *addr2,
124 unsigned int total_size,
125 unsigned int block_size)
126{
127 unsigned int row_index, column_index;
128 unsigned int row_max = MD5_PER_ROW_NUM;
129 unsigned int column_max, ddr_size, offset;
130 unsigned int err_addr[5] = {0};
131 unsigned int err_count = 0, ret = 0;
132 unsigned int skip1_index_s, skip1_index_e;
133 unsigned int skip2_index_s, skip2_index_e;
134 unsigned int skip3_index_s;
135 struct rammd5_info_t *md5_info1 = (struct rammd5_info_t *)addr1;
136 struct rammd5_info_t *md5_info2 = (struct rammd5_info_t *)addr2;
137
138 if ((memcmp((char *)addr1, MD5_MAGIC, strlen(MD5_MAGIC)) != 0) ||
139 (memcmp((char *)addr2, MD5_MAGIC, strlen(MD5_MAGIC)) != 0))
140 return 0;
141
142 addr1 += sizeof(struct rammd5_info_t) / sizeof(unsigned int);
143 addr2 += sizeof(struct rammd5_info_t) / sizeof(unsigned int);
144
145 ddr_size = total_size > 0xe0000000 ? 0xe0000000 : total_size;
146 column_max = ddr_size / block_size / row_max;
147
148 /* fix up area1: bl33z reserved */
149 skip1_index_s = min(md5_info1->area1_start, md5_info2->area1_start) / block_size;
150 skip1_index_e = max(md5_info1->area1_end, md5_info2->area1_end) / block_size;
151
152 /* fix up area2: bl31 and bl32 reserved */
153 skip2_index_s = min(md5_info1->area2_start, md5_info2->area2_start) / block_size;
154 skip2_index_e = max(md5_info1->area2_end, md5_info2->area2_end) / block_size + 1;
155
156 /* fix up area3: ramdump compress end ~ ddr_end */
157 skip3_index_s = (ramdump_base + ramdump_size) / block_size + 1;
158
159 printf("ramdump MD5sum check %-7s vs %-7s, skip: %d~%d, %d~%d, %d~ ...",
160 md5_info1->stage, md5_info2->stage, skip1_index_s, skip1_index_e,
161 skip2_index_s, skip2_index_e, skip3_index_s);
162
163 for (column_index = 0; column_index < column_max; column_index++) {
164 for (row_index = 0; row_index < row_max; row_index++) {
165 offset = column_index * row_max + row_index;
166 if ((offset >= skip1_index_s && offset < skip1_index_e) ||
167 (offset >= skip2_index_s && offset < skip2_index_e) ||
168 offset >= skip3_index_s) {
169 continue;
170 } else {
171 if (addr1[offset] != addr2[offset]) {
172 if (err_count < 5)
173 err_addr[err_count++] = offset * block_size;
174 }
175 }
176 }
177 }
178
179 if (err_count == 0) {
180 ret = 0;
181 printf(" PASS.\n");
182 } else {
183 ret = -1;
184 printf(" ERROR !!\n");
185 printf("ramdump Polluted addr: ");
186 for (unsigned int i = 0; i < err_count; i++) {
187 if (err_addr[i] != 0)
188 printf("0x%08x, ", err_addr[i]);
189 }
190 printf(" ...\n");
191
192 for (column_index = 0; column_index < column_max; column_index++) {
193 printf("[0x%8x]:", column_index * row_max * block_size);
194
195 for (row_index = 0; row_index < row_max; row_index++) {
196 offset = column_index * row_max + row_index;
197
198 if ((row_index % 8) == 0)
199 printf(" ");
200 if (addr1[offset] == addr2[offset])
201 printf("- ");
202 else
203 printf("* ");
204 }
205 printf("\n");
206 }
207 }
208
209 return ret;
210}
211
212static int ramdump_save_ddr_md5_info(unsigned long ddr_size,
213 unsigned int block_size,
214 unsigned int *store_addr,
215 char *stage_info)
216{
217 unsigned int i, j;
218 unsigned int total_size, blk_uint_num;
219 unsigned int *src_addr = (unsigned int *)0x0;
220 unsigned long sum = 0;
221 uintptr_t addr_ptr;
222 unsigned int skip1_start, skip2_start;
223 unsigned int skip1_end, skip2_end;
224 struct rammd5_info_t *md5_info;
225
226 /* Max check size is 3.5GB */
227 total_size = ddr_size > 0xe0000000 ? 0xe0000000 : ddr_size;
228
229 /* set ddr md5 skip area */
230#ifdef MD5_SKIP_UBOOT_END
231 skip1_start = MD5_SKIP_UBOOT_START;
232 skip1_end = MD5_SKIP_UBOOT_END;
233#else
234 skip1_start = 0;
235 skip1_end = 0x01800000;
236#endif
237
238#ifdef REG_RSVMEM_SIZE
239 unsigned int data = 0;
240
241 /* bl31/32 rsvmem start */
242 skip2_start = readl(REG_MDUMP_RSVMEM_BL31_START);
243 skip2_end = readl(REG_MDUMP_RSVMEM_BL32_START);
244
245 /* bl32_start + bl32_rsvmem_size = skip2_end */
246 data = readl(REG_RSVMEM_SIZE);
247 if ((data >> 16) & 0xff)
248 skip2_end += (data & 0x0000ffff) << 16;
249 else
250 skip2_end += (data & 0x0000ffff) << 10;
251
252 /* + bl32 stack reserved 1MB */
253 skip2_end += (1 << 20);
254#else
255 printf("ramdump md5 use default bl32 size.\n");
256 skip2_start = 0x05000000;
257 skip2_end = 0x08400000;
258#endif
259 printf("ramdump md5sum skip: 0x%08x~0x%08x, 0x%08x~0x%08x\n",
260 skip1_start, skip1_end, skip2_start, skip2_end);
261
262 md5_info = (struct rammd5_info_t *)store_addr;
263 memcpy(md5_info->magic, MD5_MAGIC, sizeof(md5_info->magic));
264 memcpy(md5_info->stage, stage_info, sizeof(md5_info->stage));
265 md5_info->block_size = block_size;
266 md5_info->ddr_size = ddr_size;
267 md5_info->area1_start = skip1_start;
268 md5_info->area1_end = skip1_end;
269 md5_info->area2_start = skip2_start;
270 md5_info->area2_end = skip2_end;
271
272 store_addr += sizeof(struct rammd5_info_t) / sizeof(unsigned int);
273 printf("ramdump md5sum total=0x%x, block=%x, store_addr=0x%lx\n",
274 total_size, block_size, (unsigned long)store_addr);
275 blk_uint_num = block_size / sizeof(unsigned int);
276 for (i = 0; i < (total_size / block_size - 1); i++) {
277 for (j = 0, sum = 0; j < blk_uint_num; j++) {
278 addr_ptr = (uintptr_t)&src_addr[i * blk_uint_num + j];
279 if ((addr_ptr >= skip1_start && addr_ptr < skip1_end) ||
280 (addr_ptr >= skip2_start && addr_ptr < skip2_end))
281 sum += 0;
282 else
283 sum += src_addr[i * blk_uint_num + j];
284 }
285 *store_addr = (unsigned int)(sum & 0xFFFFFFFF);
286 store_addr++;
287 }
288
289 return 0;
290}
291
292static int ramdump_check_ddr_md5_info(void)
293{
294 int ret1 = 0, ret2 = 0, ret3 = 0;
295 ulong ddr_size = ((readl(SYSCTRL_SEC_STATUS_REG4) & ~0xfffffUL) << 4) >
296 0xe0000000 ? 0xe0000000 : ((readl(SYSCTRL_SEC_STATUS_REG4) & ~0xfffffUL) << 4);
297
298 ramdump_save_ddr_md5_info(ddr_size, MD5_BLOCK_SIZE,
299 (unsigned int *)MD5_BL33X_1_BASE_ADDR, "BL33X");
300
301 /* compare_memory_regions BL2E1 vs BL2E2 */
302 ret1 = compare_memory_regions((unsigned int *)MD5_BL2E_1_BASE_ADDR,
303 (unsigned int *)MD5_BL2E_2_BASE_ADDR, ddr_size, MD5_BLOCK_SIZE);
304
305 /* compare_memory_regions BL2E2 vs BL33Z-1 */
306 ret2 = compare_memory_regions((unsigned int *)MD5_BL2E_2_BASE_ADDR,
307 (unsigned int *)MD5_BL33Z_1_BASE_ADDR, ddr_size, MD5_BLOCK_SIZE);
308
309 /* compare_memory_regions BL33Z-2 vs BL33x */
310 ret3 = compare_memory_regions((unsigned int *)MD5_BL33Z_2_BASE_ADDR,
311 (unsigned int *)MD5_BL33X_1_BASE_ADDR, ddr_size, MD5_BLOCK_SIZE);
312
313 if (ret1 < 0 || ret2 < 0 || ret3 < 0)
314 return -1;
315 else
316 return 0;
317}
318
Bo Lv72d0e902023-01-02 14:27:34 +0000319unsigned int get_reboot_mode(void)
320{
321 uint32_t reboot_mode_val = ((readl(REG_MDUMP_REBOOT_MODE) >> 12) & 0xf);
322 return reboot_mode_val;
323}
324
325void ramdump_init(void)
326{
dongqing.li3d3670e2023-10-17 11:15:45 +0800327 unsigned int data, reboot_mode;
328
Bo Lv72d0e902023-01-02 14:27:34 +0000329 printf("%s, base reg:0x%08x, size reg:0x%08x\n", __func__,
330 REG_MDUMP_COMPRESS_BASE, REG_MDUMP_COMPRESS_SIZE);
331 ramdump_base = readl(REG_MDUMP_COMPRESS_BASE);
332 ramdump_size = readl(REG_MDUMP_COMPRESS_SIZE);
dongqing.li3d3670e2023-10-17 11:15:45 +0800333#if defined(CONFIG_MDUMP_COMPRESS) && defined(CONFIG_COMPRESSED_ADDR)
334 printf("%s, ramdump_base(0x%08lx) is overwritten as 0x%08x\n",
335 __func__, ramdump_base, CONFIG_COMPRESSED_ADDR);
336 ramdump_base = (unsigned long)CONFIG_COMPRESSED_ADDR;
337#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000338 if (ramdump_base & 0x80) {
339 /* 0x80: The flag indicates that the addr exceeds 4G. */
340 /* real size = size[31:0] + addr[6:0]<<32 */
341 ramdump_size += (ramdump_base & 0x7f) << 32;
342 /* real addr = addr[31:8] << 8 */
343 ramdump_base = (ramdump_base & 0xffffff00) << 8;
344 }
345
dongqing.li3d3670e2023-10-17 11:15:45 +0800346 data = readl(REG_MDUMP_CPUBOOT_STATUS);
347 writel(data & ~RAMDUMP_STICKY_DATA_MASK, REG_MDUMP_CPUBOOT_STATUS);
Bo Lv72d0e902023-01-02 14:27:34 +0000348 printf("%s, add:%lx, size:%lx\n", __func__, ramdump_base, ramdump_size);
349
350#ifdef CONFIG_DUMP_COMPRESS_HEAD
351 dump_info((unsigned int)ramdump_base, 0x80, "bl33 check COMPRESS DATA 1");
352#endif
dongqing.li3d3670e2023-10-17 11:15:45 +0800353
354 reboot_mode = get_reboot_mode();
355 if ((reboot_mode == AMLOGIC_WATCHDOG_REBOOT ||
356 reboot_mode == AMLOGIC_KERNEL_PANIC)) {
357 if (ramdump_base && ramdump_size) {
358#ifdef CONFIG_DUMP_COMPRESS_HEAD
359 parse_dump_file_v2((char *)ramdump_base, ramdump_size);
360#endif
dongqing.li4c9adeb2024-09-14 09:58:20 +0000361 if (ramdump_check_ddr_md5_info() < 0)
362 printf("%s, The core-dump is polluted !!!\n\n", __func__);
dongqing.li3d3670e2023-10-17 11:15:45 +0800363 ramdump_save_compress_data();
364 }
365 }
Bo Lv72d0e902023-01-02 14:27:34 +0000366}
367
Zhongfu Luobef22a72023-12-07 16:30:21 +0800368#ifdef CONFIG_USB_STORAGE
Bo Lv72d0e902023-01-02 14:27:34 +0000369static void wait_usb_dev(void)
370{
371 int print_cnt = 0, ret;
372
373 while (1) {
374 run_command("usb start", 1);
375 mdelay(2000);
376 run_command("usb reset", 1);
377 ret = usb_stor_scan(1);
378 if (ret) {
dongqing.li4c9adeb2024-09-14 09:58:20 +0000379 print_cnt++;
380 if (print_cnt > 100) {
381 printf("ramdump: USB device not found after 100 attempts.");
382 printf(" Exiting...\n\n");
383 return;
Bo Lv72d0e902023-01-02 14:27:34 +0000384 }
dongqing.li4c9adeb2024-09-14 09:58:20 +0000385 printf("ramdump: can't find USB device, attempt %d.", print_cnt);
386 printf(" Please insert FAT32 Udisk!\n\n");
dongqing.lia972f8b2024-02-06 11:27:01 +0800387 mdelay(15000);
Bo Lv72d0e902023-01-02 14:27:34 +0000388 } else {
389 run_command("usb dev", 1);
390 break;
391 }
392 }
393}
Zhongfu Luobef22a72023-12-07 16:30:21 +0800394#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000395/*
396 * NOTE: this is a default implementation for writing compressed ramdump data
397 * to /data/ partition for Android platform. You can read out dumpfile in
398 * path /data/crashdump-1.bin when enter Android for crash analyze.
399 * by default, /data/ partition for android is EXT4 fs.
400 *
401 * TODO:
402 * If you are using different fs or OS on your platform, implement compress
403 * data save command for your fs and OS in your board.c with same function
404 * name "ramdump_save_compress_data".
405 */
406__weak int ramdump_save_compress_data(void)
407{
408 char cmd[128] = {0};
409 char *env;
410 int ret = 0;
411
dongqing.lia972f8b2024-02-06 11:27:01 +0800412 env = env_get("ramdump_enable");
413 if (!env || strcmp(env, "1") != 0)
414 return 0;
415
Bo Lv72d0e902023-01-02 14:27:34 +0000416 env = env_get("ramdump_location");
417 if (!env)
418 return 0;
419
420 printf("ramdump_location:%s\n", env);
421 /* currently we only support write to usb disk */
422 if (strncmp(env, "usb", 3)) {
423 printf("not supported location\n");
424 return 0;
425 }
Zhongfu Luobef22a72023-12-07 16:30:21 +0800426#ifdef CONFIG_USB_STORAGE
Bo Lv72d0e902023-01-02 14:27:34 +0000427 wait_usb_dev();
Zhongfu Luobef22a72023-12-07 16:30:21 +0800428#endif
dongqing.lia972f8b2024-02-06 11:27:01 +0800429 printf("\nPrepare to save crash file: base=0x%08lx, size=0x%08lx (%ld MB)\n",
430 ramdump_base, ramdump_size, ramdump_size / 1024 / 1024);
Bo Lv72d0e902023-01-02 14:27:34 +0000431 sprintf(cmd, "fatwrite usb 0 %lx crashdump-1.bin %lx\n",
432 ramdump_base, ramdump_size);
433 printf("CMD:%s\n", cmd);
dongqing.lia972f8b2024-02-06 11:27:01 +0800434#ifdef CONFIG_USB_STORAGE
435 printf("It may take about 3 minutes, please wait...\n");
Bo Lv72d0e902023-01-02 14:27:34 +0000436 ret = run_command(cmd, 0);
dongqing.li3d3670e2023-10-17 11:15:45 +0800437 if (ret != 0) {
438 printf("run fatwrite usb ERROR!\n");
439 return -1;
440 }
441 printf("run fatwrite usb OK!\n");
dongqing.lia972f8b2024-02-06 11:27:01 +0800442#else
443 printf("CONFIG_USB_STORAGE is not defined! Could it be in PRODUCT mode?\n");
444 printf("ERROR: The usb drv is not available!\n");
445#endif
446 printf("Rebooting in 5 seconds ...\n\n\n");
dongqing.li3d3670e2023-10-17 11:15:45 +0800447 mdelay(5000);
dongqing.lia972f8b2024-02-06 11:27:01 +0800448 run_command("reboot", 1);
449 return ret;
Bo Lv72d0e902023-01-02 14:27:34 +0000450}
451
452static void ramdump_env_setup(unsigned long addr, unsigned long size)
453{
454 unsigned int data[10] = {
455 0x8E9C929F, 0x9E9C9791,
456 0xD28C9191, 0x97949B8D,
457 0x888B92, 0xCEBB97,
458 0x938E9B90, 0x978D8D97,
459 0xC8009B8A, 0xB99CDB
460 };
dongqing.lia972f8b2024-02-06 11:27:01 +0800461 char *line, *o;
Bo Lv72d0e902023-01-02 14:27:34 +0000462 unsigned char *p;
463 int i;
464
465 p = (unsigned char *)data;
466 for (i = 0; i < 40; i++)
467 p[i] = ~(p[i] - 1);
468
469 /*
470 * TODO: Make sure address for fdt_high and initrd_high
471 * are suitable for all boards
472 *
473 * usually kernel load address is 0x010800000
474 * Make sure:
475 * (kernel image size + ramdisk size) <
476 * (initrd_high - 0x010800000)
477 * dts file size < (fdt_high - initrd_high)
478 */
dongqing.li3d3670e2023-10-17 11:15:45 +0800479 //env_set("initrd_high", "0x0BB00000");
480 //env_set("fdt_high", "0x0BE00000");
Bo Lv72d0e902023-01-02 14:27:34 +0000481 line = env_get("bootargs");
482 if (!line)
483 return;
484
485 i = strlen(line);
486 o = malloc(i + 128);
487 if (!o)
488 return;
489
490 memset(o, 0, i + 128);
dongqing.lia972f8b2024-02-06 11:27:01 +0800491 sprintf(o, "%s=%s ramdump=%lx,%lx %s\n",
492 (char *)data, (char *)(data + 6), addr, size, line);
Bo Lv72d0e902023-01-02 14:27:34 +0000493 env_set("bootargs", o);
dongqing.lia972f8b2024-02-06 11:27:01 +0800494 free(o);
495 line = NULL;
Bo Lv72d0e902023-01-02 14:27:34 +0000496
497#if DEBUG_RAMDUMP
498 run_command("printenv bootargs", 1);
dongqing.lia972f8b2024-02-06 11:27:01 +0800499 printf("\n");
Bo Lv72d0e902023-01-02 14:27:34 +0000500#endif
Bo Lv72d0e902023-01-02 14:27:34 +0000501}
502
dongqing.li3d3670e2023-10-17 11:15:45 +0800503static int overwrite_bl33z_rsvmem_info(unsigned long addr, unsigned long size)
504{
505 int address_cells = 0;
506 unsigned long align_size = PAGE_ALIGN(size);
507 char cmd[0x80];
508
509 address_cells = fdt_address_cells(gd->fdt_blob, 0);
510 if (address_cells < 1) {
511 printf("%s, bad #address-cells !\n", __func__);
512 return -1;
513 }
514 printf("%s, get fdt #address-cells = %d\n", __func__, address_cells);
515
516 memset(cmd, 0, sizeof(cmd));
517 if (address_cells == 2)
518 sprintf(cmd,
519 "fdt set /reserved-memory/ramdump_bl33z reg '<0x0 0x%08lx 0x0 0x%08lx>'",
520 addr, align_size);
521 else
522 sprintf(cmd, "fdt set /reserved-memory/ramdump_bl33z reg '<0x%08lx 0x%08lx>'",
523 addr, align_size);
524
525 printf("%s\n", cmd);
526 run_command(cmd, 0);
527
528 printf("fdt set /reserved-memory/ramdump_bl33z status okay\n");
529 run_command("fdt set /reserved-memory/ramdump_bl33z status okay", 0);
530
531 return 0;
532}
533
534static int reduce_dts_reserved_memory(void)
535{
536 int address_cells = 0;
537
538 address_cells = fdt_address_cells(gd->fdt_blob, 0);
539 if (address_cells < 1) {
540 printf("%s, bad #address-cells !\n", __func__);
541 return -1;
542 }
543 printf("%s, get fdt #address-cells = %d\n", __func__, address_cells);
544 if (address_cells == 2) {
545 printf("\nReduce dts reserved memory:\n");
546 printf(" * disabled logo_reserved\n");
547 run_command("fdt set /reserved-memory/linux,meson-fb reg '<0x0 0x0 0x0 0x0>'", 0);
548 printf(" * disabled vdin1_cma_reserved\n");
549 run_command("fdt set /reserved-memory/linux,vdin1_cma reg '<0x0 0x0 0x0 0x0>'", 0);
550 printf(" * disabled ion_cma_reserved\n");
551 run_command("fdt set /reserved-memory/linux,ion-dev size '<0 0>'", 0);
552 printf(" * disabled dsp_fw_reserved\n");
553 run_command("fdt set /reserved-memory/linux,dsp_fw size '<0 0>'", 0);
554 printf(" * disabled lcd_tcon_reserved\n");
555 run_command("fdt set /reserved-memory/linux,lcd_tcon reg '<0x0 0x0 0x0 0x0>'", 0);
556 printf(" * reduce codec_mm_cma_reserved\n");
557 run_command("fdt set /reserved-memory/linux,codec_mm_cma size '<0x0 0x5000000>'", 0);
558 printf(" * reduce ion_fb_reserved, display\n");
559 run_command("fdt set /reserved-memory/linux,ion-fb size '<0x0 0x1000000>'", 0);
560 } else {
561 printf("\nReduce dts reserved memory:\n");
562 printf(" * disabled logo_reserved\n");
563 run_command("fdt set /reserved-memory/linux,meson-fb reg '<0x0 0x0>'", 0);
564 printf(" * disabled vdin1_cma_reserved\n");
565 run_command("fdt set /reserved-memory/linux,vdin1_cma reg '<0x0 0x0>'", 0);
566 printf(" * disabled ion_cma_reserved\n");
567 run_command("fdt set /reserved-memory/linux,ion-dev size '<0>'", 0);
568 printf(" * disabled dsp_fw_reserved\n");
569 run_command("fdt set /reserved-memory/linux,dsp_fw size '<0>'", 0);
570 printf(" * disabled lcd_tcon_reserved\n");
571 run_command("fdt set /reserved-memory/linux,lcd_tcon reg '<0x0 0x0>'", 0);
572 printf(" * reduce codec_mm_cma_reserved\n");
573 run_command("fdt set /reserved-memory/linux,codec_mm_cma size '<0x5000000>'", 0);
574 printf(" * reduce ion_fb_reserved, display\n");
575 run_command("fdt set /reserved-memory/linux,ion-fb size '<0x1000000>'", 0);
576 }
577
578 //run_command("fdt print /reserved-memory", 0);
579 return 0;
580}
581
Bo Lv72d0e902023-01-02 14:27:34 +0000582void check_ramdump(void)
583{
584 unsigned long size = 0;
585 unsigned long addr = 0;
586 char *env;
587 int reboot_mode;
dongqing.li3d3670e2023-10-17 11:15:45 +0800588 char str[128] = "";
589 unsigned int ddr_scramble_reg = 0xfe02e030;
Bo Lv72d0e902023-01-02 14:27:34 +0000590
591 env = env_get("ramdump_enable");
592 printf("%s, ramdump_enable = %s\n", __func__, env);
593 if (env) {
594 if (!strcmp(env, "1")) {
595 reboot_mode = get_reboot_mode();
596 if ((reboot_mode == AMLOGIC_WATCHDOG_REBOOT ||
597 reboot_mode == AMLOGIC_KERNEL_PANIC)) {
598 addr = ramdump_base;
599 size = ramdump_size;
600 printf("%s, addr:%lx, size:%lx\n",
601 __func__, addr, size);
602 if (addr && size) {
603 ramdump_env_setup(addr, size);
604#ifdef CONFIG_DUMP_COMPRESS_HEAD
605 dump_info((unsigned int)ramdump_base, 0x80, "bl33 check COMPRESS DATA 2");
606#endif
dongqing.li3d3670e2023-10-17 11:15:45 +0800607 env = env_get("ramdump_location");
dongqing.lia972f8b2024-02-06 11:27:01 +0800608 if (!strncmp(env, "data", 4)) {
dongqing.li3d3670e2023-10-17 11:15:45 +0800609 printf("Crash file will save to Android /data.\n");
610 reduce_dts_reserved_memory();
611 overwrite_bl33z_rsvmem_info(addr, size);
612 env_set("initrd_high", "0x0BB00000");
613 env_set("fdt_high", "0x0BE00000");
614 }
615 } else {
616 ramdump_env_setup(0, 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000617 }
618 } else {
619 ramdump_env_setup(0, 0);
620 }
dongqing.li3d3670e2023-10-17 11:15:45 +0800621#ifndef CONFIG_MDUMP_COMPRESS
622 //ramdump bl33z
Bo Lv72d0e902023-01-02 14:27:34 +0000623 printf("%s, fdt: rsvmem ramdump_bl33z enable.\n", __func__);
624 run_command("fdt set /reserved-memory/ramdump_bl33z status okay", 0);
625#endif
dongqing.li3d3670e2023-10-17 11:15:45 +0800626 //ddr scramble
627 sprintf(str, "setenv initargs ${initargs} scramble_reg=0x%08x",
628 ddr_scramble_reg);
629 printf("set_scramble: %s\n", str);
630 run_command(str, 0);
Bo Lv72d0e902023-01-02 14:27:34 +0000631 }
632 }
633}