blob: fa2f4dfec4fa088a4c2689fc94da3f96ec8a0a3b [file] [log] [blame]
Googler695f9d92023-09-11 15:38:29 +08001/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
Googler06419a42022-05-17 21:32:34 +08002/*
Googler695f9d92023-09-11 15:38:29 +08003 * common/ramdump.c
4 *
5 * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
6 *
Googler15b35d92022-10-03 17:48:21 +08007 */
Googler06419a42022-05-17 21:32:34 +08008
9#include <common.h>
10#include <asm/arch/bl31_apis.h>
Googler695f9d92023-09-11 15:38:29 +080011#include <asm/reboot.h>
Googler06419a42022-05-17 21:32:34 +080012#include <asm/arch/secure_apb.h>
13#include <ramdump.h>
14#include <emmc_partitions.h>
Googler695f9d92023-09-11 15:38:29 +080015#include <asm/cpu_id.h>
Googler06419a42022-05-17 21:32:34 +080016
17#define DEBUG_RAMDUMP 0
Googler06419a42022-05-17 21:32:34 +080018
19unsigned long ramdump_base = 0;
20unsigned long ramdump_size = 0;
21unsigned int get_reboot_mode(void)
22{
23 uint32_t reboot_mode_val = ((readl(AO_SEC_SD_CFG15) >> 12) & 0xf);
Googler695f9d92023-09-11 15:38:29 +080024
Googler06419a42022-05-17 21:32:34 +080025 return reboot_mode_val;
26}
27
28void ramdump_init(void)
29{
30 unsigned int data;
31
32 ramdump_base = readl(P_AO_SEC_GP_CFG12);
33 ramdump_size = readl(P_AO_SEC_GP_CFG13);
34
35 data = readl(PREG_STICKY_REG8);
36 writel(data & ~RAMDUMP_STICKY_DATA_MASK, PREG_STICKY_REG8);
37 printf("%s, add:%lx, size:%lx\n", __func__, ramdump_base, ramdump_size);
38}
39
40/*
41 * NOTE: this is a default impemention for writing compressed ramdump data
42 * to /data/ partition for Android platform. You can read out dumpfile in
43 * path /data/crashdump-1.bin when enter Android for crash analyze.
44 * by default, /data/ partion for android is EXT4 fs.
45 *
46 * TODO:
47 * If you are using different fs or OS on your platform, implement compress
48 * data save command for your fs and OS in your board.c with same function
49 * name "ramdump_save_compress_data".
50 */
51__weak int ramdump_save_compress_data(void)
52{
53 int data_pid;
54 char cmd[128] = {0};
55
56 data_pid = get_partition_num_by_name("data");
57 if (data_pid < 0) {
58 printf("can't find data partition\n");
59 return -1;
60 }
61 sprintf(cmd, "ext4write mmc 1:%x %lx /crashdump-1.bin %lx\n",
62 data_pid, ramdump_base, ramdump_size);
63 printf("CMD:%s\n", cmd);
64 run_command(cmd, 1);
65 return 0;
66}
67
68static void ramdump_env_setup(unsigned long addr, unsigned long size)
69{
70 unsigned int data[10] = {
71 0x8E9C929F, 0x9E9C9791,
72 0xD28C9191, 0x97949B8D,
73 0x888B92, 0xCEBB97,
74 0x938E9B90, 0x978D8D97,
75 0xC8009B8A, 0xB99CDB
76 };
77 char *line, *p1, *p2, *o;
78 unsigned char *p;
79 int i;
80
81 p = (unsigned char *)data;
82 for (i = 0; i < 40; i++)
83 p[i] = ~(p[i] - 1);
84
85 /*
86 * TODO: Make sure address for fdt_high and initrd_high
87 * are suitable for all boards
88 *
89 * usually kernel load address is 0x010800000
90 * Make sure:
91 * (kernel image size + ramdisk size) <
92 * (initrd_high - 0x010800000)
93 * dts file size < (fdt_high - initrd_high)
94 */
Googler695f9d92023-09-11 15:38:29 +080095 setenv("initrd_high", "0x04400000");
96 setenv("fdt_high", "0x04E00000");
97 line = getenv("bootargs");
Googler06419a42022-05-17 21:32:34 +080098 if (!line)
99 return;
100
101 i = strlen(line);
102 o = malloc(i + 128);
103 if (!o)
104 return;
105
106 memset(o, 0, i + 128);
107 memcpy(o, line, i);
108 line = o + i + 128;
109 p1 = strstr(o, (const char *)p);
110 if (p1) {
111 p2 = strchr(p1, ' ');
112 if (!p2)
113 p2 = p1;
114 memmove(p1, p2, line - p2);
115 }
116 i = strlen(o);
117 p1 = o + i;
118 p1[0] = ' ';
119 sprintf(p1 + 1, "%s=%s ramdump=%lx,%lx",
120 (char *)data, (char *)(data + 6), addr, size);
Googler695f9d92023-09-11 15:38:29 +0800121 setenv("bootargs", o);
Googler06419a42022-05-17 21:32:34 +0800122
123#if DEBUG_RAMDUMP
124 run_command("printenv bootargs", 1);
125#endif
126 free(o);
127}
128
129void check_ramdump(void)
130{
131 unsigned long size = 0;
132 unsigned long addr = 0;
133 char *env;
134 int reboot_mode;
135
Googler695f9d92023-09-11 15:38:29 +0800136 env = getenv("ramdump_enable");
Googler06419a42022-05-17 21:32:34 +0800137 if (env) {
138 printf("%s,%s\n", __func__, env);
139 if (!strcmp(env, "1")) {
140 reboot_mode = get_reboot_mode();
141 if ((reboot_mode == AMLOGIC_WATCHDOG_REBOOT ||
142 reboot_mode == AMLOGIC_KERNEL_PANIC)) {
143 addr = ramdump_base;
144 size = ramdump_size;
145 printf("%s, addr:%lx, size:%lx\n",
146 __func__, addr, size);
147 if (addr && size)
148 ramdump_env_setup(addr, size);
149 }
150 }
151 }
152}