| /* |
| * common/cmd_rsvmem.c |
| * |
| * Copyright (C) 2015 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| * more details. |
| * |
| */ |
| |
| #include <common.h> |
| #include <command.h> |
| #include <asm/io.h> |
| #include <asm/arch/secure_apb.h> |
| |
| #ifdef CONFIG_CMD_RSVMEM |
| |
| //#define RSVMEM_DEBUG_ENABLE |
| #ifdef RSVMEM_DEBUG_ENABLE |
| #define rsvmem_dbg(fmt...) printf("[rsvmem] "fmt) |
| #else |
| #define rsvmem_dbg(fmt...) |
| #endif |
| #define rsvmem_info(fmt...) printf("[rsvmem] "fmt) |
| #define rsvmem_err(fmt...) printf("[rsvmem] "fmt) |
| |
| #ifndef DTB_BIND_KERNEL |
| #define RSVMEM_NONE -1 |
| #define RSVMEM_RESERVED 0 |
| #define RSVMEM_CMA 1 |
| static int do_rsvmem_check(cmd_tbl_t *cmdtp, int flag, int argc, |
| char *const argv[]) |
| { |
| unsigned int data = 0; |
| unsigned int bl31_rsvmem_size = 0; |
| unsigned int bl32_rsvmem_size = 0; |
| unsigned int bl31_rsvmem_start = 0; |
| unsigned int bl32_rsvmem_start = 0; |
| char cmdbuf[128]; |
| char *fdtaddr = NULL; |
| int ret = 0; |
| char *temp_env = NULL; |
| int rsvmemtype = RSVMEM_NONE; |
| |
| rsvmem_dbg("reserved memory check!\n"); |
| data = readl(P_AO_SEC_GP_CFG3); |
| bl31_rsvmem_size = ((data & 0xffff0000) >> 16) << 10; |
| bl32_rsvmem_size = (data & 0x0000ffff) << 10; |
| bl31_rsvmem_start = readl(P_AO_SEC_GP_CFG5); |
| bl32_rsvmem_start = readl(P_AO_SEC_GP_CFG4); |
| |
| fdtaddr = getenv("fdtaddr"); |
| if (fdtaddr == NULL) { |
| rsvmem_err("get fdtaddr NULL!\n"); |
| return -1; |
| } |
| |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt addr %s;", fdtaddr); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("fdt addr error.\n"); |
| return -2; |
| } |
| |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt get value env_compatible /reserved-memory/linux,secmon compatible;"); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0) { |
| rsvmem_err("fdt get prop fail.\n"); |
| return -2; |
| } |
| temp_env = getenv("env_compatible"); |
| if (strcmp(temp_env, "shared-dma-pool") == 0) |
| rsvmemtype = RSVMEM_CMA; |
| else if (strcmp(temp_env, "amlogic, aml_secmon_memory") == 0) |
| rsvmemtype = RSVMEM_RESERVED; |
| else |
| rsvmemtype = RSVMEM_NONE; |
| if (rsvmemtype == RSVMEM_NONE) { |
| rsvmem_err("env set fail.\n"); |
| return -2; |
| } |
| run_command("setenv env_compatible;", 0); |
| |
| if ((bl31_rsvmem_size > 0) && (bl31_rsvmem_start > 0)) { |
| if (rsvmemtype == RSVMEM_RESERVED) { |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon reg <0x0 0x%x 0x0 0x%x>;", |
| bl31_rsvmem_start, bl31_rsvmem_size); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl31 reserved memory set addr error.\n"); |
| return -3; |
| } |
| } |
| if (rsvmemtype == RSVMEM_CMA) { |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon size <0x0 0x%x>;", |
| ((bl31_rsvmem_size + 0x400000 - 1) / 0x400000)*0x400000); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl31 reserved memory set size error.\n"); |
| return -3; |
| } |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon alloc-ranges <0x0 0x%x 0x0 0x%x>;", |
| bl31_rsvmem_start, ((bl31_rsvmem_size + 0x400000 - 1) / 0x400000)*0x400000); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl31 reserved memory set alloc-ranges error.\n"); |
| return -3; |
| } |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /secmon reserve_mem_size <0x%x>;", |
| bl31_rsvmem_size); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl31 reserved memory set reserve_mem_size error.\n"); |
| return -3; |
| } |
| } |
| } |
| |
| if ((bl32_rsvmem_size > 0) && (bl32_rsvmem_start > 0)) { |
| if ((rsvmemtype == RSVMEM_RESERVED) |
| || ((bl31_rsvmem_start + bl31_rsvmem_size != bl32_rsvmem_start) |
| && (rsvmemtype == RSVMEM_CMA))) { |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secos status okay;"); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl32 reserved memory set status error.\n"); |
| return -3; |
| } |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secos reg <0x0 0x%x 0x0 0x%x>;", |
| bl32_rsvmem_start, bl32_rsvmem_size); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl32 reserved memory set addr error.\n"); |
| return -3; |
| } |
| } |
| if ((bl31_rsvmem_start + bl31_rsvmem_size == bl32_rsvmem_start) |
| && (rsvmemtype == RSVMEM_CMA)) { |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon size <0x0 0x%x>;", |
| ((bl31_rsvmem_size + bl32_rsvmem_size + 0x400000 - 1) / 0x400000)*0x400000); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl32 reserved memory set size error.\n"); |
| return -3; |
| } |
| |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /reserved-memory/linux,secmon alloc-ranges <0x0 0x%x 0x0 0x%x>;", |
| bl31_rsvmem_start, |
| ((bl31_rsvmem_size + bl32_rsvmem_size + 0x400000 - 1) / 0x400000)*0x400000); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl32 reserved memory set alloc-ranges error.\n"); |
| return -3; |
| } |
| |
| memset(cmdbuf, 0, sizeof(cmdbuf)); |
| sprintf(cmdbuf, "fdt set /secmon reserve_mem_size <0x%x>;", |
| bl31_rsvmem_size + bl32_rsvmem_size); |
| rsvmem_dbg("CMD: %s\n", cmdbuf); |
| ret = run_command(cmdbuf, 0); |
| if (ret != 0 ) { |
| rsvmem_err("bl32 reserved memory set reserve_mem_size error.\n"); |
| return -3; |
| } |
| } |
| } |
| |
| return ret; |
| } |
| |
| static int do_rsvmem_dump(cmd_tbl_t *cmdtp, int flag, int argc, |
| char *const argv[]) |
| { |
| unsigned int data = 0; |
| unsigned int bl31_rsvmem_size = 0; |
| unsigned int bl32_rsvmem_size = 0; |
| unsigned int bl31_rsvmem_start = 0; |
| unsigned int bl32_rsvmem_start = 0; |
| |
| rsvmem_info("reserved memory:\n"); |
| data = readl(P_AO_SEC_GP_CFG3); |
| bl31_rsvmem_size = ((data & 0xffff0000) >> 16) << 10; |
| bl32_rsvmem_size = (data & 0x0000ffff) << 10; |
| bl31_rsvmem_start = readl(P_AO_SEC_GP_CFG5); |
| bl32_rsvmem_start = readl(P_AO_SEC_GP_CFG4); |
| |
| rsvmem_info("bl31 reserved memory start: 0x%08x\n", bl31_rsvmem_start); |
| rsvmem_info("bl31 reserved memory size: 0x%08x\n", bl31_rsvmem_size); |
| rsvmem_info("bl32 reserved memory start: 0x%08x\n", bl32_rsvmem_start); |
| rsvmem_info("bl32 reserved memory size: 0x%08x\n", bl32_rsvmem_size); |
| |
| return 0; |
| } |
| |
| static cmd_tbl_t cmd_rsvmem_sub[] = { |
| U_BOOT_CMD_MKENT(check, 2, 0, do_rsvmem_check, "", ""), |
| U_BOOT_CMD_MKENT(dump, 2, 0, do_rsvmem_dump, "", ""), |
| }; |
| #endif |
| |
| static int do_rsvmem(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
| { |
| #ifdef DTB_BIND_KERNEL |
| rsvmem_err("no check for rsvmem, should check int kernel\n"); |
| return 0; |
| #else |
| cmd_tbl_t *c; |
| |
| /* Strip off leading 'rsvmem' command argument */ |
| argc--; |
| argv++; |
| |
| c = find_cmd_tbl(argv[0], &cmd_rsvmem_sub[0], ARRAY_SIZE(cmd_rsvmem_sub)); |
| |
| if (c) |
| return c->cmd(cmdtp, flag, argc, argv); |
| else |
| return CMD_RET_USAGE; |
| #endif |
| } |
| |
| U_BOOT_CMD( |
| rsvmem, 2, 0, do_rsvmem, |
| "reserve memory", |
| "check - check reserved memory\n" |
| "rsvmem dump - dump reserved memory\n" |
| ); |
| #endif |