blob: 964543d49d9fb483f8cbf2f93bac48a3f527337c [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>
7#include <command.h>
8#include <asm/io.h>
9#include <asm/amlogic/arch/secure_apb.h>
10
11#ifdef CONFIG_CMD_RSVMEM
12
13#if defined(P_AO_SEC_GP_CFG3)
14#define REG_RSVMEM_SIZE P_AO_SEC_GP_CFG3
15#define REG_RSVMEM_BL32_START P_AO_SEC_GP_CFG4
16#define REG_RSVMEM_BL31_START P_AO_SEC_GP_CFG5
17#elif defined(SYSCTRL_SEC_STATUS_REG15)
18#define REG_RSVMEM_SIZE SYSCTRL_SEC_STATUS_REG15
19#define REG_RSVMEM_BL32_START SYSCTRL_SEC_STATUS_REG16
20#define REG_RSVMEM_BL31_START SYSCTRL_SEC_STATUS_REG17
21#endif
22
23//#define RSVMEM_DEBUG_ENABLE
24#ifdef RSVMEM_DEBUG_ENABLE
25#define rsvmem_dbg(fmt...) printf("[rsvmem] "fmt)
26#else
27#define rsvmem_dbg(fmt...)
28#endif
29#define rsvmem_info(fmt...) printf("[rsvmem] "fmt)
30#define rsvmem_err(fmt...) printf("[rsvmem] "fmt)
31
32#ifndef DTB_BIND_KERNEL
33#define RSVMEM_NONE -1
34#define RSVMEM_RESERVED 0
35#define RSVMEM_CMA 1
36#define BL31_SHARE_MEM_SIZE 0x100000
37#ifndef BL32_SHARE_MEM_SIZE
38#define BL32_SHARE_MEM_SIZE 0x400000
39#endif
40
41static int do_rsvmem_check(cmd_tbl_t *cmdtp, int flag, int argc,
42 char *const argv[])
43{
44 unsigned int data = 0;
45 unsigned int bl31_rsvmem_size = 0;
46 unsigned int bl32_rsvmem_size = 0;
47 unsigned int bl31_rsvmem_start = 0;
48 unsigned int bl32_rsvmem_start = 0;
49 unsigned int alignment = 0;
50 unsigned int alignment_temp = 0;
51 unsigned int secure_monitor_size = 0;
52 unsigned int secure_monitor_size_final = 0;
53 unsigned int ramoops_start = 0;
54 int reg_flag = 0;
55 char cmdbuf[128];
56 char *fdtaddr = NULL;
57 int ret = 0;
58 char *temp_env = NULL;
59 int rsvmemtype = RSVMEM_NONE;
60 unsigned int aarch32 = 0;
61
62 rsvmem_dbg("reserved memory check!\n");
63 data = readl(REG_RSVMEM_SIZE);
64 /* workaround for bl3x size */
65 if ((data >> 16) & 0xf0) {
66 bl31_rsvmem_size = ((data & 0xffff0000) >> 16) << 16;
67 bl32_rsvmem_size = (data & 0x0000ffff) << 16;
68 } else {
69 bl31_rsvmem_size = ((data & 0xffff0000) >> 16) << 10;
70 bl32_rsvmem_size = (data & 0x0000ffff) << 10;
71 }
72 bl31_rsvmem_start = readl(REG_RSVMEM_BL31_START);
73 bl32_rsvmem_start = readl(REG_RSVMEM_BL32_START);
74
75 fdtaddr = env_get("fdtaddr");
76 if (fdtaddr == NULL) {
77 rsvmem_err("get fdtaddr NULL!\n");
78 return -1;
79 }
80
81 memset(cmdbuf, 0, sizeof(cmdbuf));
82 sprintf(cmdbuf, "fdt addr %s;", fdtaddr);
83 rsvmem_dbg("CMD: %s\n", cmdbuf);
84 ret = run_command(cmdbuf, 0);
85 if (ret != 0 ) {
86 rsvmem_err("fdt addr error.\n");
87 return -2;
88 }
89
90 memset(cmdbuf, 0, sizeof(cmdbuf));
91 sprintf(cmdbuf, "fdt get value temp_env / \\#address-cells;");
92 ret = run_command(cmdbuf, 0);
93 if (ret != 0) {
94 rsvmem_err("fdt get size #address-cells failed.\n");
95 return -2;
96 }
97 temp_env = env_get("temp_env");
98 //if (temp_env && !strcmp(temp_env, "0x01000000"))
99 if (temp_env && !strcmp(temp_env, "0x00000001"))
100 aarch32 = 1;
101
102 /* Get alignment size
103 * If arm64, alignment has 2 parameters
104 * The second parameter need convert big-endian to little-endian
105 */
106 alignment = 0x400000;
107 memset(cmdbuf, 0, sizeof(cmdbuf));
108 sprintf(cmdbuf, "fdt get value temp_alignment /reserved-memory/linux,secmon alignment;");
109 ret = run_command(cmdbuf, 0);
110 if (!ret) {
111 temp_env = env_get("temp_alignment");
112 alignment_temp = simple_strtoul(temp_env, NULL, 16);
113 if (aarch32) {
114 alignment = alignment_temp;
115 } else {
116 alignment = (alignment_temp & 0xff) << 24;
117 alignment |= (alignment_temp & 0xff00) << 8;
118 alignment |= (alignment_temp & 0xff0000) >> 8;
119 alignment |= (alignment_temp & 0xff000000) >> 24;
120 }
121 }
122
123 memset(cmdbuf, 0, sizeof(cmdbuf));
124 sprintf(cmdbuf, "fdt get value env_compatible /reserved-memory/linux,secmon compatible;");
125 ret = run_command(cmdbuf, 0);
126 if (ret != 0) {
127 rsvmem_err("fdt get prop fail.\n");
128 return -2;
129 }
130 temp_env = env_get("env_compatible");
131 if (strcmp(temp_env, "shared-dma-pool") == 0)
132 rsvmemtype = RSVMEM_CMA;
133 else if (strcmp(temp_env, "amlogic, aml_secmon_memory") == 0)
134 rsvmemtype = RSVMEM_RESERVED;
135 else
136 rsvmemtype = RSVMEM_NONE;
137 if (rsvmemtype == RSVMEM_NONE) {
138 rsvmem_err("env set fail.\n");
139 return -2;
140 }
141 run_command("setenv env_compatible;", 0);
142
143 secure_monitor_size = ((bl31_rsvmem_size + alignment - 1) / alignment) * alignment;
144 secure_monitor_size_final = bl31_rsvmem_size + bl32_rsvmem_size + alignment - 1;
145 secure_monitor_size_final = (secure_monitor_size_final / alignment) * alignment;
146 ramoops_start = bl31_rsvmem_start + bl31_rsvmem_size + bl32_rsvmem_size + alignment - 1;
147 ramoops_start = (ramoops_start / alignment) * alignment;
148
149 if ((bl31_rsvmem_size > 0) && (bl31_rsvmem_start > 0)) {
150 if (rsvmemtype == RSVMEM_RESERVED) {
151 memset(cmdbuf, 0, sizeof(cmdbuf));
152 if (aarch32)
153 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon reg <0x%x 0x%x>;",
154 bl31_rsvmem_start, bl31_rsvmem_size);
155 else
156 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon reg <0x0 0x%x 0x0 0x%x>;",
157 bl31_rsvmem_start, bl31_rsvmem_size);
158 rsvmem_dbg("CMD: %s\n", cmdbuf);
159 ret = run_command(cmdbuf, 0);
160 if (ret != 0 ) {
161 rsvmem_err("bl31 reserved memory set addr error.\n");
162 return -3;
163 }
164 }
165 if (rsvmemtype == RSVMEM_CMA) {
166 /* Check parameter reg, add for linux 5.15 and before */
167 reg_flag = 0;
168 memset(cmdbuf, 0, sizeof(cmdbuf));
169 sprintf(cmdbuf,
170 "fdt get value temp_rsv_reg /reserved-memory/linux,secmon reg;");
171 ret = run_command(cmdbuf, 0);
172 if (!ret) {
173 reg_flag = 1;
174 if (aarch32)
175 sprintf(cmdbuf,
176 "fdt set /reserved-memory/linux,secmon reg <0x%x 0x%x>;",
177 bl31_rsvmem_start, secure_monitor_size);
178 else
179 sprintf(cmdbuf,
180 "fdt set /reserved-memory/linux,secmon reg <0x0 0x%x 0x0 0x%x>;",
181 bl31_rsvmem_start, secure_monitor_size);
182 rsvmem_dbg("CMD: %s\n", cmdbuf);
183 ret = run_command(cmdbuf, 0);
184 if (ret) {
185 rsvmem_err("bl31 reserved memory set reg error.\n");
186 return -3;
187 }
188 }
189
190 memset(cmdbuf, 0, sizeof(cmdbuf));
191 if (aarch32)
192 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon size <0x%x>;",
193 secure_monitor_size);
194 else
195 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon size <0x0 0x%x>;",
196 secure_monitor_size);
197 rsvmem_dbg("CMD: %s\n", cmdbuf);
198 ret = run_command(cmdbuf, 0);
199 if (ret != 0 ) {
200 rsvmem_err("bl31 reserved memory set size error.\n");
201 /*
202 * If reg exist, to modify bl32,
203 * need not return if modify size failed
204 */
205 if (!reg_flag)
206 return -3;
207 }
208 memset(cmdbuf, 0, sizeof(cmdbuf));
209 if (aarch32)
210 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon alloc-ranges <0x%x 0x%x>;",
211 bl31_rsvmem_start, secure_monitor_size);
212 else
213 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon alloc-ranges <0x0 0x%x 0x0 0x%x>;",
214 bl31_rsvmem_start, secure_monitor_size);
215 rsvmem_dbg("CMD: %s\n", cmdbuf);
216 ret = run_command(cmdbuf, 0);
217 if (ret != 0 ) {
218 rsvmem_err("bl31 reserved memory set alloc-ranges error.\n");
219 /*
220 * If reg exist, to modify bl32,
221 * need not return if modify size failed
222 */
223 if (!reg_flag)
224 return -3;
225 }
226 memset(cmdbuf, 0, sizeof(cmdbuf));
227 sprintf(cmdbuf, "fdt set /secmon reserve_mem_size <0x%x>;",
228 bl31_rsvmem_size);
229 rsvmem_dbg("CMD: %s\n", cmdbuf);
230 ret = run_command(cmdbuf, 0);
231 if (ret != 0 ) {
232 rsvmem_err("bl31 reserved memory set reserve_mem_size error.\n");
233 return -3;
234 }
235 }
236 }
237
238 if ((bl32_rsvmem_size > 0) && (bl32_rsvmem_start > 0)) {
239 if ((rsvmemtype == RSVMEM_RESERVED)
240 || ((bl31_rsvmem_start + bl31_rsvmem_size != bl32_rsvmem_start)
241 && (rsvmemtype == RSVMEM_CMA))) {
242 memset(cmdbuf, 0, sizeof(cmdbuf));
243 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secos status okay;");
244 rsvmem_dbg("CMD: %s\n", cmdbuf);
245 ret = run_command(cmdbuf, 0);
246 if (ret != 0 ) {
247 rsvmem_err("bl32 reserved memory set status error.\n");
248 return -3;
249 }
250 memset(cmdbuf, 0, sizeof(cmdbuf));
251 if (aarch32)
252 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secos reg <0x%x 0x%x>;",
253 bl32_rsvmem_start, bl32_rsvmem_size);
254 else
255 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secos reg <0x0 0x%x 0x0 0x%x>;",
256 bl32_rsvmem_start, bl32_rsvmem_size);
257 rsvmem_dbg("CMD: %s\n", cmdbuf);
258 ret = run_command(cmdbuf, 0);
259 if (ret != 0 ) {
260 rsvmem_err("bl32 reserved memory set addr error.\n");
261 return -3;
262 }
263 }
264 if ((bl31_rsvmem_start + bl31_rsvmem_size == bl32_rsvmem_start)
265 && (rsvmemtype == RSVMEM_CMA)) {
266 /* Modify parameter reg, add for linux 5.15 and before */
267 if (reg_flag) {
268 if (aarch32)
269 sprintf(cmdbuf,
270 "fdt set /reserved-memory/linux,secmon reg <0x%x 0x%x>;",
271 bl31_rsvmem_start, secure_monitor_size_final);
272 else
273 sprintf(cmdbuf,
274 "fdt set /reserved-memory/linux,secmon reg <0x0 0x%x 0x0 0x%x>;",
275 bl31_rsvmem_start, secure_monitor_size_final);
276 rsvmem_dbg("CMD: %s\n", cmdbuf);
277 ret = run_command(cmdbuf, 0);
278 if (ret) {
279 rsvmem_err("bl32 reserved memory set reg error.\n");
280 return -3;
281 }
282 }
283
284 memset(cmdbuf, 0, sizeof(cmdbuf));
285 if (aarch32)
286 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon size <0x%x>;",
287 secure_monitor_size_final);
288 else
289 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon size <0x0 0x%x>;",
290 secure_monitor_size_final);
291 rsvmem_dbg("CMD: %s\n", cmdbuf);
292 ret = run_command(cmdbuf, 0);
293 if (ret != 0 ) {
294 rsvmem_err("bl32 reserved memory set size error.\n");
295 /*
296 * If reg exist, to modify reserve_mem_size,
297 * need not return if modify size failed
298 */
299 if (!reg_flag)
300 return -3;
301 }
302
303 memset(cmdbuf, 0, sizeof(cmdbuf));
304 if (aarch32)
305 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon alloc-ranges <0x%x 0x%x>;",
306 bl31_rsvmem_start, secure_monitor_size_final);
307 else
308 sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon alloc-ranges <0x0 0x%x 0x0 0x%x>;",
309 bl31_rsvmem_start, secure_monitor_size_final);
310 rsvmem_dbg("CMD: %s\n", cmdbuf);
311 ret = run_command(cmdbuf, 0);
312 if (ret != 0 ) {
313 rsvmem_err("bl32 reserved memory set alloc-ranges error.\n");
314 /*
315 * If reg exist, to modify reserve_mem_size,
316 * need not return if modify size failed
317 */
318 if (!reg_flag)
319 return -3;
320 }
321
322 memset(cmdbuf, 0, sizeof(cmdbuf));
323 sprintf(cmdbuf, "fdt set /secmon reserve_mem_size <0x%x>;",
324 bl31_rsvmem_size + bl32_rsvmem_size);
325 rsvmem_dbg("CMD: %s\n", cmdbuf);
326 ret = run_command(cmdbuf, 0);
327 if (ret != 0 ) {
328 rsvmem_err("bl32 reserved memory set reserve_mem_size error.\n");
329 return -3;
330 }
331
332 memset(cmdbuf, 0, sizeof(cmdbuf));
333 sprintf(cmdbuf, "fdt get value ramoops_reg /reserved-memory/ramoops reg;");
334 if (run_command(cmdbuf, 0) == 0) {
335 memset(cmdbuf, 0, sizeof(cmdbuf));
336 if (aarch32)
337 sprintf(cmdbuf, "fdt set /reserved-memory/ramoops reg <0x%x 0x%x>;",
338 ramoops_start, 0x100000);
339 else
340 sprintf(cmdbuf, "fdt set /reserved-memory/ramoops reg <0x0 0x%x 0x0 0x%x>;",
341 ramoops_start, 0x100000);
342
343 rsvmem_dbg("CMD: %s\n", cmdbuf);
344 ret = run_command(cmdbuf, 0);
345 if (ret != 0 ) {
346 rsvmem_err("fdt set /reserved-memory/ramoops reg error.\n");
347 return -3;
348 }
349 }
350
351 memset(cmdbuf, 0, sizeof(cmdbuf));
352 sprintf(cmdbuf, "fdt get value secmon_clear_range /secmon clear_range;");
353 if (run_command(cmdbuf, 0) == 0) {
354 memset(cmdbuf, 0, sizeof(cmdbuf));
355 sprintf(cmdbuf, "fdt set /secmon clear_range <0x%x 0x%x>;",
356 bl31_rsvmem_start + BL31_SHARE_MEM_SIZE , bl31_rsvmem_size + bl32_rsvmem_size
357 - BL31_SHARE_MEM_SIZE - BL32_SHARE_MEM_SIZE);
358 rsvmem_dbg("CMD: %s\n", cmdbuf);
359 ret = run_command(cmdbuf, 0);
360 if (ret != 0 ) {
361 rsvmem_err("bl32 reserved memory set clear_range error.\n");
362 return -3;
363 }
364 }
365 }
366 }
367
368 return ret;
369}
370
371static int do_rsvmem_dump(cmd_tbl_t *cmdtp, int flag, int argc,
372 char *const argv[])
373{
374 unsigned int data = 0;
375 unsigned int bl31_rsvmem_size = 0;
376 unsigned int bl32_rsvmem_size = 0;
377 unsigned int bl31_rsvmem_start = 0;
378 unsigned int bl32_rsvmem_start = 0;
379
380 rsvmem_info("reserved memory:\n");
381 data = readl(REG_RSVMEM_SIZE);
382 /* workaround for bl3x size */
383 if ((data >> 16) & 0xf0) {
384 bl31_rsvmem_size = ((data & 0xffff0000) >> 16) << 16;
385 bl32_rsvmem_size = (data & 0x0000ffff) << 16;
386 } else {
387 bl31_rsvmem_size = ((data & 0xffff0000) >> 16) << 10;
388 bl32_rsvmem_size = (data & 0x0000ffff) << 10;
389 }
390 bl31_rsvmem_start = readl(REG_RSVMEM_BL31_START);
391 bl32_rsvmem_start = readl(REG_RSVMEM_BL32_START);
392
393 rsvmem_info("bl31 reserved memory start: 0x%08x\n", bl31_rsvmem_start);
394 rsvmem_info("bl31 reserved memory size: 0x%08x\n", bl31_rsvmem_size);
395 rsvmem_info("bl32 reserved memory start: 0x%08x\n", bl32_rsvmem_start);
396 rsvmem_info("bl32 reserved memory size: 0x%08x\n", bl32_rsvmem_size);
397
398 return 0;
399}
400
401static cmd_tbl_t cmd_rsvmem_sub[] = {
402 U_BOOT_CMD_MKENT(check, 2, 0, do_rsvmem_check, "", ""),
403 U_BOOT_CMD_MKENT(dump, 2, 0, do_rsvmem_dump, "", ""),
404};
405#endif
406
407static int do_rsvmem(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
408{
409#ifdef DTB_BIND_KERNEL
410 rsvmem_err("no check for rsvmem, should check int kernel\n");
411 return 0;
412#else
413 cmd_tbl_t *c;
414
415 /* Strip off leading 'rsvmem' command argument */
416 argc--;
417 argv++;
418
419 c = find_cmd_tbl(argv[0], &cmd_rsvmem_sub[0], ARRAY_SIZE(cmd_rsvmem_sub));
420
421 if (c)
422 return c->cmd(cmdtp, flag, argc, argv);
423 else
424 return CMD_RET_USAGE;
425#endif
426}
427
428U_BOOT_CMD(
429 rsvmem, 2, 0, do_rsvmem,
430 "reserve memory",
431 "check - check reserved memory\n"
432 "rsvmem dump - dump reserved memory\n"
433);
434#endif