diff mbox

[2/3] ppc/pnv: add a PnvChip object

Message ID 1470388537-2908-3-git-send-email-clg@kaod.org
State New
Headers show

Commit Message

Cédric Le Goater Aug. 5, 2016, 9:15 a.m. UTC
This is is an abstraction of a P8 chip which is a set of cores plus
other 'units', like the pervasive unit, the interrupt controller, the
memory controller, the on-chip microcontroller, etc. The whole can be
seen as a socket.

We start with an empty PnvChip which we will grow in the subsequent
patches with controllers required to run the system.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/pnv.c         | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/pnv.h | 15 +++++++++++++++
 2 files changed, 62 insertions(+)

Comments

Benjamin Herrenschmidt Aug. 5, 2016, 9:44 a.m. UTC | #1
On Fri, 2016-08-05 at 11:15 +0200, Cédric Le Goater wrote:
> This is is an abstraction of a P8 chip which is a set of cores plus

> other 'units', like the pervasive unit, the interrupt controller, the

> memory controller, the on-chip microcontroller, etc. The whole can be

> seen as a socket.

> 

> We start with an empty PnvChip which we will grow in the subsequent

> patches with controllers required to run the system..


We should create a subclass PnvChipP8 which we instanciate for now
since P9 is around the corner and will be a bit different

Cheers,
Ben.

> Signed-off-by: Cédric Le Goater <clg@kaod.org>

> ---

>  hw/ppc/pnv.c         | 47

> +++++++++++++++++++++++++++++++++++++++++++++++

>  include/hw/ppc/pnv.h | 15 +++++++++++++++

>  2 files changed, 62 insertions(+)

> 

> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c

> index 3bb6a240c25b..a680780e9dea 100644

> --- a/hw/ppc/pnv.c

> +++ b/hw/ppc/pnv.c

> @@ -185,6 +185,7 @@ static void ppc_powernv_init(MachineState

> *machine)

>      sPowerNVMachineState *pnv = POWERNV_MACHINE(machine);

>      long fw_size;

>      char *filename;

> +    int i;

>  

>      if (ram_size < (1 * G_BYTE)) {

>          error_report("Warning: skiboot may not work with < 1GB of

> RAM");

> @@ -236,6 +237,23 @@ static void ppc_powernv_init(MachineState

> *machine)

>              pnv->initrd_base = 0;

>              pnv->initrd_size = 0;

>      }

> +

> +    /* Create PowerNV chips

> +     *

> +     * FIXME: We should decide how many chips to create based on

> +     * #cores and Venice vs. Murano vs. Naples chip type etc..., for

> +     * now, just create one chip, with all the cores.

> +     */

> +    pnv->num_chips = 1;

> +

> +    pnv->chips = g_new0(PnvChip, pnv->num_chips);

> +    for (i = 0; i < pnv->num_chips; i++) {

> +        PnvChip *chip = &pnv->chips[i];

> +

> +        object_initialize(chip, sizeof(*chip), TYPE_PNV_CHIP);

> +        object_property_set_int(OBJECT(chip), i, "chip-id",

> &error_abort);

> +        object_property_set_bool(OBJECT(chip), true, "realized",

> &error_abort);

> +    }

>  }

>  

>  static void powernv_machine_class_init(ObjectClass *oc, void *data)

> @@ -274,10 +292,39 @@ static const TypeInfo powernv_machine_2_8_info

> = {

>      .class_init    = powernv_machine_2_8_class_init,

>  };

>  

> +

> +static void pnv_chip_realize(DeviceState *dev, Error **errp)

> +{

> +    ;

> +}

> +

> +static Property pnv_chip_properties[] = {

> +    DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),

> +    DEFINE_PROP_END_OF_LIST(),

> +};

> +

> +static void pnv_chip_class_init(ObjectClass *klass, void *data)

> +{

> +    DeviceClass *dc = DEVICE_CLASS(klass);

> +

> +    dc->realize = pnv_chip_realize;

> +    dc->props = pnv_chip_properties;

> +    dc->desc = "PowerNV Chip";

> + }

> +

> +static const TypeInfo pnv_chip_info = {

> +    .name          = TYPE_PNV_CHIP,

> +    .parent        = TYPE_SYS_BUS_DEVICE,

> +    .instance_size = sizeof(PnvChip),

> +    .class_init    = pnv_chip_class_init,

> +};

