From: Titus Rwantare <titusr@google.com>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org, peter@pjd.dev, patrick@stwcx.xyz,
iwona.winiarska@intel.com, tmaimon77@gmail.com,
quic_jaehyoo@quicinc.com, Titus Rwantare <titusr@google.com>,
Patrick Venture <venture@google.com>
Subject: [RFC PATCH v2 2/3] hw/peci: add PECI support for NPCM7xx BMCs
Date: Tue, 13 Sep 2022 18:21:48 +0000 [thread overview]
Message-ID: <20220913182149.1468366-3-titusr@google.com> (raw)
In-Reply-To: <20220913182149.1468366-1-titusr@google.com>
This allows BMC firmware for npcm7xx BMCs to talk to a PECI client
in qemu.
Signed-off-by: Titus Rwantare <titusr@google.com>
Reviewed-by: Patrick Venture <venture@google.com>
Reviewed-by: Peter Delevoryas <peter@pjd.dev>
---
MAINTAINERS | 1 +
hw/arm/Kconfig | 1 +
hw/arm/npcm7xx.c | 9 ++
hw/peci/meson.build | 1 +
hw/peci/npcm7xx_peci.c | 204 +++++++++++++++++++++++++++++++++
hw/peci/trace-events | 5 +
include/hw/arm/npcm7xx.h | 2 +
include/hw/peci/npcm7xx_peci.h | 37 ++++++
8 files changed, 260 insertions(+)
create mode 100644 hw/peci/npcm7xx_peci.c
create mode 100644 include/hw/peci/npcm7xx_peci.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 14ab29679d..f11a31cf57 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3218,6 +3218,7 @@ S: Maintained
F: hw/peci/peci-core.c
F: hw/peci/peci-client.c
F: include/hw/peci/peci.h
+F: hw/peci/npcm7xx_peci.c
Firmware schema specifications
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 15fa79afd3..cb38c6c88f 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -408,6 +408,7 @@ config NPCM7XX
select SSI
select UNIMP
select PCA954X
+ select PECI
config FSL_IMX25
bool
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d85cc02765..d408dd7eb4 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -45,6 +45,7 @@
#define NPCM7XX_CLK_BA (0xf0801000)
#define NPCM7XX_MC_BA (0xf0824000)
#define NPCM7XX_RNG_BA (0xf000b000)
+#define NPCM7XX_PECI_BA (0xf0100000)
/* USB Host modules */
#define NPCM7XX_EHCI_BA (0xf0806000)
@@ -83,6 +84,7 @@ enum NPCM7xxInterrupt {
NPCM7XX_UART1_IRQ,
NPCM7XX_UART2_IRQ,
NPCM7XX_UART3_IRQ,
+ NPCM7XX_PECI_IRQ = 6,
NPCM7XX_EMC1RX_IRQ = 15,
NPCM7XX_EMC1TX_IRQ,
NPCM7XX_MMC_IRQ = 26,
@@ -445,6 +447,7 @@ static void npcm7xx_init(Object *obj)
}
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
+ object_initialize_child(obj, "peci", &s->peci, TYPE_NPCM7XX_PECI);
}
static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -715,6 +718,12 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
+ /* PECI */
+ sysbus_realize(SYS_BUS_DEVICE(&s->peci), &error_abort);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->peci), 0, NPCM7XX_PECI_BA);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
+ npcm7xx_irq(s, NPCM7XX_PECI_IRQ));
+
create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
diff --git a/hw/peci/meson.build b/hw/peci/meson.build
index 01cfa95abe..ee033eb915 100644
--- a/hw/peci/meson.build
+++ b/hw/peci/meson.build
@@ -1 +1,2 @@
softmmu_ss.add(when: 'CONFIG_PECI', if_true: files('peci-core.c', 'peci-client.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_peci.c'))
diff --git a/hw/peci/npcm7xx_peci.c b/hw/peci/npcm7xx_peci.c
new file mode 100644
index 0000000000..17a2642898
--- /dev/null
+++ b/hw/peci/npcm7xx_peci.c
@@ -0,0 +1,204 @@
+/*
+ * Nuvoton NPCM7xx PECI Module
+ *
+ * Copyright 2021 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/peci/npcm7xx_peci.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/units.h"
+#include "trace.h"
+
+#define PECI_CTL_STS 0
+#define PECI_CTL_STS_DONE_EN BIT(6)
+#define PECI_CTL_STS_ABRT_ERR BIT(4)
+#define PECI_CTL_STS_CRC_ERR BIT(3)
+#define PECI_CTL_STS_DONE BIT(1)
+#define PECI_CTL_STS_START_BUSY BIT(0)
+#define PECI_RD_LENGTH 0x4
+#define PECI_ADDR 0x8
+#define PECI_CMD 0xC
+#define PECI_CTL2 0x10
+#define PECI_WR_LENGTH 0x1C
+#define PECI_PDDR 0x2C
+#define PECI_DAT_INOUT(reg) (0x100 + (reg) * 4)
+
+static uint64_t npcm7xx_peci_read(void *opaque, hwaddr offset, unsigned size)
+{
+ NPCM7xxPECIState *ps = NPCM7XX_PECI(opaque);
+ uint8_t ret = 0;
+
+ if (!ps->bus->num_clients) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no peci clients added to board\n",
+ __func__);
+ return 0;
+ }
+
+ qemu_irq_lower(ps->irq);
+
+ switch (offset) {
+ case PECI_CTL_STS:
+ ret = ps->status;
+ break;
+
+ case PECI_RD_LENGTH:
+ ret = ps->pcmd.rd_length;
+ break;
+
+ case PECI_ADDR:
+ ret = ps->pcmd.addr;
+ break;
+
+ case PECI_CMD:
+ ret = ps->pcmd.cmd;
+ break;
+
+ case PECI_CTL2:
+ ret = ps->ctl2;
+ break;
+
+ case PECI_WR_LENGTH:
+ ret = ps->pcmd.wr_length;
+ break;
+
+ case PECI_PDDR:
+ qemu_log_mask(LOG_UNIMP, "%s: PECI PDDR is unimplemented.\n", __func__);
+ ret = ps->pddr; /* undoc register */
+ break;
+
+ case PECI_DAT_INOUT(0) ... PECI_DAT_INOUT(63):
+ ret = ps->pcmd.tx[(offset - PECI_DAT_INOUT(0)) / 4];
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: unknown register 0x%lx\n",
+ __func__, offset);
+ ret = 0xff;
+ break;
+ }
+ trace_npcm7xx_peci_read(offset, ret);
+ return ret;
+}
+
+static void npcm7xx_peci_write(void *opaque, hwaddr offset, uint64_t input,
+ unsigned size)
+{
+ NPCM7xxPECIState *ps = NPCM7XX_PECI(opaque);
+ uint8_t data = input & 0xff;
+
+ trace_npcm7xx_peci_write(offset, input);
+
+ /* ignore writes if the bus has not been populated */
+ if (!ps->bus->num_clients) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no peci clients added to board\n",
+ __func__);
+ return;
+ }
+
+ switch (offset) {
+ case PECI_CTL_STS:
+ ps->status = data;
+ /* STS_START busy is set by the bmc when the request is written */
+ if (data & PECI_CTL_STS_START_BUSY) {
+ if (!peci_handle_cmd(ps->bus, &(ps->pcmd))) {
+ ps->status |= PECI_CTL_STS_ABRT_ERR;
+ }
+ ps->status |= PECI_CTL_STS_DONE;
+ ps->status &= ~PECI_CTL_STS_START_BUSY;
+ qemu_irq_raise(ps->irq);
+ }
+ break;
+
+ case PECI_RD_LENGTH:
+ ps->pcmd.rd_length = data;
+ break;
+
+ case PECI_ADDR:
+ ps->pcmd.addr = data;
+ break;
+
+ case PECI_CMD:
+ ps->pcmd.cmd = data;
+ break;
+
+ case PECI_CTL2:
+ ps->ctl2 = data;
+ break;
+
+ case PECI_WR_LENGTH:
+ ps->pcmd.wr_length = data;
+ break;
+
+ case PECI_PDDR:
+ ps->pddr = data;
+ break;
+
+ case PECI_DAT_INOUT(0) ... PECI_DAT_INOUT(63):
+ ps->pcmd.rx[(offset - PECI_DAT_INOUT(0)) / 4] = data;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: to unknown register 0x%lx : 0x%lx\n",
+ __func__, offset, input);
+ return;
+ }
+
+}
+
+static void npcm7xx_peci_reset(Object *obj, ResetType type)
+{
+ NPCM7xxPECIState *ps = NPCM7XX_PECI(obj);
+
+ ps->status = PECI_CTL_STS_DONE_EN;
+}
+
+static const MemoryRegionOps npcm7xx_peci_ops = {
+ .read = npcm7xx_peci_read,
+ .write = npcm7xx_peci_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .min_access_size = 1,
+ .unaligned = false,
+ },
+};
+
+static void npcm7xx_peci_realize(DeviceState *dev, Error **errp)
+{
+ NPCM7xxPECIState *ps = NPCM7XX_PECI(dev);
+ SysBusDevice *sbd = &ps->parent;
+
+ memory_region_init_io(&ps->iomem, OBJECT(ps), &npcm7xx_peci_ops, ps,
+ TYPE_NPCM7XX_PECI, 4 * KiB);
+
+ sysbus_init_mmio(sbd, &ps->iomem);
+ sysbus_init_irq(sbd, &ps->irq);
+
+ ps->bus = peci_bus_create(DEVICE(ps));
+}
+
+static void npcm7xx_peci_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->desc = "NPCM7xx PECI Module";
+ dc->realize = npcm7xx_peci_realize;
+ rc->phases.enter = npcm7xx_peci_reset;
+}
+
+static const TypeInfo npcm7xx_peci_types[] = {
+ {
+ .name = TYPE_NPCM7XX_PECI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NPCM7xxPECIState),
+ .class_init = npcm7xx_peci_class_init,
+ },
+};
+
+DEFINE_TYPES(npcm7xx_peci_types)
diff --git a/hw/peci/trace-events b/hw/peci/trace-events
index f90c998dd9..a895b21f7b 100644
--- a/hw/peci/trace-events
+++ b/hw/peci/trace-events
@@ -3,3 +3,8 @@
# peci-core.c
peci_handle_cmd(const char* s, uint8_t addr) "%s @ 0x%02" PRIx8
peci_rd_pkg_cfg(const char* s) "%s"
+
+# npcm7xx_peci.c
+npcm7xx_peci_cmd(uint64_t cmd) "cmd: 0x%04" PRIx64
+npcm7xx_peci_read(uint64_t offset, uint64_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
+npcm7xx_peci_write(uint64_t offset, uint64_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx64
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index ce593235d9..9e7cf8b774 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -30,6 +30,7 @@
#include "hw/misc/npcm7xx_rng.h"
#include "hw/net/npcm7xx_emc.h"
#include "hw/nvram/npcm7xx_otp.h"
+#include "hw/peci/npcm7xx_peci.h"
#include "hw/timer/npcm7xx_timer.h"
#include "hw/ssi/npcm7xx_fiu.h"
#include "hw/usb/hcd-ehci.h"
@@ -105,6 +106,7 @@ typedef struct NPCM7xxState {
NPCM7xxFIUState fiu[2];
NPCM7xxEMCState emc[2];
NPCM7xxSDHCIState mmc;
+ NPCM7xxPECIState peci;
} NPCM7xxState;
#define TYPE_NPCM7XX "npcm7xx"
diff --git a/include/hw/peci/npcm7xx_peci.h b/include/hw/peci/npcm7xx_peci.h
new file mode 100644
index 0000000000..421f445041
--- /dev/null
+++ b/include/hw/peci/npcm7xx_peci.h
@@ -0,0 +1,37 @@
+/*
+ * Nuvoton NPCM7xx PECI Module
+ *
+ * Copyright 2021 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef NPCM7XX_PECI_H
+#define NPCM7XX_PECI_H
+
+#include "exec/memory.h"
+#include "hw/irq.h"
+#include "hw/peci/peci.h"
+#include "hw/sysbus.h"
+
+typedef struct NPCM7xxPECIState {
+ SysBusDevice parent;
+
+ MemoryRegion iomem;
+
+ PECIBus *bus;
+ qemu_irq irq;
+
+ PECICmd pcmd;
+
+ /* Registers */
+ uint8_t status;
+ uint8_t ctl2;
+ uint8_t pddr;
+} NPCM7xxPECIState;
+
+#define TYPE_NPCM7XX_PECI "npcm7xx-peci"
+#define NPCM7XX_PECI(obj) \
+ OBJECT_CHECK(NPCM7xxPECIState, (obj), TYPE_NPCM7XX_PECI)
+
+#endif /* NPCM7XX_PECI_H */
--
2.37.3.968.ga6b4b080e4-goog
next prev parent reply other threads:[~2022-09-13 18:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-13 18:21 [RFC PATCH v2 0/3] Initial PECI bus support Titus Rwantare
2022-09-13 18:21 ` [RFC PATCH v2 1/3] hw/peci: add initial support for PECI Titus Rwantare
2022-09-13 18:29 ` Peter Delevoryas
2022-09-13 18:21 ` Titus Rwantare [this message]
2022-09-13 18:21 ` [RFC PATCH v2 3/3] hw/peci: add support for EndPointConfig reads Titus Rwantare
2022-09-13 18:30 ` Peter Delevoryas
2022-09-22 15:09 ` [RFC PATCH v2 0/3] Initial PECI bus support Peter Maydell
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=20220913182149.1468366-3-titusr@google.com \
--to=titusr@google.com \
--cc=iwona.winiarska@intel.com \
--cc=patrick@stwcx.xyz \
--cc=peter@pjd.dev \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=quic_jaehyoo@quicinc.com \
--cc=tmaimon77@gmail.com \
--cc=venture@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.