diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index 6751c6a624..4bffee0f37 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -39,6 +39,232 @@
 #include "hw/intc/arm_gic.h"
 #include "kvm_arm.h"
 
+void create_fdt(ArmMachineState *ams)
+{
+    MachineState *ms = MACHINE(ams);
+    int nb_numa_nodes = ms->numa_state->num_nodes;
+    void *fdt = create_device_tree(&ams->fdt_size);
+
+    if (!fdt) {
+        error_report("create_device_tree() failed");
+        exit(1);
+    }
+
+    ams->fdt = fdt;
+
+    /* Header */
+    qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
+    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
+
+    /* /chosen must exist for load_dtb to fill in necessary properties later */
+    qemu_fdt_add_subnode(fdt, "/chosen");
+
+    /* Clock node, for the benefit of the UART. The kernel device tree
+     * binding documentation claims the PL011 node clock properties are
+     * optional but in practice if you omit them the kernel refuses to
+     * probe for the device.
+     */
+    ams->clock_phandle = qemu_fdt_alloc_phandle(fdt);
+    qemu_fdt_add_subnode(fdt, "/apb-pclk");
+    qemu_fdt_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
+    qemu_fdt_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
+    qemu_fdt_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
+    qemu_fdt_setprop_string(fdt, "/apb-pclk", "clock-output-names",
+                                "clk24mhz");
+    qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", ams->clock_phandle);
+
+    if (nb_numa_nodes > 0 && ms->numa_state->have_numa_distance) {
+        int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
+        uint32_t *matrix = g_malloc0(size);
+        int idx, i, j;
+
+        for (i = 0; i < nb_numa_nodes; i++) {
+            for (j = 0; j < nb_numa_nodes; j++) {
+                idx = (i * nb_numa_nodes + j) * 3;
+                matrix[idx + 0] = cpu_to_be32(i);
+                matrix[idx + 1] = cpu_to_be32(j);
+                matrix[idx + 2] =
+                    cpu_to_be32(ms->numa_state->nodes[i].distance[j]);
+            }
+        }
+
+        qemu_fdt_add_subnode(fdt, "/distance-map");
+        qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
+                                "numa-distance-map-v1");
+        qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
+                         matrix, size);
+        g_free(matrix);
+    }
+}
+
+void fdt_add_timer_nodes(const ArmMachineState *ams)
+{
+    /* On real hardware these interrupts are level-triggered.
+     * On KVM they were edge-triggered before host kernel version 4.4,
+     * and level-triggered afterwards.
+     * On emulated QEMU they are level-triggered.
+     *
+     * Getting the DTB info about them wrong is awkward for some
+     * guest kernels:
+     *  pre-4.8 ignore the DT and leave the interrupt configured
+     *   with whatever the GIC reset value (or the bootloader) left it at
+     *  4.8 before rc6 honour the incorrect data by programming it back
+     *   into the GIC, causing problems
+     *  4.8rc6 and later ignore the DT and always write "level triggered"
+     *   into the GIC
+     *
+     * For backwards-compatibility, virt-2.8 and earlier will continue
+     * to say these are edge-triggered, but later machines will report
+     * the correct information.
+     */
+    ARMCPU *armcpu;
+    ArmMachineClass *amc = ARM_MACHINE_GET_CLASS(ams);
+    uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
+
+    if (amc->claim_edge_triggered_timers) {
+        irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
+    }
+
+    if (ams->gic_version == 2) {
+        irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
+                             GIC_FDT_IRQ_PPI_CPU_WIDTH,
+                             (1 << ams->smp_cpus) - 1);
+    }
+
+    qemu_fdt_add_subnode(ams->fdt, "/timer");
+
+    armcpu = ARM_CPU(qemu_get_cpu(0));
+    if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {
+        const char compat[] = "arm,armv8-timer\0arm,armv7-timer";
+        qemu_fdt_setprop(ams->fdt, "/timer", "compatible",
+                         compat, sizeof(compat));
+    } else {
+        qemu_fdt_setprop_string(ams->fdt, "/timer", "compatible",
+                                "arm,armv7-timer");
+    }
+    qemu_fdt_setprop(ams->fdt, "/timer", "always-on", NULL, 0);
+    qemu_fdt_setprop_cells(ams->fdt, "/timer", "interrupts",
+                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
+                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
+                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
+                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
+}
+
+void fdt_add_cpu_nodes(const ArmMachineState *ams)
+{
+    int cpu;
+    int addr_cells = 1;
+    const MachineState *ms = MACHINE(ams);
+
+    /*
+     * From Documentation/devicetree/bindings/arm/cpus.txt
+     *  On ARM v8 64-bit systems value should be set to 2,
+     *  that corresponds to the MPIDR_EL1 register size.
+     *  If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
+     *  in the system, #address-cells can be set to 1, since
+     *  MPIDR_EL1[63:32] bits are not used for CPUs
+     *  identification.
+     *
+     *  Here we actually don't know whether our system is 32- or 64-bit one.
+     *  The simplest way to go is to examine affinity IDs of all our CPUs. If
+     *  at least one of them has Aff3 populated, we set #address-cells to 2.
+     */
+    for (cpu = 0; cpu < ams->smp_cpus; cpu++) {
+        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+
+        if (armcpu->mp_affinity & ARM_AFF3_MASK) {
+            addr_cells = 2;
+            break;
+        }
+    }
+
+    qemu_fdt_add_subnode(ams->fdt, "/cpus");
+    qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#address-cells", addr_cells);
+    qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#size-cells", 0x0);
+
+    for (cpu = ams->smp_cpus - 1; cpu >= 0; cpu--) {
+        char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+        CPUState *cs = CPU(armcpu);
+
+        qemu_fdt_add_subnode(ams->fdt, nodename);
+        qemu_fdt_setprop_string(ams->fdt, nodename, "device_type", "cpu");
+        qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
+                                    armcpu->dtb_compatible);
+
+        if (ams->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
+            && ams->smp_cpus > 1) {
+            qemu_fdt_setprop_string(ams->fdt, nodename,
+                                        "enable-method", "psci");
+        }
+
+        if (addr_cells == 2) {
+            qemu_fdt_setprop_u64(ams->fdt, nodename, "reg",
+                                 armcpu->mp_affinity);
+        } else {
+            qemu_fdt_setprop_cell(ams->fdt, nodename, "reg",
+                                  armcpu->mp_affinity);
+        }
+
+        if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
+            qemu_fdt_setprop_cell(ams->fdt, nodename, "numa-node-id",
+                ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
+        }
+
+        g_free(nodename);
+    }
+}
+
+void fdt_add_gic_node(ArmMachineState *ams)
+{
+    char *nodename;
+
+    ams->gic_phandle = qemu_fdt_alloc_phandle(ams->fdt);
+    qemu_fdt_setprop_cell(ams->fdt, "/", "interrupt-parent", ams->gic_phandle);
+
+    nodename = g_strdup_printf("/intc@%" PRIx64,
+                               ams->memmap[VIRT_GIC_DIST].base);
+    qemu_fdt_add_subnode(ams->fdt, nodename);
+    qemu_fdt_setprop_cell(ams->fdt, nodename, "#interrupt-cells", 3);
+    qemu_fdt_setprop(ams->fdt, nodename, "interrupt-controller", NULL, 0);
+    qemu_fdt_setprop_cell(ams->fdt, nodename, "#address-cells", 0x2);
+    qemu_fdt_setprop_cell(ams->fdt, nodename, "#size-cells", 0x2);
+    qemu_fdt_setprop(ams->fdt, nodename, "ranges", NULL, 0);
+    if (ams->gic_version == 3) {
+        int nb_redist_regions = virt_gicv3_redist_region_count(ams);
+
+        qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
+                                "arm,gic-v3");
+
+        qemu_fdt_setprop_cell(ams->fdt, nodename,
+                              "#redistributor-regions", nb_redist_regions);
+
+        if (nb_redist_regions == 1) {
+            qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
+                                         2, ams->memmap[VIRT_GIC_DIST].base,
+                                         2, ams->memmap[VIRT_GIC_DIST].size,
+                                         2, ams->memmap[VIRT_GIC_REDIST].base,
+                                         2, ams->memmap[VIRT_GIC_REDIST].size);
+        } else {
+            qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
+                                 2, ams->memmap[VIRT_GIC_DIST].base,
+                                 2, ams->memmap[VIRT_GIC_DIST].size,
+                                 2, ams->memmap[VIRT_GIC_REDIST].base,
+                                 2, ams->memmap[VIRT_GIC_REDIST].size,
+                                 2, ams->memmap[VIRT_HIGH_GIC_REDIST2].base,
+                                 2, ams->memmap[VIRT_HIGH_GIC_REDIST2].size);
+        }
+    } else {
+        /* 'cortex-a15-gic' means 'GIC v2' */
+        qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
+                                "arm,cortex-a15-gic");
+    }
+
+    qemu_fdt_setprop_cell(ams->fdt, nodename, "phandle", ams->gic_phandle);
+    g_free(nodename);
+}
+
 void qdev_create_gic(ArmMachineState *ams)
 {
     MachineState *ms = MACHINE(ams);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b3267b873a..11e753906b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -204,186 +204,6 @@ static bool cpu_type_valid(const char *cpu)
     return false;
 }
 