> +

> +

>  static void powernv_machine_register_types(void)

>  {

>      type_register_static(&powernv_machine_info);

>      type_register_static(&powernv_machine_2_8_info);

> +    type_register_static(&pnv_chip_info);

>  }

>  

>  type_init(powernv_machine_register_types)

> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h

> index 2990f691672d..6907dc9e5c3d 100644

> --- a/include/hw/ppc/pnv.h

> +++ b/include/hw/ppc/pnv.h

> @@ -20,6 +20,18 @@

>  #define _PPC_PNV_H

>  

>  #include "hw/boards.h"

> +#include "hw/sysbus.h"

> +

> +#define TYPE_PNV_CHIP "powernv-chip"

> +#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)

> +

> +typedef struct PnvChip {

> +    /*< private >*/

> +    SysBusDevice parent_obj;

> +

> +    /*< public >*/

> +    uint32_t     chip_id;

> +} PnvChip;

>  

>  #define TYPE_POWERNV_MACHINE      "powernv-machine"

>  #define POWERNV_MACHINE(obj) \

> @@ -31,6 +43,9 @@ typedef struct sPowerNVMachineState {

>  

>      uint32_t initrd_base;

>      long initrd_size;

> +

> +    uint32_t  num_chips;

> +    PnvChip   *chips;

>  } sPowerNVMachineState;

>  

>  #endif /* _PPC_PNV_H */
Cédric Le Goater Aug. 5, 2016, 4:48 p.m. UTC | #2
On 08/05/2016 11:44 AM, Benjamin Herrenschmidt wrote:
> On Fri, 2016-08-05 at 11:15 +0200, Cédric Le Goater wrote:
>> This is is an abstraction of a P8 chip which is a set of cores plus
>> other 'units', like the pervasive unit, the interrupt controller, the
>> memory controller, the on-chip microcontroller, etc. The whole can be
>> seen as a socket.
>>
>> We start with an empty PnvChip which we will grow in the subsequent
>> patches with controllers required to run the system..
> 
> We should create a subclass PnvChipP8 which we instanciate for now
> since P9 is around the corner and will be a bit different

Yes. I gave it a try on a new 2.8 branch, check it here : 

	https://github.com/legoater/qemu/commit/60a6206c2b31d897d1af2ea3641870c2cc0e8c41

It defines a PnvChip base class with a realize routine in which 
we can handle specific attributes of child classes like the 
PnvChipPower8. I will send it in v2 for review when David has 
taken a look at v1.

All the controllers are still under the base class, so all looks
good. But when the PnvChipPower9 comes in play, we will need to 
redispatch and see how it fits the purpose of supporting multiple
Chip models.

The core initialization should be ok but building the device 
tree might be a bit of a burden if we have to 'cast' in the chip 
type we need. We will see.


So what would be the big differences with what we have today ?   

Thanks,

C.
 
