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)
next prev parent 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