-static void create_fdt(VirtMachineState *vms)
-{
-    MachineState *ms = MACHINE(vms);
-    ArmMachineState *ams = ARM_MACHINE(vms);
-    int nb_numa_nodes = ms->numa_state->num_nodes;
-    void *fdt = create_device_tree(&ams->fdt_size);
-
-    if (!fdt) {
-        error_report("create_device_tree() failed");
-        exit(1);
-    }
-
-    ams->fdt = fdt;
-
-    /* Header */
-    qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
-    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
-    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
-
-    /* /chosen must exist for load_dtb to fill in necessary properties later */
-    qemu_fdt_add_subnode(fdt, "/chosen");
-
-    /* Clock node, for the benefit of the UART. The kernel device tree
-     * binding documentation claims the PL011 node clock properties are
-     * optional but in practice if you omit them the kernel refuses to
-     * probe for the device.
-     */
-    ams->clock_phandle = qemu_fdt_alloc_phandle(fdt);
-    qemu_fdt_add_subnode(fdt, "/apb-pclk");
-    qemu_fdt_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
-    qemu_fdt_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
-    qemu_fdt_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
-    qemu_fdt_setprop_string(fdt, "/apb-pclk", "clock-output-names",
-                                "clk24mhz");
-    qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", ams->clock_phandle);
-
-    if (nb_numa_nodes > 0 && ms->numa_state->have_numa_distance) {
-        int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
-        uint32_t *matrix = g_malloc0(size);
-        int idx, i, j;
-
-        for (i = 0; i < nb_numa_nodes; i++) {
-            for (j = 0; j < nb_numa_nodes; j++) {
-                idx = (i * nb_numa_nodes + j) * 3;
-                matrix[idx + 0] = cpu_to_be32(i);
-                matrix[idx + 1] = cpu_to_be32(j);
-                matrix[idx + 2] =
-                    cpu_to_be32(ms->numa_state->nodes[i].distance[j]);
-            }
-        }
-
-        qemu_fdt_add_subnode(fdt, "/distance-map");
-        qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
-                                "numa-distance-map-v1");
-        qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
-                         matrix, size);
-        g_free(matrix);
-    }
-}
-
-static void fdt_add_timer_nodes(const VirtMachineState *vms)
-{
-    /* On real hardware these interrupts are level-triggered.
-     * On KVM they were edge-triggered before host kernel version 4.4,
-     * and level-triggered afterwards.
-     * On emulated QEMU they are level-triggered.
-     *
-     * Getting the DTB info about them wrong is awkward for some
-     * guest kernels:
-     *  pre-4.8 ignore the DT and leave the interrupt configured
-     *   with whatever the GIC reset value (or the bootloader) left it at
-     *  4.8 before rc6 honour the incorrect data by programming it back
-     *   into the GIC, causing problems
-     *  4.8rc6 and later ignore the DT and always write "level triggered"
-     *   into the GIC
-     *
-     * For backwards-compatibility, virt-2.8 and earlier will continue
-     * to say these are edge-triggered, but later machines will report
-     * the correct information.
-     */
-    ARMCPU *armcpu;
-    ArmMachineState *ams = ARM_MACHINE(vms);
-    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
-    uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
-
-    if (vmc->claim_edge_triggered_timers) {
-        irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
-    }
-
-    if (ams->gic_version == 2) {
-        irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
-                             GIC_FDT_IRQ_PPI_CPU_WIDTH,
-                             (1 << ams->smp_cpus) - 1);
-    }
-
-    qemu_fdt_add_subnode(ams->fdt, "/timer");
-
-    armcpu = ARM_CPU(qemu_get_cpu(0));
-    if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {
-        const char compat[] = "arm,armv8-timer\0arm,armv7-timer";
-        qemu_fdt_setprop(ams->fdt, "/timer", "compatible",
-                         compat, sizeof(compat));
-    } else {
-        qemu_fdt_setprop_string(ams->fdt, "/timer", "compatible",
-                                "arm,armv7-timer");
-    }
-    qemu_fdt_setprop(ams->fdt, "/timer", "always-on", NULL, 0);
-    qemu_fdt_setprop_cells(ams->fdt, "/timer", "interrupts",
-                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
-                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
-                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
-                       GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
-}
-
-static void fdt_add_cpu_nodes(const VirtMachineState *vms)
-{
-    int cpu;
-    int addr_cells = 1;
-    const MachineState *ms = MACHINE(vms);
-    const ArmMachineState *ams = ARM_MACHINE(vms);
-
-    /*
-     * From Documentation/devicetree/bindings/arm/cpus.txt
-     *  On ARM v8 64-bit systems value should be set to 2,
-     *  that corresponds to the MPIDR_EL1 register size.
-     *  If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
-     *  in the system, #address-cells can be set to 1, since
-     *  MPIDR_EL1[63:32] bits are not used for CPUs
-     *  identification.
-     *
-     *  Here we actually don't know whether our system is 32- or 64-bit one.
-     *  The simplest way to go is to examine affinity IDs of all our CPUs. If
-     *  at least one of them has Aff3 populated, we set #address-cells to 2.
-     */
-    for (cpu = 0; cpu < ams->smp_cpus; cpu++) {
-        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
-
-        if (armcpu->mp_affinity & ARM_AFF3_MASK) {
-            addr_cells = 2;
-            break;
-        }
-    }
-
-    qemu_fdt_add_subnode(ams->fdt, "/cpus");
-    qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#address-cells", addr_cells);
-    qemu_fdt_setprop_cell(ams->fdt, "/cpus", "#size-cells", 0x0);
-
-    for (cpu = ams->smp_cpus - 1; cpu >= 0; cpu--) {
-        char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
-        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
-        CPUState *cs = CPU(armcpu);
-
-        qemu_fdt_add_subnode(ams->fdt, nodename);
-        qemu_fdt_setprop_string(ams->fdt, nodename, "device_type", "cpu");
-        qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
-                                    armcpu->dtb_compatible);
-
-        if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
-            && ams->smp_cpus > 1) {
-            qemu_fdt_setprop_string(ams->fdt, nodename,
-                                        "enable-method", "psci");
-        }
-
-        if (addr_cells == 2) {
-            qemu_fdt_setprop_u64(ams->fdt, nodename, "reg",
-                                 armcpu->mp_affinity);
-        } else {
-            qemu_fdt_setprop_cell(ams->fdt, nodename, "reg",
-                                  armcpu->mp_affinity);
-        }
-
-        if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
-            qemu_fdt_setprop_cell(ams->fdt, nodename, "numa-node-id",
-                ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
-        }
-
-        g_free(nodename);
-    }
-}
-
 static void fdt_add_its_gic_node(VirtMachineState *vms)
 {
     char *nodename;
@@ -461,56 +281,6 @@ static void fdt_gic_set_virt_extension(VirtMachineState *vms)
     }
 }
 
