#include <dm/ofnode.h>
#include <linux/ctype.h>
#include <linux/types.h>
+#include <linux/sizes.h>
#include <asm/global_data.h>
#include <asm/unaligned.h>
#include <linux/libfdt.h>
do_fixup_by_compat(fdt, compat, prop, &tmp, 4, create);
}
-#ifdef CONFIG_ARCH_FIXUP_FDT_MEMORY
/*
* fdt_pack_reg - pack address and size array into the "reg"-suitable stream
*/
return p - (char *)buf;
}
+#ifdef CONFIG_ARCH_FIXUP_FDT_MEMORY
#if CONFIG_NR_DRAM_BANKS > 4
#define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS
#else
}
return 1;
}
+
+int fdt_fixup_pmem_region(void *fdt, u64 pmem_start, u64 pmem_size)
+{
+ char node_name[32];
+ int nodeoffset, len;
+ int err;
+ u8 tmp[4 * 16]; /* Up to 64-bit address + 64-bit size */
+
+ if (!IS_ALIGNED(pmem_start, SZ_2M) ||
+ !IS_ALIGNED(pmem_start + pmem_size, SZ_2M)) {
+ printf("Start and end address must be 2MiB aligned\n");
+ return -1;
+ }
+
+ snprintf(node_name, sizeof(node_name), "pmem@%llx", pmem_start);
+ nodeoffset = fdt_find_or_add_subnode(fdt, 0, node_name);
+ if (nodeoffset < 0)
+ return nodeoffset;
+
+ err = fdt_setprop_string(fdt, nodeoffset, "compatible", "pmem-region");
+ if (err)
+ return err;
+ err = fdt_setprop_empty(fdt, nodeoffset, "volatile");
+ if (err)
+ return err;
+
+ len = fdt_pack_reg(fdt, tmp, &pmem_start, &pmem_size, 1);
+ err = fdt_setprop(fdt, nodeoffset, "reg", tmp, len);
+ if (err < 0) {
+ printf("WARNING: could not set pmem %s %s.\n", "reg",
+ fdt_strerror(err));
+ return err;
+ }
+
+ return 0;
+}
*/
int fdt_get_cells_len(const void *blob, char *nr_cells_name);
+/**
+ * fdt_fixup_pmem_region() - add a pmem node on the device tree
+ *
+ * This functions adds/updates a pmem node to the device tree.
+ * Usually used with EFI installers to preserve installer
+ * images
+ *
+ * @fdt: device tree provided by caller
+ * @addr: start address of the pmem node
+ * @size: size of the memory of the pmem node
+ * Return: 0 on success or < 0 on failure
+ */
+int fdt_fixup_pmem_region(void *fdt, u64 pmem_start, u64 pmem_size);
+
#endif /* !USE_HOSTCC */
#ifdef USE_HOSTCC