> Cheers,
> Ben.
> 
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/ppc/pnv.c         | 47
>> +++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/pnv.h | 15 +++++++++++++++
>>  2 files changed, 62 insertions(+)
>>
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 3bb6a240c25b..a680780e9dea 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -185,6 +185,7 @@ static void ppc_powernv_init(MachineState
>> *machine)
>>      sPowerNVMachineState *pnv = POWERNV_MACHINE(machine);
>>      long fw_size;
>>      char *filename;
>> +    int i;
>>  
>>      if (ram_size < (1 * G_BYTE)) {
>>          error_report("Warning: skiboot may not work with < 1GB of
>> RAM");
>> @@ -236,6 +237,23 @@ static void ppc_powernv_init(MachineState
>> *machine)
>>              pnv->initrd_base = 0;
>>              pnv->initrd_size = 0;
>>      }
>> +
>> +    /* Create PowerNV chips
>> +     *
>> +     * FIXME: We should decide how many chips to create based on
>> +     * #cores and Venice vs. Murano vs. Naples chip type etc..., for
>> +     * now, just create one chip, with all the cores.
>> +     */
>> +    pnv->num_chips = 1;
>> +
>> +    pnv->chips = g_new0(PnvChip, pnv->num_chips);
>> +    for (i = 0; i < pnv->num_chips; i++) {
>> +        PnvChip *chip = &pnv->chips[i];
>> +
>> +        object_initialize(chip, sizeof(*chip), TYPE_PNV_CHIP);
>> +        object_property_set_int(OBJECT(chip), i, "chip-id",
>> &error_abort);
>> +        object_property_set_bool(OBJECT(chip), true, "realized",
>> &error_abort);
>> +    }
>>  }
>>  
>>  static void powernv_machine_class_init(ObjectClass *oc, void *data)
>> @@ -274,10 +292,39 @@ static const TypeInfo powernv_machine_2_8_info
>> = {
>>      .class_init    = powernv_machine_2_8_class_init,
>>  };
>>  
>> +
>> +static void pnv_chip_realize(DeviceState *dev, Error **errp)
>> +{
>> +    ;
>> +}
>> +
>> +static Property pnv_chip_properties[] = {
>> +    DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void pnv_chip_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->realize = pnv_chip_realize;
>> +    dc->props = pnv_chip_properties;
>> +    dc->desc = "PowerNV Chip";
>> + }
>> +
>> +static const TypeInfo pnv_chip_info = {
>> +    .name          = TYPE_PNV_CHIP,
>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>> +    .instance_size = sizeof(PnvChip),
>> +    .class_init    = pnv_chip_class_init,
>> +};
>> +
>> +
>>  static void powernv_machine_register_types(void)
>>  {
>>      type_register_static(&powernv_machine_info);
>>      type_register_static(&powernv_machine_2_8_info);
>> +    type_register_static(&pnv_chip_info);
>>  }
>>  
>>  type_init(powernv_machine_register_types)
>> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
>> index 2990f691672d..6907dc9e5c3d 100644
>> --- a/include/hw/ppc/pnv.h
>> +++ b/include/hw/ppc/pnv.h
>> @@ -20,6 +20,18 @@
>>  #define _PPC_PNV_H
>>  
>>  #include "hw/boards.h"
>> +#include "hw/sysbus.h"
>> +
>> +#define TYPE_PNV_CHIP "powernv-chip"
>> +#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
>> +
>> +typedef struct PnvChip {
>> +    /*< private >*/
>> +    SysBusDevice parent_obj;
>> +
>> +    /*< public >*/
>> +    uint32_t     chip_id;
>> +} PnvChip;
>>  
>>  #define TYPE_POWERNV_MACHINE      "powernv-machine"
>>  #define POWERNV_MACHINE(obj) \
>> @@ -31,6 +43,9 @@ typedef struct sPowerNVMachineState {
>>  
>>      uint32_t initrd_base;
>>      long initrd_size;
>> +
>> +    uint32_t  num_chips;
>> +    PnvChip   *chips;
>>  } sPowerNVMachineState;
>>  
>>  #endif /* _PPC_PNV_H */
Benjamin Herrenschmidt Aug. 5, 2016, 10:43 p.m. UTC | #3
On Fri, 2016-08-05 at 18:48 +0200, Cédric Le Goater wrote:
> The core initialization should be ok but building the device 
> tree might be a bit of a burden if we have to 'cast' in the chip 
> type we need. We will see.

We don't cast, we use a method.

> So what would be the big differences with what we have today ?   

The XSCOM controller has a different address decoding scheme, so
we'll have two variants and a base class there. The number and
location of functional units changes, so we'll probably need to make
them properties or something, the core XSCOM addressing is completely
different, we use PHB4 rather than PHB3, etc...

(Note that for PHB we should probably rename PHB3 to PnvPhb with a
subclass as well as there is a lot in common between the two, though
the PBCQ bit is quite different).

Cheers,
Ben.
David Gibson Aug. 16, 2016, 2:18 a.m. UTC | #4
On Sat, Aug 06, 2016 at 08:43:21AM +1000, Benjamin Herrenschmidt wrote:
> On Fri, 2016-08-05 at 18:48 +0200, Cédric Le Goater wrote:
> > The core initialization should be ok but building the device 
> > tree might be a bit of a burden if we have to 'cast' in the chip 
> > type we need. We will see.
> 
> We don't cast, we use a method.

Right.  You can have a look at the sPAPR VIO stuff for an example
where we use a method in the individual devices to do the device
specific fdt construction.

