aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/boot.c')
-rw-r--r--hw/arm/boot.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index becd827..d084030 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -15,6 +15,7 @@
#include "hw/arm/boot.h"
#include "hw/arm/linux-boot-if.h"
#include "cpu.h"
+#include "exec/tswap.h"
#include "exec/target_page.h"
#include "system/kvm.h"
#include "system/tcg.h"
@@ -24,11 +25,13 @@
#include "hw/boards.h"
#include "system/reset.h"
#include "hw/loader.h"
+#include "hw/mem/memory-device.h"
#include "elf.h"
#include "system/device_tree.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/units.h"
+#include "qemu/bswap.h"
/* Kernel boot protocol is specified in the kernel docs
* Documentation/arm/Booting and Documentation/arm64/booting.txt
@@ -513,6 +516,29 @@ static void fdt_add_psci_node(void *fdt, ARMCPU *armcpu)
qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
}
+static int fdt_add_pmem_node(void *fdt, uint32_t acells, uint32_t scells,
+ int64_t mem_base, int64_t size, int64_t node)
+{
+ int ret;
+
+ g_autofree char *nodename = g_strdup_printf("/pmem@%" PRIx64, mem_base);
+
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "pmem-region");
+ ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells,
+ mem_base, scells, size);
+ if (ret) {
+ return ret;
+ }
+
+ if (node >= 0) {
+ return qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id",
+ node);
+ }
+
+ return 0;
+}
+
int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
hwaddr addr_limit, AddressSpace *as, MachineState *ms,
ARMCPU *cpu)
@@ -523,6 +549,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
unsigned int i;
hwaddr mem_base, mem_len;
char **node_path;
+ g_autoptr(MemoryDeviceInfoList) md_list = NULL;
Error *err = NULL;
if (binfo->dtb_filename) {
@@ -626,6 +653,23 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
}
}
+ md_list = qmp_memory_device_list();
+ for (MemoryDeviceInfoList *m = md_list; m != NULL; m = m->next) {
+ MemoryDeviceInfo *mi = m->value;
+
+ if (mi->type == MEMORY_DEVICE_INFO_KIND_NVDIMM) {
+ PCDIMMDeviceInfo *di = mi->u.nvdimm.data;
+
+ rc = fdt_add_pmem_node(fdt, acells, scells,
+ di->addr, di->size, di->node);
+ if (rc < 0) {
+ fprintf(stderr, "couldn't add NVDIMM /pmem@%"PRIx64" node\n",
+ di->addr);
+ goto fail;
+ }
+ }
+ }
+
rc = fdt_path_offset(fdt, "/chosen");
if (rc < 0) {
qemu_fdt_add_subnode(fdt, "/chosen");