[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 07/14] aspeed: Add PECI controller
From: |
Peter Delevoryas |
Subject: |
Re: [PATCH 07/14] aspeed: Add PECI controller |
Date: |
Tue, 28 Jun 2022 06:58:40 +0000 |
> On Jun 27, 2022, at 11:47 PM, Cédric Le Goater <clg@kaod.org> wrote:
>
> On 6/27/22 21:54, Peter Delevoryas wrote:
>
> Could we have some short intro ? :)
Yes, definitely, I’ll resubmit with some more details.
>
>> Signed-off-by: Peter Delevoryas <pdel@fb.com>
>> ---
>> hw/arm/aspeed_ast10x0.c | 11 ++
>> hw/misc/aspeed_peci.c | 225 ++++++++++++++++++++++++++++++++++
>> hw/misc/meson.build | 3 +-
>> include/hw/arm/aspeed_soc.h | 3 +
>> include/hw/misc/aspeed_peci.h | 34 +++++
>> 5 files changed, 275 insertions(+), 1 deletion(-)
>> create mode 100644 hw/misc/aspeed_peci.c
>> create mode 100644 include/hw/misc/aspeed_peci.h
>> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
>> index 5df480a21f..780841ea84 100644
>> --- a/hw/arm/aspeed_ast10x0.c
>> +++ b/hw/arm/aspeed_ast10x0.c
>> @@ -47,6 +47,7 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
>> [ASPEED_DEV_UART13] = 0x7E790700,
>> [ASPEED_DEV_WDT] = 0x7E785000,
>> [ASPEED_DEV_LPC] = 0x7E789000,
>> + [ASPEED_DEV_PECI] = 0x7E78B000,
>> [ASPEED_DEV_I2C] = 0x7E7B0000,
>> };
>> @@ -75,6 +76,7 @@ static const int aspeed_soc_ast1030_irqmap[] = {
>> [ASPEED_DEV_TIMER8] = 23,
>> [ASPEED_DEV_WDT] = 24,
>> [ASPEED_DEV_LPC] = 35,
>> + [ASPEED_DEV_PECI] = 38,
>> [ASPEED_DEV_FMC] = 39,
>> [ASPEED_DEV_PWM] = 44,
>> [ASPEED_DEV_ADC] = 46,
>> @@ -133,6 +135,8 @@ static void aspeed_soc_ast1030_init(Object *obj)
>> object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
>> + object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
>> +
>> object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
>> for (i = 0; i < sc->wdts_num; i++) {
>> @@ -238,6 +242,13 @@ static void aspeed_soc_ast1030_realize(DeviceState
>> *dev_soc, Error **errp)
>> /* UART */
>> aspeed_soc_uart_init(s);
>> + /* PECI */
>> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) {
>> + return;
>> + }
>> + sysbus_mmio_map(SYS_BUS_DEVICE(&s->peci), 0,
>> sc->memmap[ASPEED_DEV_PECI]);
>> + sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0, aspeed_soc_get_irq(s,
>> ASPEED_DEV_PECI));
>> +
>> /* Timer */
>> object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
>> &error_abort);
>> diff --git a/hw/misc/aspeed_peci.c b/hw/misc/aspeed_peci.c
>> new file mode 100644
>> index 0000000000..670e532fc0
>> --- /dev/null
>> +++ b/hw/misc/aspeed_peci.c
>> @@ -0,0 +1,225 @@
>> +/*
>> + * Aspeed PECI Controller
>> + *
>> + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
>> + *
>> + * This code is licensed under the GPL version 2 or later. See the COPYING
>> + * file in the top-level directory.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu/log.h"
>> +#include "hw/irq.h"
>> +#include "hw/misc/aspeed_peci.h"
>> +
>> +#define U(x) (x##U)
>> +#define GENMASK(h, l) \
>> + (((~U(0)) - (U(1) << (l)) + 1) & \
>> + (~U(0) >> (32 - 1 - (h))))
>
> I beleive QEMU has similar macros to generate masks.
Ah yes good catch, I can probably fix that pretty easily.
>
>
>> +/* ASPEED PECI Registers */
>> +/* Control Register */
>> +#define ASPEED_PECI_CTRL (0x00 / 4)
>> +#define ASPEED_PECI_CTRL_SAMPLING_MASK GENMASK(19, 16)
>> +#define ASPEED_PECI_CTRL_RD_MODE_MASK GENMASK(13, 12)
>> +#define ASPEED_PECI_CTRL_RD_MODE_DBG BIT(13)
>> +#define ASPEED_PECI_CTRL_RD_MODE_COUNT BIT(12)
>> +#define ASPEED_PECI_CTRL_CLK_SRC_HCLK BIT(11)
>> +#define ASPEED_PECI_CTRL_CLK_DIV_MASK GENMASK(10, 8)
>> +#define ASPEED_PECI_CTRL_INVERT_OUT BIT(7)
>> +#define ASPEED_PECI_CTRL_INVERT_IN BIT(6)
>> +#define ASPEED_PECI_CTRL_BUS_CONTENTION_EN BIT(5)
>> +#define ASPEED_PECI_CTRL_PECI_EN BIT(4)
>> +#define ASPEED_PECI_CTRL_PECI_CLK_EN BIT(0)
>> +
>> +/* Timing Negotiation Register */
>> +#define ASPEED_PECI_TIMING_NEGOTIATION (0x04 / 4)
>> +#define ASPEED_PECI_T_NEGO_MSG_MASK GENMASK(15, 8)
>> +#define ASPEED_PECI_T_NEGO_ADDR_MASK GENMASK(7, 0)
>> +
>> +/* Command Register */
>> +#define ASPEED_PECI_CMD (0x08 / 4)
>> +#define ASPEED_PECI_CMD_PIN_MONITORING BIT(31)
>> +#define ASPEED_PECI_CMD_STS_MASK GENMASK(27, 24)
>> +#define ASPEED_PECI_CMD_STS_ADDR_T_NEGO 0x3
>> +#define ASPEED_PECI_CMD_IDLE_MASK \
>> + (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
>> +#define ASPEED_PECI_CMD_FIRE BIT(0)
>> +
>> +/* Read/Write Length Register */
>> +#define ASPEED_PECI_RW_LENGTH (0x0c / 4)
>> +#define ASPEED_PECI_AW_FCS_EN BIT(31)
>> +#define ASPEED_PECI_RD_LEN_MASK GENMASK(23, 16)
>> +#define ASPEED_PECI_WR_LEN_MASK GENMASK(15, 8)
>> +#define ASPEED_PECI_TARGET_ADDR_MASK GENMASK(7, 0)
>> +
>> +/* Expected FCS Data Register */
>> +#define ASPEED_PECI_EXPECTED_FCS (0x10 / 4)
>> +#define ASPEED_PECI_EXPECTED_RD_FCS_MASK GENMASK(23, 16)
>> +#define ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK GENMASK(15, 8)
>> +#define ASPEED_PECI_EXPECTED_WR_FCS_MASK GENMASK(7, 0)
>> +
>> +/* Captured FCS Data Register */
>> +#define ASPEED_PECI_CAPTURED_FCS (0x14 / 4)
>> +#define ASPEED_PECI_CAPTURED_RD_FCS_MASK GENMASK(23, 16)
>> +#define ASPEED_PECI_CAPTURED_WR_FCS_MASK GENMASK(7, 0)
>> +
>> +/* Interrupt Register */
>> +#define ASPEED_PECI_INT_CTRL (0x18 / 4)
>> +#define ASPEED_PECI_TIMING_NEGO_SEL_MASK GENMASK(31, 30)
>> +#define ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO 0
>> +#define ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO 1
>> +#define ASPEED_PECI_MESSAGE_NEGO 2
>> +#define ASPEED_PECI_INT_MASK GENMASK(4, 0)
>> +#define ASPEED_PECI_INT_BUS_TIMEOUT BIT(4)
>> +#define ASPEED_PECI_INT_BUS_CONTENTION BIT(3)
>> +#define ASPEED_PECI_INT_WR_FCS_BAD BIT(2)
>> +#define ASPEED_PECI_INT_WR_FCS_ABORT BIT(1)
>> +#define ASPEED_PECI_INT_CMD_DONE BIT(0)
>> +
>> +/* Interrupt Status Register */
>> +#define ASPEED_PECI_INT_STS (0x1c / 4)
>> +#define ASPEED_PECI_INT_TIMING_RESULT_MASK GENMASK(29, 16)
>> + /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
>> +
>> +/* Rx/Tx Data Buffer Registers */
>> +#define ASPEED_PECI_WR_DATA0 (0x20 / 4)
>> +#define ASPEED_PECI_WR_DATA1 (0x24 / 4)
>> +#define ASPEED_PECI_WR_DATA2 (0x28 / 4)
>> +#define ASPEED_PECI_WR_DATA3 (0x2c / 4)
>> +#define ASPEED_PECI_RD_DATA0 (0x30 / 4)
>> +#define ASPEED_PECI_RD_DATA1 (0x34 / 4)
>> +#define ASPEED_PECI_RD_DATA2 (0x38 / 4)
>> +#define ASPEED_PECI_RD_DATA3 (0x3c / 4)
>> +#define ASPEED_PECI_WR_DATA4 (0x40 / 4)
>> +#define ASPEED_PECI_WR_DATA5 (0x44 / 4)
>> +#define ASPEED_PECI_WR_DATA6 (0x48 / 4)
>> +#define ASPEED_PECI_WR_DATA7 (0x4c / 4)
>> +#define ASPEED_PECI_RD_DATA4 (0x50 / 4)
>> +#define ASPEED_PECI_RD_DATA5 (0x54 / 4)
>> +#define ASPEED_PECI_RD_DATA6 (0x58 / 4)
>> +#define ASPEED_PECI_RD_DATA7 (0x5c / 4)
>> +#define ASPEED_PECI_DATA_BUF_SIZE_MAX 32
>> +
>> +/** PECI read/write supported responses */
>> +#define PECI_CC_RSP_SUCCESS (0x40U)
>> +#define PECI_CC_RSP_TIMEOUT (0x80U)
>> +#define PECI_CC_OUT_OF_RESOURCES_TIMEOUT (0x81U)
>> +#define PECI_CC_RESOURCES_LOWPWR_TIMEOUT (0x82U)
>> +#define PECI_CC_ILLEGAL_REQUEST (0x90U)
>> +
>> +static void aspeed_peci_instance_init(Object *obj)
>> +{
>> +}
>
> May be drop this routine if it is empty.
Agreed, will do.
>
>> +static uint64_t aspeed_peci_read(void *opaque, hwaddr addr, unsigned size)
>> +{
>> + AspeedPECIState *s = ASPEED_PECI(opaque);
>> +
>> + if (addr >= ASPEED_PECI_NR_REGS << 2) {
>> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Out-of-bounds read at offset
>> 0x%" HWADDR_PRIx "\n",
>> + __func__, addr);
>> + return 0;
>> + }
>> + addr >>= 2;
>> +
>> + uint32_t reg = s->regs[addr];
>> + //printf("%s: 0x%08lx 0x%08x %u\n", __func__, addr << 2, reg, size);
>
> Convert to trace event ? or please remove.
Arg yes, I’ll fix this.
>
>> +
>> + return reg;
>> +}
>> +
>> +static void aspeed_peci_write(void *opaque, hwaddr addr, uint64_t data,
>> unsigned size)
>> +{
>> + AspeedPECIState *s = ASPEED_PECI(opaque);
>> +
>> + //printf("%s: 0x%08lx 0x%08x %u\n", __func__, addr, reg, size);
>> +
>> + if (addr >= ASPEED_PECI_NR_REGS << 2) {
>> + qemu_log_mask(LOG_GUEST_ERROR, "%s: Out-of-bounds write at offset
>> 0x%" HWADDR_PRIx "\n",
>> + __func__, addr);
>> + return;
>> + }
>> + addr >>= 2;
>> +
>> + switch (addr) {
>> + case ASPEED_PECI_INT_STS:
>> + s->regs[addr] &= ~data;
>> + break;
>> + default:
>> + s->regs[addr] = data;
>> + break;
>> + }
>> +
>> + switch (addr) {
>> + case ASPEED_PECI_CMD:
>> + if (!(s->regs[ASPEED_PECI_CMD] & ASPEED_PECI_CMD_FIRE)) {
>> + break;
>> + }
>> + s->regs[ASPEED_PECI_RD_DATA0] = PECI_CC_RSP_SUCCESS;
>> + s->regs[ASPEED_PECI_WR_DATA0] = PECI_CC_RSP_SUCCESS;
>> +
>> + s->regs[ASPEED_PECI_INT_STS] |= ASPEED_PECI_INT_CMD_DONE;
>> + qemu_irq_raise(s->irq);
>> + break;
>> + case ASPEED_PECI_INT_STS:
>> + if (s->regs[ASPEED_PECI_INT_STS]) {
>> + break;
>> + }
>> + qemu_irq_lower(s->irq);
>> + break;
>> + default:
>> + qemu_log_mask(LOG_UNIMP, "%s: register 0x%03" HWADDR_PRIx " writes
>> unimplemented\n",
>> + __func__, addr);
>> + break;
>> + }
>> +}
>> +
>> +static const MemoryRegionOps aspeed_peci_ops = {
>> + .read = aspeed_peci_read,
>> + .write = aspeed_peci_write,
>> + .endianness = DEVICE_LITTLE_ENDIAN,
>> +};
>> +
>> +static void aspeed_peci_realize(DeviceState *dev, Error **errp)
>> +{
>> + AspeedPECIState *s = ASPEED_PECI(dev);
>> + SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
>> +
>> + memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_peci_ops, s,
>> TYPE_ASPEED_PECI, 0x1000);
>> + sysbus_init_mmio(sbd, &s->mmio);
>> + sysbus_init_irq(sbd, &s->irq);
>> +}
>> +
>> +static void aspeed_peci_reset(DeviceState *dev)
>> +{
>> + AspeedPECIState *s = ASPEED_PECI(dev);
>> +
>> + memset(s->regs, 0, sizeof(s->regs));
>> +}
>> +
>> +static void aspeed_peci_class_init(ObjectClass *klass, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> + dc->realize = aspeed_peci_realize;
>> + dc->reset = aspeed_peci_reset;
>> + dc->desc = "Aspeed PECI Controller";
>> +}
>> +
>> +static const TypeInfo aspeed_peci_info = {
>> + .name = TYPE_ASPEED_PECI,
>> + .parent = TYPE_SYS_BUS_DEVICE,
>> + .instance_init = aspeed_peci_instance_init,
>> + .instance_size = sizeof(AspeedPECIState),
>> + .class_init = aspeed_peci_class_init,
>> + .class_size = sizeof(AspeedPECIClass),
>> + .abstract = false,
>> +};
>> +
>> +static void aspeed_peci_register_types(void)
>> +{
>> + type_register_static(&aspeed_peci_info);
>> +}
>> +
>> +type_init(aspeed_peci_register_types);
>> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
>> index 132b7b7344..95268eddc0 100644
>> --- a/hw/misc/meson.build
>> +++ b/hw/misc/meson.build
>> @@ -116,7 +116,8 @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
>> 'aspeed_scu.c',
>> 'aspeed_sbc.c',
>> 'aspeed_sdmc.c',
>> - 'aspeed_xdma.c'))
>> + 'aspeed_xdma.c',
>> + 'aspeed_peci.c'))
>> softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c'))
>> softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c'))
>> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
>> index 02a5a9ffcb..fd2aa1880a 100644
>> --- a/include/hw/arm/aspeed_soc.h
>> +++ b/include/hw/arm/aspeed_soc.h
>> @@ -34,6 +34,7 @@
>> #include "hw/usb/hcd-ehci.h"
>> #include "qom/object.h"
>> #include "hw/misc/aspeed_lpc.h"
>> +#include "hw/misc/aspeed_peci.h"
>> #define ASPEED_SPIS_NUM 2
>> #define ASPEED_EHCIS_NUM 2
>> @@ -73,6 +74,7 @@ struct AspeedSoCState {
>> AspeedSDHCIState sdhci;
>> AspeedSDHCIState emmc;
>> AspeedLPCState lpc;
>> + AspeedPECIState peci;
>> uint32_t uart_default;
>> Clock *sysclk;
>> };
>> @@ -161,6 +163,7 @@ enum {
>> ASPEED_DEV_DPMCU,
>> ASPEED_DEV_DP,
>> ASPEED_DEV_I3C,
>> + ASPEED_DEV_PECI,
>> };
>> qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
>> diff --git a/include/hw/misc/aspeed_peci.h b/include/hw/misc/aspeed_peci.h
>> new file mode 100644
>> index 0000000000..81c7d31700
>> --- /dev/null
>> +++ b/include/hw/misc/aspeed_peci.h
>> @@ -0,0 +1,34 @@
>> +/*
>> + * Aspeed PECI Controller
>> + *
>> + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
>> + *
>> + * This code is licensed under the GPL version 2 or later. See the COPYING
>> + * file in the top-level directory.
>> + */
>> +
>> +#ifndef ASPEED_PECI_H
>> +#define ASPEED_PECI_H
>> +
>> +#include "hw/sysbus.h"
>> +
>> +#define TYPE_ASPEED_PECI "aspeed.peci"
>> +OBJECT_DECLARE_TYPE(AspeedPECIState, AspeedPECIClass, ASPEED_PECI);
>> +
>> +#define ASPEED_PECI_NR_REGS ((0xFC + 4) >> 2)
>> +
>> +struct AspeedPECIState {
>> + /* <private> */
>> + SysBusDevice parent;
>> +
>> + MemoryRegion mmio;
>> + qemu_irq irq;
>> +
>> + uint32_t regs[ASPEED_PECI_NR_REGS];
>> +};
>> +
>> +struct AspeedPECIClass {
>> + SysBusDeviceClass parent_class;
>> +};
>> +
>> +#endif
>
- Re: [PATCH 05/14] aspeed: i2c: Fix R_I2CD_FUN_CTRL reference, (continued)
- [PATCH 08/14] hw/misc: Add fby35-cpld, Peter Delevoryas, 2022/06/27
- [PATCH 04/14] aspeed: i2c: Fix DMA len write-enable bit handling, Peter Delevoryas, 2022/06/27
- [PATCH 07/14] aspeed: Add PECI controller, Peter Delevoryas, 2022/06/27
- [PATCH 09/14] pmbus: Reset out buf after switching pages, Peter Delevoryas, 2022/06/27
- [PATCH 10/14] pmbus: Add read-only IC_DEVICE_ID support, Peter Delevoryas, 2022/06/27
- [PATCH 11/14] aspeed: Add oby35-cl machine, Peter Delevoryas, 2022/06/27
- Re: [PATCH 00/14] aspeed: Add I2C new register DMA slave mode support, Peter Delevoryas, 2022/06/27
- [PATCH 12/14] hw/misc: Add intel-me, Peter Delevoryas, 2022/06/27