aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2020-07-07 10:40:46 +0100
committerAndre Przywara <andre.przywara@arm.com>2020-07-30 17:18:37 +0100
commitfa30f73b37b498273ec0b315048c06315c7c25e3 (patch)
tree310c7d81205b655da982e0b6f90842625e4a434d
parentf0b1864f8e309a41d2eb1c9510f8cd3c7aacbb1d (diff)
downloadtrusted-firmware-a-fa30f73b37b498273ec0b315048c06315c7c25e3.tar.gz
arm_fpga: Support uploading a custom command line
The command line for BL33 payloads is typically taken from the DTB. On "normal" systems the bootloader will put the right version in there, but we typically don't use one on the FPGAs. To avoid editing (and possibly re-packaging) the DTB for every change in the command line, try to read it from some "magic" memory location instead. It can be easily placed there by the tool that uploads the other payloads to the FPGA's memory. BL31 will then replace the existing command line in the DTB with that new string. To avoid reading garbage, check the memory location for containing a magic value. This is conveniently chosen to be a simple ASCII string, so it can just preceed the actual command line in a text file: -------------------------------- CMD:console=ttyAMA0,38400n8 debug loglevel=8 -------------------------------- Change-Id: I5923a80332c9fac3b4afd1a6aaa321233d0f60da Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-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