> 
> > So what would be the big differences with what we have today ?   
> 
> The XSCOM controller has a different address decoding scheme, so
> we'll have two variants and a base class there. The number and
> location of functional units changes, so we'll probably need to make
> them properties or something, the core XSCOM addressing is completely
> different, we use PHB4 rather than PHB3, etc...
> 
> (Note that for PHB we should probably rename PHB3 to PnvPhb with a
> subclass as well as there is a lot in common between the two, though
> the PBCQ bit is quite different).
>
David Gibson Aug. 16, 2016, 2:21 a.m. UTC | #5
On Fri, Aug 05, 2016 at 11:15:36AM +0200, Cédric Le Goater wrote:
> This is is an abstraction of a P8 chip which is a set of cores plus
> other 'units', like the pervasive unit, the interrupt controller, the
> memory controller, the on-chip microcontroller, etc. The whole can be
> seen as a socket.
> 
> We start with an empty PnvChip which we will grow in the subsequent
> patches with controllers required to run the system.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/ppc/pnv.c         | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/pnv.h | 15 +++++++++++++++
>  2 files changed, 62 insertions(+)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 3bb6a240c25b..a680780e9dea 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -185,6 +185,7 @@ static void ppc_powernv_init(MachineState *machine)
>      sPowerNVMachineState *pnv = POWERNV_MACHINE(machine);
>      long fw_size;
>      char *filename;
> +    int i;
>  
>      if (ram_size < (1 * G_BYTE)) {
>          error_report("Warning: skiboot may not work with < 1GB of RAM");
> @@ -236,6 +237,23 @@ static void ppc_powernv_init(MachineState *machine)
>              pnv->initrd_base = 0;
>              pnv->initrd_size = 0;
>      }
> +
> +    /* Create PowerNV chips
> +     *
> +     * FIXME: We should decide how many chips to create based on
> +     * #cores and Venice vs. Murano vs. Naples chip type etc..., for
> +     * now, just create one chip, with all the cores.
> +     */
> +    pnv->num_chips = 1;
> +
> +    pnv->chips = g_new0(PnvChip, pnv->num_chips);
> +    for (i = 0; i < pnv->num_chips; i++) {
> +        PnvChip *chip = &pnv->chips[i];
> +
> +        object_initialize(chip, sizeof(*chip), TYPE_PNV_CHIP);

I think you'd be better off having an array of pointers, each one you
allocate with object_new() rather than doing an explicit g_new0() for
the whole array then using object_initialize().

For one thing, if certain chip subtypes need to allocate more space
for their instance, then this approach will break, whereas
object_new() will get that right.

> +        object_property_set_int(OBJECT(chip), i, "chip-id", &error_abort);
> +        object_property_set_bool(OBJECT(chip), true, "realized", &error_abort);
> +    }
>  }
>  
>  static void powernv_machine_class_init(ObjectClass *oc, void *data)
> @@ -274,10 +292,39 @@ static const TypeInfo powernv_machine_2_8_info = {
>      .class_init    = powernv_machine_2_8_class_init,
>  };
>  
> +
> +static void pnv_chip_realize(DeviceState *dev, Error **errp)
> +{
> +    ;
> +}
> +
> +static Property pnv_chip_properties[] = {
> +    DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void pnv_chip_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = pnv_chip_realize;
> +    dc->props = pnv_chip_properties;
> +    dc->desc = "PowerNV Chip";
> + }
> +
> +static const TypeInfo pnv_chip_info = {
> +    .name          = TYPE_PNV_CHIP,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(PnvChip),
> +    .class_init    = pnv_chip_class_init,
> +};
> +
> +
>  static void powernv_machine_register_types(void)
>  {
>      type_register_static(&powernv_machine_info);
>      type_register_static(&powernv_machine_2_8_info);
> +    type_register_static(&pnv_chip_info);
>  }
>  
>  type_init(powernv_machine_register_types)
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index 2990f691672d..6907dc9e5c3d 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -20,6 +20,18 @@
>  #define _PPC_PNV_H
>  
>  #include "hw/boards.h"
> +#include "hw/sysbus.h"
> +
> +#define TYPE_PNV_CHIP "powernv-chip"
> +#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
> +
> +typedef struct PnvChip {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +
> +    /*< public >*/
> +    uint32_t     chip_id;
> +} PnvChip;
>  
>  #define TYPE_POWERNV_MACHINE      "powernv-machine"
>  #define POWERNV_MACHINE(obj) \
> @@ -31,6 +43,9 @@ typedef struct sPowerNVMachineState {
>  
>      uint32_t initrd_base;
>      long initrd_size;
> +
> +    uint32_t  num_chips;
> +    PnvChip   *chips;
>  } sPowerNVMachineState;
>  
>  #endif /* _PPC_PNV_H */
Cédric Le Goater Aug. 26, 2016, 4:31 p.m. UTC | #6
On 08/16/2016 04:21 AM, David Gibson wrote:
> On Fri, Aug 05, 2016 at 11:15:36AM +0200, Cédric Le Goater wrote:
>> This is is an abstraction of a P8 chip which is a set of cores plus
>> other 'units', like the pervasive unit, the interrupt controller, the
>> memory controller, the on-chip microcontroller, etc. The whole can be
>> seen as a socket.
>>
>> We start with an empty PnvChip which we will grow in the subsequent
>> patches with controllers required to run the system.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/ppc/pnv.c         | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>>  include/hw/ppc/pnv.h | 15 +++++++++++++++
>>  2 files changed, 62 insertions(+)
>>
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 3bb6a240c25b..a680780e9dea 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -185,6 +185,7 @@ static void ppc_powernv_init(MachineState *machine)
>>      sPowerNVMachineState *pnv = POWERNV_MACHINE(machine);
>>      long fw_size;
>>      char *filename;
>> +    int i;
>>  
>>      if (ram_size < (1 * G_BYTE)) {
>>          error_report("Warning: skiboot may not work with < 1GB of RAM");
>> @@ -236,6 +237,23 @@ static void ppc_powernv_init(MachineState *machine)
>>              pnv->initrd_base = 0;
>>              pnv->initrd_size = 0;
>>      }
>> +
>> +    /* Create PowerNV chips
>> +     *
>> +     * FIXME: We should decide how many chips to create based on
>> +     * #cores and Venice vs. Murano vs. Naples chip type etc..., for
>> +     * now, just create one chip, with all the cores.
>> +     */
>> +    pnv->num_chips = 1;
>> +
>> +    pnv->chips = g_new0(PnvChip, pnv->num_chips);
>> +    for (i = 0; i < pnv->num_chips; i++) {
>> +        PnvChip *chip = &pnv->chips[i];
>> +
>> +        object_initialize(chip, sizeof(*chip), TYPE_PNV_CHIP);
> 
> I think you'd be better off having an array of pointers, each one you
> allocate with object_new() rather than doing an explicit g_new0() for
> the whole array then using object_initialize().
> 
> For one thing, if certain chip subtypes need to allocate more space
> for their instance, then this approach will break, whereas
> object_new() will get that right.

ok. I did not know that. This is the approach I have taken in the 
new patchset but for another reason. I made the type of the PnvChip
object depend on the cpu_model. It should be useful for other chiplets 
which can behave differently.  

A first specificity to handle is the support of the LPC interrupts via 
the LPC controller for the Power8NVL chip. Ben just worked that out. 
I need to see how this comes together with the model I have.

Thanks,

C. 


>> +        object_property_set_int(OBJECT(chip), i, "chip-id", &error_abort);
>> +        object_property_set_bool(OBJECT(chip), true, "realized", &error_abort);
>> +    }
>>  }
>>  
>>  static void powernv_machine_class_init(ObjectClass *oc, void *data)
>> @@ -274,10 +292,39 @@ static const TypeInfo powernv_machine_2_8_info = {
>>      .class_init    = powernv_machine_2_8_class_init,
>>  };
>>  
>> +
>> +static void pnv_chip_realize(DeviceState *dev, Error **errp)
>> +{
>> +    ;
>> +}
>> +
>> +static Property pnv_chip_properties[] = {
>> +    DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void pnv_chip_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->realize = pnv_chip_realize;
>> +    dc->props = pnv_chip_properties;
>> +    dc->desc = "PowerNV Chip";
>> + }
>> +
>> +static const TypeInfo pnv_chip_info = {
>> +    .name          = TYPE_PNV_CHIP,
>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>> +    .instance_size = sizeof(PnvChip),
>> +    .class_init    = pnv_chip_class_init,
>> +};
>> +
>> +
>>  static void powernv_machine_register_types(void)
>>  {
>>      type_register_static(&powernv_machine_info);
>>      type_register_static(&powernv_machine_2_8_info);
>> +    type_register_static(&pnv_chip_info);
>>  }
>>  
>>  type_init(powernv_machine_register_types)
>> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
>> index 2990f691672d..6907dc9e5c3d 100644
>> --- a/include/hw/ppc/pnv.h
>> +++ b/include/hw/ppc/pnv.h
>> @@ -20,6 +20,18 @@
>>  #define _PPC_PNV_H
>>  
>>  #include "hw/boards.h"
>> +#include "hw/sysbus.h"
>> +
>> +#define TYPE_PNV_CHIP "powernv-chip"
>> +#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
>> +
>> +typedef struct PnvChip {
>> +    /*< private >*/
>> +    SysBusDevice parent_obj;
>> +
>> +    /*< public >*/
>> +    uint32_t     chip_id;
>> +} PnvChip;
>>  
>>  #define TYPE_POWERNV_MACHINE      "powernv-machine"
>>  #define POWERNV_MACHINE(obj) \
>> @@ -31,6 +43,9 @@ typedef struct sPowerNVMachineState {
>>  
>>      uint32_t initrd_base;
>>      long initrd_size;
>> +
>> +    uint32_t  num_chips;
>> +    PnvChip   *chips;
>>  } sPowerNVMachineState;
>>  
>>  #endif /* _PPC_PNV_H */
>
diff mbox

Patch

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 3bb6a240c25b..a680780e9dea 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -185,6 +185,7 @@  static void ppc_powernv_init(MachineState *machine)
     sPowerNVMachineState *pnv = POWERNV_MACHINE(machine);
     long fw_size;
     char *filename;
+    int i;
 
     if (ram_size < (1 * G_BYTE)) {
         error_report("Warning: skiboot may not work with < 1GB of RAM");
@@ -236,6 +237,23 @@  static void ppc_powernv_init(MachineState *machine)
             pnv->initrd_base = 0;
             pnv->initrd_size = 0;
     }
+
+    /* Create PowerNV chips
+     *
+     * FIXME: We should decide how many chips to create based on
+     * #cores and Venice vs. Murano vs. Naples chip type etc..., for
+     * now, just create one chip, with all the cores.
+     */
+    pnv->num_chips = 1;
+
+    pnv->chips = g_new0(PnvChip, pnv->num_chips);
+    for (i = 0; i < pnv->num_chips; i++) {
+        PnvChip *chip = &pnv->chips[i];
+
+        object_initialize(chip, sizeof(*chip), TYPE_PNV_CHIP);
+        object_property_set_int(OBJECT(chip), i, "chip-id", &error_abort);
+        object_property_set_bool(OBJECT(chip), true, "realized", &error_abort);
+    }
 }
 
 static void powernv_machine_class_init(ObjectClass *oc, void *data)
