[PATCH] pstore: Do not fail if a reserved-memory node already exists

Detlev Casanova detlev.casanova at collabora.com
Wed Feb 2 17:47:53 CET 2022


The pstore command tries to create a reserved-memory node but fails if
it is already present with:

    Add 'reserved-memory' node failed: FDT_ERR_EXISTS

This patch creates the node only if it does not exist and adapts the reg
values sizes depending on already present #address-cells and #size-cells
values.

Signed-off-by: Detlev Casanova <detlev.casanova at collabora.com>
---
 cmd/pstore.c | 43 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/cmd/pstore.c b/cmd/pstore.c
index 9fac8c7218..40d3cc9340 100644
--- a/cmd/pstore.c
+++ b/cmd/pstore.c
@@ -11,6 +11,7 @@
 #include <mapmem.h>
 #include <memalign.h>
 #include <part.h>
+#include <fdt_support.h>
 
 struct persistent_ram_buffer {
 	u32    sig;
@@ -493,14 +494,18 @@ void fdt_fixup_pstore(void *blob)
 		return;
 	}
 
-	nodeoffset = fdt_add_subnode(blob, nodeoffset, "reserved-memory");
+	nodeoffset = fdt_find_or_add_subnode(blob, nodeoffset, "reserved-memory");
 	if (nodeoffset < 0) {
 		log_err("Add 'reserved-memory' node failed: %s\n",
 				fdt_strerror(nodeoffset));
 		return;
 	}
-	fdt_setprop_u32(blob, nodeoffset, "#address-cells", 2);
-	fdt_setprop_u32(blob, nodeoffset, "#size-cells", 2);
+
+	u32 addr_cells = fdt_getprop_u32_default_node(blob, nodeoffset, 0, "#address-cells", 2);
+	u32 size_cells = fdt_getprop_u32_default_node(blob, nodeoffset, 0, "#size-cells", 2);
+	fdt_setprop_u32(blob, nodeoffset, "#address-cells", addr_cells);
+	fdt_setprop_u32(blob, nodeoffset, "#size-cells", size_cells);
+
 	fdt_setprop_empty(blob, nodeoffset, "ranges");
 
 	sprintf(node, "ramoops@%llx", (unsigned long long)pstore_addr);
@@ -509,14 +514,42 @@ void fdt_fixup_pstore(void *blob)
 		log_err("Add '%s' node failed: %s\n", node, fdt_strerror(nodeoffset));
 		return;
 	}
+
 	fdt_setprop_string(blob, nodeoffset, "compatible", "ramoops");
-	fdt_setprop_u64(blob, nodeoffset, "reg", pstore_addr);
-	fdt_appendprop_u64(blob, nodeoffset, "reg", pstore_length);
+
+	switch (addr_cells) {
+	case 1:
+		fdt_setprop_u32(blob, nodeoffset, "reg", pstore_addr);
+		break;
+	case 2:
+		fdt_setprop_u64(blob, nodeoffset, "reg", pstore_addr);
+		break;
+	default:
+		log_err("Unsupported #address-cells: %u\n", addr_cells);
+		goto clean_ramoops;
+	}
+
+	switch (size_cells) {
+	case 1:
+		// Let's consider that the pstore_length fits in a 32 bits value
+		fdt_appendprop_u32(blob, nodeoffset, "reg", pstore_length);
+		break;
+	case 2:
+		fdt_appendprop_u64(blob, nodeoffset, "reg", pstore_length);
+		break;
+	default:
+		log_err("Unsupported #size-cells: %u\n", addr_cells);
+		goto clean_ramoops;
+	}
+
 	fdt_setprop_u32(blob, nodeoffset, "record-size", pstore_record_size);
 	fdt_setprop_u32(blob, nodeoffset, "console-size", pstore_console_size);
 	fdt_setprop_u32(blob, nodeoffset, "ftrace-size", pstore_ftrace_size);
 	fdt_setprop_u32(blob, nodeoffset, "pmsg-size", pstore_pmsg_size);
 	fdt_setprop_u32(blob, nodeoffset, "ecc-size", pstore_ecc_size);
+
+clean_ramoops:
+	fdt_del_node_and_alias(blob, node);
 }
 
 U_BOOT_CMD(pstore, 10, 0, do_pstore,
-- 
2.35.0



More information about the U-Boot mailing list