Commit 960fbd29 authored by Cédric Le Goater's avatar Cédric Le Goater Committed by David Gibson
Browse files

ppc/pnv: create the ICP object under PnvCore



Each thread of a core is linked to an ICP. This allocates a PnvICPState
object before the PowerPCCPU object is realized and lets the XICSFabric
do the store under the 'intc' backlink when xics_cpu_setup() is
called.

This modeling removes the need of maintaining an array of ICP objects
under the PowerNV machine and also simplifies the XICSFabric icp_get()
handler.

Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 47fea43a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -694,6 +694,8 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
        object_property_set_int(OBJECT(pnv_core),
                                pcc->core_pir(chip, core_hwid),
                                "pir", &error_fatal);
        object_property_add_const_link(OBJECT(pnv_core), "xics",
                                       qdev_get_machine(), &error_fatal);
        object_property_set_bool(OBJECT(pnv_core), true, "realized",
                                 &error_fatal);
        object_unref(OBJECT(pnv_core));
+25 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_core.h"
#include "hw/ppc/pnv_xscom.h"
#include "hw/ppc/xics.h"

static void powernv_cpu_reset(void *opaque)
{
@@ -110,23 +111,37 @@ static const MemoryRegionOps pnv_core_xscom_ops = {
    .endianness = DEVICE_BIG_ENDIAN,
};

static void pnv_core_realize_child(Object *child, Error **errp)
static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
{
    Error *local_err = NULL;
    CPUState *cs = CPU(child);
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    Object *obj;

    obj = object_new(TYPE_PNV_ICP);
    object_property_add_child(OBJECT(cpu), "icp", obj, NULL);
    object_property_add_const_link(obj, "xics", OBJECT(xi), &error_abort);
    object_property_set_bool(obj, true, "realized", &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    object_property_set_bool(child, true, "realized", &local_err);
    if (local_err) {
        object_unparent(obj);
        error_propagate(errp, local_err);
        return;
    }

    powernv_cpu_init(cpu, &local_err);
    if (local_err) {
        object_unparent(obj);
        error_propagate(errp, local_err);
        return;
    }

    xics_cpu_setup(xi, cpu, ICP(obj));
}

static void pnv_core_realize(DeviceState *dev, Error **errp)
@@ -140,6 +155,14 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
    void *obj;
    int i, j;
    char name[32];
    Object *xi;

    xi = object_property_get_link(OBJECT(dev), "xics", &local_err);
    if (!xi) {
        error_setg(errp, "%s: required link 'xics' not found: %s",
                   __func__, error_get_pretty(local_err));
        return;
    }

    pc->threads = g_malloc0(size * cc->nr_threads);
    for (i = 0; i < cc->nr_threads; i++) {
@@ -160,7 +183,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
    for (j = 0; j < cc->nr_threads; j++) {
        obj = pc->threads + j * size;

        pnv_core_realize_child(obj, &local_err);
        pnv_core_realize_child(obj, XICS_FABRIC(xi), &local_err);
        if (local_err) {
            goto err;
        }