[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v1 6/7] hw/fsi: Aspeed APB2OPB interface
From: |
Joel Stanley |
Subject: |
Re: [PATCH v1 6/7] hw/fsi: Aspeed APB2OPB interface |
Date: |
Mon, 28 Aug 2023 08:55:52 +0000 |
On Fri, 25 Aug 2023 at 20:31, Ninad Palsule <ninad@linux.ibm.com> wrote:
>
> This is a part of patchset where IBM's Flexible Service Interface is
> introduced.
>
> An APB-to-OPB bridge enabling access to the OPB from the ARM core in
> the AST2600. Hardware limitations prevent the OPB from being directly
> mapped into APB, so all accesses are indirect through the bridge.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Signed-off-by: Ninad Palsule <ninad@linux.ibm.com>
> ---
> hw/arm/Kconfig | 1 +
> hw/fsi/Kconfig | 4 +
> hw/fsi/aspeed-apb2opb.c | 346 ++++++++++++++++++++++++++++++++
> hw/fsi/meson.build | 1 +
> hw/fsi/trace-events | 2 +
> hw/fsi/trace.h | 1 +
> include/hw/fsi/aspeed-apb2opb.h | 32 +++
> meson.build | 1 +
> 8 files changed, 388 insertions(+)
> create mode 100644 hw/fsi/aspeed-apb2opb.c
> create mode 100644 hw/fsi/trace-events
> create mode 100644 hw/fsi/trace.h
> create mode 100644 include/hw/fsi/aspeed-apb2opb.h
>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 7e68348440..a6994cd9d7 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -589,6 +589,7 @@ config FSL_IMX7
> select PCI_EXPRESS_DESIGNWARE
> select SDHCI
> select UNIMP
> + select APB2OPB_ASPEED
>
> config ARM_SMMUV3
> bool
> diff --git a/hw/fsi/Kconfig b/hw/fsi/Kconfig
> index 560ce536db..fbb021658d 100644
> --- a/hw/fsi/Kconfig
> +++ b/hw/fsi/Kconfig
> @@ -1,3 +1,7 @@
> +config APB2OPB_ASPEED
> + bool
> + select OPB
> +
> config OPB
> bool
> select CFAM
> diff --git a/hw/fsi/aspeed-apb2opb.c b/hw/fsi/aspeed-apb2opb.c
> new file mode 100644
> index 0000000000..bbc63f2eb3
> --- /dev/null
> +++ b/hw/fsi/aspeed-apb2opb.c
> @@ -0,0 +1,346 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * Copyright (C) 2023 IBM Corp.
> + *
> + * ASPEED APB-OPB FSI interface
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qom/object.h"
> +#include "qapi/error.h"
> +#include "trace.h"
> +
> +#include "hw/fsi/aspeed-apb2opb.h"
> +#include "hw/qdev-core.h"
> +
> +#define TO_REG(x) (x >> 2)
> +#define GENMASK(t, b) (((1ULL << ((t) + 1)) - 1) & ~((1ULL << (b)) - 1))
We should put this in a common header.
> +
> +#define APB2OPB_VERSION TO_REG(0x00)
> +#define APB2OPB_VERSION_VER GENMASK(7, 0)
> +
> +#define APB2OPB_TRIGGER TO_REG(0x04)
> +#define APB2OPB_TRIGGER_EN BIT(0)
> +
> +#define APB2OPB_CONTROL TO_REG(0x08)
> +#define APB2OPB_CONTROL_OFF GENMASK(31, 13)
> +
> +#define APB2OPB_OPB2FSI TO_REG(0x0c)
> +#define APB2OPB_OPB2FSI_OFF GENMASK(31, 22)
> +
> +#define APB2OPB_OPB0_SEL TO_REG(0x10)
> +#define APB2OPB_OPB1_SEL TO_REG(0x28)
> +#define APB2OPB_OPB_SEL_EN BIT(0)
> +
> +#define APB2OPB_OPB0_MODE TO_REG(0x14)
> +#define APB2OPB_OPB1_MODE TO_REG(0x2c)
> +#define APB2OPB_OPB_MODE_RD BIT(0)
> +
> +#define APB2OPB_OPB0_XFER TO_REG(0x18)
> +#define APB2OPB_OPB1_XFER TO_REG(0x30)
> +#define APB2OPB_OPB_XFER_FULL BIT(1)
> +#define APB2OPB_OPB_XFER_HALF BIT(0)
> +
> +#define APB2OPB_OPB0_ADDR TO_REG(0x1c)
> +#define APB2OPB_OPB0_WRITE_DATA TO_REG(0x20)
> +
> +#define APB2OPB_OPB1_DMA_EN TO_REG(0x24)
> +#define APB2OPB_OPB1_DMA_EN_3 BIT(3)
> +#define APB2OPB_OPB1_DMA_EN_2 BIT(2)
> +#define APB2OPB_OPB1_DMA_EN_1 BIT(1)
> +#define APB2OPB_OPB1_DMA_EN_0 BIT(0)
> +
> +#define APB2OPB_OPB1_ADDR TO_REG(0x34)
> +#define APB2OPB_OPB1_WRITE_DATA TO_REG(0x38)
> +
> +#define APB2OPB_OPB_CLK TO_REG(0x3c)
> +#define APB2OPB_OPB_CLK_SYNC BIT(0)
> +
> +#define APB2OPB_IRQ_CLEAR TO_REG(0x40)
> +#define APB2OPB_IRQ_CLEAR_EN BIT(0)
> +
> +#define APB2OPB_IRQ_MASK TO_REG(0x44)
> +#define APB2OPB_IRQ_MASK_OPB1_TX_ACK BIT(17)
> +#define APB2OPB_IRQ_MASK_OPB0_TX_ACK BIT(16)
> +#define APB2OPB_IRQ_MASK_CH3_TCONT BIT(15)
> +#define APB2OPB_IRQ_MASK_CH2_TCONT BIT(14)
> +#define APB2OPB_IRQ_MASK_CH1_TCONT BIT(13)
> +#define APB2OPB_IRQ_MASK_CH0_TCONT BIT(12)
> +#define APB2OPB_IRQ_MASK_CH3_FIFO_EMPTY BIT(11)
> +#define APB2OPB_IRQ_MASK_CH2_FIFO_EMPTY BIT(10)
> +#define APB2OPB_IRQ_MASK_CH1_FIFO_EMPTY BIT(9)
> +#define APB2OPB_IRQ_MASK_CH0_FIFO_EMPTY BIT(8)
> +#define APB2OPB_IRQ_MASK_CH3_FIFO_FULL BIT(7)
> +#define APB2OPB_IRQ_MASK_CH2_FIFO_FULL BIT(6)
> +#define APB2OPB_IRQ_MASK_CH1_FIFO_FULL BIT(5)
> +#define APB2OPB_IRQ_MASK_CH0_FIFO_FULL BIT(4)
> +#define APB2OPB_IRQ_MASK_CH3_DMA_EOT BIT(3)
> +#define APB2OPB_IRQ_MASK_CH2_DMA_EOT BIT(2)
> +#define APB2OPB_IRQ_MASK_CH1_DMA_EOT BIT(1)
> +#define APB2OPB_IRQ_MASK_CH0_DMA_EOT BIT(0)
> +
> +#define APB2OPB_IRQ_STS TO_REG(0x48)
> +#define APB2OPB_IRQ_STS_MASTER_ERROR BIT(28)
> +#define APB2OPB_IRQ_STS_PORT_ERROR BIT(27)
> +#define APB2OPB_IRQ_STS_HOTPLUG BIT(26)
> +#define APB2OPB_IRQ_STS_SLAVE_7 BIT(25)
> +#define APB2OPB_IRQ_STS_SLAVE_6 BIT(24)
> +#define APB2OPB_IRQ_STS_SLAVE_5 BIT(23)
> +#define APB2OPB_IRQ_STS_SLAVE_4 BIT(22)
> +#define APB2OPB_IRQ_STS_SLAVE_3 BIT(21)
> +#define APB2OPB_IRQ_STS_SLAVE_2 BIT(20)
> +#define APB2OPB_IRQ_STS_SLAVE_1 BIT(19)
> +#define APB2OPB_IRQ_STS_SLAVE_0 BIT(18)
> +#define APB2OPB_IRQ_STS_OPB1_TX_ACK BIT(17)
> +#define APB2OPB_IRQ_STS_OPB0_TX_ACK BIT(16)
> +#define APB2OPB_IRQ_STS_CH3_TCONT BIT(15)
> +#define APB2OPB_IRQ_STS_CH2_TCONT BIT(14)
> +#define APB2OPB_IRQ_STS_CH1_TCONT BIT(13)
> +#define APB2OPB_IRQ_STS_CH0_TCONT BIT(12)
> +#define APB2OPB_IRQ_STS_CH3_FIFO_EMPTY BIT(11)
> +#define APB2OPB_IRQ_STS_CH2_FIFO_EMPTY BIT(10)
> +#define APB2OPB_IRQ_STS_CH1_FIFO_EMPTY BIT(9)
> +#define APB2OPB_IRQ_STS_CH0_FIFO_EMPTY BIT(8)
> +#define APB2OPB_IRQ_STS_CH3_FIFO_FULL BIT(7)
> +#define APB2OPB_IRQ_STS_CH2_FIFO_FULL BIT(6)
> +#define APB2OPB_IRQ_STS_CH1_FIFO_FULL BIT(5)
> +#define APB2OPB_IRQ_STS_CH0_FIFO_FULL BIT(4)
> +#define APB2OPB_IRQ_STS_CH3_DMA_EOT BIT(3)
> +#define APB2OPB_IRQ_STS_CH2_DMA_EOT BIT(2)
> +#define APB2OPB_IRQ_STS_CH1_DMA_EOT BIT(1)
> +#define APB2OPB_IRQ_STS_CH0_DMA_EOT BIT(0)
> +
> +#define APB2OPB_OPB0_WRITE_WORD_ENDIAN TO_REG(0x4c)
> +#define APB2OPB_OPB0_WRITE_WORD_ENDIAN_BE 0x0011101b
> +#define APB2OPB_OPB0_WRITE_BYTE_ENDIAN TO_REG(0x50)
> +#define APB2OPB_OPB0_WRITE_BYTE_ENDIAN_BE 0x0c330f3f
> +#define APB2OPB_OPB1_WRITE_WORD_ENDIAN TO_REG(0x54)
> +#define APB2OPB_OPB1_WRITE_BYTE_ENDIAN TO_REG(0x58)
> +#define APB2OPB_OPB0_READ_BYTE_ENDIAN TO_REG(0x5c)
> +#define APB2OPB_OPB0_READ_WORD_ENDIAN_BE 0x00030b1b
> +#define APB2OPB_OPB1_READ_BYTE_ENDIAN TO_REG(0x60)
> +
> +#define APB2OPB_RETRY TO_REG(0x64)
> +#define APB2OPB_RETRY_COUNTER GENMASK(15, 0)
> +
> +#define APB2OPB_OPB0_STATUS TO_REG(0x80)
> +#define APB2OPB_OPB1_STATUS TO_REG(0x8c)
> +#define APB2OPB_OPB_STATUS_TIMEOUT BIT(4)
> +#define APB2OPB_OPB_STATUS_RETRY BIT(3)
> +#define APB2OPB_OPB_STATUS_ERROR_ACK BIT(2)
> +#define APB2OPB_OPB_STATUS_FW_ACK BIT(1)
> +#define APB2OPB_OPB_STATUS_HW_ACK BIT(0)
> +
> +#define APB2OPB_OPB0_READ_DATA TO_REG(0x84)
> +
> +#define APB2OPB_OPB1_DMA_STATUS TO_REG(0x88)
> +#define APB2OPB_OPB1_DMA_STATUS_CH3_EOT BIT(7)
> +#define APB2OPB_OPB1_DMA_STATUS_CH2_EOT BIT(6)
> +#define APB2OPB_OPB1_DMA_STATUS_CH1_EOT BIT(5)
> +#define APB2OPB_OPB1_DMA_STATUS_CH0_EOT BIT(4)
> +#define APB2OPB_OPB1_DMA_STATUS_CH3_REQ BIT(3)
> +#define APB2OPB_OPB1_DMA_STATUS_CH2_REQ BIT(2)
> +#define APB2OPB_OPB1_DMA_STATUS_CH1_REQ BIT(1)
> +#define APB2OPB_OPB1_DMA_STATUS_CH0_REQ BIT(0)
> +
> +#define APB2OPB_OPB1_READ_DATA TO_REG(0x90)
> +
> +static uint64_t aspeed_apb2opb_read(void *opaque, hwaddr addr, unsigned size)
> +{
> + AspeedAPB2OPBState *s = ASPEED_APB2OPB(opaque);
> +
> + trace_aspeed_apb2opb_read(addr, size);
> +
> + assert(!(addr & 3));
> + assert(size == 4);
> +
> + if (addr + size > sizeof(s->regs)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Out of bounds read: 0x%"HWADDR_PRIx" for %u\n",
> + __func__, addr, size);
> + return 0;
> + }
> +
> + return s->regs[TO_REG(addr)];
> +}
> +
> +static void aspeed_apb2opb_write(void *opaque, hwaddr addr, uint64_t data,
> + unsigned size)
> +{
> + AspeedAPB2OPBState *s = ASPEED_APB2OPB(opaque);
> +
> + trace_aspeed_apb2opb_write(addr, size, data);
> +
> + assert(!(addr & 3));
> + assert(size == 4);
> +
> + if (addr + size > sizeof(s->regs)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Out of bounds write: %"HWADDR_PRIx" for %u\n",
> + __func__, addr, size);
> + return;
> + }
> +
> + switch (TO_REG(addr)) {
> + case APB2OPB_CONTROL:
> + opb_fsi_master_address(&s->opb[0], data & APB2OPB_CONTROL_OFF);
> + break;
> + case APB2OPB_OPB2FSI:
> + opb_opb2fsi_address(&s->opb[0], data & APB2OPB_OPB2FSI_OFF);
> + break;
> + case APB2OPB_OPB0_WRITE_WORD_ENDIAN:
> + if (data != APB2OPB_OPB0_WRITE_WORD_ENDIAN_BE) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Bridge needs to be driven as BE (0x%x)\n",
> + __func__, APB2OPB_OPB0_WRITE_WORD_ENDIAN_BE);
> + }
> + break;
> + case APB2OPB_OPB0_WRITE_BYTE_ENDIAN:
> + if (data != APB2OPB_OPB0_WRITE_BYTE_ENDIAN_BE) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Bridge needs to be driven as BE (0x%x)\n",
> + __func__, APB2OPB_OPB0_WRITE_BYTE_ENDIAN_BE);
> + }
> + break;
> + case APB2OPB_OPB0_READ_BYTE_ENDIAN:
> + if (data != APB2OPB_OPB0_READ_WORD_ENDIAN_BE) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "%s: Bridge needs to be driven as BE (0x%x)\n",
> + __func__, APB2OPB_OPB0_READ_WORD_ENDIAN_BE);
> + }
> + break;
> + case APB2OPB_TRIGGER:
> + {
> + uint32_t opb, op_mode, op_size, op_addr, op_data;
> +
> + assert((s->regs[APB2OPB_OPB0_SEL] & APB2OPB_OPB_SEL_EN) ^
> + (s->regs[APB2OPB_OPB1_SEL] & APB2OPB_OPB_SEL_EN));
> +
> + if (s->regs[APB2OPB_OPB0_SEL] & APB2OPB_OPB_SEL_EN) {
> + opb = 0;
> + op_mode = s->regs[APB2OPB_OPB0_MODE];
> + op_size = s->regs[APB2OPB_OPB0_XFER];
> + op_addr = s->regs[APB2OPB_OPB0_ADDR];
> + op_data = s->regs[APB2OPB_OPB0_WRITE_DATA];
> + } else if (s->regs[APB2OPB_OPB1_SEL] & APB2OPB_OPB_SEL_EN) {
> + opb = 1;
> + op_mode = s->regs[APB2OPB_OPB1_MODE];
> + op_size = s->regs[APB2OPB_OPB1_XFER];
> + op_addr = s->regs[APB2OPB_OPB1_ADDR];
> + op_data = s->regs[APB2OPB_OPB1_WRITE_DATA];
> + } else {
> + g_assert_not_reached();
> + }
> +
> + if (op_size & ~(APB2OPB_OPB_XFER_HALF | APB2OPB_OPB_XFER_FULL)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "OPB transaction failed: Unrecognised access
> width: %d\n",
> + op_size);
> + return;
> + }
> +
> + op_size += 1;
> +
> + if (op_mode & APB2OPB_OPB_MODE_RD) {
> + int index = opb ? APB2OPB_OPB1_READ_DATA
> + : APB2OPB_OPB0_READ_DATA;
> +
> + switch (op_size) {
> + case 1:
> + s->regs[index] = opb_read8(&s->opb[opb], op_addr);
> + break;
> + case 2:
> + s->regs[index] = opb_read16(&s->opb[opb], op_addr);
> + break;
> + case 4:
> + s->regs[index] = opb_read32(&s->opb[opb], op_addr);
> + break;
> + default:
> + g_assert_not_reached(); /* should have bailed above */
> + }
> + } else {
> + /* FIXME: Endian swizzling */
> + switch (op_size) {
> + case 1:
> + opb_write8(&s->opb[opb], op_addr, op_data);
> + break;
> + case 2:
> + opb_write16(&s->opb[opb], op_addr, op_data);
> + break;
> + case 4:
> + opb_write32(&s->opb[opb], op_addr, op_data);
> + break;
> + default:
> + g_assert_not_reached(); /* should have bailed above */
> + }
> + }
> + s->regs[APB2OPB_IRQ_STS] |= opb ? APB2OPB_IRQ_STS_OPB1_TX_ACK
> + : APB2OPB_IRQ_STS_OPB0_TX_ACK;
> + break;
> + }
> + }
> +
> + s->regs[TO_REG(addr)] = data;
> +}
> +
> +static const struct MemoryRegionOps aspeed_apb2opb_ops = {
> + .read = aspeed_apb2opb_read,
> + .write = aspeed_apb2opb_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static void aspeed_apb2opb_realize(DeviceState *dev, Error **errp)
> +{
> + SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> + AspeedAPB2OPBState *s = ASPEED_APB2OPB(dev);
> +
> + qbus_init(&s->opb[0], sizeof(s->opb[0]), TYPE_OP_BUS,
> + DEVICE(s), NULL);
> + qbus_init(&s->opb[1], sizeof(s->opb[1]), TYPE_OP_BUS,
> + DEVICE(s), NULL);
> +
> + sysbus_init_irq(sbd, &s->irq);
> +
> + memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_apb2opb_ops, s,
> + TYPE_ASPEED_APB2OPB, 0x1000);
> + sysbus_init_mmio(sbd, &s->iomem);
> +}
> +
> +static void aspeed_apb2opb_reset(DeviceState *dev)
> +{
> + AspeedAPB2OPBState *s = ASPEED_APB2OPB(dev);
> +
> + memset(s->regs, 0, sizeof(s->regs));
> +
> + s->regs[APB2OPB_VERSION] = 0x000000a1;
> + s->regs[APB2OPB_OPB0_WRITE_WORD_ENDIAN] = 0x0044eee4;
> + s->regs[APB2OPB_OPB0_WRITE_BYTE_ENDIAN] = 0x0055aaff;
> + s->regs[APB2OPB_OPB1_WRITE_WORD_ENDIAN] = 0x00117717;
> + s->regs[APB2OPB_OPB1_WRITE_BYTE_ENDIAN] = 0xffaa5500;
> + s->regs[APB2OPB_OPB0_READ_BYTE_ENDIAN] = 0x0044eee4;
> + s->regs[APB2OPB_OPB0_READ_BYTE_ENDIAN] = 0x00117717;
Add a comment about the source of these magic numbers. I think this is
the best reference we have:
https://git.kernel.org/torvalds/c/5e5022995683539609b3904213b7d72ab71188b7
I'm not sure if the reset values were taken from the hardware, or the
kernel driver.
> +}
> +
> +static void aspeed_apb2opb_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->desc = "ASPEED APB2OPB Bridge";
> + dc->realize = aspeed_apb2opb_realize;
> + dc->reset = aspeed_apb2opb_reset;
> +}
> +
> +static const TypeInfo aspeed_apb2opb_info = {
> + .name = TYPE_ASPEED_APB2OPB,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(AspeedAPB2OPBState),
> + .class_init = aspeed_apb2opb_class_init,
> +};
> +
> +static void aspeed_apb2opb_register_types(void)
> +{
> + type_register_static(&aspeed_apb2opb_info);
> +}
> +
> +type_init(aspeed_apb2opb_register_types);
> diff --git a/hw/fsi/meson.build b/hw/fsi/meson.build
> index cab645f4ea..ce8b9555ce 100644
> --- a/hw/fsi/meson.build
> +++ b/hw/fsi/meson.build
> @@ -3,3 +3,4 @@ system_ss.add(when: 'CONFIG_SCRATCHPAD', if_true:
> files('engine-scratchpad.c'))
> system_ss.add(when: 'CONFIG_CFAM', if_true: files('cfam.c'))
> system_ss.add(when: 'CONFIG_FSI', if_true:
> files('fsi.c','fsi-master.c','fsi-slave.c'))
> system_ss.add(when: 'CONFIG_OPB', if_true: files('opb.c'))
> +system_ss.add(when: 'CONFIG_APB2OPB_ASPEED', if_true:
> files('aspeed-apb2opb.c'))
> diff --git a/hw/fsi/trace-events b/hw/fsi/trace-events
> new file mode 100644
> index 0000000000..c64245f7f6
> --- /dev/null
> +++ b/hw/fsi/trace-events
> @@ -0,0 +1,2 @@
> +aspeed_apb2opb_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d"
> +aspeed_apb2opb_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%"
> PRIx64 " size=%d value=0x%"PRIx64
> diff --git a/hw/fsi/trace.h b/hw/fsi/trace.h
> new file mode 100644
> index 0000000000..ee67c7fb04
> --- /dev/null
> +++ b/hw/fsi/trace.h
> @@ -0,0 +1 @@
> +#include "trace/trace-hw_fsi.h"
> diff --git a/include/hw/fsi/aspeed-apb2opb.h b/include/hw/fsi/aspeed-apb2opb.h
> new file mode 100644
> index 0000000000..4acc980e7d
> --- /dev/null
> +++ b/include/hw/fsi/aspeed-apb2opb.h
> @@ -0,0 +1,32 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * Copyright (C) 2023 IBM Corp.
> + *
> + * ASPEED APB2OPB Bridge
> + */
> +#ifndef FSI_ASPEED_APB2OPB_H
> +#define FSI_ASPEED_APB2OPB_H
> +
> +#include "hw/sysbus.h"
> +#include "hw/fsi/opb.h"
> +
> +#define TYPE_ASPEED_APB2OPB "aspeed.apb2opb"
> +#define ASPEED_APB2OPB(obj) \
> + OBJECT_CHECK(AspeedAPB2OPBState, (obj), TYPE_ASPEED_APB2OPB)
> +
> +#define ASPEED_APB2OPB_NR_REGS ((0xe8 >> 2) + 1)
> +
> +typedef struct AspeedAPB2OPBState {
> + /*< private >*/
> + SysBusDevice parent_obj;
> +
> + /*< public >*/
> + MemoryRegion iomem;
> +
> + uint32_t regs[ASPEED_APB2OPB_NR_REGS];
> + qemu_irq irq;
> +
> + OPBus opb[2];
> +} AspeedAPB2OPBState;
> +
> +#endif /* FSI_ASPEED_APB2OPB_H */
> diff --git a/meson.build b/meson.build
> index 98e68ef0b1..1a722693a6 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -3244,6 +3244,7 @@ if have_system
> 'hw/char',
> 'hw/display',
> 'hw/dma',
> + 'hw/fsi',
> 'hw/hyperv',
> 'hw/i2c',
> 'hw/i386',
> --
> 2.39.2
>
- [PATCH v1 0/7] Introduce model for IBM's FSP, Ninad Palsule, 2023/08/25
- [PATCH v1 1/7] hw/fsi: Introduce IBM's Local bus, Ninad Palsule, 2023/08/25
- [PATCH v1 6/7] hw/fsi: Aspeed APB2OPB interface, Ninad Palsule, 2023/08/25
- Re: [PATCH v1 6/7] hw/fsi: Aspeed APB2OPB interface,
Joel Stanley <=
- [PATCH v1 7/7] hw/arm: Hook up FSI module in AST2600, Ninad Palsule, 2023/08/25
- [PATCH v1 5/7] hw/fsi: IBM's On-chip Peripheral Bus, Ninad Palsule, 2023/08/25
- [PATCH v1 4/7] hw/fsi: Introduce IBM's FSI, Ninad Palsule, 2023/08/25