QEMU-Arm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Miles Glenn <milesg@linux.ibm.com>
To: Mikail Sadic <mikail.sadic@ibm.com>,
	clg@kaod.org, peter.maydell@linaro.org
Cc: pbonzini@redhat.com, ninad@linux.ibm.com, titusr@google.com,
	jeuk20.kim@samsung.com, philmd@mailo.com,
	steven_lee@aspeedtech.com, leetroy@gmail.com,
	jamin_lin@aspeedtech.com, kane_chen@aspeedtech.com,
	andrew@codeconstruct.com.au, joel@jms.id.au,
	calebs@linux.ibm.com, qemu-arm@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [PATCH v3 1/8] fsi/cfam: Add common CFAM base class
Date: Tue, 11 Aug 2026 08:36:23 -0500	[thread overview]
Message-ID: <238ac7e72f1a6da53a61ca48ab8c016ef4d4e40d.camel@linux.ibm.com> (raw)
In-Reply-To: <20260810185748.1253-2-mikail.sadic@ibm.com>

I'm fine with having the extended addressing added later.

Reviewed-by: Glenn Miles <milesg@linux.ibm.com>

Thanks,

Glenn

On Mon, 2026-08-10 at 13:57 -0500, Mikail Sadic wrote:
> Prepare a common CFAM parent class for CFAM-S implementation.
> 
> Add an abstract TYPE_FSI_CFAM_COMMON with an FSICFAMCommonClass holding
> what varies between types: the config table, the offsets of the FSI
> responder and the local bus within the register slot, and a
> realize_engines() hook for the engines on the local bus. Its realize is
> driven by those fields, so one realize serves every type. TYPE_FSI_CFAM
> keeps its name and becomes the first derived type, supplying the P9
> config table, its slot offsets and the scratchpad engine. The config
> table becomes data, still written with the same CFAM_CONFIG_REG()
> expressions, which move to the header so a derived type can describe its
> own table the same way.
> 
> Name the new instance struct without a State suffix and rename
> FSICFAMState to FSICFAM to match.
> 
> No functional change: same memory map, same config words, same type and
> child names. aspeed_fsi-test verified.
> 
> Signed-off-by: Mikail Sadic <mikail.sadic@ibm.com>
> ---
>  include/hw/fsi/cfam.h       |  58 ++++++++++++++++-
>  include/hw/fsi/fsi-master.h |   2 +-
>  hw/fsi/cfam.c               | 125 +++++++++++++++++++++---------------
>  hw/fsi/fsi-master.c         |   2 +-
>  4 files changed, 130 insertions(+), 57 deletions(-)
> 
> diff --git a/include/hw/fsi/cfam.h b/include/hw/fsi/cfam.h
> index cceb4bd6f1..bdf579b4fe 100644
> --- a/include/hw/fsi/cfam.h
> +++ b/include/hw/fsi/cfam.h
> @@ -7,18 +7,44 @@
>  #ifndef FSI_CFAM_H
>  #define FSI_CFAM_H
>  
> +#include "qemu/units.h"
>  #include "system/memory.h"
>  
>  #include "hw/fsi/fsi.h"
>  #include "hw/fsi/lbus.h"
>  
> +/*
> + * All CFAM flavors present a register slot holding a config table, an FSI
> + * responder and a local bus carrying the engines the config table describes.
> + * That is the common model; each flavor supplies its own table, slot layout
> + * and engines.
> + */
> +#define TYPE_FSI_CFAM_COMMON "cfam-common"
> +OBJECT_DECLARE_TYPE(FSICFAMCommon, FSICFAMCommonClass, FSI_CFAM_COMMON)
> +
>  #define TYPE_FSI_CFAM "cfam"
> -#define FSI_CFAM(obj) OBJECT_CHECK(FSICFAMState, (obj), TYPE_FSI_CFAM)
> +OBJECT_DECLARE_SIMPLE_TYPE(FSICFAM, FSI_CFAM)
>  
>  /* P9-ism */
>  #define CFAM_CONFIG_NR_REGS 0x28
>  
> -typedef struct FSICFAMState {
> +#define FSI_CFAM_SLOT_SIZE   (2 * MiB)
> +#define FSI_CFAM_CONFIG_SIZE 0x400
> +
> +#define ENGINE_CONFIG_NEXT            BIT(31)
> +#define ENGINE_CONFIG_TYPE_PEEK       (0x02 << 4)
> +#define ENGINE_CONFIG_TYPE_FSI        (0x03 << 4)
> +#define ENGINE_CONFIG_TYPE_SCRATCHPAD (0x06 << 4)
> +
> +/* Valid, slots, version, type, crc */
> +#define CFAM_CONFIG_REG(__VER, __TYPE, __CRC)   \
> +    (ENGINE_CONFIG_NEXT       |   \
> +     0x00010000               |   \
> +     (__VER)                  |   \
> +     (__TYPE)                 |   \
> +     (__CRC))
> +
> +struct FSICFAMCommon {
>      /* < private > */
>      FSISlaveState parent;
>  
> @@ -28,7 +54,33 @@ typedef struct FSICFAMState {
>      MemoryRegion mr;
>  
>      FSILBus lbus;
> +};
> +
> +struct FSICFAMCommonClass {
> +    /* < private > */
> +    DeviceClass parent_class;
> +
> +    /* < public > */
> +    /* Config table served by the common ops, one word per 4-byte offset */
> +    const uint32_t *config;
> +    unsigned config_nr;
> +
> +    /* Layout of the register slot */
> +    hwaddr responder_offset;
> +    hwaddr lbus_offset;
> +
> +    /* Realize and map this flavor's local bus engines */
> +    bool (*realize_engines)(FSICFAMCommon *cfam, Error **errp);
> +};
> +
> +struct FSICFAM {
> +    /* < private > */
> +    FSICFAMCommon parent;
> +
>      FSIScratchPad scratchpad;
> -} FSICFAMState;
> +};
> +
> +bool fsi_cfam_add_engine(FSICFAMCommon *cfam, DeviceState *engine,
> +                         hwaddr offset, Error **errp);
>  
>  #endif /* FSI_CFAM_H */
> diff --git a/include/hw/fsi/fsi-master.h b/include/hw/fsi/fsi-master.h
> index 60ddaa994f..87c11ec3dc 100644
> --- a/include/hw/fsi/fsi-master.h
> +++ b/include/hw/fsi/fsi-master.h
> @@ -25,7 +25,7 @@ typedef struct FSIMasterState {
>      FSIBus bus;
>  
>      uint32_t regs[FSI_MASTER_NR_REGS];
> -    FSICFAMState cfam;
> +    FSICFAM cfam;
>  } FSIMasterState;
>  
>  
> diff --git a/hw/fsi/cfam.c b/hw/fsi/cfam.c
> index 54c0b05769..5d4d0622d0 100644
> --- a/hw/fsi/cfam.c
> +++ b/hw/fsi/cfam.c
> @@ -16,19 +16,6 @@
>  
>  #include "hw/core/qdev-properties.h"
>  
> -#define ENGINE_CONFIG_NEXT            BIT(31)
> -#define ENGINE_CONFIG_TYPE_PEEK       (0x02 << 4)
> -#define ENGINE_CONFIG_TYPE_FSI        (0x03 << 4)
> -#define ENGINE_CONFIG_TYPE_SCRATCHPAD (0x06 << 4)
> -
> -/* Valid, slots, version, type, crc */
> -#define CFAM_CONFIG_REG(__VER, __TYPE, __CRC)   \
> -    (ENGINE_CONFIG_NEXT       |   \
> -     0x00010000               |   \
> -     (__VER)                  |   \
> -     (__TYPE)                 |   \
> -     (__CRC))
> -
>  #define TO_REG(x)                          ((x) >> 2)
>  
>  #define CFAM_CONFIG_CHIP_ID                TO_REG(0x00)
> @@ -36,34 +23,33 @@
>  #define CFAM_CONFIG_CHIP_ID_P9             0xc0022d15
>  #define CFAM_CONFIG_CHIP_ID_BREAK          0xc0de0000
>  
> +/*
> + * Config table of the P9 CFAM: the chip ID followed by one entry per engine,
> + * entry n describing the engine at address n * 4. We need to add future
> + * engines from address 0x10 onwards.
> + */
> +static const uint32_t cfam_p9_config[] = {
> +    CFAM_CONFIG_CHIP_ID_P9,
> +    CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_PEEK, 0xc),
> +    CFAM_CONFIG_REG(0x5000, ENGINE_CONFIG_TYPE_FSI, 0xa),
> +    CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_SCRATCHPAD, 0x7),
> +};
> +
>  static uint64_t fsi_cfam_config_read(void *opaque, hwaddr addr, unsigned size)
>  {
> +    FSICFAMCommonClass *cc = FSI_CFAM_COMMON_GET_CLASS(opaque);
> +    unsigned int reg = TO_REG(addr);
> +
>      trace_fsi_cfam_config_read(addr, size);
>  
> -    switch (addr) {
> -    case 0x00:
> -        return CFAM_CONFIG_CHIP_ID_P9;
> -    case 0x04:
> -        return CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_PEEK, 0xc);
> -    case 0x08:
> -        return CFAM_CONFIG_REG(0x5000, ENGINE_CONFIG_TYPE_FSI, 0xa);
> -    case 0xc:
> -        return CFAM_CONFIG_REG(0x1000, ENGINE_CONFIG_TYPE_SCRATCHPAD, 0x7);
> -    default:
> -        /*
> -         * The config table contains different engines from 0xc onwards.
> -         * The scratch pad is already added at address 0xc. We need to add
> -         * future engines from address 0x10 onwards. Returning 0 as engine
> -         * is not implemented.
> -         */
> -        return 0;
> -    }
> +    /* Engines past the end of the table are not implemented */
> +    return reg < cc->config_nr ? cc->config[reg] : 0;
>  }
>  
>  static void fsi_cfam_config_write(void *opaque, hwaddr addr, uint64_t data,
>                                    unsigned size)
>  {
> -    FSICFAMState *cfam = FSI_CFAM(opaque);
> +    FSICFAMCommon *cfam = FSI_CFAM_COMMON(opaque);
>  
>      trace_fsi_cfam_config_write(addr, size, data);
>  
> @@ -109,59 +95,94 @@ static const struct MemoryRegionOps fsi_cfam_unimplemented_ops = {
>      .endianness = DEVICE_BIG_ENDIAN,
>  };
>  
> -static void fsi_cfam_instance_init(Object *obj)
> +bool fsi_cfam_add_engine(FSICFAMCommon *cfam, DeviceState *engine,
> +                         hwaddr offset, Error **errp)
>  {
> -    FSICFAMState *s = FSI_CFAM(obj);
> +    if (!qdev_realize(engine, BUS(&cfam->lbus), errp)) {
> +        return false;
> +    }
>  
> -    object_initialize_child(obj, "scratchpad", &s->scratchpad,
> -                            TYPE_FSI_SCRATCHPAD);
> +    memory_region_add_subregion(&cfam->lbus.mr, offset,
> +                                &FSI_LBUS_DEVICE(engine)->iomem);
> +    return true;
>  }
>  
> -static void fsi_cfam_realize(DeviceState *dev, Error **errp)
> +static void fsi_cfam_common_realize(DeviceState *dev, Error **errp)
>  {
> -    FSICFAMState *cfam = FSI_CFAM(dev);
> +    FSICFAMCommon *cfam = FSI_CFAM_COMMON(dev);
> +    FSICFAMCommonClass *cc = FSI_CFAM_COMMON_GET_CLASS(dev);
>      FSISlaveState *slave = FSI_SLAVE(dev);
> +    const char *type = object_get_typename(OBJECT(dev));
> +    g_autofree char *config_name = g_strdup_printf("%s.config", type);
>  
>      /* Each slave has a 2MiB address space */
>      memory_region_init_io(&cfam->mr, OBJECT(cfam), &fsi_cfam_unimplemented_ops,
> -                          cfam, TYPE_FSI_CFAM, 2 * MiB);
> +                          cfam, type, FSI_CFAM_SLOT_SIZE);
>  
>      qbus_init(&cfam->lbus, sizeof(cfam->lbus), TYPE_FSI_LBUS, DEVICE(cfam),
>                NULL);
>  
>      memory_region_init_io(&cfam->config_iomem, OBJECT(cfam), &cfam_config_ops,
> -                          cfam, TYPE_FSI_CFAM ".config", 0x400);
> +                          cfam, config_name, FSI_CFAM_CONFIG_SIZE);
>  
>      memory_region_add_subregion(&cfam->mr, 0, &cfam->config_iomem);
> -    memory_region_add_subregion(&cfam->mr, 0x800, &slave->iomem);
> -    memory_region_add_subregion(&cfam->mr, 0xc00, &cfam->lbus.mr);
> +    memory_region_add_subregion(&cfam->mr, cc->responder_offset, &slave->iomem);
> +    memory_region_add_subregion(&cfam->mr, cc->lbus_offset, &cfam->lbus.mr);
>  
> -    /* Add scratchpad engine */
> -    if (!qdev_realize(DEVICE(&cfam->scratchpad), BUS(&cfam->lbus), errp)) {
> +    if (!cc->realize_engines(cfam, errp)) {
>          return;
>      }
> -
> -    FSILBusDevice *fsi_dev = FSI_LBUS_DEVICE(&cfam->scratchpad);
> -    memory_region_add_subregion(&cfam->lbus.mr, 0, &fsi_dev->iomem);
>  }
>  
> -static void fsi_cfam_class_init(ObjectClass *klass, const void *data)
> +static void fsi_cfam_common_class_init(ObjectClass *klass, const void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> +
>      dc->bus_type = TYPE_FSI_BUS;
> -    dc->realize = fsi_cfam_realize;
> +    dc->realize = fsi_cfam_common_realize;
> +}
> +
> +static bool fsi_cfam_realize_engines(FSICFAMCommon *cfam, Error **errp)
> +{
> +    FSICFAM *s = FSI_CFAM(cfam);
> +
> +    /* Add scratchpad engine */
> +    object_initialize_child(OBJECT(s), "scratchpad", &s->scratchpad,
> +                            TYPE_FSI_SCRATCHPAD);
> +
> +    return fsi_cfam_add_engine(cfam, DEVICE(&s->scratchpad), 0, errp);
>  }
>  
> +static void fsi_cfam_class_init(ObjectClass *klass, const void *data)
> +{
> +    FSICFAMCommonClass *cc = FSI_CFAM_COMMON_CLASS(klass);
> +
> +    cc->config = cfam_p9_config;
> +    cc->config_nr = ARRAY_SIZE(cfam_p9_config);
> +    cc->responder_offset = 0x800;
> +    cc->lbus_offset = 0xc00;
> +    cc->realize_engines = fsi_cfam_realize_engines;
> +}
> +
> +static const TypeInfo fsi_cfam_common_info = {
> +    .name = TYPE_FSI_CFAM_COMMON,
> +    .parent = TYPE_FSI_SLAVE,
> +    .instance_size = sizeof(FSICFAMCommon),
> +    .class_size = sizeof(FSICFAMCommonClass),
> +    .class_init = fsi_cfam_common_class_init,
> +    .abstract = true,
> +};
> +
>  static const TypeInfo fsi_cfam_info = {
>      .name = TYPE_FSI_CFAM,
> -    .parent = TYPE_FSI_SLAVE,
> -    .instance_init = fsi_cfam_instance_init,
> -    .instance_size = sizeof(FSICFAMState),
> +    .parent = TYPE_FSI_CFAM_COMMON,
> +    .instance_size = sizeof(FSICFAM),
>      .class_init = fsi_cfam_class_init,
>  };
>  
>  static void fsi_cfam_register_types(void)
>  {
> +    type_register_static(&fsi_cfam_common_info);
>      type_register_static(&fsi_cfam_info);
>  }
>  
> diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c
> index 083a5507ab..d82df1c094 100644
> --- a/hw/fsi/fsi-master.c
> +++ b/hw/fsi/fsi-master.c
> @@ -130,7 +130,7 @@ static void fsi_master_realize(DeviceState *dev, Error **errp)
>      }
>  
>      /* address ? */
> -    memory_region_add_subregion(&s->opb2fsi, 0, &s->cfam.mr);
> +    memory_region_add_subregion(&s->opb2fsi, 0, &s->cfam.parent.mr);
>  }
>  
>  static void fsi_master_reset(DeviceState *dev)



  reply	other threads:[~2026-08-11 13:37 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10 18:57 [PATCH v3 0/8] Add IBM Huygens BMC machine for AST2700 Mikail Sadic
2026-08-10 18:57 ` [PATCH v3 1/8] fsi/cfam: Add common CFAM base class Mikail Sadic
2026-08-11 13:36   ` Miles Glenn [this message]
2026-08-10 18:57 ` [PATCH v3 2/8] fsi/cfam: Add CFAM-S model Mikail Sadic
2026-08-10 18:57 ` [PATCH v3 3/8] arm/aspeed: Wire AST2700 FSI controllers to APB-to-OPB bridges Mikail Sadic
2026-08-11  4:32   ` Cédric Le Goater
2026-08-10 18:57 ` [PATCH v3 4/8] i2c/aspeed: Fix DMA receive first-byte handling for block reads Mikail Sadic
2026-08-11  4:30   ` Cédric Le Goater
2026-08-11  7:33     ` Jamin Lin
2026-08-10 18:57 ` [PATCH v3 5/8] hw/sensor: Add UCD90320 model Mikail Sadic
2026-08-10 18:57 ` [PATCH v3 6/8] ufs: Make the logical block size configurable and answer absent LUNs Mikail Sadic
2026-08-10 18:57 ` [PATCH v3 7/8] ufs/aspeed: Add AST2700 UFS host controller Mikail Sadic
2026-08-10 18:57 ` [PATCH v3 8/8] arm/aspeed: Add AST2700 Huygens machine Mikail Sadic
2026-08-11  4:35   ` Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=238ac7e72f1a6da53a61ca48ab8c016ef4d4e40d.camel@linux.ibm.com \
    --to=milesg@linux.ibm.com \
    --cc=andrew@codeconstruct.com.au \
    --cc=calebs@linux.ibm.com \
    --cc=clg@kaod.org \
    --cc=jamin_lin@aspeedtech.com \
    --cc=jeuk20.kim@samsung.com \
    --cc=joel@jms.id.au \
    --cc=kane_chen@aspeedtech.com \
    --cc=leetroy@gmail.com \
    --cc=mikail.sadic@ibm.com \
    --cc=ninad@linux.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@mailo.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=steven_lee@aspeedtech.com \
    --cc=titusr@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox