aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc')
-rw-r--r--hw/ppc/pnv.c46
-rw-r--r--hw/ppc/pnv_core.c2
-rw-r--r--hw/ppc/pnv_xscom.c2
-rw-r--r--hw/ppc/spapr_pci.c22
4 files changed, 44 insertions, 28 deletions
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d16dd2d..2f5358b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -710,6 +710,23 @@ static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon)
pnv_psi_pic_print_info(&chip10->psi, mon);
}
+/* Always give the first 1GB to chip 0 else we won't boot */
+static uint64_t pnv_chip_get_ram_size(PnvMachineState *pnv, int chip_id)
+{
+ MachineState *machine = MACHINE(pnv);
+ uint64_t ram_per_chip;
+
+ assert(machine->ram_size >= 1 * GiB);
+
+ ram_per_chip = machine->ram_size / pnv->num_chips;
+ if (ram_per_chip >= 1 * GiB) {
+ return QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
+ }
+
+ ram_per_chip = (machine->ram_size - 1 * GiB) / (pnv->num_chips - 1);
+ return chip_id == 0 ? 1 * GiB : QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
+}
+
static void pnv_init(MachineState *machine)
{
const char *bios_name = machine->firmware ?: FW_FILE_NAME;
@@ -717,6 +734,7 @@ static void pnv_init(MachineState *machine)
MachineClass *mc = MACHINE_GET_CLASS(machine);
char *fw_filename;
long fw_size;
+ uint64_t chip_ram_start = 0;
int i;
char *chip_typename;
DriveInfo *pnor = drive_get(IF_MTD, 0, 0);
@@ -809,9 +827,10 @@ static void pnv_init(MachineState *machine)
* TODO: should we decide on how many chips we can create based
* on #cores and Venice vs. Murano vs. Naples chip type etc...,
*/
- if (!is_power_of_2(pnv->num_chips) || pnv->num_chips > 4) {
+ if (!is_power_of_2(pnv->num_chips) || pnv->num_chips > 16) {
error_report("invalid number of chips: '%d'", pnv->num_chips);
- error_printf("Try '-smp sockets=N'. Valid values are : 1, 2 or 4.\n");
+ error_printf(
+ "Try '-smp sockets=N'. Valid values are : 1, 2, 4, 8 and 16.\n");
exit(1);
}
@@ -819,22 +838,21 @@ static void pnv_init(MachineState *machine)
for (i = 0; i < pnv->num_chips; i++) {
char chip_name[32];
Object *chip = OBJECT(qdev_new(chip_typename));
+ int chip_id = i;
+ uint64_t chip_ram_size = pnv_chip_get_ram_size(pnv, chip_id);
pnv->chips[i] = PNV_CHIP(chip);
- /*
- * TODO: put all the memory in one node on chip 0 until we find a
- * way to specify different ranges for each chip
- */
- if (i == 0) {
- object_property_set_int(chip, "ram-size", machine->ram_size,
- &error_fatal);
- }
+ /* Distribute RAM among the chips */
+ object_property_set_int(chip, "ram-start", chip_ram_start,
+ &error_fatal);
+ object_property_set_int(chip, "ram-size", chip_ram_size,
+ &error_fatal);
+ chip_ram_start += chip_ram_size;
- snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));
+ snprintf(chip_name, sizeof(chip_name), "chip[%d]", chip_id);
object_property_add_child(OBJECT(pnv), chip_name, chip);
- object_property_set_int(chip, "chip-id", PNV_CHIP_HWID(i),
- &error_fatal);
+ object_property_set_int(chip, "chip-id", chip_id, &error_fatal);
object_property_set_int(chip, "nr-cores", machine->smp.cores,
&error_fatal);
object_property_set_int(chip, "nr-threads", machine->smp.threads,
@@ -1916,7 +1934,7 @@ static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
static const char compat[] = "qemu,powernv10\0ibm,powernv";
mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
- mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v1.0");
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
pmc->compat = compat;
pmc->compat_size = sizeof(compat);
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 8c2a15a..4de8414 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -347,7 +347,7 @@ static const TypeInfo pnv_core_infos[] = {
DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
- DEFINE_PNV_CORE_TYPE(power10, "power10_v1.0"),
+ DEFINE_PNV_CORE_TYPE(power10, "power10_v2.0"),
};
DEFINE_TYPES(pnv_core_infos)
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index be7018e..faa488e 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -284,6 +284,8 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
_FDT(xscom_offset);
g_free(name);
_FDT((fdt_setprop_cell(fdt, xscom_offset, "ibm,chip-id", chip->chip_id)));
+ _FDT((fdt_setprop_cell(fdt, xscom_offset, "ibm,primary-topology-index",
+ chip->chip_id)));
_FDT((fdt_setprop_cell(fdt, xscom_offset, "#address-cells", 1)));
_FDT((fdt_setprop_cell(fdt, xscom_offset, "#size-cells", 1)));
_FDT((fdt_setprop(fdt, xscom_offset, "reg", reg, sizeof(reg))));
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7a72585..7430bd6 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -782,33 +782,29 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
{
- char *path = NULL, *buf = NULL, *host = NULL;
+ g_autofree char *path = NULL;
+ g_autofree char *host = NULL;
+ g_autofree char *devspec = NULL;
+ char *buf = NULL;
/* Get the PCI VFIO host id */
host = object_property_get_str(OBJECT(pdev), "host", NULL);
if (!host) {
- goto err_out;
+ return NULL;
}
/* Construct the path of the file that will give us the DT location */
path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
- g_free(host);
- if (!g_file_get_contents(path, &buf, NULL, NULL)) {
- goto err_out;
+ if (!g_file_get_contents(path, &devspec, NULL, NULL)) {
+ return NULL;
}
- g_free(path);
/* Construct and read from host device tree the loc-code */
- path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
- g_free(buf);
+ path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", devspec);
if (!g_file_get_contents(path, &buf, NULL, NULL)) {
- goto err_out;
+ return NULL;
}
return buf;
-
-err_out:
- g_free(path);
- return NULL;
}
static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)