-static void fdt_add_gic_node(VirtMachineState *vms)
-{
-    char *nodename;
-    ArmMachineState *ams = ARM_MACHINE(vms);
-
-    ams->gic_phandle = qemu_fdt_alloc_phandle(ams->fdt);
-    qemu_fdt_setprop_cell(ams->fdt, "/", "interrupt-parent", ams->gic_phandle);
-
-    nodename = g_strdup_printf("/intc@%" PRIx64,
-                               ams->memmap[VIRT_GIC_DIST].base);
-    qemu_fdt_add_subnode(ams->fdt, nodename);
-    qemu_fdt_setprop_cell(ams->fdt, nodename, "#interrupt-cells", 3);
-    qemu_fdt_setprop(ams->fdt, nodename, "interrupt-controller", NULL, 0);
-    qemu_fdt_setprop_cell(ams->fdt, nodename, "#address-cells", 0x2);
-    qemu_fdt_setprop_cell(ams->fdt, nodename, "#size-cells", 0x2);
-    qemu_fdt_setprop(ams->fdt, nodename, "ranges", NULL, 0);
-    if (ams->gic_version == 3) {
-        int nb_redist_regions = virt_gicv3_redist_region_count(ams);
-
-        qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
-                                "arm,gic-v3");
-
-        qemu_fdt_setprop_cell(ams->fdt, nodename,
-                              "#redistributor-regions", nb_redist_regions);
-
-        if (nb_redist_regions == 1) {
-            qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
-                                         2, ams->memmap[VIRT_GIC_DIST].base,
-                                         2, ams->memmap[VIRT_GIC_DIST].size,
-                                         2, ams->memmap[VIRT_GIC_REDIST].base,
-                                         2, ams->memmap[VIRT_GIC_REDIST].size);
-        } else {
-            qemu_fdt_setprop_sized_cells(ams->fdt, nodename, "reg",
-                                 2, ams->memmap[VIRT_GIC_DIST].base,
-                                 2, ams->memmap[VIRT_GIC_DIST].size,
-                                 2, ams->memmap[VIRT_GIC_REDIST].base,
-                                 2, ams->memmap[VIRT_GIC_REDIST].size,
-                                 2, ams->memmap[VIRT_HIGH_GIC_REDIST2].base,
-                                 2, ams->memmap[VIRT_HIGH_GIC_REDIST2].size);
-        }
-    } else {
-        /* 'cortex-a15-gic' means 'GIC v2' */
-        qemu_fdt_setprop_string(ams->fdt, nodename, "compatible",
-                                "arm,cortex-a15-gic");
-    }
-
-    qemu_fdt_setprop_cell(ams->fdt, nodename, "phandle", ams->gic_phandle);
-    g_free(nodename);
-}
-
 static void fdt_add_pmu_nodes(const VirtMachineState *vms)
 {
     CPUState *cpu;
@@ -681,7 +451,7 @@ static void create_gic(VirtMachineState *vms)
 
     init_gic_sysbus(ams);
     set_gic_virt_sysbus(vms);
-    fdt_add_gic_node(vms);
+    fdt_add_gic_node(ams);
     fdt_gic_set_virt_extension(vms);
 
     gic_set_msi_interrupt(vms);
@@ -1470,7 +1240,7 @@ static void machvirt_init(MachineState *machine)
         exit(1);
     }
 