@@ -274,10 +292,39 @@  static const TypeInfo powernv_machine_2_8_info = {
     .class_init    = powernv_machine_2_8_class_init,
 };
 
+
+static void pnv_chip_realize(DeviceState *dev, Error **errp)
+{
+    ;
+}
+
+static Property pnv_chip_properties[] = {
+    DEFINE_PROP_UINT32("chip-id", PnvChip, chip_id, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pnv_chip_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = pnv_chip_realize;
+    dc->props = pnv_chip_properties;
+    dc->desc = "PowerNV Chip";
+ }
+
+static const TypeInfo pnv_chip_info = {
+    .name          = TYPE_PNV_CHIP,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PnvChip),
+    .class_init    = pnv_chip_class_init,
+};
+
+
 static void powernv_machine_register_types(void)
 {
     type_register_static(&powernv_machine_info);
     type_register_static(&powernv_machine_2_8_info);
+    type_register_static(&pnv_chip_info);
 }
 
 type_init(powernv_machine_register_types)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 2990f691672d..6907dc9e5c3d 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -20,6 +20,18 @@ 
 #define _PPC_PNV_H
 
 #include "hw/boards.h"
+#include "hw/sysbus.h"
+
+#define TYPE_PNV_CHIP "powernv-chip"
+#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
+
+typedef struct PnvChip {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    uint32_t     chip_id;
+} PnvChip;
 
 #define TYPE_POWERNV_MACHINE      "powernv-machine"
 #define POWERNV_MACHINE(obj) \
@@ -31,6 +43,9 @@  typedef struct sPowerNVMachineState {
 
     uint32_t initrd_base;
     long initrd_size;
+
+    uint32_t  num_chips;
+    PnvChip   *chips;
 } sPowerNVMachineState;
 
 #endif /* _PPC_PNV_H */