const uint64_t ram128mb = bankbase[0] + (128<<20);
xen_pfn_t p2m_size;
- xen_pfn_t rambank_size[GUEST_RAM_BANKS];
uint64_t bank0end;
assert(dom->rambase_pfn << XC_PAGE_SHIFT == bankbase[0]);
p2m_size = ( bankbase[i] + banksize - bankbase[0] ) >> XC_PAGE_SHIFT;
- rambank_size[i] = banksize >> XC_PAGE_SHIFT;
+ dom->rambank_size[i] = banksize >> XC_PAGE_SHIFT;
}
- assert(rambank_size[0] != 0);
+ assert(dom->rambank_size[0] != 0);
assert(ramsize == 0); /* Too much RAM is rejected above */
dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * p2m_size);
dom->p2m_host[pfn] = INVALID_MFN;
/* setup initial p2m and allocate guest memory */
- for ( i = 0; rambank_size[i] && i < GUEST_RAM_BANKS; i++ )
+ for ( i = 0; dom->rambank_size[i] && i < GUEST_RAM_BANKS; i++ )
{
if ((rc = populate_guest_memory(dom,
bankbase[i] >> XC_PAGE_SHIFT,
- rambank_size[i])))
+ dom->rambank_size[i])))
return rc;
}
* If changing this then consider
* xen/arch/arm/kernel.c:place_modules as well.
*/
- bank0end = bankbase[0] + ((uint64_t)rambank_size[0] << XC_PAGE_SHIFT);
+ bank0end = bankbase[0] + ((uint64_t)dom->rambank_size[0] << XC_PAGE_SHIFT);
if ( bank0end >= ram128mb + modsize && kernend < ram128mb )
modbase = ram128mb;
return 0;
}
-static int make_memory_node(libxl__gc *gc, void *fdt,
- uint64_t base, uint64_t size)
+static int make_memory_nodes(libxl__gc *gc, void *fdt,
+ const struct xc_dom_image *dom)
{
- int res;
- const char *name = GCSPRINTF("memory@%"PRIx64, base);
+ int res, i;
+ const char *name;
+ const uint64_t bankbase[] = GUEST_RAM_BANK_BASES;
- res = fdt_begin_node(fdt, name);
- if (res) return res;
+ for (i = 0; i < GUEST_RAM_BANKS; i++) {
+ name = GCSPRINTF("memory@%"PRIx64, bankbase[i]);
- res = fdt_property_string(fdt, "device_type", "memory");
- if (res) return res;
+ LOG(DEBUG, "Creating placeholder node /%s", name);
- res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
- 1, base, size);
- if (res) return res;
+ res = fdt_begin_node(fdt, name);
+ if (res) return res;
- res = fdt_end_node(fdt);
- if (res) return res;
+ res = fdt_property_string(fdt, "device_type", "memory");
+ if (res) return res;
+
+ res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
+ 1, 0, 0);
+ if (res) return res;
+
+ res = fdt_end_node(fdt);
+ if (res) return res;
+ }
return 0;
}
FDT( make_cpus_node(gc, fdt, info->max_vcpus, ainfo) );
FDT( make_psci_node(gc, fdt) );
- FDT( make_memory_node(gc, fdt,
- dom->rambase_pfn << XC_PAGE_SHIFT,
- info->target_memkb * 1024) );
+ FDT( make_memory_nodes(gc, fdt, dom) );
FDT( make_intc_node(gc, fdt,
GUEST_GICD_BASE, GUEST_GICD_SIZE,
GUEST_GICC_BASE, GUEST_GICD_SIZE) );
return rc;
}
+static void finalise_one_memory_node(libxl__gc *gc, void *fdt,
+ uint64_t base, uint64_t size)
+{
+ int node, res;
+ const char *name = GCSPRINTF("/memory@%"PRIx64, base);
+
+ node = fdt_path_offset(fdt, name);
+ assert(node > 0);
+
+ if (size == 0) {
+ LOG(DEBUG, "Nopping out placeholder node %s", name);
+ fdt_nop_node(fdt, node);
+ } else {
+ uint32_t regs[ROOT_ADDRESS_CELLS+ROOT_SIZE_CELLS];
+ be32 *cells = ®s[0];
+
+ LOG(DEBUG, "Populating placeholder node %s", name);
+
+ set_range(&cells, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS, base, size);
+
+ res = fdt_setprop_inplace(fdt, node, "reg", regs, sizeof(regs));
+ assert(!res);
+ }
+}
+
int libxl__arch_domain_finalise_hw_description(libxl__gc *gc,
libxl_domain_build_info *info,
struct xc_dom_image *dom)
{
void *fdt = dom->devicetree_blob;
+ int i;
+ const uint64_t bankbase[] = GUEST_RAM_BANK_BASES;
const struct xc_dom_seg *ramdisk = dom->ramdisk_blob ?
&dom->ramdisk_seg : NULL;
assert(!res);
val = cpu_to_fdt64(ramdisk->vend);
- res = fdt_setprop_inplace(fdt, chosen,PROP_INITRD_END,
+ res = fdt_setprop_inplace(fdt, chosen, PROP_INITRD_END,
&val, sizeof(val));
assert(!res);
+
+ }
+
+ for (i = 0; i < GUEST_RAM_BANKS; i++) {
+ const uint64_t size = (uint64_t)dom->rambank_size[i] << XC_PAGE_SHIFT;
+
+ finalise_one_memory_node(gc, fdt, bankbase[i], size);
}
debug_dump_fdt(gc, fdt);