*/
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qemu-common.h"
#include "hw/pci/pci.h"
#include "hw/pci-host/spapr.h"
+#include "hw/ppc/spapr_numa.h"
#include "qemu/error-report.h"
#include "hw/ppc/fdt.h"
#include "hw/pci/pci_bridge.h"
#define PHANDLE_NVLINK(phb, gn, nn) (0x00130000 | (((phb)->index) << 8) | \
((gn) << 4) | (nn))
-#define SPAPR_GPU_NUMA_ID (cpu_to_be32(1))
-
typedef struct SpaprPhbPciNvGpuSlot {
uint64_t tgt;
uint64_t gpa;
uint64_t nv2_atsd_current;
int num; /* number of non empty (i.e. tgt!=0) entries in slots[] */
SpaprPhbPciNvGpuSlot slots[NVGPU_MAX_NUM];
- Error *errp;
+ Error *err;
};
static SpaprPhbPciNvGpuSlot *
spapr_pci_collect_nvnpu(nvgpus, pdev, tgt, MEMORY_REGION(mr_npu),
&local_err);
}
- error_propagate(&nvgpus->errp, local_err);
+ error_propagate(&nvgpus->err, local_err);
}
if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
PCI_HEADER_TYPE_BRIDGE)) {
return;
}
- pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
- spapr_phb_pci_collect_nvgpu, opaque);
+ pci_for_each_device_under_bus(sec_bus, spapr_phb_pci_collect_nvgpu, opaque);
}
void spapr_phb_nvgpu_setup(SpaprPhbState *sphb, Error **errp)
sphb->nvgpus->nv2_atsd_current = sphb->nv2_atsd_win_addr;
bus = PCI_HOST_BRIDGE(sphb)->bus;
- pci_for_each_device(bus, pci_bus_num(bus),
- spapr_phb_pci_collect_nvgpu, sphb->nvgpus);
+ pci_for_each_device_under_bus(bus, spapr_phb_pci_collect_nvgpu,
+ sphb->nvgpus);
- if (sphb->nvgpus->errp) {
- error_propagate(errp, sphb->nvgpus->errp);
- sphb->nvgpus->errp = NULL;
+ if (sphb->nvgpus->err) {
+ error_propagate(errp, sphb->nvgpus->err);
+ sphb->nvgpus->err = NULL;
goto cleanup_exit;
}
void spapr_phb_nvgpu_ram_populate_dt(SpaprPhbState *sphb, void *fdt)
{
int i, j, linkidx, npuoff;
- char *npuname;
+ g_autofree char *npuname = NULL;
if (!sphb->nvgpus) {
return;
_FDT(fdt_setprop_cell(fdt, npuoff, "#size-cells", 0));
/* Advertise NPU as POWER9 so the guest can enable NPU2 contexts */
_FDT((fdt_setprop_string(fdt, npuoff, "compatible", "ibm,power9-npu")));
- g_free(npuname);
for (i = 0, linkidx = 0; i < sphb->nvgpus->num; ++i) {
for (j = 0; j < sphb->nvgpus->slots[i].linknum; ++j) {
- char *linkname = g_strdup_printf("link@%d", linkidx);
+ g_autofree char *linkname = g_strdup_printf("link@%d", linkidx);
int off = fdt_add_subnode(fdt, npuoff, linkname);
_FDT(off);
_FDT((fdt_setprop_cell(fdt, off, "phandle",
PHANDLE_NVLINK(sphb, i, j))));
_FDT((fdt_setprop_cell(fdt, off, "ibm,npu-link-index", linkidx)));
- g_free(linkname);
++linkidx;
}
}
for (i = 0; i < sphb->nvgpus->num; ++i) {
SpaprPhbPciNvGpuSlot *nvslot = &sphb->nvgpus->slots[i];
Object *nv_mrobj = object_property_get_link(OBJECT(nvslot->gpdev),
- "nvlink2-mr[0]", NULL);
- uint32_t associativity[] = {
- cpu_to_be32(0x4),
- SPAPR_GPU_NUMA_ID,
- SPAPR_GPU_NUMA_ID,
- SPAPR_GPU_NUMA_ID,
- cpu_to_be32(nvslot->numa_id)
- };
+ "nvlink2-mr[0]",
+ &error_abort);
uint64_t size = object_property_get_uint(nv_mrobj, "size", NULL);
uint64_t mem_reg[2] = { cpu_to_be64(nvslot->gpa), cpu_to_be64(size) };
- char *mem_name = g_strdup_printf("memory@%"PRIx64, nvslot->gpa);
+ g_autofree char *mem_name = g_strdup_printf("memory@%"PRIx64,
+ nvslot->gpa);
int off = fdt_add_subnode(fdt, 0, mem_name);
_FDT(off);
_FDT((fdt_setprop_string(fdt, off, "device_type", "memory")));
_FDT((fdt_setprop(fdt, off, "reg", mem_reg, sizeof(mem_reg))));
- _FDT((fdt_setprop(fdt, off, "ibm,associativity", associativity,
- sizeof(associativity))));
+
+ spapr_numa_write_associativity_dt(SPAPR_MACHINE(qdev_get_machine()),
+ fdt, off, nvslot->numa_id);
_FDT((fdt_setprop_string(fdt, off, "compatible",
"ibm,coherent-device-memory")));
sizeof(mem_reg))));
_FDT((fdt_setprop_cell(fdt, off, "phandle",
PHANDLE_GPURAM(sphb, i))));
- g_free(mem_name);
}
}