Re: [PATCH v11 06/11] hw/fsi: Introduce IBM's FSI master
Hello Cedric, v9: - Initialized registers. - Fixed the address check. v11: - Replaced for loop with memset. - Removed Joel's review tag as per Cedric. Reviewed-by: Cédric Le Goater Added tag. Thanks for the review. Regards, Ninad
Re: [PATCH v11 06/11] hw/fsi: Introduce IBM's FSI master
On 1/26/24 04:40, Ninad Palsule wrote: This is a part of patchset where IBM's Flexible Service Interface is introduced. This commit models the FSI master. CFAM is hanging out of FSI master which is a bus controller. The FSI master: A controller in the platform service processor (e.g. BMC) driving CFAM engine accesses into the POWER chip. At the hardware level FSI is a bit-based protocol supporting synchronous and DMA-driven accesses of engines in a CFAM. Signed-off-by: Andrew Jeffery Signed-off-by: Cédric Le Goater [ clg: - move FSICFAMState object under FSIMasterState - introduced fsi_master_init() - reworked fsi_master_realize() - dropped FSIBus definition ] Signed-off-by: Ninad Palsule --- v9: - Initialized registers. - Fixed the address check. v11: - Replaced for loop with memset. - Removed Joel's review tag as per Cedric. Reviewed-by: Cédric Le Goater Thanks, C. --- include/hw/fsi/fsi-master.h | 32 +++ hw/fsi/fsi-master.c | 170 hw/fsi/meson.build | 2 +- hw/fsi/trace-events | 2 + 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 include/hw/fsi/fsi-master.h create mode 100644 hw/fsi/fsi-master.c diff --git a/include/hw/fsi/fsi-master.h b/include/hw/fsi/fsi-master.h new file mode 100644 index 00..68e5f56db2 --- /dev/null +++ b/include/hw/fsi/fsi-master.h @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2024 IBM Corp. + * + * IBM Flexible Service Interface Master + */ +#ifndef FSI_FSI_MASTER_H +#define FSI_FSI_MASTER_H + +#include "exec/memory.h" +#include "hw/qdev-core.h" +#include "hw/fsi/fsi.h" +#include "hw/fsi/cfam.h" + +#define TYPE_FSI_MASTER "fsi.master" +OBJECT_DECLARE_SIMPLE_TYPE(FSIMasterState, FSI_MASTER) + +#define FSI_MASTER_NR_REGS ((0x2e0 >> 2) + 1) + +typedef struct FSIMasterState { +DeviceState parent; +MemoryRegion iomem; +MemoryRegion opb2fsi; + +FSIBus bus; + +uint32_t regs[FSI_MASTER_NR_REGS]; +FSICFAMState cfam; +} FSIMasterState; + + +#endif /* FSI_FSI_H */ diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c new file mode 100644 index 00..49ad4b988f --- /dev/null +++ b/hw/fsi/fsi-master.c @@ -0,0 +1,170 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2024 IBM Corp. + * + * IBM Flexible Service Interface master + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "trace.h" + +#include "hw/fsi/fsi-master.h" + +#define TYPE_OP_BUS "opb" + +#define TO_REG(x) ((x) >> 2) + +#define FSI_MENP0 TO_REG(0x010) +#define FSI_MENP32 TO_REG(0x014) +#define FSI_MSENP0 TO_REG(0x018) +#define FSI_MLEVP0 TO_REG(0x018) +#define FSI_MSENP32 TO_REG(0x01c) +#define FSI_MLEVP32 TO_REG(0x01c) +#define FSI_MCENP0 TO_REG(0x020) +#define FSI_MREFP0 TO_REG(0x020) +#define FSI_MCENP32 TO_REG(0x024) +#define FSI_MREFP32 TO_REG(0x024) + +#define FSI_MVERTO_REG(0x074) +#define FSI_MRESP0 TO_REG(0x0d0) + +#define FSI_MRESB0 TO_REG(0x1d0) +#define FSI_MRESB0_RESET_GENERAL BE_BIT(0) +#define FSI_MRESB0_RESET_ERRORBE_BIT(1) + +static uint64_t fsi_master_read(void *opaque, hwaddr addr, unsigned size) +{ +FSIMasterState *s = FSI_MASTER(opaque); +int reg = TO_REG(addr); + +trace_fsi_master_read(addr, size); + +if (reg >= FSI_MASTER_NR_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[reg]; +} + +static void fsi_master_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ +FSIMasterState *s = FSI_MASTER(opaque); +int reg = TO_REG(addr); + +trace_fsi_master_write(addr, size, data); + +if (reg >= FSI_MASTER_NR_REGS) { +qemu_log_mask(LOG_GUEST_ERROR, + "%s: Out of bounds write: %"HWADDR_PRIx" for %u\n", + __func__, addr, size); +return; +} + +switch (reg) { +case FSI_MENP0: +s->regs[FSI_MENP0] = data; +break; +case FSI_MENP32: +s->regs[FSI_MENP32] = data; +break; +case FSI_MSENP0: +s->regs[FSI_MENP0] |= data; +break; +case FSI_MSENP32: +s->regs[FSI_MENP32] |= data; +break; +case FSI_MCENP0: +s->regs[FSI_MENP0] &= ~data; +break; +case FSI_MCENP32: +s->regs[FSI_MENP32] &= ~data; +bre
[PATCH v11 06/11] hw/fsi: Introduce IBM's FSI master
This is a part of patchset where IBM's Flexible Service Interface is introduced. This commit models the FSI master. CFAM is hanging out of FSI master which is a bus controller. The FSI master: A controller in the platform service processor (e.g. BMC) driving CFAM engine accesses into the POWER chip. At the hardware level FSI is a bit-based protocol supporting synchronous and DMA-driven accesses of engines in a CFAM. Signed-off-by: Andrew Jeffery Signed-off-by: Cédric Le Goater [ clg: - move FSICFAMState object under FSIMasterState - introduced fsi_master_init() - reworked fsi_master_realize() - dropped FSIBus definition ] Signed-off-by: Ninad Palsule --- v9: - Initialized registers. - Fixed the address check. v11: - Replaced for loop with memset. - Removed Joel's review tag as per Cedric. --- include/hw/fsi/fsi-master.h | 32 +++ hw/fsi/fsi-master.c | 170 hw/fsi/meson.build | 2 +- hw/fsi/trace-events | 2 + 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 include/hw/fsi/fsi-master.h create mode 100644 hw/fsi/fsi-master.c diff --git a/include/hw/fsi/fsi-master.h b/include/hw/fsi/fsi-master.h new file mode 100644 index 00..68e5f56db2 --- /dev/null +++ b/include/hw/fsi/fsi-master.h @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2024 IBM Corp. + * + * IBM Flexible Service Interface Master + */ +#ifndef FSI_FSI_MASTER_H +#define FSI_FSI_MASTER_H + +#include "exec/memory.h" +#include "hw/qdev-core.h" +#include "hw/fsi/fsi.h" +#include "hw/fsi/cfam.h" + +#define TYPE_FSI_MASTER "fsi.master" +OBJECT_DECLARE_SIMPLE_TYPE(FSIMasterState, FSI_MASTER) + +#define FSI_MASTER_NR_REGS ((0x2e0 >> 2) + 1) + +typedef struct FSIMasterState { +DeviceState parent; +MemoryRegion iomem; +MemoryRegion opb2fsi; + +FSIBus bus; + +uint32_t regs[FSI_MASTER_NR_REGS]; +FSICFAMState cfam; +} FSIMasterState; + + +#endif /* FSI_FSI_H */ diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c new file mode 100644 index 00..49ad4b988f --- /dev/null +++ b/hw/fsi/fsi-master.c @@ -0,0 +1,170 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2024 IBM Corp. + * + * IBM Flexible Service Interface master + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "trace.h" + +#include "hw/fsi/fsi-master.h" + +#define TYPE_OP_BUS "opb" + +#define TO_REG(x) ((x) >> 2) + +#define FSI_MENP0 TO_REG(0x010) +#define FSI_MENP32 TO_REG(0x014) +#define FSI_MSENP0 TO_REG(0x018) +#define FSI_MLEVP0 TO_REG(0x018) +#define FSI_MSENP32 TO_REG(0x01c) +#define FSI_MLEVP32 TO_REG(0x01c) +#define FSI_MCENP0 TO_REG(0x020) +#define FSI_MREFP0 TO_REG(0x020) +#define FSI_MCENP32 TO_REG(0x024) +#define FSI_MREFP32 TO_REG(0x024) + +#define FSI_MVERTO_REG(0x074) +#define FSI_MRESP0 TO_REG(0x0d0) + +#define FSI_MRESB0 TO_REG(0x1d0) +#define FSI_MRESB0_RESET_GENERAL BE_BIT(0) +#define FSI_MRESB0_RESET_ERRORBE_BIT(1) + +static uint64_t fsi_master_read(void *opaque, hwaddr addr, unsigned size) +{ +FSIMasterState *s = FSI_MASTER(opaque); +int reg = TO_REG(addr); + +trace_fsi_master_read(addr, size); + +if (reg >= FSI_MASTER_NR_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[reg]; +} + +static void fsi_master_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ +FSIMasterState *s = FSI_MASTER(opaque); +int reg = TO_REG(addr); + +trace_fsi_master_write(addr, size, data); + +if (reg >= FSI_MASTER_NR_REGS) { +qemu_log_mask(LOG_GUEST_ERROR, + "%s: Out of bounds write: %"HWADDR_PRIx" for %u\n", + __func__, addr, size); +return; +} + +switch (reg) { +case FSI_MENP0: +s->regs[FSI_MENP0] = data; +break; +case FSI_MENP32: +s->regs[FSI_MENP32] = data; +break; +case FSI_MSENP0: +s->regs[FSI_MENP0] |= data; +break; +case FSI_MSENP32: +s->regs[FSI_MENP32] |= data; +break; +case FSI_MCENP0: +s->regs[FSI_MENP0] &= ~data; +break; +case FSI_MCENP32: +s->regs[FSI_MENP32] &= ~data; +break; +case FSI_MRESP0: +/* Perform necessary resets leave register 0 to indicate no errors */