aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Przywara <andre.przywara@arm.com>2020-08-03 10:37:27 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2020-08-03 10:37:27 +0000
commitadca03e6966d041e77e5ffda4c2884b92938d83f (patch)
tree0cf1a0bb30ab83672915f3949ee5213b68e336e1
parentcf44cb2c65e7472153a9e5bb2d3cbe0d08cdd3d3 (diff)
parentfa30f73b37b498273ec0b315048c06315c7c25e3 (diff)
downloadtrusted-firmware-a-adca03e6966d041e77e5ffda4c2884b92938d83f.tar.gz
Merge "arm_fpga: Support uploading a custom command line" into integration
-rw-r--r--plat/arm/board/arm_fpga/fpga_bl31_setup.c78
-rw-r--r--plat/arm/board/arm_fpga/fpga_private.h1
-rw-r--r--plat/arm/board/arm_fpga/platform.mk3
3 files changed, 82 insertions, 0 deletions
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index 6eeff451cc..9db107cc88 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -128,6 +128,84 @@ unsigned int plat_get_syscnt_freq2(void)
FPGA_DEFAULT_TIMER_FREQUENCY);
}
+static void fpga_prepare_dtb(void)
+{
+ void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE;
+ const char *cmdline = (void *)(uintptr_t)FPGA_PRELOADED_CMD_LINE;
+ int err;
+
+ err = fdt_open_into(fdt, fdt, FPGA_MAX_DTB_SIZE);
+ if (err < 0) {
+ ERROR("cannot open devicetree at %p: %d\n", fdt, err);
+ panic();
+ }
+
+ /* Check for the command line signature. */
+ if (!strncmp(cmdline, "CMD:", 4)) {
+ int chosen;
+
+ INFO("using command line at 0x%x\n", FPGA_PRELOADED_CMD_LINE);
+
+ chosen = fdt_add_subnode(fdt, 0, "chosen");
+ if (chosen == -FDT_ERR_EXISTS) {
+ chosen = fdt_path_offset(fdt, "/chosen");
+ }
+ if (chosen < 0) {
+ ERROR("cannot find /chosen node: %d\n", chosen);
+ } else {
+ const char *eol;
+ char nul = 0;
+ int slen;
+
+ /*
+ * There is most likely an EOL at the end of the
+ * command line, make sure we terminate the line there.
+ * We can't replace the EOL with a NUL byte in the
+ * source, as this is in read-only memory. So we first
+ * create the property without any termination, then
+ * append a single NUL byte.
+ */
+ eol = strchr(cmdline, '\n');
+ if (!eol) {
+ eol = strchr(cmdline, 0);
+ }
+ /* Skip the signature and omit the EOL/NUL byte. */
+ slen = eol - (cmdline + 4);
+
+ /*
+ * Let's limit the size of the property, just in case
+ * we find the signature by accident. The Linux kernel
+ * limits to 4096 characters at most (in fact 2048 for
+ * arm64), so that sounds like a reasonable number.
+ */
+ if (slen > 4095) {
+ slen = 4095;
+ }
+ err = fdt_setprop(fdt, chosen, "bootargs",
+ cmdline + 4, slen);
+ if (!err) {
+ err = fdt_appendprop(fdt, chosen, "bootargs",
+ &nul, 1);
+ }
+ if (err) {
+ ERROR("Could not set command line: %d\n", err);
+ }
+ }
+ }
+
+ err = fdt_pack(fdt);
+ if (err < 0) {
+ ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err);
+ }
+
+ clean_dcache_range((uintptr_t)fdt, fdt_blob_size(fdt));
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ fpga_prepare_dtb();
+}
+
void bl31_plat_enable_mmu(uint32_t flags)
{
/* TODO: determine if MMU needs to be enabled */
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index 46287adea7..47059d64a9 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -12,6 +12,7 @@
#define C_RUNTIME_READY_KEY (0xaa55aa55)
#define VALID_MPID (1U)
+#define FPGA_MAX_DTB_SIZE 0x10000
#ifndef __ASSEMBLER__
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index e57912cfec..1e7badf508 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -29,6 +29,9 @@ PRELOADED_BL33_BASE := 0x80080000
FPGA_PRELOADED_DTB_BASE := 0x80070000
$(eval $(call add_define,FPGA_PRELOADED_DTB_BASE))
+FPGA_PRELOADED_CMD_LINE := 0x1000
+$(eval $(call add_define,FPGA_PRELOADED_CMD_LINE))
+
# Treating this as a memory-constrained port for now
USE_COHERENT_MEM := 0