-    create_fdt(vms);
+    create_fdt(ams);
 
     possible_cpus = mc->possible_cpu_arch_ids(machine);
     for (n = 0; n < possible_cpus->len; n++) {
@@ -1536,8 +1306,8 @@ static void machvirt_init(MachineState *machine)
         object_property_set_bool(cpuobj, true, "realized", &error_fatal);
         object_unref(cpuobj);
     }
-    fdt_add_timer_nodes(vms);
-    fdt_add_cpu_nodes(vms);
+    fdt_add_timer_nodes(ams);
+    fdt_add_cpu_nodes(ams);
 
    if (!kvm_enabled()) {
         ARMCPU *cpu = ARM_CPU(first_cpu);
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 8fec23985e..743a90ba36 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -111,6 +111,14 @@ typedef struct {
 #define ARM_MACHINE_CLASS(klass) \
     OBJECT_CLASS_CHECK(ArmMachineClass, klass, TYPE_ARM_MACHINE)
 
+void create_fdt(ArmMachineState *ams);
+
+void fdt_add_timer_nodes(const ArmMachineState *ams);
+
+void fdt_add_cpu_nodes(const ArmMachineState *ams);
+
+void fdt_add_gic_node(ArmMachineState *ams);
+
 void qdev_create_gic(ArmMachineState *ams);
 
 void init_gic_sysbus(ArmMachineState *ams);
