static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) { MachineState *machine = MACHINE(spapr); int ret, i, offset; uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; uint32_t nr_lmbs = (machine->maxram_size - machine->ram_size)/lmb_size; uint32_t *int_buf, *cur_index, buf_len; int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1; /* Allocate enough buffer size to fit in ibm,dynamic-memory */ buf_len = nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE * sizeof(uint32_t) + sizeof(uint32_t); cur_index = int_buf = g_malloc0(buf_len); offset = fdt_add_subnode(fdt, 0, "ibm,dynamic-reconfiguration-memory"); ret = fdt_setprop(fdt, offset, "ibm,lmb-size", prop_lmb_size, sizeof(prop_lmb_size)); if (ret < 0) { goto out; } ret = fdt_setprop_cell(fdt, offset, "ibm,memory-flags-mask", 0xff); if (ret < 0) { goto out; } ret = fdt_setprop_cell(fdt, offset, "ibm,memory-preservation-time", 0x0); if (ret < 0) { goto out; } /* ibm,dynamic-memory */ int_buf[0] = cpu_to_be32(nr_lmbs); cur_index++; for (i = 0; i < nr_lmbs; i++) { sPAPRDRConnector *drc; sPAPRDRConnectorClass *drck; uint64_t addr = i * lmb_size + spapr->hotplug_memory.base;; uint32_t *dynamic_memory = cur_index; drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_LMB, addr/lmb_size); g_assert(drc); drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); dynamic_memory[0] = cpu_to_be32(addr >> 32); dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff); dynamic_memory[2] = cpu_to_be32(drck->get_index(drc)); dynamic_memory[3] = cpu_to_be32(0); /* reserved */ dynamic_memory[4] = cpu_to_be32(numa_get_node(addr, NULL)); if (addr < machine->ram_size || memory_region_present(get_system_memory(), addr)) { dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED); } else { dynamic_memory[5] = cpu_to_be32(0); } cur_index += SPAPR_DR_LMB_LIST_ENTRY_SIZE; } ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory", int_buf, buf_len); if (ret < 0) { goto out; } /* ibm,associativity-lookup-arrays */ cur_index = int_buf; int_buf[0] = cpu_to_be32(nr_nodes); int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity list */ cur_index += 2; for (i = 0; i < nr_nodes; i++) { uint32_t associativity[] = { cpu_to_be32(0x0), cpu_to_be32(0x0), cpu_to_be32(0x0), cpu_to_be32(i) }; memcpy(cur_index, associativity, sizeof(associativity)); cur_index += 4; } ret = fdt_setprop(fdt, offset, "ibm,associativity-lookup-arrays", int_buf, (cur_index - int_buf) * sizeof(uint32_t)); out: g_free(int_buf); return ret; }