Re: [PATCH 19/25] hw/misc: add i2c-tester

2024-09-18 Thread Corey Minyard
On Wed, Sep 18, 2024 at 04:03:12PM -0700, Octavian Purdila wrote:
> On Wed, Sep 18, 2024 at 1:06 PM Corey Minyard  wrote:
> >
> > On Wed, Sep 18, 2024 at 12:22:47PM -0700, Octavian Purdila wrote:
> > > Add a simple i2c peripheral to be used for testing I2C device
> > > models. The peripheral has a fixed number of registers that can be
> > > read and written.
> >
> > Why is this better than just using the eeprom device?
> >
> 
> The main reason for adding it is that, AFAICT, there is no i2c slave
> device that responds with I2C_NACK during a transaction.
> 
> Also, having a dedicated device for testing purposes makes it easier
> to add new features than adding it to a real device where it might not
> always be possible. I tried to add the NACK functionality but I did
> not find one where the datasheet would confirm the behaviour I was
> looking for.

SMBUS devices (like the eeprom) use NACKs as part of the protocol, to
mark the end of a transfer, but that's probably not what you are looking
for.  You are using it to signal an error, which I don't think any
existing device will do.  Real devices, in general, don't NACK anything
for errors, but the protocol allows it.

Somehow in my previous look I completely missed i2c_tester_event(), so
this works like a normal I2C device, except that most of them
auto-increment the index register.  But some don't, so it's fine.

If you could document the rationale for this, it would help a lot, for
others that might want to use it.  Also, I would expect people might
add their own test code to this.  I'm not sure what you can do at the
moment about that, but just a heads up that people will probably hack on
this in the future.

So this is good.

-corey

> 
> > This has some uncommon attributes compared to most i2c devices.  For
> > instance, most i2c devices take their address as the first bytes of a
> > write operation, then auto-increment after that for reads and writes.
> > This seems to take one address on a write after a system reset, then use
> > that forever.
> >
> > Anyway, unless there is a compelling reason to use this over the eeprom
> > device, I'm going to recommend against it.
> >
> 
> 
> > -corey
> >
> > >
> > > Signed-off-by: Octavian Purdila 
> > > ---
> > >  include/hw/misc/i2c_tester.h |  30 ++
> > >  hw/misc/i2c_tester.c | 109 +++
> > >  hw/misc/Kconfig  |   5 ++
> > >  hw/misc/meson.build  |   2 +
> > >  4 files changed, 146 insertions(+)
> > >  create mode 100644 include/hw/misc/i2c_tester.h
> > >  create mode 100644 hw/misc/i2c_tester.c
> > >
> > > diff --git a/include/hw/misc/i2c_tester.h b/include/hw/misc/i2c_tester.h
> > > new file mode 100644
> > > index 00..f6b6491008
> > > --- /dev/null
> > > +++ b/include/hw/misc/i2c_tester.h
> > > @@ -0,0 +1,30 @@
> > > +/*
> > > + *
> > > + * Copyright (c) 2024 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 or 
> > > later.
> > > + * See the COPYING file in the top-level directory.
> > > + */
> > > +
> > > +#ifndef HW_I2C_TESTER_H
> > > +#define HW_I2C_TESTER_H
> > > +
> > > +#include "qemu/osdep.h"
> > > +#include "hw/i2c/i2c.h"
> > > +#include "hw/irq.h"
> > > +
> > > +#define I2C_TESTER_NUM_REGS0x31
> > > +
> > > +#define TYPE_I2C_TESTER "i2c-tester"
> > > +#define I2C_TESTER(obj) OBJECT_CHECK(I2cTesterState, (obj), 
> > > TYPE_I2C_TESTER)
> > > +
> > > +typedef struct {
> > > +I2CSlave i2c;
> > > +bool set_reg_idx;
> > > +uint8_t reg_idx;
> > > +uint8_t regs[I2C_TESTER_NUM_REGS];
> > > +} I2cTesterState;
> > > +
> > > +#endif /* HW_I2C_TESTER_H */
> > > diff --git a/hw/misc/i2c_tester.c b/hw/misc/i2c_tester.c
> > > new file mode 100644
> > > index 00..77ce8bf91a
> > > --- /dev/null
> > > +++ b/hw/misc/i2c_tester.c
> > > @@ -0,0 +1,109 @@
> > > +/*
> > > + * Simple I2C peripheral for testing I2C device models.
> > > + *
> > > + * Copyright (c) 2024 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + *
> > > + * This work is licensed under the terms of the GNU GPL, version 2 o

Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c

2024-09-18 Thread Corey Minyard
On Wed, Sep 18, 2024 at 02:04:58PM -0700, Octavian Purdila wrote:
> On Wed, Sep 18, 2024 at 1:17???PM Corey Minyard  wrote:
> >
> > On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote:
> > > Add support for NXP's flexcomm i2c. It does not support slave mode or
> > > DMA.
> > >
> > > The patch includes an automatically generated header which contains
> > > the register layout and helpers.
> > >
> > > The header can be regenerated with the svd-flexcomm-i2c target when
> > > the build is configured with --enable-mcux-soc-svd.
> > >
> > > Signed-off-by: Octavian Purdila 
> > > ---
> > >  include/hw/arm/svd/flexcomm_i2c.h | 1190 +
> > >  include/hw/i2c/flexcomm_i2c.h |   40 +
> > >  include/hw/misc/flexcomm.h|2 +
> > >  hw/i2c/flexcomm_i2c.c |  250 ++
> > >  hw/misc/flexcomm.c|3 +
> > >  hw/arm/svd/meson.build|3 +
> > >  hw/i2c/meson.build|1 +
> > >  hw/i2c/trace-events   |   10 +
> > >  hw/misc/Kconfig   |1 +
> > >  9 files changed, 1500 insertions(+)
> > >  create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
> > >  create mode 100644 include/hw/i2c/flexcomm_i2c.h
> > >  create mode 100644 hw/i2c/flexcomm_i2c.c
> > >
> > > diff --git a/include/hw/arm/svd/flexcomm_i2c.h 
> > > b/include/hw/arm/svd/flexcomm_i2c.h
> > > new file mode 100644
> > > index 00..9017d48446
> > > --- /dev/null
> > > +++ b/include/hw/arm/svd/flexcomm_i2c.h
> > > @@ -0,0 +1,1190 @@
> > > +/*
> > > + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> > > + *
> > > + * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> > > + */
> > > +#pragma once
> > > +
> > > +#include "hw/register.h"
> > > +
> > > +/* I2C Bus Interface */
> > > +#define FLEXCOMM_I2C_REGS_NO (1024)
> > > +
> > > +/* Configuration Register */
> > > +REG32(FLEXCOMM_I2C_CFG, 2048);
> > > +/* Master Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> > > +/* Slave Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> > > +/* Monitor Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> > > +/* I2C bus Time-out Enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> > > +/* Monitor function Clock Stretching */
> > > +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> > > +/* High Speed mode Capable enable */
> > > +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
> > > +
> > > +/* Status Register */
> > > +REG32(FLEXCOMM_I2C_STAT, 2052);
> > > +/* Master Pending */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> > > +/* Master State code */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> > > +/* Master Arbitration Loss flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
> > > +/* Master Start/Stop Error flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
> > > +/* Slave Pending */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
> > > +/* Slave State */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
> > > +/* Slave Not Stretching */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
> > > +/* Slave address match Index T */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
> > > +/* Slave selected flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
> > > +/* Slave Deselected flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
> > > +/* Monitor Ready */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
> > > +/* Monitor Overflow flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
> > > +/* Monitor Active flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
> > > +/* Monitor Idle flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
> > > +/* Event Time-out Interrupt flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
> > > +/* SCL Time-out Interrupt flag */
> > > +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
> > > +
> > > +/* Interrupt Enable Set Register */
> > > +REG32(FLEXCOMM_I2C_INTENSET, 2056);
> > > +/* Master Pending interrupt Enable */
> > > +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
> > > +/* Mast

Re: [PATCH 08/25] hw/i2c: add support for flexcomm i2c

2024-09-18 Thread Corey Minyard
On Wed, Sep 18, 2024 at 12:22:36PM -0700, Octavian Purdila wrote:
> Add support for NXP's flexcomm i2c. It does not support slave mode or
> DMA.
> 
> The patch includes an automatically generated header which contains
> the register layout and helpers.
> 
> The header can be regenerated with the svd-flexcomm-i2c target when
> the build is configured with --enable-mcux-soc-svd.
> 
> Signed-off-by: Octavian Purdila 
> ---
>  include/hw/arm/svd/flexcomm_i2c.h | 1190 +
>  include/hw/i2c/flexcomm_i2c.h |   40 +
>  include/hw/misc/flexcomm.h|2 +
>  hw/i2c/flexcomm_i2c.c |  250 ++
>  hw/misc/flexcomm.c|3 +
>  hw/arm/svd/meson.build|3 +
>  hw/i2c/meson.build|1 +
>  hw/i2c/trace-events   |   10 +
>  hw/misc/Kconfig   |1 +
>  9 files changed, 1500 insertions(+)
>  create mode 100644 include/hw/arm/svd/flexcomm_i2c.h
>  create mode 100644 include/hw/i2c/flexcomm_i2c.h
>  create mode 100644 hw/i2c/flexcomm_i2c.c
> 
> diff --git a/include/hw/arm/svd/flexcomm_i2c.h 
> b/include/hw/arm/svd/flexcomm_i2c.h
> new file mode 100644
> index 00..9017d48446
> --- /dev/null
> +++ b/include/hw/arm/svd/flexcomm_i2c.h
> @@ -0,0 +1,1190 @@
> +/*
> + * Copyright 2016-2023 NXP SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Automatically generated by svd-gen-header.py from MIMXRT595S_cm33.xml
> + */
> +#pragma once
> +
> +#include "hw/register.h"
> +
> +/* I2C Bus Interface */
> +#define FLEXCOMM_I2C_REGS_NO (1024)
> +
> +/* Configuration Register */
> +REG32(FLEXCOMM_I2C_CFG, 2048);
> +/* Master Enable */
> +FIELD(FLEXCOMM_I2C_CFG, MSTEN, 0, 1);
> +/* Slave Enable */
> +FIELD(FLEXCOMM_I2C_CFG, SLVEN, 1, 1);
> +/* Monitor Enable */
> +FIELD(FLEXCOMM_I2C_CFG, MONEN, 2, 1);
> +/* I2C bus Time-out Enable */
> +FIELD(FLEXCOMM_I2C_CFG, TIMEOUTEN, 3, 1);
> +/* Monitor function Clock Stretching */
> +FIELD(FLEXCOMM_I2C_CFG, MONCLKSTR, 4, 1);
> +/* High Speed mode Capable enable */
> +FIELD(FLEXCOMM_I2C_CFG, HSCAPABLE, 5, 1);
> +
> +/* Status Register */
> +REG32(FLEXCOMM_I2C_STAT, 2052);
> +/* Master Pending */
> +FIELD(FLEXCOMM_I2C_STAT, MSTPENDING, 0, 1);
> +/* Master State code */
> +FIELD(FLEXCOMM_I2C_STAT, MSTSTATE, 1, 3);
> +/* Master Arbitration Loss flag */
> +FIELD(FLEXCOMM_I2C_STAT, MSTARBLOSS, 4, 1);
> +/* Master Start/Stop Error flag */
> +FIELD(FLEXCOMM_I2C_STAT, MSTSTSTPERR, 6, 1);
> +/* Slave Pending */
> +FIELD(FLEXCOMM_I2C_STAT, SLVPENDING, 8, 1);
> +/* Slave State */
> +FIELD(FLEXCOMM_I2C_STAT, SLVSTATE, 9, 2);
> +/* Slave Not Stretching */
> +FIELD(FLEXCOMM_I2C_STAT, SLVNOTSTR, 11, 1);
> +/* Slave address match Index T */
> +FIELD(FLEXCOMM_I2C_STAT, SLVIDX, 12, 2);
> +/* Slave selected flag */
> +FIELD(FLEXCOMM_I2C_STAT, SLVSEL, 14, 1);
> +/* Slave Deselected flag */
> +FIELD(FLEXCOMM_I2C_STAT, SLVDESEL, 15, 1);
> +/* Monitor Ready */
> +FIELD(FLEXCOMM_I2C_STAT, MONRDY, 16, 1);
> +/* Monitor Overflow flag */
> +FIELD(FLEXCOMM_I2C_STAT, MONOV, 17, 1);
> +/* Monitor Active flag */
> +FIELD(FLEXCOMM_I2C_STAT, MONACTIVE, 18, 1);
> +/* Monitor Idle flag */
> +FIELD(FLEXCOMM_I2C_STAT, MONIDLE, 19, 1);
> +/* Event Time-out Interrupt flag */
> +FIELD(FLEXCOMM_I2C_STAT, EVENTTIMEOUT, 24, 1);
> +/* SCL Time-out Interrupt flag */
> +FIELD(FLEXCOMM_I2C_STAT, SCLTIMEOUT, 25, 1);
> +
> +/* Interrupt Enable Set Register */
> +REG32(FLEXCOMM_I2C_INTENSET, 2056);
> +/* Master Pending interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MSTPENDINGEN, 0, 1);
> +/* Master Arbitration Loss interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MSTARBLOSSEN, 4, 1);
> +/* Master Start/Stop Error interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MSTSTSTPERREN, 6, 1);
> +/* Slave Pending interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SLVPENDINGEN, 8, 1);
> +/* Slave Not Stretching interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SLVNOTSTREN, 11, 1);
> +/* Slave Deselect interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SLVDESELEN, 15, 1);
> +/* Monitor data Ready interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MONRDYEN, 16, 1);
> +/* Monitor Overrun interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MONOVEN, 17, 1);
> +/* Monitor Idle interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, MONIDLEEN, 19, 1);
> +/* Event Time-out interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, EVENTTIMEOUTEN, 24, 1);
> +/* SCL Time-out interrupt Enable */
> +FIELD(FLEXCOMM_I2C_INTENSET, SCLTIMEOUTEN, 25, 1);
> +
> +/* Interrupt Enable Clear Register */
> +REG32(FLEXCOMM_I2C_INTENCLR, 2060);
> +/* Master Pending interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MSTPENDINGCLR, 0, 1);
> +/* Master Arbitration Loss interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MSTARBLOSSCLR, 4, 1);
> +/* Master Start/Stop Error interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, MSTSTSTPERRCLR, 6, 1);
> +/* Slave Pending interrupt clear */
> +FIELD(FLEXCOMM_I2C_INTENCLR, SLVPENDINGCLR, 8, 1);
> +/* Slave Not Stret

Re: [PATCH 19/25] hw/misc: add i2c-tester

2024-09-18 Thread Corey Minyard
On Wed, Sep 18, 2024 at 12:22:47PM -0700, Octavian Purdila wrote:
> Add a simple i2c peripheral to be used for testing I2C device
> models. The peripheral has a fixed number of registers that can be
> read and written.

Why is this better than just using the eeprom device?

This has some uncommon attributes compared to most i2c devices.  For
instance, most i2c devices take their address as the first bytes of a
write operation, then auto-increment after that for reads and writes.
This seems to take one address on a write after a system reset, then use
that forever.

Anyway, unless there is a compelling reason to use this over the eeprom
device, I'm going to recommend against it.

-corey

> 
> Signed-off-by: Octavian Purdila 
> ---
>  include/hw/misc/i2c_tester.h |  30 ++
>  hw/misc/i2c_tester.c | 109 +++
>  hw/misc/Kconfig  |   5 ++
>  hw/misc/meson.build  |   2 +
>  4 files changed, 146 insertions(+)
>  create mode 100644 include/hw/misc/i2c_tester.h
>  create mode 100644 hw/misc/i2c_tester.c
> 
> diff --git a/include/hw/misc/i2c_tester.h b/include/hw/misc/i2c_tester.h
> new file mode 100644
> index 00..f6b6491008
> --- /dev/null
> +++ b/include/hw/misc/i2c_tester.h
> @@ -0,0 +1,30 @@
> +/*
> + *
> + * Copyright (c) 2024 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef HW_I2C_TESTER_H
> +#define HW_I2C_TESTER_H
> +
> +#include "qemu/osdep.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/irq.h"
> +
> +#define I2C_TESTER_NUM_REGS0x31
> +
> +#define TYPE_I2C_TESTER "i2c-tester"
> +#define I2C_TESTER(obj) OBJECT_CHECK(I2cTesterState, (obj), TYPE_I2C_TESTER)
> +
> +typedef struct {
> +I2CSlave i2c;
> +bool set_reg_idx;
> +uint8_t reg_idx;
> +uint8_t regs[I2C_TESTER_NUM_REGS];
> +} I2cTesterState;
> +
> +#endif /* HW_I2C_TESTER_H */
> diff --git a/hw/misc/i2c_tester.c b/hw/misc/i2c_tester.c
> new file mode 100644
> index 00..77ce8bf91a
> --- /dev/null
> +++ b/hw/misc/i2c_tester.c
> @@ -0,0 +1,109 @@
> +/*
> + * Simple I2C peripheral for testing I2C device models.
> + *
> + * Copyright (c) 2024 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "hw/misc/i2c_tester.h"
> +
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "migration/vmstate.h"
> +
> +static void i2c_tester_reset_enter(Object *o, ResetType type)
> +{
> +I2cTesterState *s = I2C_TESTER(o);
> +
> +s->set_reg_idx = false;
> +s->reg_idx = 0;
> +memset(s->regs, 0, I2C_TESTER_NUM_REGS);
> +}
> +
> +static int i2c_tester_event(I2CSlave *i2c, enum i2c_event event)
> +{
> +I2cTesterState *s = I2C_TESTER(i2c);
> +
> +if (event == I2C_START_SEND) {
> +s->set_reg_idx = true;
> +}
> +
> +return 0;
> +}
> +
> +static uint8_t i2c_tester_rx(I2CSlave *i2c)
> +{
> +I2cTesterState *s = I2C_TESTER(i2c);
> +
> +if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> +  s->reg_idx);
> +return I2C_NACK;
> +}
> +
> +return s->regs[s->reg_idx];
> +}
> +
> +static int i2c_tester_tx(I2CSlave *i2c, uint8_t data)
> +{
> +I2cTesterState *s = I2C_TESTER(i2c);
> +
> +if (s->set_reg_idx) {
> +/* Setting the register in which the operation will be done. */
> +s->reg_idx = data;
> +s->set_reg_idx = false;
> +return 0;
> +}
> +
> +if (s->reg_idx >= I2C_TESTER_NUM_REGS) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reg 0x%02x\n", __func__,
> +  s->reg_idx);
> +return I2C_NACK;
> +}
> +
> +/* Write reg data. */
> +s->regs[s->reg_idx] = data;
> +
> +return 0;
> +}
> +
> +static const VMStateDescription vmstate_i2c_tester = {
> +.name = "i2c-tester",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (const VMStateField[]) {
> +VMSTATE_I2C_SLAVE(i2c, I2cTesterState),
> +VMSTATE_BOOL(set_reg_idx, I2cTesterState),
> +VMSTATE_UINT8(reg_idx, I2cTesterState),
> +VMSTATE_UINT8_ARRAY(regs, I2cTesterState, I2C_TESTER_NUM_REGS),
> +VMSTATE_END_OF_LIST()
> +}
> +};
> +
> +static void i2c_tester_class_init(ObjectClass *oc, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(oc);
> +ResettableClass *rc = RESETTABLE_CLASS(oc);
> +I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
> +
> +rc->phases.enter = i2c_tester_reset_enter;
> +dc->vmsd = &vmstate_i2c_tester;
> +isc->event = i2c_tester_event;
> +isc->recv = i2c_tester_rx;
> +isc->send = i2c_tester_tx;
> +}
> +
> +static const TypeInfo i2c_te

Re: [RFC PATCH-for-9.1 0/4] hw/i2c: Convert to spec v7 (inclusive) terminology

2024-05-15 Thread Corey Minyard via
On Mon, Apr 08, 2024 at 11:33:34PM +0200, Philippe Mathieu-Daudé wrote:
> Mechanical (mostly) conversion inspired by Wolfram [*] to
> use inclusive terminology, similarly to the other renames
> we did 3 years ago, shortly before the I2C spec v7 was
> published.

Sorry, I've been extremely busy on this.

Since the spec has been redone, I'm good with the renames.

As far as the >80 character lines, I'm fine either way.  I actually like
to keep them in 80 characters, but the Linux kernel has moved away from
that, and if it's easier to read with a longer line, that's probably
better.

-corey

> 
> Posted as RFC to get feedback, if no objection I plan to
> finish the conversion (SMBus and rest if hw/i2c/).
> 
> [*] 
> https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/
> 
> Philippe Mathieu-Daudé (4):
>   hw/i2c: Fix checkpatch block comment warnings
>   hw/i2c: Fix checkpatch line over 80 chars warnings
>   hw/i2c: Convert to spec v7 terminology (automatically)
>   hw/i2c: Convert to spec v7 terminology (manually)
> 
>  include/hw/display/i2c-ddc.h |   2 +-
>  include/hw/gpio/pca9552.h|   2 +-
>  include/hw/gpio/pca9554.h|   2 +-
>  include/hw/i2c/aspeed_i2c.h  |   4 +-
>  include/hw/i2c/i2c.h | 123 ++---
>  include/hw/i2c/i2c_mux_pca954x.h |   2 +-
>  include/hw/i2c/smbus_slave.h |   4 +-
>  include/hw/nvram/eeprom_at24c.h  |   8 +-
>  include/hw/sensor/tmp105.h   |   2 +-
>  hw/arm/aspeed.c  | 290 +--
>  hw/arm/bananapi_m2u.c|   2 +-
>  hw/arm/cubieboard.c  |   2 +-
>  hw/arm/musicpal.c|   6 +-
>  hw/arm/npcm7xx_boards.c  |  44 ++---
>  hw/arm/nseries.c |   6 +-
>  hw/arm/pxa2xx.c  |  36 ++--
>  hw/arm/realview.c|   2 +-
>  hw/arm/spitz.c   |  12 +-
>  hw/arm/stellaris.c   |   2 +-
>  hw/arm/tosa.c|  14 +-
>  hw/arm/versatilepb.c |   2 +-
>  hw/arm/vexpress.c|   2 +-
>  hw/arm/z2.c  |  20 +--
>  hw/audio/wm8750.c|  18 +-
>  hw/display/ati.c |   4 +-
>  hw/display/i2c-ddc.c |  10 +-
>  hw/display/sii9022.c |  16 +-
>  hw/display/sm501.c   |   2 +-
>  hw/display/ssd0303.c |  14 +-
>  hw/display/xlnx_dp.c |   2 +-
>  hw/gpio/max7310.c|  14 +-
>  hw/gpio/pca9552.c|  14 +-
>  hw/gpio/pca9554.c|  14 +-
>  hw/gpio/pcf8574.c|  12 +-
>  hw/i2c/aspeed_i2c.c  |  16 +-
>  hw/i2c/core.c|  90 +-
>  hw/i2c/i2c_mux_pca954x.c |   6 +-
>  hw/i2c/imx_i2c.c |   2 +-
>  hw/i2c/smbus_slave.c |  12 +-
>  hw/input/lm832x.c|  14 +-
>  hw/misc/axp2xx.c |  14 +-
>  hw/misc/i2c-echo.c   |  14 +-
>  hw/nvram/eeprom_at24c.c  |  26 +--
>  hw/ppc/e500.c|   2 +-
>  hw/ppc/pnv.c |   4 +-
>  hw/ppc/sam460ex.c|   2 +-
>  hw/rtc/ds1338.c  |  14 +-
>  hw/rtc/m41t80.c  |  12 +-
>  hw/rtc/twl92230.c|  16 +-
>  hw/sensor/dps310.c   |  14 +-
>  hw/sensor/emc141x.c  |  16 +-
>  hw/sensor/lsm303dlhc_mag.c   |  16 +-
>  hw/sensor/tmp105.c   |  16 +-
>  hw/sensor/tmp421.c   |  20 +--
>  hw/tpm/tpm_tis_i2c.c |  12 +-
>  55 files changed, 541 insertions(+), 506 deletions(-)
> 
> -- 
> 2.41.0
> 
> 



Re: Trying to write data to i2c bus

2024-02-19 Thread Corey Minyard
On Mon, Feb 19, 2024 at 04:53:47PM +, Paz Offer wrote:
> Thank you very much Corey,
> 
> I am simulating an external module that wants to communicate with the board 
> management controller (BMC).
> The real device will be connected to the board using i2c bus, and could 
> initiate communication at any time, by sending bytes over the bus.

And you have a simulated BMC that can do this?  Or is the system running
in qemu the BMC.

> 
> I am not sure whether the 'Master-side' (the side the initiating 
> communication) needs to simulate a full i2c-master device, or whether my code 
> could 'simply' write directly to the appropriate registers of the guest OS.
> Are there some examples or documentation on how to implement something like 
> this?

The aspeed i2c controller is capable of having another bus master on an
I2C but, but it is the only host that can currently do it.

It is doable, the code is ther for multiple bus masters, but there is no
device currently that does it.  I assume that is coming at some point,
but no documentation exists on how to do it.

You can look at the git commits in hw/i2c around 37fa5ca42623 "hw/i2c:
support multiple masters" for the changes that were done to support
this.

I haven't done it, and I don't remember exactly how it works.

> 
> Sorry for my lacking knowledge on this, but I am quite new to QEMU...

You have a lot more to learn than this to make a qemu device.  And i2c
bus mastering in qemu is pretty esoteric, not many people know anything
about it.

-corey

> 
> Thanks again,
> Paz
> 
> 
> 
> 
> 
> From: Corey Minyard  on behalf of Corey Minyard 
> 
> Sent: Monday, February 19, 2024 6:32 PM
> To: Paz Offer 
> Cc: qemu-devel@nongnu.org 
> Subject: Re: Trying to write data to i2c bus
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, Feb 19, 2024 at 01:49:44PM +, Paz Offer wrote:
> > Hi,
> >
> > I am new to QEMU development, so please excuse if I my direction here is 
> > wrong:
> >
> > I am trying to implement an i2c slave device.
> > My device should be able to read/write data from its i2c bus.
> >
> > I defined my device-state object like so:
> >
> > typedef struct {
> >   I2CSlave i2c;
> >   void *my_data;
> >
> > }   MyI2CSlave;
> >
> >
> > In my implementation occasionally I may have to send data on the bus, due 
> > to an internal event on my side.
> > For this I implemented the following code:
> >
> > //  Get bus pointer:
> > BusState *parentBus = qdev_get_parent_bus(DEVICE(&obj->i2c));
> > I2CBus   *i2cBus= I2C_BUS(parentBus);
> >   
> > //  Try to send data on bus:  
> > if (i2c_start_send(i2cBus, address)) {
> > //  error?
> > return;
> > }
> > for (int i = 0; i < size; i++) {
> > i2c_send(i2cBus, data[i]);
> > }
> > i2c_end_transfer(i2cBus);
> >
> >   
> > The problem is that 'i2c_start_send()' always fails here:
> >
> > if (QLIST_EMPTY(&bus->current_devs)) {
> > return 1;
> > }
> >
> > The member 'i2cBus->current_devs.lh_first' is always null.
> >
> > I will add that in my QEMU execution I specify the bus 'aspeed.i2c.bus.0' 
> > to be used with my device.
> > In my 'realize' method I can see that a bus is connected to my device, as 
> > 'qdev_get_parent_bus()' does return a valid pointer.
> >
> > My question:
> > 1. Am I missing some initialization for the bus?
> > 2. Is there other way to send data on the i2c bus, assuming it can happen 
> > anytime due to an internal event on my device side?
> 
> You are missing a lot of stuff, but let's start with basics...
> 
> First of all, this is not how i2c generally works.  Generally you have a
> bus master, the host, that reads and writes to slave devices on the bus.
> The devices on the bus don't asynchronously send data to the host.
> 
> That said, you can have multiple bus masters on the bus.  If that's what
> you are doing, what are you sending your data to?  You have to have
> something that will receive it.
> 
> If you have some slave device that has data it's holding for the host,
> the host has to fetch it.  You could have an interrupt that comes from
> the slave device saying it has data, and there's something called SMBus
> alert that can consolidate interrupts (though it's not implemented in
> QEMU at the moment).
> 
> Are you simulating some real device here?
> 
> -corey
> 
> >
> > Thanks for any tip,
> > Pazo  



Re: Trying to write data to i2c bus

2024-02-19 Thread Corey Minyard
On Mon, Feb 19, 2024 at 01:49:44PM +, Paz Offer wrote:
> Hi,
> 
> I am new to QEMU development, so please excuse if I my direction here is 
> wrong:
> 
> I am trying to implement an i2c slave device.
> My device should be able to read/write data from its i2c bus.
> 
> I defined my device-state object like so:
> 
> typedef struct {
>   I2CSlave i2c;
>   void *my_data;
> 
> }   MyI2CSlave;
> 
> 
> In my implementation occasionally I may have to send data on the bus, due to 
> an internal event on my side.
> For this I implemented the following code:
> 
> //  Get bus pointer:
> BusState *parentBus = qdev_get_parent_bus(DEVICE(&obj->i2c));
> I2CBus   *i2cBus= I2C_BUS(parentBus);
>   
> //  Try to send data on bus:  
> if (i2c_start_send(i2cBus, address)) {
> //  error?
> return;
> }
> for (int i = 0; i < size; i++) {
> i2c_send(i2cBus, data[i]);
> }
> i2c_end_transfer(i2cBus);
> 
>   
> The problem is that 'i2c_start_send()' always fails here:
> 
> if (QLIST_EMPTY(&bus->current_devs)) {
> return 1;
> }
> 
> The member 'i2cBus->current_devs.lh_first' is always null.
> 
> I will add that in my QEMU execution I specify the bus 'aspeed.i2c.bus.0' to 
> be used with my device.
> In my 'realize' method I can see that a bus is connected to my device, as 
> 'qdev_get_parent_bus()' does return a valid pointer.
> 
> My question:
> 1. Am I missing some initialization for the bus?
> 2. Is there other way to send data on the i2c bus, assuming it can happen 
> anytime due to an internal event on my device side?

You are missing a lot of stuff, but let's start with basics...

First of all, this is not how i2c generally works.  Generally you have a
bus master, the host, that reads and writes to slave devices on the bus.
The devices on the bus don't asynchronously send data to the host.

That said, you can have multiple bus masters on the bus.  If that's what
you are doing, what are you sending your data to?  You have to have
something that will receive it.

If you have some slave device that has data it's holding for the host,
the host has to fetch it.  You could have an interrupt that comes from
the slave device saying it has data, and there's something called SMBus
alert that can consolidate interrupts (though it's not implemented in
QEMU at the moment).

Are you simulating some real device here?

-corey

> 
> Thanks for any tip,
> Pazo  



Re: [PATCH v3 1/3] hw/i2c: core: Add reset

2024-02-16 Thread Corey Minyard
On Thu, Feb 08, 2024 at 04:39:10PM +, Peter Maydell wrote:
> On Fri, 2 Feb 2024 at 20:48, Joe Komlodi  wrote:
> >
> > It's possible for a reset to come in the middle of a transaction, which
> > causes the bus to be in an old state when a new transaction comes in.
> >
> > Signed-off-by: Joe Komlodi 
> > ---
> >  hw/i2c/core.c| 19 +++
> >  include/hw/i2c/i2c.h |  2 +-
> >  2 files changed, 20 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> > index 4cf30b2c86..3128067bba 100644
> > --- a/hw/i2c/core.c
> > +++ b/hw/i2c/core.c
> > @@ -23,10 +23,29 @@ static Property i2c_props[] = {
> >  DEFINE_PROP_END_OF_LIST(),
> >  };
> >
> > +static void i2c_bus_hold_reset(Object *obj)
> > +{
> > +I2CBus *bus = I2C_BUS(obj);
> > +I2CNode *node, *next;
> > +
> > +bus->broadcast = false;
> > +QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
> > +QLIST_REMOVE(node, next);
> > +g_free(node);
> > +}
> > +}
> 
> This does what it says it's going to do; but I think it
> would be good to hear from Corey whether it's better to
> do this, or instead to call i2c_end_transfer() in the
> reset-enter phase.

Sorry, I missed this, I'm having major chaos going on right now in my
life.

I don't think i2c_end_transfer() is the right thing to do.  The transfer
has not cleanly ended, it is just forgotten.

> 
> Mostly QEMU's "reset" is like power-cycling, in which case
> I guess that what we have here where we just forget about
> the in-progress transfer and assume the device on the other
> end is also going to reset back to a neutral state is what
> we want.
> 
> Does i2c have a concept of a bus-level "reset" operation?

No, it does not.  Most I2C devices don't even have a reset pin.  In a
reset situation in real hardware, the operation would be aborted by
the lines drifting high after the bus master has been reset.

So I think this is fine as is.

-corey

> 
> > +
> > +static void i2c_bus_class_init(ObjectClass *klass, void *data)
> > +{
> > +ResettableClass *rc = RESETTABLE_CLASS(klass);
> > +rc->phases.hold = i2c_bus_hold_reset;
> > +}
> > +
> >  static const TypeInfo i2c_bus_info = {
> >  .name = TYPE_I2C_BUS,
> >  .parent = TYPE_BUS,
> >  .instance_size = sizeof(I2CBus),
> > +.class_init = i2c_bus_class_init,
> >  };
> 
> 
> 
> >  static int i2c_bus_pre_save(void *opaque)
> > diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
> > index 2a3abacd1b..49580e30e2 100644
> > --- a/include/hw/i2c/i2c.h
> > +++ b/include/hw/i2c/i2c.h
> > @@ -64,7 +64,7 @@ struct I2CSlave {
> >  };
> >
> >  #define TYPE_I2C_BUS "i2c-bus"
> > -OBJECT_DECLARE_SIMPLE_TYPE(I2CBus, I2C_BUS)
> > +OBJECT_DECLARE_TYPE(I2CBus, I2CBusClass, I2C_BUS)
> 
> I don't think you need this change any more ?
> 
> thanks
> -- PMM
> 



Re: [PATCH 0/4] hw/i2c: smbus: Reset fixes

2024-01-11 Thread Corey Minyard
On Wed, Jan 10, 2024 at 09:26:37PM +, Joe Komlodi wrote:
> Hi all,
> 
> This series adds some resets for SMBus and for the I2C core. Along with
> it, we make SMBus slave error printing a little more helpful.
> 
> These reset issues were very infrequent, they would maybe occur in 1 out
> of hundreds of resets in our testing, but the way they happen is pretty
> straightforward.
> Basically as long as a reset happens in the middle of a transaction, the
> state of the old transaction would still partially be there after the
> reset. Once a new transaction comes in, the partial stale state can
> cause the new transaction to incorrectly fail.

This seems wrong to me.  In a real system, the reset would be done on
the smbus master and not necessarily on the mux (though I looked at a
few of the PCA954x devices and they appear to have reset lines, but
different systems may drive that reset differently).

It seems to me that the bug is the smbus master device isn't getting
reset in a system reset.  Just adding the reset logic there would be
easier and more consistent with the real hardware.

-corey

> 
> Thanks,
> Joe
> 
> Joe Komlodi (4):
>   hw/i2c: core: Add reset
>   hw/i2c/smbus_slave: Add object path on error prints
>   hw/i2c: smbus_slave: Reset state on reset
>   hw/i2c: smbus: mux: Reset SMBusDevice state on reset
> 
>  hw/i2c/core.c| 30 +-
>  hw/i2c/i2c_mux_pca954x.c |  5 +
>  hw/i2c/smbus_slave.c | 20 ++--
>  include/hw/i2c/i2c.h |  6 +-
>  include/hw/i2c/smbus_slave.h |  1 +
>  5 files changed, 54 insertions(+), 8 deletions(-)
> 
> -- 
> 2.43.0.472.g3155946c3a-goog
> 
> 



[PULL 0/2] Pull request for some I2C changes

2023-12-06 Thread minyard
From: Corey Minyard 

Some minor I2C changes.  One has been sitting in my queue forgotten for
a while, but still needs to go in.  The other is fairly recent.  Both
are for BMC related stuff.

These are available at:
   https://github.com/cminyard/qemu.git i2c-for-release-2023-12-06
and signed by me.

Potin Lai (1):
  hw/i2c: add pca9543 i2c-mux switch

Titus Rwantare (1):
  hw/sensor: enable setting adm1272 temperature with qmp

 hw/i2c/i2c_mux_pca954x.c | 12 
 hw/sensor/adm1272.c  | 27 ++-
 include/hw/i2c/i2c_mux_pca954x.h |  1 +
 tests/qtest/adm1272-test.c   | 28 +++-
 4 files changed, 66 insertions(+), 2 deletions(-)

-- 
2.34.1




[PULL 1/2] hw/sensor: enable setting adm1272 temperature with qmp

2023-12-06 Thread minyard
From: Titus Rwantare 

Reviewed-by: Patrick Venture 
Reviewed-by: Chris Rauer 
Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
Message-Id: <20220106173814.3580141-1-vent...@google.com>
Signed-off-by: Corey Minyard 
---
 hw/sensor/adm1272.c| 27 ++-
 tests/qtest/adm1272-test.c | 28 +++-
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/hw/sensor/adm1272.c b/hw/sensor/adm1272.c
index 8f4a1c2cd4..6e5ae6e63b 100644
--- a/hw/sensor/adm1272.c
+++ b/hw/sensor/adm1272.c
@@ -65,6 +65,7 @@
 #define ADM1272_VOLTAGE_COEFF_DEFAULT   1
 #define ADM1272_CURRENT_COEFF_DEFAULT   3
 #define ADM1272_PWR_COEFF_DEFAULT   7
+#define ADM1272_TEMP_COEFF_DEFAULT  8
 #define ADM1272_IOUT_OFFSET 0x5000
 #define ADM1272_IOUT_OFFSET 0x5000
 
@@ -185,6 +186,22 @@ static uint32_t adm1272_direct_to_watts(uint16_t value)
 return pmbus_direct_mode2data(c, value);
 }
 
+static uint16_t adm1272_millidegrees_to_direct(uint32_t value)
+{
+PMBusCoefficients c = adm1272_coefficients[ADM1272_TEMP_COEFF_DEFAULT];
+c.b = c.b * 1000;
+c.R = c.R - 3;
+return pmbus_data2direct_mode(c, value);
+}
+
+static uint32_t adm1272_direct_to_millidegrees(uint16_t value)
+{
+PMBusCoefficients c = adm1272_coefficients[ADM1272_TEMP_COEFF_DEFAULT];
+c.b = c.b * 1000;
+c.R = c.R - 3;
+return pmbus_direct_mode2data(c, value);
+}
+
 static void adm1272_exit_reset(Object *obj)
 {
 ADM1272State *s = ADM1272(obj);
@@ -219,7 +236,7 @@ static void adm1272_exit_reset(Object *obj)
 = adm1272_millivolts_to_direct(ADM1272_VOLT_DEFAULT);
 pmdev->pages[0].read_iout
 = adm1272_milliamps_to_direct(ADM1272_IOUT_DEFAULT);
-pmdev->pages[0].read_temperature_1 = 0;
+pmdev->pages[0].read_temperature_1 = adm1272_millidegrees_to_direct(3);
 pmdev->pages[0].read_pin = adm1272_watts_to_direct(ADM1272_PWR_DEFAULT);
 pmdev->pages[0].revision = ADM1272_PMBUS_REVISION_DEFAULT;
 pmdev->pages[0].mfr_id = ADM1272_MFR_ID_DEFAULT;
@@ -422,6 +439,8 @@ static void adm1272_get(Object *obj, Visitor *v, const char 
*name, void *opaque,
 value = adm1272_direct_to_milliamps(*(uint16_t *)opaque);
 } else if (strcmp(name, "pin") == 0) {
 value = adm1272_direct_to_watts(*(uint16_t *)opaque);
+} else if (strcmp(name, "temperature") == 0) {
+value = adm1272_direct_to_millidegrees(*(uint16_t *)opaque);
 } else {
 value = *(uint16_t *)opaque;
 }
@@ -446,6 +465,8 @@ static void adm1272_set(Object *obj, Visitor *v, const char 
*name, void *opaque,
 *internal = adm1272_milliamps_to_direct(value);
 } else if (strcmp(name, "pin") == 0) {
 *internal = adm1272_watts_to_direct(value);
+} else if (strcmp(name, "temperature") == 0) {
+*internal = adm1272_millidegrees_to_direct(value);
 } else {
 *internal = value;
 }
@@ -509,6 +530,10 @@ static void adm1272_init(Object *obj)
 adm1272_get,
 adm1272_set, NULL, &pmdev->pages[0].read_pin);
 
+object_property_add(obj, "temperature", "uint16",
+adm1272_get,
+adm1272_set, NULL, 
&pmdev->pages[0].read_temperature_1);
+
 }
 
 static void adm1272_class_init(ObjectClass *klass, void *data)
diff --git a/tests/qtest/adm1272-test.c b/tests/qtest/adm1272-test.c
index 63f8514801..98134aabd2 100644
--- a/tests/qtest/adm1272-test.c
+++ b/tests/qtest/adm1272-test.c
@@ -65,6 +65,7 @@
 #define ADM1272_VOLTAGE_COEFF_DEFAULT   1
 #define ADM1272_CURRENT_COEFF_DEFAULT   3
 #define ADM1272_PWR_COEFF_DEFAULT   7
+#define ADM1272_TEMP_COEFF_DEFAULT  8
 #define ADM1272_IOUT_OFFSET 0x5000
 #define ADM1272_IOUT_OFFSET 0x5000
 
@@ -144,6 +145,22 @@ static uint32_t adm1272_direct_to_watts(uint16_t value)
 return pmbus_direct_mode2data(c, value);
 }
 
+static uint16_t adm1272_millidegrees_to_direct(uint32_t value)
+{
+PMBusCoefficients c = adm1272_coefficients[ADM1272_TEMP_COEFF_DEFAULT];
+c.b = c.b * 1000;
+c.R = c.R - 3;
+return pmbus_data2direct_mode(c, value);
+}
+
+static uint32_t adm1272_direct_to_millidegrees(uint16_t value)
+{
+PMBusCoefficients c = adm1272_coefficients[ADM1272_TEMP_COEFF_DEFAULT];
+c.b = c.b * 1000;
+c.R = c.R - 3;
+return pmbus_direct_mode2data(c, value);
+}
+
 static uint16_t qmp_adm1272_get(const char *id, const char *property)
 {
 QDict *response;
@@ -248,7 +265,7 @@ static void test_defaults(void *obj, void *data, 
QGuestAllocator *alloc)
 /* test qmp access */
 static void test_tx_rx(void *obj, void *data, QGuestAllocator *alloc)
 {
-uint16_t i2c_value, value, i2c_voltage, i2c_pwr, lossy_value;
+uint16_t i2c_value, value, i2c_voltage, i2c_pwr, i2c_temp, lossy_value;
 QI2CDevice *i2cdev = (QI2CDevice *)obj;

[PULL 2/2] hw/i2c: add pca9543 i2c-mux switch

2023-12-06 Thread minyard
From: Potin Lai 

Add pca9543 2-channel i2c-mux switch support.

Signed-off-by: Potin Lai 
Reviewed-by: Patrick Venture 
Message-Id: <20231113063156.2264941-1-potin.lai...@gmail.com>
Signed-off-by: Corey Minyard 
---
 hw/i2c/i2c_mux_pca954x.c | 12 
 include/hw/i2c/i2c_mux_pca954x.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
index db5db956a6..6aace0fc47 100644
--- a/hw/i2c/i2c_mux_pca954x.c
+++ b/hw/i2c/i2c_mux_pca954x.c
@@ -30,6 +30,7 @@
 
 #define PCA9548_CHANNEL_COUNT 8
 #define PCA9546_CHANNEL_COUNT 4
+#define PCA9543_CHANNEL_COUNT 2
 
 /*
  * struct Pca954xState - The pca954x state object.
@@ -172,6 +173,12 @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
 return pca954x->bus[channel];
 }
 
+static void pca9543_class_init(ObjectClass *klass, void *data)
+{
+Pca954xClass *s = PCA954X_CLASS(klass);
+s->nchans = PCA9543_CHANNEL_COUNT;
+}
+
 static void pca9546_class_init(ObjectClass *klass, void *data)
 {
 Pca954xClass *s = PCA954X_CLASS(klass);
@@ -246,6 +253,11 @@ static const TypeInfo pca954x_info[] = {
 .class_init= pca954x_class_init,
 .abstract  = true,
 },
+{
+.name  = TYPE_PCA9543,
+.parent= TYPE_PCA954X,
+.class_init= pca9543_class_init,
+},
 {
 .name  = TYPE_PCA9546,
 .parent= TYPE_PCA954X,
diff --git a/include/hw/i2c/i2c_mux_pca954x.h b/include/hw/i2c/i2c_mux_pca954x.h
index 3dd25ec983..1da5508ed5 100644
--- a/include/hw/i2c/i2c_mux_pca954x.h
+++ b/include/hw/i2c/i2c_mux_pca954x.h
@@ -3,6 +3,7 @@
 
 #include "hw/i2c/i2c.h"
 
+#define TYPE_PCA9543 "pca9543"
 #define TYPE_PCA9546 "pca9546"
 #define TYPE_PCA9548 "pca9548"
 
-- 
2.34.1




Re: [PATCH 1/1] hw/i2c: add pca9543 i2c-mux switch

2023-12-06 Thread Corey Minyard
On Tue, Dec 05, 2023 at 11:05:33AM -0800, Patrick Venture wrote:
> On Tue, Nov 14, 2023 at 3:30 PM Corey Minyard  wrote:
> 
> > On Mon, Nov 13, 2023 at 02:31:56PM +0800, Potin Lai wrote:
> > > Add pca9543 2-channel i2c-mux switch support.
> > >
> > > Signed-off-by: Potin Lai 
> >
> > Looks good to me.
> >
> > Acked-by: Corey Minyard 
> >
> > > ---
> > >  hw/i2c/i2c_mux_pca954x.c | 12 
> > >  include/hw/i2c/i2c_mux_pca954x.h |  1 +
> > >  2 files changed, 13 insertions(+)
> > >
> > > diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> > > index db5db956a6..6aace0fc47 100644
> > > --- a/hw/i2c/i2c_mux_pca954x.c
> > > +++ b/hw/i2c/i2c_mux_pca954x.c
> > > @@ -30,6 +30,7 @@
> > >
> > >  #define PCA9548_CHANNEL_COUNT 8
> > >  #define PCA9546_CHANNEL_COUNT 4
> > > +#define PCA9543_CHANNEL_COUNT 2
> > >
> > >  /*
> > >   * struct Pca954xState - The pca954x state object.
> > > @@ -172,6 +173,12 @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t
> > channel)
> > >  return pca954x->bus[channel];
> > >  }
> > >
> > > +static void pca9543_class_init(ObjectClass *klass, void *data)
> > > +{
> > > +Pca954xClass *s = PCA954X_CLASS(klass);
> > > +s->nchans = PCA9543_CHANNEL_COUNT;
> > > +}
> > > +
> > >  static void pca9546_class_init(ObjectClass *klass, void *data)
> > >  {
> > >  Pca954xClass *s = PCA954X_CLASS(klass);
> > > @@ -246,6 +253,11 @@ static const TypeInfo pca954x_info[] = {
> > >  .class_init= pca954x_class_init,
> > >  .abstract  = true,
> > >  },
> > > +{
> > > +.name  = TYPE_PCA9543,
> > > +.parent= TYPE_PCA954X,
> > > +.class_init= pca9543_class_init,
> > > +},
> > >  {
> > >  .name  = TYPE_PCA9546,
> > >  .parent= TYPE_PCA954X,
> > > diff --git a/include/hw/i2c/i2c_mux_pca954x.h
> > b/include/hw/i2c/i2c_mux_pca954x.h
> > > index 3dd25ec983..1da5508ed5 100644
> > > --- a/include/hw/i2c/i2c_mux_pca954x.h
> > > +++ b/include/hw/i2c/i2c_mux_pca954x.h
> > > @@ -3,6 +3,7 @@
> > >
> > >  #include "hw/i2c/i2c.h"
> > >
> > > +#define TYPE_PCA9543 "pca9543"
> > >  #define TYPE_PCA9546 "pca9546"
> > >  #define TYPE_PCA9548 "pca9548"
> > >
> > > --
> > > 2.31.1
> > >
> > >
> 
> 
> Corey, can you include this in a pull email? I don't quite have that set up
> at present, Titus is going to help me figure it out.

Ok, I'm running tests now, I'll get a pull request in assuming
everything is ok.

-corey



Re: [PATCH 1/1] hw/i2c: add pca9543 i2c-mux switch

2023-11-14 Thread Corey Minyard
On Mon, Nov 13, 2023 at 02:31:56PM +0800, Potin Lai wrote:
> Add pca9543 2-channel i2c-mux switch support.
> 
> Signed-off-by: Potin Lai 

Looks good to me.

Acked-by: Corey Minyard 

> ---
>  hw/i2c/i2c_mux_pca954x.c | 12 
>  include/hw/i2c/i2c_mux_pca954x.h |  1 +
>  2 files changed, 13 insertions(+)
> 
> diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> index db5db956a6..6aace0fc47 100644
> --- a/hw/i2c/i2c_mux_pca954x.c
> +++ b/hw/i2c/i2c_mux_pca954x.c
> @@ -30,6 +30,7 @@
>  
>  #define PCA9548_CHANNEL_COUNT 8
>  #define PCA9546_CHANNEL_COUNT 4
> +#define PCA9543_CHANNEL_COUNT 2
>  
>  /*
>   * struct Pca954xState - The pca954x state object.
> @@ -172,6 +173,12 @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t 
> channel)
>  return pca954x->bus[channel];
>  }
>  
> +static void pca9543_class_init(ObjectClass *klass, void *data)
> +{
> +Pca954xClass *s = PCA954X_CLASS(klass);
> +s->nchans = PCA9543_CHANNEL_COUNT;
> +}
> +
>  static void pca9546_class_init(ObjectClass *klass, void *data)
>  {
>  Pca954xClass *s = PCA954X_CLASS(klass);
> @@ -246,6 +253,11 @@ static const TypeInfo pca954x_info[] = {
>  .class_init= pca954x_class_init,
>  .abstract  = true,
>  },
> +{
> +.name  = TYPE_PCA9543,
> +.parent= TYPE_PCA954X,
> +.class_init= pca9543_class_init,
> +},
>  {
>  .name  = TYPE_PCA9546,
>  .parent= TYPE_PCA954X,
> diff --git a/include/hw/i2c/i2c_mux_pca954x.h 
> b/include/hw/i2c/i2c_mux_pca954x.h
> index 3dd25ec983..1da5508ed5 100644
> --- a/include/hw/i2c/i2c_mux_pca954x.h
> +++ b/include/hw/i2c/i2c_mux_pca954x.h
> @@ -3,6 +3,7 @@
>  
>  #include "hw/i2c/i2c.h"
>  
> +#define TYPE_PCA9543 "pca9543"
>  #define TYPE_PCA9546 "pca9546"
>  #define TYPE_PCA9548 "pca9548"
>  
> -- 
> 2.31.1
> 
> 



Re: [PATCH 5/6] hw/i2c/pm_smbus: Convert DPRINTF to trace events

2023-10-31 Thread Corey Minyard
On Sat, Oct 28, 2023 at 02:24:14PM +0200, Bernhard Beschow wrote:
> Let the trace messages slightly deviate from the function names
> ("smb" -> "smbus") being traced in order to avoid conflights with the SMB
> protocol.
> 
> Signed-off-by: Bernhard Beschow 

Looks good to me.

Acked-by: Corey Minyard 

> ---
>  hw/i2c/pm_smbus.c   | 18 --
>  hw/i2c/trace-events |  6 ++
>  2 files changed, 10 insertions(+), 14 deletions(-)
> 
> diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
> index 4e1b8a5182..78e7c229a8 100644
> --- a/hw/i2c/pm_smbus.c
> +++ b/hw/i2c/pm_smbus.c
> @@ -23,6 +23,7 @@
>  #include "hw/i2c/pm_smbus.h"
>  #include "hw/i2c/smbus_master.h"
>  #include "migration/vmstate.h"
> +#include "trace.h"
>  
>  #define SMBHSTSTS   0x00
>  #define SMBHSTCNT   0x02
> @@ -64,15 +65,6 @@
>  #define AUX_BLK   (1 << 1)
>  #define AUX_MASK  0x3
>  
> -/*#define DEBUG*/
> -
> -#ifdef DEBUG
> -# define SMBUS_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
> -#else
> -# define SMBUS_DPRINTF(format, ...) do { } while (0)
> -#endif
> -
> -
>  static void smb_transaction(PMSMBus *s)
>  {
>  uint8_t prot = (s->smb_ctl >> 2) & 0x07;
> @@ -82,7 +74,7 @@ static void smb_transaction(PMSMBus *s)
>  I2CBus *bus = s->smbus;
>  int ret;
>  
> -SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
> +trace_smbus_transaction(addr, prot);
>  /* Transaction isn't exec if STS_DEV_ERR bit set */
>  if ((s->smb_stat & STS_DEV_ERR) != 0)  {
>  goto error;
> @@ -258,8 +250,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, 
> uint64_t val,
>  PMSMBus *s = opaque;
>  uint8_t clear_byte_done;
>  
> -SMBUS_DPRINTF("SMB writeb port=0x%04" HWADDR_PRIx
> -  " val=0x%02" PRIx64 "\n", addr, val);
> +trace_smbus_ioport_writeb(addr, val);
>  switch(addr) {
>  case SMBHSTSTS:
>  clear_byte_done = s->smb_stat & val & STS_BYTE_DONE;
> @@ -429,8 +420,7 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr 
> addr, unsigned width)
>  val = 0;
>  break;
>  }
> -SMBUS_DPRINTF("SMB readb port=0x%04" HWADDR_PRIx " val=0x%02x\n",
> -  addr, val);
> +trace_smbus_ioport_readb(addr, val);
>  
>  if (s->set_irq) {
>  s->set_irq(s, smb_irq_value(s));
> diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
> index d7b1e25858..6900e06eda 100644
> --- a/hw/i2c/trace-events
> +++ b/hw/i2c/trace-events
> @@ -15,6 +15,12 @@ i2c_send_async(uint8_t address, uint8_t data) 
> "send_async(addr:0x%02x) data:0x%0
>  i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
>  i2c_ack(void) ""
>  
> +# pm_smbus.c
> +
> +smbus_ioport_readb(uint16_t addr, uint8_t data) "[0x%04" PRIx16 "] -> 
> val=0x%02x"
> +smbus_ioport_writeb(uint16_t addr, uint8_t data) "[0x%04" PRIx16 "] <- 
> val=0x%02x"
> +smbus_transaction(uint8_t addr, uint8_t prot) "addr=0x%02x prot=0x%02x"
> +
>  # allwinner_i2c.c
>  
>  allwinner_i2c_read(const char* reg_name, uint64_t offset, uint64_t value) 
> "read %s [0x%" PRIx64 "]: -> 0x%" PRIx64
> -- 
> 2.42.0
> 
> 



Re: [PATCH] hw/ipmi: Don't call vmstate_register() from instance_init() functions

2023-10-23 Thread Corey Minyard
On Mon, Oct 23, 2023 at 01:30:09PM +0200, Juan Quintela wrote:
> Thomas Huth  wrote:
> > instance_init() can be called multiple times, e.g. during introspection
> > of the device. We should not install the vmstate handlers here. Do it
> > in the realize() function instead.
> >
> > Signed-off-by: Thomas Huth 
> 
> Reviewed-by: Juan Quintela 
> 
> It fixes my issues.
> 
> Should I take this through the Migration tree?

That's fine with me.

Acked-by: Corey Minyard 

> 



Re: [PATCH] ipmi-bt-test: force ipv4

2023-10-19 Thread Corey Minyard
On Wed, Oct 18, 2023 at 10:11:23PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> We open ipv4 listening socket. But "localhost" in qemu parameters may
> load to Qemu trying to connect with ipv6 and fail with "Connection
> refused". Force ipv4 by using ipv4 ip address.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  tests/qtest/ipmi-bt-test.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/ipmi-bt-test.c b/tests/qtest/ipmi-bt-test.c
> index ed431e34e6..383239bcd4 100644
> --- a/tests/qtest/ipmi-bt-test.c
> +++ b/tests/qtest/ipmi-bt-test.c
> @@ -411,7 +411,7 @@ int main(int argc, char **argv)
>  g_test_init(&argc, &argv, NULL);
>  
>  global_qtest = qtest_initf(
> -" -chardev socket,id=ipmi0,host=localhost,port=%d,reconnect=10"
> +" -chardev socket,id=ipmi0,host=127.0.0.1,port=%d,reconnect=10"

Yeah, this make sense.

Acked-by: Corey Minyard 

>  " -device ipmi-bmc-extern,chardev=ipmi0,id=bmc0"
>  " -device isa-ipmi-bt,bmc=bmc0", emu_port);
>  qtest_irq_intercept_in(global_qtest, "ioapic");
> -- 
> 2.34.1
> 



Re: [PATCH] pm_smbus: rename variable to avoid shadowing

2023-09-26 Thread Corey Minyard
On Mon, Sep 25, 2023 at 04:47:39PM +0200, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini 
> ---
>  hw/i2c/pm_smbus.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

This looks ok to me.

Acked-by: Corey Minyard 

> 
> diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
> index 9ad6a47739b..4e1b8a5182d 100644
> --- a/hw/i2c/pm_smbus.c
> +++ b/hw/i2c/pm_smbus.c
> @@ -279,7 +279,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, 
> uint64_t val,
>  if (!read && s->smb_index == s->smb_data0) {
>  uint8_t prot = (s->smb_ctl >> 2) & 0x07;
>  uint8_t cmd = s->smb_cmd;
> -uint8_t addr = s->smb_addr >> 1;
> +uint8_t smb_addr = s->smb_addr >> 1;
>  int ret;
>  
>  if (prot == PROT_I2C_BLOCK_READ) {
> @@ -287,7 +287,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, 
> uint64_t val,
>  goto out;
>  }
>  
> -ret = smbus_write_block(s->smbus, addr, cmd, s->smb_data,
> +ret = smbus_write_block(s->smbus, smb_addr, cmd, s->smb_data,
>  s->smb_data0, !s->i2c_enable);
>  if (ret < 0) {
>  s->smb_stat |= STS_DEV_ERR;
> -- 
> 2.41.0
> 
> 



Re: [PATCH v6 0/3] hw/{i2c,nvme}: mctp endpoint, nvme management interface model

2023-09-20 Thread Corey Minyard
On Wed, Sep 20, 2023 at 06:31:25AM -0700, Klaus Jensen wrote:
> On Sep 20 07:54, Corey Minyard wrote:
> > On Wed, Sep 20, 2023 at 12:48:03PM +0100, Jonathan Cameron via wrote:
> > > On Thu, 14 Sep 2023 11:53:40 +0200
> > > Klaus Jensen  wrote:
> > > 
> > > > This adds a generic MCTP endpoint model that other devices may derive
> > > > from.
> > > > 
> > > > Also included is a very basic implementation of an NVMe-MI device,
> > > > supporting only a small subset of the required commands.
> > > > 
> > > > Since this all relies on i2c target mode, this can currently only be
> > > > used with an SoC that includes the Aspeed I2C controller.
> > > > 
> > > > The easiest way to get up and running with this, is to grab my buildroot
> > > > overlay[1] (aspeed_ast2600evb_nmi_defconfig). It includes modified a
> > > > modified dts as well as a couple of required packages.
> > > > 
> > > > QEMU can then be launched along these lines:
> > > > 
> > > >   qemu-system-arm \
> > > > -nographic \
> > > > -M ast2600-evb \
> > > > -kernel output/images/zImage \
> > > > -initrd output/images/rootfs.cpio \
> > > > -dtb output/images/aspeed-ast2600-evb-nmi.dtb \
> > > > -nic user,hostfwd=tcp::-:22 \
> > > > -device nmi-i2c,address=0x3a \
> > > > -serial mon:stdio
> > > > 
> > > > From within the booted system,
> > > > 
> > > >   mctp addr add 8 dev mctpi2c15
> > > >   mctp link set mctpi2c15 up
> > > >   mctp route add 9 via mctpi2c15
> > > >   mctp neigh add 9 dev mctpi2c15 lladdr 0x3a
> > > >   mi-mctp 1 9 info
> > > > 
> > > > Comments are very welcome!
> > > > 
> > > >   [1]: https://github.com/birkelund/hwtests/tree/main/br2-external
> > > > 
> > > > Signed-off-by: Klaus Jensen 
> > > 
> > > Hi Klaus,
> > > 
> > > Silly question, but who is likely to pick this up? + likely to be soon?
> > > 
> > > I'm going to post the CXL stuff that makes use of the core support shortly
> > > and whilst I can point at this patch set on list, I'd keen to see it 
> > > upstream
> > > to reduce the dependencies (it's got 2 sets ahead of it of CXL stuff
> > > anyway but that will all hopefully go through Michael Tsirkin's tree
> > > for PCI stuff in one go).
> > 
> > I can pick it up, but he can just request a merge, too.
> > 
> > I did have a question I asked earlier about tests.  It would be unusual
> > at this point to add something like this without having some tests,
> > especially injecting invalid data.
> > 
> 
> Hi all,
> 
> Sorry for the late reply. I'm currently at SDC, but I will write up some
> tests when I get back to in the office on Monday.
> 
> Corey, what kinds of tests would be best here? Avocado "acceptance"
> tests or would you like to see something lower level?

My main concern is testing what happens when bad data gets injected, to
avoid people coming up with clever names for exploits in qemu.  It's not
so much for this code, it's for the changes that comes in the future.

And, of course, normal functional tests to make sure it works.  What a
friend of mine calls "dead chicken" tests.  You wave a dead chicken at
it, and if the chicken is still dead everything is ok :).

I'm fine with either type of tests, but I'm not sure you can do this
with avocado.  It's probably about the same amount of work either path
you choose.

-corey



Re: [PATCH v6 0/3] hw/{i2c,nvme}: mctp endpoint, nvme management interface model

2023-09-20 Thread Corey Minyard
On Wed, Sep 20, 2023 at 12:48:03PM +0100, Jonathan Cameron via wrote:
> On Thu, 14 Sep 2023 11:53:40 +0200
> Klaus Jensen  wrote:
> 
> > This adds a generic MCTP endpoint model that other devices may derive
> > from.
> > 
> > Also included is a very basic implementation of an NVMe-MI device,
> > supporting only a small subset of the required commands.
> > 
> > Since this all relies on i2c target mode, this can currently only be
> > used with an SoC that includes the Aspeed I2C controller.
> > 
> > The easiest way to get up and running with this, is to grab my buildroot
> > overlay[1] (aspeed_ast2600evb_nmi_defconfig). It includes modified a
> > modified dts as well as a couple of required packages.
> > 
> > QEMU can then be launched along these lines:
> > 
> >   qemu-system-arm \
> > -nographic \
> > -M ast2600-evb \
> > -kernel output/images/zImage \
> > -initrd output/images/rootfs.cpio \
> > -dtb output/images/aspeed-ast2600-evb-nmi.dtb \
> > -nic user,hostfwd=tcp::-:22 \
> > -device nmi-i2c,address=0x3a \
> > -serial mon:stdio
> > 
> > From within the booted system,
> > 
> >   mctp addr add 8 dev mctpi2c15
> >   mctp link set mctpi2c15 up
> >   mctp route add 9 via mctpi2c15
> >   mctp neigh add 9 dev mctpi2c15 lladdr 0x3a
> >   mi-mctp 1 9 info
> > 
> > Comments are very welcome!
> > 
> >   [1]: https://github.com/birkelund/hwtests/tree/main/br2-external
> > 
> > Signed-off-by: Klaus Jensen 
> 
> Hi Klaus,
> 
> Silly question, but who is likely to pick this up? + likely to be soon?
> 
> I'm going to post the CXL stuff that makes use of the core support shortly
> and whilst I can point at this patch set on list, I'd keen to see it upstream
> to reduce the dependencies (it's got 2 sets ahead of it of CXL stuff
> anyway but that will all hopefully go through Michael Tsirkin's tree
> for PCI stuff in one go).

I can pick it up, but he can just request a merge, too.

I did have a question I asked earlier about tests.  It would be unusual
at this point to add something like this without having some tests,
especially injecting invalid data.

-corey

> 
> Jonathan
> 
> > ---
> > Changes in v6:
> > - Use nmi_scratch_append() directly where it makes sense. Fixes bug
> >   observed by Andrew.
> > - Link to v5: 
> > https://lore.kernel.org/r/20230905-nmi-i2c-v5-0-0001d372a...@samsung.com
> > 
> > Changes in v5:
> > - Added a nmi_scratch_append() that asserts available space in the
> >   scratch buffer. This is a similar defensive strategy as used in
> >   hw/i2c/mctp.c
> > - Various small fixups in response to review (Jonathan)
> > - Link to v4: 
> > https://lore.kernel.org/r/20230823-nmi-i2c-v4-0-2b0f86e5b...@samsung.com
> > 
> > ---
> > Klaus Jensen (3):
> >   hw/i2c: add smbus pec utility function
> >   hw/i2c: add mctp core
> >   hw/nvme: add nvme management interface model
> > 
> >  MAINTAINERS   |   7 +
> >  hw/arm/Kconfig|   1 +
> >  hw/i2c/Kconfig|   4 +
> >  hw/i2c/mctp.c | 432 
> > ++
> >  hw/i2c/meson.build|   1 +
> >  hw/i2c/smbus_master.c |  26 +++
> >  hw/i2c/trace-events   |  13 ++
> >  hw/nvme/Kconfig   |   4 +
> >  hw/nvme/meson.build   |   1 +
> >  hw/nvme/nmi-i2c.c | 407 +++
> >  hw/nvme/trace-events  |   6 +
> >  include/hw/i2c/mctp.h | 125 
> >  include/hw/i2c/smbus_master.h |   2 +
> >  include/net/mctp.h|  35 
> >  14 files changed, 1064 insertions(+)
> > ---
> > base-commit: 005ad32358f12fe9313a4a01918a55e60d4f39e5
> > change-id: 20230822-nmi-i2c-d804ed5be7e6
> > 
> > Best regards,
> 
> 



Re: [PATCH v6 3/3] hw/nvme: add nvme management interface model

2023-09-14 Thread Corey Minyard
On Thu, Sep 14, 2023 at 11:53:43AM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add the 'nmi-i2c' device that emulates an NVMe Management Interface
> controller.
> 
> Initial support is very basic (Read NMI DS, Configuration Get).
> 
> This is based on previously posted code by Padmakar Kalghatgi, Arun
> Kumar Agasar and Saurav Kumar.

This seems fine.

Acked-by: Corey Minyard 

One question, though.  You don't have any tests.  Did you test invalid
packets and such?  I think the logic is correct, but those are things
that are good to test.  Having tests in qemu would be even better.


> 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Klaus Jensen 
> ---
>  hw/nvme/Kconfig  |   4 +
>  hw/nvme/meson.build  |   1 +
>  hw/nvme/nmi-i2c.c| 407 
> +++
>  hw/nvme/trace-events |   6 +
>  4 files changed, 418 insertions(+)
> 
> diff --git a/hw/nvme/Kconfig b/hw/nvme/Kconfig
> index cfa2ab0f9d5a..e1f6360c0f4b 100644
> --- a/hw/nvme/Kconfig
> +++ b/hw/nvme/Kconfig
> @@ -2,3 +2,7 @@ config NVME_PCI
>  bool
>  default y if PCI_DEVICES || PCIE_DEVICES
>  depends on PCI
> +
> +config NVME_NMI_I2C
> +bool
> +default y if I2C_MCTP
> diff --git a/hw/nvme/meson.build b/hw/nvme/meson.build
> index 1a6a2ca2f307..7bc85f31c149 100644
> --- a/hw/nvme/meson.build
> +++ b/hw/nvme/meson.build
> @@ -1 +1,2 @@
>  system_ss.add(when: 'CONFIG_NVME_PCI', if_true: files('ctrl.c', 'dif.c', 
> 'ns.c', 'subsys.c'))
> +system_ss.add(when: 'CONFIG_NVME_NMI_I2C', if_true: files('nmi-i2c.c'))
> diff --git a/hw/nvme/nmi-i2c.c b/hw/nvme/nmi-i2c.c
> new file mode 100644
> index ..bf4648db0457
> --- /dev/null
> +++ b/hw/nvme/nmi-i2c.c
> @@ -0,0 +1,407 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * SPDX-FileCopyrightText: Copyright (c) 2023 Samsung Electronics Co., Ltd.
> + *
> + * SPDX-FileContributor: Padmakar Kalghatgi 
> + * SPDX-FileContributor: Arun Kumar Agasar 
> + * SPDX-FileContributor: Saurav Kumar 
> + * SPDX-FileContributor: Klaus Jensen 
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/crc32c.h"
> +#include "hw/registerfields.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/i2c/mctp.h"
> +#include "net/mctp.h"
> +#include "trace.h"
> +
> +/* NVM Express Management Interface 1.2c, Section 3.1 */
> +#define NMI_MAX_MESSAGE_LENGTH 4224
> +
> +#define TYPE_NMI_I2C_DEVICE "nmi-i2c"
> +OBJECT_DECLARE_SIMPLE_TYPE(NMIDevice, NMI_I2C_DEVICE)
> +
> +typedef struct NMIDevice {
> +MCTPI2CEndpoint mctp;
> +
> +uint8_t buffer[NMI_MAX_MESSAGE_LENGTH];
> +uint8_t scratch[NMI_MAX_MESSAGE_LENGTH];
> +
> +size_t  len;
> +int64_t pos;
> +} NMIDevice;
> +
> +FIELD(NMI_MCTPD, MT, 0, 7)
> +FIELD(NMI_MCTPD, IC, 7, 1)
> +
> +#define NMI_MCTPD_MT_NMI 0x4
> +#define NMI_MCTPD_IC_ENABLED 0x1
> +
> +FIELD(NMI_NMP, ROR, 7, 1)
> +FIELD(NMI_NMP, NMIMT, 3, 4)
> +
> +#define NMI_NMP_NMIMT_NVME_MI 0x1
> +#define NMI_NMP_NMIMT_NVME_ADMIN 0x2
> +
> +typedef struct NMIMessage {
> +uint8_t mctpd;
> +uint8_t nmp;
> +uint8_t rsvd2[2];
> +uint8_t payload[]; /* includes the Message Integrity Check */
> +} NMIMessage;
> +
> +typedef struct NMIRequest {
> +   uint8_t opc;
> +   uint8_t rsvd1[3];
> +   uint32_t dw0;
> +   uint32_t dw1;
> +   uint32_t mic;
> +} NMIRequest;
> +
> +FIELD(NMI_CMD_READ_NMI_DS_DW0, DTYP, 24, 8)
> +
> +typedef enum NMIReadDSType {
> +NMI_CMD_READ_NMI_DS_SUBSYSTEM   = 0x0,
> +NMI_CMD_READ_NMI_DS_PORTS   = 0x1,
> +NMI_CMD_READ_NMI_DS_CTRL_LIST   = 0x2,
> +NMI_CMD_READ_NMI_DS_CTRL_INFO   = 0x3,
> +NMI_CMD_READ_NMI_DS_OPT_CMD_SUPPORT = 0x4,
> +NMI_CMD_READ_NMI_DS_MEB_CMD_SUPPORT = 0x5,
> +} NMIReadDSType;
> +
> +#define NMI_STATUS_INVALID_PARAMETER 0x4
> +
> +static void nmi_scratch_append(NMIDevice *nmi, const void *buf, size_t count)
> +{
> +assert(nmi->pos + count <= NMI_MAX_MESSAGE_LENGTH);
> +
> +memcpy(nmi->scratch + nmi->pos, buf, count);
> +nmi->pos += count;
> +}
> +
> +static void nmi_set_parameter_error(NMIDevice *nmi, uint8_t bit, uint16_t 
> byte)
> +{
> +/* NVM Express Management Interface 1.2c, Figure 30 */
> +struct resp {
> +uint8_t  status;
> +uint8_t  bit;
> +uint16_t byte;
> +};
> +
> +struct resp buf = {
> +.status = NMI_STATUS_INVALID_PARAMETER,
> +.bit = bit & 0x3,
&g

Re: [PATCH v6 2/3] hw/i2c: add mctp core

2023-09-14 Thread Corey Minyard
On Thu, Sep 14, 2023 at 11:53:42AM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add an abstract MCTP over I2C endpoint model. This implements MCTP
> control message handling as well as handling the actual I2C transport
> (packetization).
> 
> Devices are intended to derive from this and implement the class
> methods.
> 
> Parts of this implementation is inspired by code[1] previously posted by
> Jonathan Cameron.

I've been kind of watching this, I guess I need to review.  I've been
over the logic and it all looks good, I think.  So I can do:

Acked-by: Corey Minyard 

Thanks to everyone that reviewed.

> 
> Squashed a fix[2] from Matt Johnston.
> 
>   [1]: 
> https://lore.kernel.org/qemu-devel/20220520170128.4436-1-jonathan.came...@huawei.com/
>   [2]: 
> https://lore.kernel.org/qemu-devel/20221121080445.ga29...@codeconstruct.com.au/
> 
> Tested-by: Jonathan Cameron 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Klaus Jensen 
> ---
>  MAINTAINERS   |   7 +
>  hw/arm/Kconfig|   1 +
>  hw/i2c/Kconfig|   4 +
>  hw/i2c/mctp.c | 432 
> ++
>  hw/i2c/meson.build|   1 +
>  hw/i2c/trace-events   |  13 ++
>  include/hw/i2c/mctp.h | 125 +++
>  include/net/mctp.h|  35 
>  8 files changed, 618 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 00562f924f7a..3208ebb1bcde 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3404,6 +3404,13 @@ F: tests/qtest/adm1272-test.c
>  F: tests/qtest/max34451-test.c
>  F: tests/qtest/isl_pmbus_vr-test.c
>  
> +MCTP I2C Transport
> +M: Klaus Jensen 
> +S: Maintained
> +F: hw/i2c/mctp.c
> +F: include/hw/i2c/mctp.h
> +F: include/net/mctp.h
> +
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
>  R: Daniel P. Berrange 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 7e6834844051..5bcb1e0e8a6f 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -541,6 +541,7 @@ config ASPEED_SOC
>  select DS1338
>  select FTGMAC100
>  select I2C
> +select I2C_MCTP
>  select DPS310
>  select PCA9552
>  select SERIAL
> diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
> index 14886b35dac2..2b2a50b83d1e 100644
> --- a/hw/i2c/Kconfig
> +++ b/hw/i2c/Kconfig
> @@ -6,6 +6,10 @@ config I2C_DEVICES
>  # to any board's i2c bus
>  bool
>  
> +config I2C_MCTP
> +bool
> +select I2C
> +
>  config SMBUS
>  bool
>  select I2C
> diff --git a/hw/i2c/mctp.c b/hw/i2c/mctp.c
> new file mode 100644
> index ..8d8e74567745
> --- /dev/null
> +++ b/hw/i2c/mctp.c
> @@ -0,0 +1,432 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * SPDX-FileCopyrightText: Copyright (c) 2023 Samsung Electronics Co., Ltd.
> + * SPDX-FileContributor: Klaus Jensen 
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/main-loop.h"
> +
> +#include "hw/qdev-properties.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/i2c/smbus_master.h"
> +#include "hw/i2c/mctp.h"
> +#include "net/mctp.h"
> +
> +#include "trace.h"
> +
> +/* DSP0237 1.2.0, Figure 1 */
> +typedef struct MCTPI2CPacketHeader {
> +uint8_t dest;
> +#define MCTP_I2C_COMMAND_CODE 0xf
> +uint8_t command_code;
> +uint8_t byte_count;
> +uint8_t source;
> +} MCTPI2CPacketHeader;
> +
> +typedef struct MCTPI2CPacket {
> +MCTPI2CPacketHeader i2c;
> +MCTPPacket  mctp;
> +} MCTPI2CPacket;
> +
> +#define i2c_mctp_payload_offset offsetof(MCTPI2CPacket, mctp.payload)
> +#define i2c_mctp_payload(buf) (buf + i2c_mctp_payload_offset)
> +
> +/* DSP0236 1.3.0, Figure 20 */
> +typedef struct MCTPControlMessage {
> +#define MCTP_MESSAGE_TYPE_CONTROL 0x0
> +uint8_t type;
> +#define MCTP_CONTROL_FLAGS_RQ   (1 << 7)
> +#define MCTP_CONTROL_FLAGS_D(1 << 6)
> +uint8_t flags;
> +uint8_t command_code;
> +uint8_t data[];
> +} MCTPControlMessage;
> +
> +enum MCTPControlCommandCodes {
> +MCTP_CONTROL_SET_EID= 0x01,
> +MCTP_CONTROL_GET_EID= 0x02,
> +MCTP_CONTROL_GET_VERSION= 0x04,
> +MCTP_CONTROL_GET_MESSAGE_TYPE_SUPPORT   = 0x05,
> +};
> +
> +#define MCTP_CONTROL_ERROR_UNSUPPORTED_CMD 0x5
> +
> +#define i2c_mctp_control_data_offset \
> +(i2c_mctp_payload_offset + offsetof(MCTPControlMessage, data))
> +#define i2c_mctp_control_data(buf) (buf + i2c_mctp_control_data_offset)
> +
> +/**
> + 

Re: [PATCH v6 1/3] hw/i2c: add smbus pec utility function

2023-09-14 Thread Corey Minyard
On Thu, Sep 14, 2023 at 11:53:41AM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add i2c_smbus_pec() to calculate the SMBus Packet Error Code for a
> message.

Seems fine.

Acked-by: Corey Minyard 

> 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Klaus Jensen 
> ---
>  hw/i2c/smbus_master.c | 26 ++
>  include/hw/i2c/smbus_master.h |  2 ++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/hw/i2c/smbus_master.c b/hw/i2c/smbus_master.c
> index 6a53c34e70b7..01a8e4700222 100644
> --- a/hw/i2c/smbus_master.c
> +++ b/hw/i2c/smbus_master.c
> @@ -15,6 +15,32 @@
>  #include "hw/i2c/i2c.h"
>  #include "hw/i2c/smbus_master.h"
>  
> +static uint8_t crc8(uint16_t data)
> +{
> +int i;
> +
> +for (i = 0; i < 8; i++) {
> +if (data & 0x8000) {
> +data ^= 0x1070U << 3;
> +}
> +
> +data <<= 1;
> +}
> +
> +return (uint8_t)(data >> 8);
> +}
> +
> +uint8_t i2c_smbus_pec(uint8_t crc, uint8_t *buf, size_t len)
> +{
> +int i;
> +
> +for (i = 0; i < len; i++) {
> +crc = crc8((crc ^ buf[i]) << 8);
> +}
> +
> +return crc;
> +}
> +
>  /* Master device commands.  */
>  int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
>  {
> diff --git a/include/hw/i2c/smbus_master.h b/include/hw/i2c/smbus_master.h
> index bb13bc423c22..d90f81767d86 100644
> --- a/include/hw/i2c/smbus_master.h
> +++ b/include/hw/i2c/smbus_master.h
> @@ -27,6 +27,8 @@
>  
>  #include "hw/i2c/i2c.h"
>  
> +uint8_t i2c_smbus_pec(uint8_t crc, uint8_t *buf, size_t len);
> +
>  /* Master device commands.  */
>  int smbus_quick_command(I2CBus *bus, uint8_t addr, int read);
>  int smbus_receive_byte(I2CBus *bus, uint8_t addr);
> 
> -- 
> 2.42.0
> 
> 



Re: [PATCH v3 0/3] hw/{i2c, nvme}: mctp endpoint, nvme management interface model

2023-06-01 Thread Corey Minyard
On Wed, May 31, 2023 at 01:47:41PM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> This adds a generic MCTP endpoint model that other devices may derive
> from. I'm not 100% happy with the design of the class methods, but it's
> a start.
> 
> Also included is a very basic implementation of an NVMe-MI device,
> supporting only a small subset of the required commands. Lior (CC'ed) has some
> patches coming up that adds futher support.
> 
> Since this all relies on i2c target mode, this can currently only be
> used with an SoC that includes the Aspeed I2C controller.
> 
> The easiest way to get up and running with this, is to grab my buildroot
> overlay[1]. It includes modified a modified dts as well as a couple of
> required packages.
> 
> QEMU can then be launched along these lines:
> 
>   qemu-system-arm \
> -nographic \
> -M ast2600-evb \
> -kernel output/images/zImage \
> -initrd output/images/rootfs.cpio \
> -dtb output/images/aspeed-ast2600-evb-nmi.dtb \
> -nic user,hostfwd=tcp::-:22 \
> -device nmi-i2c,address=0x3a \
> -serial mon:stdio
> 
> From within the booted system,
> 
>   mctp addr add 8 dev mctpi2c15
>   mctp link set mctpi2c15 up
>   mctp route add 9 via mctpi2c15
>   mctp neigh add 9 dev mctpi2c15 lladdr 0x3a
>   mi-mctp 1 9 info
> 
> Comments are very welcome!
> 
>   [1]: https://github.com/birkelund/buildroots/tree/main/mctp-i2c
> 
> Changes since v2
> 
> 
>   - Applied a bunch of feedback from Jonathan:
> + Moved a lot of internally used structs out of the include headers
>   and into the source files.
> + Added spec references in various places
> + Split the patch for i2c_smbus_pec() into its own
> + Fix a compile error (and bug) in nmi-i2c.c.
> 
>   - From Corey:
> + Reworked the buffer handling. The deriving devices now returns a
>   pointer to their own buffer that the mctp core copies into.

You didn't do what I asked here, I guess I wasn't clear.  You have:

+static void i2c_mctp_handle_control_set_eid(MCTPI2CEndpoint *mctp, uint8_t eid)
+{
+mctp->my_eid = eid;
+
+uint8_t buf[] = {
+0x0, 0x0, eid, 0x0,
+};
+
+memcpy(i2c_mctp_control_data(mctp->buffer), buf, sizeof(buf));
+mctp->len += sizeof(buf);
+}

That style of programming can lead to buffer overruns as code changes,
as you aren't checking the length of the target buffer.  I don't think
there are any issues now, but as people change the code you might end up
with one if someone gets a length wrong.

What I would like is for you to create a function like:

  i2c_mctp_add_bytes(mctp, buf, len)

that checks that len bytes will fit, then does the addition of the
bytes.  You need to adjust this to fit how you are doing things, and you
probably want one that adds just one byte, but hopefully you get the idea.

I'm sorry to be picky, but I've seen and fixed too many buffer overruns
(including one in the qemu i2c code) in situations like this.  Corey's
rule is: Never add anything to a buffer without checking the length.

Everything else looks good.

-corey

> + Added a couple of extra debugging trace events.
> 
> Changes since v1
> 
> 
>   - Fix SPDX-License tag for hw/nvme/nmi-i2c.c (Philippe)
>   - Add some asserts to verify buffer indices (by request from Corey).
>   - Drop short packets that could result in underflow (Corey)
>   - Move i2c_smbus_pec() to smbus common code (Corey)
>   - A couple of logic fixes (patch from Jeremy squashed in)
>   - Added a patch to handle messages with dest eid 0 (Matt)
> Maybe squash this as well.
> 
> Klaus Jensen (3):
>   hw/i2c: add smbus pec utility function
>   hw/i2c: add mctp core
>   hw/nvme: add nvme management interface model
> 
>  MAINTAINERS   |   7 +
>  hw/arm/Kconfig|   1 +
>  hw/i2c/Kconfig|   4 +
>  hw/i2c/mctp.c | 398 ++
>  hw/i2c/meson.build|   1 +
>  hw/i2c/smbus_master.c |  28 +++
>  hw/i2c/trace-events   |  13 ++
>  hw/nvme/meson.build   |   1 +
>  hw/nvme/nmi-i2c.c | 367 +++
>  hw/nvme/trace-events  |   6 +
>  include/hw/i2c/mctp.h | 137 
>  include/hw/i2c/smbus_master.h |   2 +
>  include/net/mctp.h|  28 +++
>  13 files changed, 993 insertions(+)
>  create mode 100644 hw/i2c/mctp.c
>  create mode 100644 hw/nvme/nmi-i2c.c
>  create mode 100644 include/hw/i2c/mctp.h
>  create mode 100644 include/net/mctp.h
> 
> -- 
> 2.40.0
> 
> 



Re: [PATCH v2 1/3] hw/i2c: add mctp core

2023-04-26 Thread Corey Minyard
On Wed, Apr 26, 2023 at 09:11:16AM +0200, Klaus Jensen wrote:
> On Apr 25 10:19, Corey Minyard wrote:
> > On Tue, Apr 25, 2023 at 08:35:38AM +0200, Klaus Jensen wrote:
> > > From: Klaus Jensen 
> > > 
> > > Add an abstract MCTP over I2C endpoint model. This implements MCTP
> > > control message handling as well as handling the actual I2C transport
> > > (packetization).
> > > 
> > > Devices are intended to derive from this and implement the class
> > > methods.
> > > 
> > > Parts of this implementation is inspired by code[1] previously posted by
> > > Jonathan Cameron.
> > 
> > All in all this looks good.  Two comments:
> > 
> > I would like to see the buffer handling consolidated into one function
> > and the length checked, even for (especially for) the outside users of
> > this code, like the nvme code.  Best to avoid future issues with buffer
> > overruns.  This will require reworking the get_message_types function,
> > unfortunately.
> > 
> 
> Right now the implementations (i.e. hw/nvme/nmi-i2c.c) writes directly
> into the mctp core buffer for get_message_bytes(). The contract is that
> it must not write more than the `maxlen` parameter. Is that bad? Would
> it be better that get_message_bytes() returned a pointer to its own
> buffer that hw/mctp can then copy from?

qemu has had several instances of unchecked writing into a buffer
eventually getting it into trouble.  It might be ok in the beginning,
but as things change and code is added, something might come in that is
not ok.

nmi_get_message_types(), for instance, does not check maxlen.

It may be borderline paranoia, but I've seen too many instances where
paranoia was warranted :).

Plus I think it would make the code a little cleaner and easier to
maintain.  If you wanted to change how the buffer worked, trace data put
into the buffer, or something like that, all the code to handle that is
in one place.

> 
> > You have one trace function on a bad receive message check, but lots of
> > other bad receive message checks with no trace.  Just a suggestion, but
> > it might be nice for tracking down issues to trace all the reasons a
> > message is dropped.
> > 
> 
> Sounds reasonable! :)
> 
> Thanks for the review!

Thank you for the submission :).

-corey



Re: [PATCH v2 1/3] hw/i2c: add mctp core

2023-04-25 Thread Corey Minyard
On Tue, Apr 25, 2023 at 08:35:38AM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add an abstract MCTP over I2C endpoint model. This implements MCTP
> control message handling as well as handling the actual I2C transport
> (packetization).
> 
> Devices are intended to derive from this and implement the class
> methods.
> 
> Parts of this implementation is inspired by code[1] previously posted by
> Jonathan Cameron.

All in all this looks good.  Two comments:

I would like to see the buffer handling consolidated into one function
and the length checked, even for (especially for) the outside users of
this code, like the nvme code.  Best to avoid future issues with buffer
overruns.  This will require reworking the get_message_types function,
unfortunately.

You have one trace function on a bad receive message check, but lots of
other bad receive message checks with no trace.  Just a suggestion, but
it might be nice for tracking down issues to trace all the reasons a
message is dropped.

Thanks,

-corey

> 
>   [1]: 
> https://lore.kernel.org/qemu-devel/20220520170128.4436-1-jonathan.came...@huawei.com/
> 
> Signed-off-by: Klaus Jensen 
> ---
>  MAINTAINERS   |   7 +
>  hw/arm/Kconfig|   1 +
>  hw/i2c/Kconfig|   4 +
>  hw/i2c/mctp.c | 352 ++
>  hw/i2c/meson.build|   1 +
>  hw/i2c/smbus_master.c |  28 +++
>  hw/i2c/trace-events   |  12 ++
>  include/hw/i2c/mctp.h | 114 +++
>  include/hw/i2c/smbus_master.h |   3 +
>  include/net/mctp.h|  43 +
>  10 files changed, 565 insertions(+)
>  create mode 100644 hw/i2c/mctp.c
>  create mode 100644 include/hw/i2c/mctp.h
>  create mode 100644 include/net/mctp.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 24154f5721c7..054aad1f3e97 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3339,6 +3339,13 @@ F: tests/qtest/adm1272-test.c
>  F: tests/qtest/max34451-test.c
>  F: tests/qtest/isl_pmbus_vr-test.c
>  
> +MCTP I2C Transport
> +M: Klaus Jensen 
> +S: Maintained
> +F: hw/i2c/mctp.c
> +F: include/hw/i2c/mctp.h
> +F: include/net/mctp.h
> +
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
>  R: Daniel P. Berrange 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index b53bd7f0b2a0..d7ecbc99e5ee 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -457,6 +457,7 @@ config ASPEED_SOC
>  select DS1338
>  select FTGMAC100
>  select I2C
> +select MCTP_I2C
>  select DPS310
>  select PCA9552
>  select SERIAL
> diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
> index 14886b35dac2..3415e8421ab1 100644
> --- a/hw/i2c/Kconfig
> +++ b/hw/i2c/Kconfig
> @@ -45,3 +45,7 @@ config PCA954X
>  config PMBUS
>  bool
>  select SMBUS
> +
> +config MCTP_I2C
> +bool
> +select I2C
> diff --git a/hw/i2c/mctp.c b/hw/i2c/mctp.c
> new file mode 100644
> index ..0f4045d0d685
> --- /dev/null
> +++ b/hw/i2c/mctp.c
> @@ -0,0 +1,352 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * SPDX-FileCopyrightText: Copyright (c) 2022 Samsung Electronics Co., Ltd.
> + * SPDX-FileContributor: Klaus Jensen 
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/main-loop.h"
> +
> +#include "hw/qdev-properties.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/i2c/smbus_master.h"
> +#include "hw/i2c/mctp.h"
> +
> +#include "trace.h"
> +
> +void i2c_mctp_schedule_send(MCTPI2CEndpoint *mctp)
> +{
> +I2CBus *i2c = I2C_BUS(qdev_get_parent_bus(DEVICE(mctp)));
> +
> +mctp->tx.state = I2C_MCTP_STATE_TX_START_SEND;
> +
> +i2c_bus_master(i2c, mctp->tx.bh);
> +}
> +
> +static void i2c_mctp_tx(void *opaque)
> +{
> +DeviceState *dev = DEVICE(opaque);
> +I2CBus *i2c = I2C_BUS(qdev_get_parent_bus(dev));
> +I2CSlave *slave = I2C_SLAVE(dev);
> +MCTPI2CEndpoint *mctp = MCTP_I2C_ENDPOINT(dev);
> +MCTPI2CEndpointClass *mc = MCTP_I2C_ENDPOINT_GET_CLASS(mctp);
> +MCTPI2CPacket *pkt = (MCTPI2CPacket *)mctp->buffer;
> +uint8_t flags = 0;
> +
> +switch (mctp->tx.state) {
> +case I2C_MCTP_STATE_TX_SEND_BYTE:
> +if (mctp->pos < mctp->len) {
> +uint8_t byte = mctp->buffer[mctp->pos];
> +
> +trace_i2c_mctp_tx_send_byte(mctp->pos, byte);
> +
> +/* send next byte */
> +i2c_send_async(i2c, byte);
> +
> +mctp->pos++;
> +
> +break;
> +}
> +
> +/* packet sent */
> +i2c_end_transfer(i2c);
> +
> +/* end of any control data */
> +mctp->len = 0;
> +
> +/* fall through */
> +
> +case I2C_MCTP_STATE_TX_START_SEND:
> +if (mctp->tx.is_control) {
> +/* packet payload is already in buffer */
> +flags |= MCTP_H_FLAGS_SOM | MCTP_H_FLAGS_EOM;
> +} else {
> +/* get message bytes from derived device */
> +mctp->len = mc->get_message_bytes(mctp, pkt->mctp.payload,
> +  

Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside

2023-04-24 Thread Corey Minyard
On Mon, Apr 24, 2023 at 11:02:08AM -0500, Corey Minyard wrote:
> On Mon, Apr 24, 2023 at 02:09:50PM +, Karol Nowak wrote:
> > Hi Corey,
> > 
> > 
> > 
> > Have you got a chance to look at the I2C code?
> 
> No, I have not.  I've been pretty busy with work stuff.
> 
> > 
> > 
> > I imagine that the I2C code has to stop the emulation and keep the main 
> > thread running so that it can receive events. Is there something like that?
> 
> No, not really.
> 
> Right now an I2C host device will submit its transactions on the virtual
> bus and get an immediate response.  Basically, they call send() for all
> the bytes and then call recv() to get the response.  Your additions
> would require blocking on each send() and recv() until the other end of
> the connection responded.
> 
> The fundamental thing that must happen is that the individual I2C host
> devices need to be modified to submit their transactions asynchronously,
> they do a send_async(), to write bytes, and have some asyncronous way to
> receive the bytes (which is going to be a little tricky, I think).
> 
> There is already a send_async() function available.  This is added so
> that external devices can bus master, but would be usable for a host
> device to talk to a slave.

I should also add that I'm not 100% sure that a blocking interface is
just a bad idea.  I am fairly sure it would be a bad idea for
production, but for test systems it might be ok.

The trouble is that once you put something in for test systems, someone
will want to use it for production systems.  So I would really rather do
it right the first time.  But other QEMU developers that are more
experienced than me can convince me otherwise.

-corey

> 
> -corey
> 
> > 
> > 
> > 
> > Karol
> > 
> > 
> > 
> > From: Corey Minyard  on behalf of Corey Minyard 
> > 
> > Sent: Wednesday, April 19, 2023 4:35 PM
> > To: Karol Nowak 
> > Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> > ; c...@kaod.org 
> > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c 
> > ops outside
> > 
> > ⚠ This email originates from outside the organization or the sender could 
> > not be verified.
> > 
> > On Wed, Apr 19, 2023 at 12:40:36PM +, Karol Nowak wrote:
> > > Hi Corey,
> > >
> > > I looked at hw/ipmi/ipmi_bmc_extern.c and I conclude that it is a bit 
> > > different case than in my one. The function 
> > > ipmi_bmc_extern_handle_command() does not wait for a response; the 
> > > response comes in a chardev-handler. If I am not mistaken, in my case I 
> > > have to arm a timer to avoid hanging of QEMU, somehow stop execution of 
> > > i2c-handler(recv/send/event), wait for a response in a chardev handler 
> > > and then resume an execution of i2c-handler when data arrive.
> > 
> > Yes, something like that.  Hopefully a timer isn't necessary (well, it's
> > necessary to make sure you don't sit there forever, but it shouldn't be
> > the main way to do it), you can use the response from the other end to
> > resume execution.
> > 
> > You don't stop execution of the i2c handler, either.  You aren't blocked
> > waiting for a response, that's the big thing you cannot do.  You send
> > the message and return.  When the response comes in, you do what the
> > hardware would do in that case.
> > 
> > I need to spend a little time looking at the I2C code.  I assume it
> > would need some adjustment to accommodate this.
> > 
> > -corey
> > 
> > >
> > > Best regards,
> > > Karol
> > >
> > >
> > >
> > > 
> > > From: Corey Minyard  on behalf of Corey Minyard 
> > > 
> > > Sent: Monday, April 17, 2023 4:34 PM
> > > To: Karol Nowak 
> > > Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> > > ; c...@kaod.org 
> > > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c 
> > > ops outside
> > >
> > > [You don't often get email from miny...@acm.org. Learn why this is 
> > > important at https://aka.ms/LearnAboutSenderIdentification ]
> > >
> > > ⚠ This email originates from outside the organization or the sender could 
> > > not be verified.
> > >
> > > On Mon, Apr 17, 2023 at 10:18:08AM +, Karol Nowak wrote:
> > > > Hi Corey,
> > > >
> > > >
> > > > thank you for your response.
> > >

Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside

2023-04-24 Thread Corey Minyard
On Mon, Apr 24, 2023 at 02:09:50PM +, Karol Nowak wrote:
> Hi Corey,
> 
> 
> 
> Have you got a chance to look at the I2C code?

No, I have not.  I've been pretty busy with work stuff.

> 
> 
> I imagine that the I2C code has to stop the emulation and keep the main 
> thread running so that it can receive events. Is there something like that?

No, not really.

Right now an I2C host device will submit its transactions on the virtual
bus and get an immediate response.  Basically, they call send() for all
the bytes and then call recv() to get the response.  Your additions
would require blocking on each send() and recv() until the other end of
the connection responded.

The fundamental thing that must happen is that the individual I2C host
devices need to be modified to submit their transactions asynchronously,
they do a send_async(), to write bytes, and have some asyncronous way to
receive the bytes (which is going to be a little tricky, I think).

There is already a send_async() function available.  This is added so
that external devices can bus master, but would be usable for a host
device to talk to a slave.

-corey

> 
> 
> 
> Karol
> 
> 
> ________
> From: Corey Minyard  on behalf of Corey Minyard 
> 
> Sent: Wednesday, April 19, 2023 4:35 PM
> To: Karol Nowak 
> Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> ; c...@kaod.org 
> Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops 
> outside
> 
> ⚠ This email originates from outside the organization or the sender could not 
> be verified.
> 
> On Wed, Apr 19, 2023 at 12:40:36PM +, Karol Nowak wrote:
> > Hi Corey,
> >
> > I looked at hw/ipmi/ipmi_bmc_extern.c and I conclude that it is a bit 
> > different case than in my one. The function 
> > ipmi_bmc_extern_handle_command() does not wait for a response; the response 
> > comes in a chardev-handler. If I am not mistaken, in my case I have to arm 
> > a timer to avoid hanging of QEMU, somehow stop execution of 
> > i2c-handler(recv/send/event), wait for a response in a chardev handler and 
> > then resume an execution of i2c-handler when data arrive.
> 
> Yes, something like that.  Hopefully a timer isn't necessary (well, it's
> necessary to make sure you don't sit there forever, but it shouldn't be
> the main way to do it), you can use the response from the other end to
> resume execution.
> 
> You don't stop execution of the i2c handler, either.  You aren't blocked
> waiting for a response, that's the big thing you cannot do.  You send
> the message and return.  When the response comes in, you do what the
> hardware would do in that case.
> 
> I need to spend a little time looking at the I2C code.  I assume it
> would need some adjustment to accommodate this.
> 
> -corey
> 
> >
> > Best regards,
> > Karol
> >
> >
> >
> > 
> > From: Corey Minyard  on behalf of Corey Minyard 
> > 
> > Sent: Monday, April 17, 2023 4:34 PM
> > To: Karol Nowak 
> > Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> > ; c...@kaod.org 
> > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c 
> > ops outside
> >
> > [You don't often get email from miny...@acm.org. Learn why this is 
> > important at https://aka.ms/LearnAboutSenderIdentification ]
> >
> > ⚠ This email originates from outside the organization or the sender could 
> > not be verified.
> >
> > On Mon, Apr 17, 2023 at 10:18:08AM +, Karol Nowak wrote:
> > > Hi Corey,
> > >
> > >
> > > thank you for your response.
> > >
> > >
> > > Could you give me some hints how to make IO operations non-blocking in 
> > > QEMU? Is there a code reference in the source code of QEMU I could use?
> > >
> >
> > You can look at hw/ipmi/ipmi_bmc_extern.c for an example.
> >
> > -corey
> >
> > >
> > > Karol
> > >
> > >
> > > 
> > > From: Corey Minyard  on behalf of Corey Minyard 
> > > 
> > > Sent: Thursday, March 23, 2023 5:03 PM
> > > To: Karol Nowak 
> > > Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> > > ; c...@kaod.org 
> > > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c 
> > > ops outside
> > >
> > > [You don't often get email from miny...@acm.org. Learn why this is 
> > > important at https://aka.ms/LearnAboutSenderIdentification ]
> > >
> > > ⚠ This email origi

Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside

2023-04-19 Thread Corey Minyard
On Wed, Apr 19, 2023 at 12:40:36PM +, Karol Nowak wrote:
> Hi Corey,
> 
> I looked at hw/ipmi/ipmi_bmc_extern.c and I conclude that it is a bit 
> different case than in my one. The function ipmi_bmc_extern_handle_command() 
> does not wait for a response; the response comes in a chardev-handler. If I 
> am not mistaken, in my case I have to arm a timer to avoid hanging of QEMU, 
> somehow stop execution of i2c-handler(recv/send/event), wait for a response 
> in a chardev handler and then resume an execution of i2c-handler when data 
> arrive.

Yes, something like that.  Hopefully a timer isn't necessary (well, it's
necessary to make sure you don't sit there forever, but it shouldn't be
the main way to do it), you can use the response from the other end to
resume execution.

You don't stop execution of the i2c handler, either.  You aren't blocked
waiting for a response, that's the big thing you cannot do.  You send
the message and return.  When the response comes in, you do what the
hardware would do in that case.

I need to spend a little time looking at the I2C code.  I assume it
would need some adjustment to accommodate this.

-corey

> 
> Best regards,
> Karol
> 
> 
> 
> 
> From: Corey Minyard  on behalf of Corey Minyard 
> 
> Sent: Monday, April 17, 2023 4:34 PM
> To: Karol Nowak 
> Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> ; c...@kaod.org 
> Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops 
> outside
> 
> [You don't often get email from miny...@acm.org. Learn why this is important 
> at https://aka.ms/LearnAboutSenderIdentification ]
> 
> ⚠ This email originates from outside the organization or the sender could not 
> be verified.
> 
> On Mon, Apr 17, 2023 at 10:18:08AM +, Karol Nowak wrote:
> > Hi Corey,
> >
> >
> > thank you for your response.
> >
> >
> > Could you give me some hints how to make IO operations non-blocking in 
> > QEMU? Is there a code reference in the source code of QEMU I could use?
> >
> 
> You can look at hw/ipmi/ipmi_bmc_extern.c for an example.
> 
> -corey
> 
> >
> > Karol
> >
> >
> > 
> > From: Corey Minyard  on behalf of Corey Minyard 
> > 
> > Sent: Thursday, March 23, 2023 5:03 PM
> > To: Karol Nowak 
> > Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> > ; c...@kaod.org 
> > Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c 
> > ops outside
> >
> > [You don't often get email from miny...@acm.org. Learn why this is 
> > important at https://aka.ms/LearnAboutSenderIdentification ]
> >
> > ⚠ This email originates from outside the organization or the sender could 
> > not be verified.
> >
> > On Thu, Mar 23, 2023 at 10:09:02AM +, Karol Nowak wrote:
> > > Hi,
> > >
> > > There is a feature I prepared which may be practical for some QEMU users.
> > >
> > > The feature provides a new I2C slave device
> > > that prepares a message depending what i2c-slave callback was called
> > > and sends it outside of QEMU through the character device to a client
> > > that receives that message, processes it and send back a response.
> > > Thanks to that feature,
> > > a user can emulate a logic of I2C device outside of QEMU.
> > > The message contains 3 bytes ended with CRLF: BBB\r\l
> > > Basically, the I2C slave does 4 steps in each i2c-slave callback:
> > > * encode
> > > * send
> > > * receive
> > > * decode
> > >
> > > I put more details in esp32_i2c_tcp_slave.c
> > > and also provided a demo client in python that uses TCP.
> > >
> > > The feature still needs some improvements, but the question is:
> > > * Do you find the feature useful?
> >
> > Someone else has proposed this before with a patch, and it was actually
> > pretty complete and mostly ok, but I pointed out an issue and never
> > heard back from them.  This feature is something that might be nice.  As
> > you say, this needs some improvements.  Some I would point out:
> >
> > Obviously this can't be named esp32, it needs to be general.
> >
> > All the I/O (reading and writing) has to be non-blocking.  I/O handling
> > in qemu is single-threaded, if you block anywhere you basically stop
> > qemu.  You need to implement something where whatever you do (like
> > handling a NAK, for instance) it doesn't block qemu.
> >
> > The protocol you have implemented is basically an extens

Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside

2023-04-17 Thread Corey Minyard
On Mon, Apr 17, 2023 at 10:18:08AM +, Karol Nowak wrote:
> Hi Corey,
> 
> 
> thank you for your response.
> 
> 
> Could you give me some hints how to make IO operations non-blocking in QEMU? 
> Is there a code reference in the source code of QEMU I could use?
> 

You can look at hw/ipmi/ipmi_bmc_extern.c for an example.

-corey

> 
> Karol
> 
> 
> ____
> From: Corey Minyard  on behalf of Corey Minyard 
> 
> Sent: Thursday, March 23, 2023 5:03 PM
> To: Karol Nowak 
> Cc: qemu-devel@nongnu.org ; phi...@linaro.org 
> ; c...@kaod.org 
> Subject: Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops 
> outside
> 
> [You don't often get email from miny...@acm.org. Learn why this is important 
> at https://aka.ms/LearnAboutSenderIdentification ]
> 
> ⚠ This email originates from outside the organization or the sender could not 
> be verified.
> 
> On Thu, Mar 23, 2023 at 10:09:02AM +, Karol Nowak wrote:
> > Hi,
> >
> > There is a feature I prepared which may be practical for some QEMU users.
> >
> > The feature provides a new I2C slave device
> > that prepares a message depending what i2c-slave callback was called
> > and sends it outside of QEMU through the character device to a client
> > that receives that message, processes it and send back a response.
> > Thanks to that feature,
> > a user can emulate a logic of I2C device outside of QEMU.
> > The message contains 3 bytes ended with CRLF: BBB\r\l
> > Basically, the I2C slave does 4 steps in each i2c-slave callback:
> > * encode
> > * send
> > * receive
> > * decode
> >
> > I put more details in esp32_i2c_tcp_slave.c
> > and also provided a demo client in python that uses TCP.
> >
> > The feature still needs some improvements, but the question is:
> > * Do you find the feature useful?
> 
> Someone else has proposed this before with a patch, and it was actually
> pretty complete and mostly ok, but I pointed out an issue and never
> heard back from them.  This feature is something that might be nice.  As
> you say, this needs some improvements.  Some I would point out:
> 
> Obviously this can't be named esp32, it needs to be general.
> 
> All the I/O (reading and writing) has to be non-blocking.  I/O handling
> in qemu is single-threaded, if you block anywhere you basically stop
> qemu.  You need to implement something where whatever you do (like
> handling a NAK, for instance) it doesn't block qemu.
> 
> The protocol you have implemented is basically an extension of the QEMU
> protocol.  That's probably not ideal, it would be best to think about a
> general protocol for extending I2C over a TCP connection.  A lot of the
> details of the QEMU implementation is probably not necessary over a TCP
> connection.
> 
> -corey
> 
> >
> >
> > NOTE:
> > The feature originally was prepared for espressif/qemu
> > that's why there are references to esp32
> >
> >
> > Signed-off-by: Karol Nowak 
> > ---
> >  hw/misc/esp32_i2c_tcp_slave.c | 288 ++
> >  include/hw/misc/esp32_i2c_tcp_slave.h |  19 ++
> >  tests/i2c-tcp-demo/i2c-tcp-demo.py| 133 
> >  3 files changed, 440 insertions(+)
> >  create mode 100644 hw/misc/esp32_i2c_tcp_slave.c
> >  create mode 100644 include/hw/misc/esp32_i2c_tcp_slave.h
> >  create mode 100644 tests/i2c-tcp-demo/i2c-tcp-demo.py
> >
> > diff --git a/hw/misc/esp32_i2c_tcp_slave.c b/hw/misc/esp32_i2c_tcp_slave.c
> > new file mode 100644
> > index 00..db3b6d366a
> > --- /dev/null
> > +++ b/hw/misc/esp32_i2c_tcp_slave.c
> > @@ -0,0 +1,288 @@
> > +#include "qemu/osdep.h"
> > +#include "qemu/error-report.h"
> > +#include "qemu/log.h"
> > +#include "hw/i2c/i2c.h"
> > +#include "hw/irq.h"
> > +#include "hw/misc/esp32_i2c_tcp_slave.h"
> > +#include "qemu/module.h"
> > +
> > +#include "qapi/qmp/json-writer.h"
> > +#include "chardev/char-fe.h"
> > +#include "io/channel-socket.h"
> > +#include "chardev/char-io.h"
> > +#include "chardev/char-socket.h"
> > +#include "qapi/error.h"
> > +
> > +/*
> > + * Description:
> > + * To allow to emulate a I2C slave device which is not supported by QEMU,
> > + * a new I2C slave device was created that encapsulates I2C operations
> > + * and passes them through a selected cha

Re: [for-8.0] hw/i2c/allwinner-i2c: Fix subclassing of TYPE_AW_I2C_SUN6I

2023-04-11 Thread Corey Minyard
On Tue, Apr 11, 2023 at 11:31:06AM +0100, Peter Maydell wrote:
> In commit 8461bfdca9c we added the TYPE_AW_I2C_SUN6I, which is a
> minor variant of the TYPE_AW_I2C device.  However, we didn't quite
> get the class hierarchy right.  We made the new TYPE_AW_I2C_SUN6I a
> subclass of TYPE_SYS_BUS_DEVICE, which means that you can't validly
> use a pointer to this object via the AW_I2C() cast macro, which
> insists on having something that is an instance of TYPE_AW_I2C or
> some subclass of that type.
> 
> This only causes a problem if QOM cast macro debugging is enabled;
> that is supposed to be on by default, but a mistake in the meson
> conversion in commit c55cf6ab03f4c meant that it ended up disabled by
> default, and we didn't catch this bug.
> 
> Fix the problem by arranging the classes in the same way we do for
> TYPE_PL011 and TYPE_PL011_LUMINARY in hw/char/pl011.c -- make the
> variant class be a subclass of the "normal" version of the device.
> 
> This was reported in
> https://gitlab.com/qemu-project/qemu/-/issues/1586 but this fix alone
> isn't sufficient, as there is a separate cast-related issue in the
> CXL code in pci_expander_bridge.c.
> 
> Signed-off-by: Peter Maydell 

Looks correct ot me.

Reviewed-by: Corey Minyard 

> ---
>  hw/i2c/allwinner-i2c.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/hw/i2c/allwinner-i2c.c b/hw/i2c/allwinner-i2c.c
> index f24c3ac6f0c..9e8efa1d63f 100644
> --- a/hw/i2c/allwinner-i2c.c
> +++ b/hw/i2c/allwinner-i2c.c
> @@ -466,10 +466,8 @@ static void allwinner_i2c_sun6i_init(Object *obj)
>  
>  static const TypeInfo allwinner_i2c_sun6i_type_info = {
>  .name = TYPE_AW_I2C_SUN6I,
> -.parent = TYPE_SYS_BUS_DEVICE,
> -.instance_size = sizeof(AWI2CState),
> +.parent = TYPE_AW_I2C,
>  .instance_init = allwinner_i2c_sun6i_init,
> -.class_init = allwinner_i2c_class_init,
>  };
>  
>  static void allwinner_i2c_register_types(void)
> -- 
> 2.34.1
> 
> 



Re: [PATCH v12 3/3] tpm: Add support for TPM device over I2C bus

2023-04-01 Thread Corey Minyard
On Fri, Mar 31, 2023 at 11:13:19AM -0500, Ninad Palsule wrote:
> From: Ninad Palsule 
> 
> Qemu already supports devices attached to ISA and sysbus. This drop adds
> support for the I2C bus attached TPM devices. I2C model only supports
> TPM2 protocol.
> 
> This commit includes changes for the common code.
> - Added I2C emulation model. Logic was added in the model to temporarily
>   cache the data as I2C interface works per byte basis.
> - New tpm type "tpm-tis-i2c" added for I2C support. The user has to
>   provide this string on command line.

There is a stray blank line near the end of tpm_tis_i2c_send(), and
above it the if statement

+if ((i2cst->offset == 0) ||
+(i2cst->data[0] != TPM_I2C_REG_DATA_FIFO)) {
+i2cst->data[i2cst->offset++] = data;

is a bit hard to read because of the indention.  But those are really
minor nits, I didn't see anything really wrong with this.

Reviewed-by: Corey Minyard 


> 
> Testing:
>   TPM I2C device module is tested using SWTPM (software based TPM
>   package). Qemu uses the rainier machine and is connected to swtpm over
>   the socket interface.
> 
>   The command to start swtpm is as follows:
>   $ swtpm socket --tpmstate dir=/tmp/mytpm1\
>  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock  \
>  --tpm2 --log level=100
> 
>   The command to start qemu is as follows:
>   $ qemu-system-arm -M rainier-bmc -nographic \
> -kernel ${IMAGEPATH}/fitImage-linux.bin \
> -dtb ${IMAGEPATH}/aspeed-bmc-ibm-rainier.dtb \
> -initrd ${IMAGEPATH}/obmc-phosphor-initramfs.rootfs.cpio.xz \
> -drive 
> file=${IMAGEPATH}/obmc-phosphor-image.rootfs.wic.qcow2,if=sd,index=2 \
> -net nic -net 
> user,hostfwd=:127.0.0.1:-:22,hostfwd=:127.0.0.1:2443-:443 \
> -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
> -tpmdev emulator,id=tpm0,chardev=chrtpm \
> -device tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e
> 
> Signed-off-by: Ninad Palsule 
> Reviewed-by: Stefan Berger 
> Tested-by: Stefan Berger 
> Reviewed-by: Cédric Le Goater 
> Reviewed-by: Joel Stanley 
> Tested-by: Joel Stanley 
> ---
> V2:
> Incorporated Stephen's review comments.
> - Handled checksum related register in I2C layer
> - Defined I2C interface capabilities and return those instead of
>   capabilities from TPM TIS. Add required capabilities from TIS.
> - Do not cache FIFO data in the I2C layer.
> - Make sure that Device address change register is not passed to I2C
>   layer as capability indicate that it is not supported.
> - Added boundary checks.
> - Make sure that bits 26-31 are zeroed for the TPM_STS register on read
> - Updated Kconfig files for new define.
> 
> ---
> V3:
> - Moved processing of register TPM_I2C_LOC_SEL in the I2C. So I2C layer
>   remembers the locality and pass it to TIS on each read/write.
> - The write data is no more cached in the I2C layer so the buffer size
>   is reduced to 16 bytes.
> - Checksum registers are now managed by the I2C layer. Added new
>   function in TIS layer to return the checksum and used that to process
>   the request.
> - Now 2-4 byte register value will be passed to TIS layer in a single
>   write call instead of 1 byte at a time. Added functions to convert
>   between little endian stream of bytes to single 32 bit unsigned
>   integer. Similarly 32  bit integer to stream of bytes.
> - Added restriction on device change register.
> - Replace few if-else statement with switch statement for clarity.
> - Log warning when unknown register is received.
> - Moved all register definations to acpi/tmp.h
> 
> ---
> V4:
> Incorporated review comments from Cedric and Stefan.
> - Reduced data[] size from 16 byte to 5 bytes.
> - Added register name in the mapping table which can be used for
>   tracing.
> - Removed the endian conversion functions instead used simple logic
>   provided by Stefan.
> - Rename I2C registers to reduce the length.
> - Added traces for send, recv and event functions. You can turn on trace
>   on command line by using "-trace "tpm_tis_i2c*" option.
> 
> ---
> V5:
> Fixed issues reported by Stefan's test.
> - Added mask for the INT_ENABLE register.
> - Use correct TIS register for reading interrupt capability.
> - Cleanup how register is converted from I2C to TIS and also saved
>   information like tis_addr and register name in the i2cst so that we
>   can only convert it once on i2c_send.
> - Trace register number for unknown registers.
> 
> ---
> V6:
> Fixed review comments from Stefan.
> - Fixed some variable size.
> - Removed u

Re: [PATCH 7/7] tests/qtest: add tests for ADM1266

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:56AM +, Titus Rwantare wrote:
>   The ADM1266 can have string fields written by the driver, so
>   it's worth specifically testing.
> 
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 

Acked-by: Corey Minyard 

> ---
>  tests/qtest/adm1266-test.c | 123 +
>  tests/qtest/meson.build|   1 +
>  2 files changed, 124 insertions(+)
>  create mode 100644 tests/qtest/adm1266-test.c
> 
> diff --git a/tests/qtest/adm1266-test.c b/tests/qtest/adm1266-test.c
> new file mode 100644
> index 00..6431a21de6
> --- /dev/null
> +++ b/tests/qtest/adm1266-test.c
> @@ -0,0 +1,123 @@
> +/*
> + * Analog Devices ADM1266 Cascadable Super Sequencer with Margin Control and
> + * Fault Recording with PMBus
> + *
> + * Copyright 2022 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include 
> +#include "hw/i2c/pmbus_device.h"
> +#include "libqtest-single.h"
> +#include "libqos/qgraph.h"
> +#include "libqos/i2c.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qnum.h"
> +#include "qemu/bitops.h"
> +
> +#define TEST_ID "adm1266-test"
> +#define TEST_ADDR (0x12)
> +
> +#define ADM1266_BLACKBOX_CONFIG 0xD3
> +#define ADM1266_PDIO_CONFIG 0xD4
> +#define ADM1266_READ_STATE  0xD9
> +#define ADM1266_READ_BLACKBOX   0xDE
> +#define ADM1266_SET_RTC 0xDF
> +#define ADM1266_GPIO_SYNC_CONFIGURATION 0xE1
> +#define ADM1266_BLACKBOX_INFORMATION0xE6
> +#define ADM1266_PDIO_STATUS 0xE9
> +#define ADM1266_GPIO_STATUS 0xEA
> +
> +/* Defaults */
> +#define ADM1266_OPERATION_DEFAULT   0x80
> +#define ADM1266_CAPABILITY_DEFAULT  0xA0
> +#define ADM1266_CAPABILITY_NO_PEC   0x20
> +#define ADM1266_PMBUS_REVISION_DEFAULT  0x22
> +#define ADM1266_MFR_ID_DEFAULT  "ADI"
> +#define ADM1266_MFR_ID_DEFAULT_LEN  32
> +#define ADM1266_MFR_MODEL_DEFAULT   "ADM1266-A1"
> +#define ADM1266_MFR_MODEL_DEFAULT_LEN   32
> +#define ADM1266_MFR_REVISION_DEFAULT"25"
> +#define ADM1266_MFR_REVISION_DEFAULT_LEN8
> +#define TEST_STRING_A   "a sample"
> +#define TEST_STRING_B   "b sample"
> +#define TEST_STRING_C   "rev c"
> +
> +static void compare_string(QI2CDevice *i2cdev, uint8_t reg,
> +   const char *test_str)
> +{
> +uint8_t len = i2c_get8(i2cdev, reg);
> +char i2c_str[SMBUS_DATA_MAX_LEN] = {0};
> +
> +i2c_read_block(i2cdev, reg, (uint8_t *)i2c_str, len);
> +g_assert_cmpstr(i2c_str, ==, test_str);
> +}
> +
> +static void write_and_compare_string(QI2CDevice *i2cdev, uint8_t reg,
> + const char *test_str, uint8_t len)
> +{
> +char buf[SMBUS_DATA_MAX_LEN] = {0};
> +buf[0] = len;
> +strncpy(buf + 1, test_str, len);
> +i2c_write_block(i2cdev, reg, (uint8_t *)buf, len + 1);
> +compare_string(i2cdev, reg, test_str);
> +}
> +
> +static void test_defaults(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +uint16_t i2c_value;
> +QI2CDevice *i2cdev = (QI2CDevice *)obj;
> +
> +i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
> +g_assert_cmphex(i2c_value, ==, ADM1266_OPERATION_DEFAULT);
> +
> +i2c_value = i2c_get8(i2cdev, PMBUS_REVISION);
> +g_assert_cmphex(i2c_value, ==, ADM1266_PMBUS_REVISION_DEFAULT);
> +
> +compare_string(i2cdev, PMBUS_MFR_ID, ADM1266_MFR_ID_DEFAULT);
> +compare_string(i2cdev, PMBUS_MFR_MODEL, ADM1266_MFR_MODEL_DEFAULT);
> +compare_string(i2cdev, PMBUS_MFR_REVISION, ADM1266_MFR_REVISION_DEFAULT);
> +}
> +
> +/* test r/w registers */
> +static void test_rw_regs(void *obj, void *data, QGuestAllocator *alloc)
> +{
> +QI2CDevice *i2cdev = (QI2CDevice *)obj;
> +
> +/* empty strings */
> +i2c_set8(i2cdev, PMBUS_MFR_ID, 0);
> +compare_string(i2cdev, PMBUS_MFR_ID, "");
> +
> +i2c_set8(i2cdev, PMBUS_MFR_MODEL, 0);
> +compare_string(i2cdev, PMBUS_MFR_MODEL, "");
> +
> +i2c_set8(i2cdev, PMBUS_MFR_REVISION, 0);
> +compare_string(i2cdev, PMBUS_MFR_REVISION, "");
> +
> +/* test strings */
> +write_and_compare_string(i2cdev, PMBUS_MFR_ID, TEST_STRING_A,
> + sizeo

Re: [PATCH 6/7] hw/sensor: add ADM1266 device model

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:55AM +, Titus Rwantare wrote:
>   The ADM1266 is a cascadable super sequencer with margin control and
>   fault recording.

This sounds like serious marketing-speak :).  I looked up the chip and
yes, that's what they say about it.

>   This commit adds basic support for its PMBus commands and models
>   the identification registers that can be modified in a firmware
>   update.
> 
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 

Looks good. 

Acked-by: Corey Minyard 

> ---
>  hw/arm/Kconfig|   1 +
>  hw/sensor/Kconfig |   5 +
>  hw/sensor/adm1266.c   | 255 ++
>  hw/sensor/meson.build |   1 +
>  4 files changed, 262 insertions(+)
>  create mode 100644 hw/sensor/adm1266.c
> 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index b5aed4aff5..4e44a7451d 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -407,6 +407,7 @@ config XLNX_VERSAL
>  config NPCM7XX
>  bool
>  select A9MPCORE
> +select ADM1266
>  select ADM1272
>  select ARM_GIC
>  select SMBUS
> diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
> index e03bd09b50..bc6331b4ab 100644
> --- a/hw/sensor/Kconfig
> +++ b/hw/sensor/Kconfig
> @@ -22,6 +22,11 @@ config ADM1272
>  bool
>  depends on I2C
>  
> +config ADM1266
> +bool
> +depends on PMBUS
> +default y if PMBUS
> +
>  config MAX34451
>  bool
>  depends on I2C
> diff --git a/hw/sensor/adm1266.c b/hw/sensor/adm1266.c
> new file mode 100644
> index 00..0745b12b1d
> --- /dev/null
> +++ b/hw/sensor/adm1266.c
> @@ -0,0 +1,255 @@
> +/*
> + * Analog Devices ADM1266 Cascadable Super Sequencer with Margin Control and
> + * Fault Recording with PMBus
> + *
> + * 
> https://www.analog.com/media/en/technical-documentation/data-sheets/adm1266.pdf
> + *
> + * Copyright 2023 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include 
> +#include "hw/i2c/pmbus_device.h"
> +#include "hw/irq.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +
> +#define TYPE_ADM1266 "adm1266"
> +OBJECT_DECLARE_SIMPLE_TYPE(ADM1266State, ADM1266)
> +
> +#define ADM1266_BLACKBOX_CONFIG 0xD3
> +#define ADM1266_PDIO_CONFIG 0xD4
> +#define ADM1266_READ_STATE  0xD9
> +#define ADM1266_READ_BLACKBOX   0xDE
> +#define ADM1266_SET_RTC 0xDF
> +#define ADM1266_GPIO_SYNC_CONFIGURATION 0xE1
> +#define ADM1266_BLACKBOX_INFORMATION0xE6
> +#define ADM1266_PDIO_STATUS 0xE9
> +#define ADM1266_GPIO_STATUS 0xEA
> +
> +/* Defaults */
> +#define ADM1266_OPERATION_DEFAULT   0x80
> +#define ADM1266_CAPABILITY_DEFAULT  0xA0
> +#define ADM1266_CAPABILITY_NO_PEC   0x20
> +#define ADM1266_PMBUS_REVISION_DEFAULT  0x22
> +#define ADM1266_MFR_ID_DEFAULT  "ADI"
> +#define ADM1266_MFR_ID_DEFAULT_LEN  32
> +#define ADM1266_MFR_MODEL_DEFAULT   "ADM1266-A1"
> +#define ADM1266_MFR_MODEL_DEFAULT_LEN   32
> +#define ADM1266_MFR_REVISION_DEFAULT"25"
> +#define ADM1266_MFR_REVISION_DEFAULT_LEN8
> +
> +#define ADM1266_NUM_PAGES   17
> +/**
> + * PAGE Index
> + * Page 0 VH1.
> + * Page 1 VH2.
> + * Page 2 VH3.
> + * Page 3 VH4.
> + * Page 4 VP1.
> + * Page 5 VP2.
> + * Page 6 VP3.
> + * Page 7 VP4.
> + * Page 8 VP5.
> + * Page 9 VP6.
> + * Page 10 VP7.
> + * Page 11 VP8.
> + * Page 12 VP9.
> + * Page 13 VP10.
> + * Page 14 VP11.
> + * Page 15 VP12.
> + * Page 16 VP13.
> + */
> +typedef struct ADM1266State {
> +PMBusDevice parent;
> +
> +char mfr_id[32];
> +char mfr_model[32];
> +char mfr_rev[8];
> +} ADM1266State;
> +
> +static const uint8_t adm1266_ic_device_id[] = {0x03, 0x41, 0x12, 0x66};
> +static const uint8_t adm1266_ic_device_rev[] = {0x08, 0x01, 0x08, 0x07, 0x0,
> +0x0, 0x07, 0x41, 0x30};
> +
> +static void adm1266_exit_reset(Object *obj)
> +{
> +ADM1266State *s = ADM1266(obj);
> +PMBusDevice *pmdev = PMBUS_DEVICE(obj);
> +
> +pmdev->page = 0;
> +pmdev->capability = ADM1266_CAPABILITY_NO_PEC;
> +
> +for (int i = 0; i < ADM1266_NUM_PAGES; i++)

Re: [PATCH 5/7] hw/i2c: pmbus: add VCAP register

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:54AM +, Titus Rwantare wrote:
> VCAP is a register for devices with energy storage capacitors.
> 
> Reviewed-by: Benjamin Streb 
> Signed-off-by: Titus Rwantare 

Acked-by: Corey Minyard 

> ---
>  hw/i2c/pmbus_device.c | 8 
>  include/hw/i2c/pmbus_device.h | 1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index 18e629eaac..ef0314a913 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -903,6 +903,14 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  }
>  break;
>  
> +case PMBUS_READ_VCAP: /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_VCAP) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_vcap);
> +} else {
> +goto passthough;
> +}
> +break;
> +
>  case PMBUS_READ_VOUT: /* Read-Only word */
>  if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
>  pmbus_send16(pmdev, pmdev->pages[index].read_vout);
> diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> index ad431bdc7c..f195c11384 100644
> --- a/include/hw/i2c/pmbus_device.h
> +++ b/include/hw/i2c/pmbus_device.h
> @@ -243,6 +243,7 @@ OBJECT_DECLARE_TYPE(PMBusDevice, PMBusDeviceClass,
>  #define PB_HAS_VIN_RATING  BIT_ULL(13)
>  #define PB_HAS_VOUT_RATING BIT_ULL(14)
>  #define PB_HAS_VOUT_MODE   BIT_ULL(15)
> +#define PB_HAS_VCAPBIT_ULL(16)
>  #define PB_HAS_IOUTBIT_ULL(21)
>  #define PB_HAS_IIN BIT_ULL(22)
>  #define PB_HAS_IOUT_RATING BIT_ULL(23)
> -- 
> 2.40.0.423.gd6c402a77b-goog
> 



Re: [PATCH 4/7] hw/i2c: pmbus: block uninitialised string reads

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:53AM +, Titus Rwantare wrote:
> Devices models calling pmbus_send_string can't be relied upon to
> send a non-zero pointer. This logs an error and doesn't segfault.
> 
> Reviewed-by: Patrick Venture 
> Signed-off-by: Titus Rwantare 

Acked-by: Corey Minyard 

> ---
>  hw/i2c/pmbus_device.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index bb42e410b4..18e629eaac 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -94,6 +94,13 @@ void pmbus_send64(PMBusDevice *pmdev, uint64_t data)
>  
>  void pmbus_send_string(PMBusDevice *pmdev, const char *data)
>  {
> +if (!data) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: %s: uninitialised read from 0x%02x\n",
> +  __func__, DEVICE(pmdev)->canonical_path, pmdev->code);
> +return;
> +}
> +
>  size_t len = strlen(data);
>  g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN);
>  pmdev->out_buf[len + pmdev->out_buf_len] = len;
> -- 
> 2.40.0.423.gd6c402a77b-goog
> 



Re: [PATCH 3/7] hw/i2c: pmbus: add fan support

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:52AM +, Titus Rwantare wrote:
> PMBus devices may integrate fans whose operation is configurable
> over PMBus. This commit allows the driver to read and write the
> fan control registers but does not model the operation of fans.
> 
> Reviewed-by: Stephen Longfield 
> Signed-off-by: Titus Rwantare 

Acked-by: Corey Minyard 

> ---
>  hw/i2c/pmbus_device.c | 176 ++
>  include/hw/i2c/pmbus_device.h |   1 +
>  2 files changed, 177 insertions(+)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index 02647769cd..bb42e410b4 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -490,6 +490,54 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  }
>  break;
>  
> +case PMBUS_FAN_CONFIG_1_2:/* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].fan_config_1_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_1: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_1);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_2: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_CONFIG_3_4:/* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].fan_config_3_4);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_3: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_3);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_4: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_4);
> +} else {
> +goto passthough;
> +}
> +break;
> +
>  case PMBUS_VOUT_OV_FAULT_LIMIT:   /* R/W word */
>  if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
>  pmbus_send16(pmdev, pmdev->pages[index].vout_ov_fault_limit);
> @@ -800,6 +848,22 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  pmbus_send8(pmdev, pmdev->pages[index].status_mfr_specific);
>  break;
>  
> +case PMBUS_STATUS_FANS_1_2:   /* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].status_fans_1_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_STATUS_FANS_3_4:   /* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].status_fans_3_4);
> +} else {
> +goto passthough;
> +}
> +break;
> +
>  case PMBUS_READ_EIN:  /* Read-Only block 5 bytes */
>  if (pmdev->pages[index].page_flags & PB_HAS_EIN) {
>  pmbus_send(pmdev, pmdev->pages[index].read_ein, 5);
> @@ -872,6 +936,54 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  }
>  break;
>  
> +case PMBUS_READ_FAN_SPEED_1:  /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_1);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_READ_FAN_SPEED_2:  /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_READ_FAN_SPEED_3:  /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_3);
> +} els

Re: [PATCH 2/7] hw/i2c: pmbus: add vout mode bitfields

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:51AM +, Titus Rwantare wrote:
> The VOUT_MODE command is described in the PMBus Specification,
> Part II, Ver 1.3 Section 8.3
> 
> VOUT_MODE has a three bit mode and 4 bit parameter, the three bit
> mode determines whether voltages are formatted as uint16, uint16,
> VID, and Direct modes. VID and Direct modes use the remaining 5 bits
> to scale the voltage readings.
> 
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 

Ok, I see the new sensor later.

Acked-by: Corey Minyard 

> ---
>  include/hw/i2c/pmbus_device.h | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> index 7dc00cc4d9..2e95164aa1 100644
> --- a/include/hw/i2c/pmbus_device.h
> +++ b/include/hw/i2c/pmbus_device.h
> @@ -444,6 +444,14 @@ typedef struct PMBusCoefficients {
>  int32_t R; /* exponent */
>  } PMBusCoefficients;
>  
> +/**
> + * VOUT_Mode bit fields
> + */
> +typedef struct PMBusVoutMode {
> +uint8_t  mode:3;
> +int8_t   exp:5;
> +} PMBusVoutMode;
> +
>  /**
>   * Convert sensor values to direct mode format
>   *
> -- 
> 2.40.0.423.gd6c402a77b-goog
> 



Re: [PATCH 1/7] hw/i2c: pmbus add support for block receive

2023-03-31 Thread Corey Minyard
On Fri, Mar 31, 2023 at 12:07:50AM +, Titus Rwantare wrote:
> PMBus devices can send and receive variable length data using the
> block read and write format, with the first byte in the payload
> denoting the length.
> 
> This is mostly used for strings and on-device logs. Devices can
> respond to a block read with an empty string.
> 
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 

Acked-by: Corey Minyard 

> ---
>  hw/i2c/pmbus_device.c | 30 +-
>  include/hw/i2c/pmbus_device.h |  7 +++
>  2 files changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index c3d6046784..02647769cd 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -95,7 +95,6 @@ void pmbus_send64(PMBusDevice *pmdev, uint64_t data)
>  void pmbus_send_string(PMBusDevice *pmdev, const char *data)
>  {
>  size_t len = strlen(data);
> -g_assert(len > 0);
>  g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN);
>  pmdev->out_buf[len + pmdev->out_buf_len] = len;
>  
> @@ -105,6 +104,35 @@ void pmbus_send_string(PMBusDevice *pmdev, const char 
> *data)
>  pmdev->out_buf_len += len + 1;
>  }
>  
> +uint8_t pmbus_receive_block(PMBusDevice *pmdev, uint8_t *dest, size_t len)
> +{
> +/* dest may contain data from previous writes */
> +memset(dest, 0, len);
> +
> +/* Exclude command code from return value */
> +pmdev->in_buf++;
> +pmdev->in_buf_len--;
> +
> +/* The byte after the command code denotes the length */
> +uint8_t sent_len = pmdev->in_buf[0];
> +
> +if (sent_len != pmdev->in_buf_len - 1) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: length mismatch. Expected %d bytes, got %d 
> bytes\n",
> +  __func__, sent_len, pmdev->in_buf_len - 1);
> +}
> +
> +/* exclude length byte */
> +pmdev->in_buf++;
> +pmdev->in_buf_len--;
> +
> +if (pmdev->in_buf_len < len) {
> +len = pmdev->in_buf_len;
> +}
> +memcpy(dest, pmdev->in_buf, len);
> +return len;
> +}
> +
>  
>  static uint64_t pmbus_receive_uint(PMBusDevice *pmdev)
>  {
> diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> index 93f5d57c9d..7dc00cc4d9 100644
> --- a/include/hw/i2c/pmbus_device.h
> +++ b/include/hw/i2c/pmbus_device.h
> @@ -501,6 +501,13 @@ void pmbus_send64(PMBusDevice *state, uint64_t data);
>   */
>  void pmbus_send_string(PMBusDevice *state, const char *data);
>  
> +/**
> + * @brief Receive data sent with Block Write.
> + * @param dest - memory with enough capacity to receive the write
> + * @param len - the capacity of dest
> + */
> +uint8_t pmbus_receive_block(PMBusDevice *pmdev, uint8_t *dest, size_t len);
> +
>  /**
>   * @brief Receive data over PMBus
>   * These methods help track how much data is being received over PMBus
> -- 
> 2.40.0.423.gd6c402a77b-goog
> 



Re: [PATCH 2/5] hw/i2c: pmbus: add vout mode bitfields

2023-03-30 Thread Corey Minyard
On Thu, Mar 30, 2023 at 11:20:11AM -0500, Corey Minyard wrote:
> I almost never say this, as patches are usually too large :), but it
> would be nice if you combined this with the patch that uses the
> structure so we can see what it's used for.  Especially since that patch
> is several patches down the line.

Actually, in re-reviewing, I don't see this used at all.  Is there
something I'm missing?

> 
> -corey
> 
> On Wed, Mar 22, 2023 at 05:55:10PM +, Titus Rwantare wrote:
> > Reviewed-by: Hao Wu 
> > Signed-off-by: Titus Rwantare 
> > ---
> >  include/hw/i2c/pmbus_device.h | 8 
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> > index 7dc00cc4d9..2e95164aa1 100644
> > --- a/include/hw/i2c/pmbus_device.h
> > +++ b/include/hw/i2c/pmbus_device.h
> > @@ -444,6 +444,14 @@ typedef struct PMBusCoefficients {
> >  int32_t R; /* exponent */
> >  } PMBusCoefficients;
> >  
> > +/**
> > + * VOUT_Mode bit fields
> > + */
> > +typedef struct PMBusVoutMode {
> > +uint8_t  mode:3;
> > +int8_t   exp:5;
> > +} PMBusVoutMode;
> > +
> >  /**
> >   * Convert sensor values to direct mode format
> >   *
> > -- 
> > 2.40.0.rc1.284.g88254d51c5-goog
> > 



Re: [PATCH 5/5] hw/i2c: pmbus: add VCAP register

2023-03-30 Thread Corey Minyard
On Wed, Mar 22, 2023 at 05:55:13PM +, Titus Rwantare wrote:
> VCAP is a register for devices with energy storage capacitors.

Acked-by: Corey MInyard 

> 
> Reviewed-by: Benjamin Streb 
> Signed-off-by: Titus Rwantare 
> ---
>  hw/i2c/pmbus_device.c | 8 
>  include/hw/i2c/pmbus_device.h | 1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index 18e629eaac..ef0314a913 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -903,6 +903,14 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  }
>  break;
>  
> +case PMBUS_READ_VCAP: /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_VCAP) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_vcap);
> +} else {
> +goto passthough;
> +}
> +break;
> +
>  case PMBUS_READ_VOUT: /* Read-Only word */
>  if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
>  pmbus_send16(pmdev, pmdev->pages[index].read_vout);
> diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> index ad431bdc7c..f195c11384 100644
> --- a/include/hw/i2c/pmbus_device.h
> +++ b/include/hw/i2c/pmbus_device.h
> @@ -243,6 +243,7 @@ OBJECT_DECLARE_TYPE(PMBusDevice, PMBusDeviceClass,
>  #define PB_HAS_VIN_RATING  BIT_ULL(13)
>  #define PB_HAS_VOUT_RATING BIT_ULL(14)
>  #define PB_HAS_VOUT_MODE   BIT_ULL(15)
> +#define PB_HAS_VCAPBIT_ULL(16)
>  #define PB_HAS_IOUTBIT_ULL(21)
>  #define PB_HAS_IIN BIT_ULL(22)
>  #define PB_HAS_IOUT_RATING BIT_ULL(23)
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
> 



Re: [PATCH 4/5] hw/i2c: pmbus: block uninitialised string reads

2023-03-30 Thread Corey Minyard
On Wed, Mar 22, 2023 at 05:55:12PM +, Titus Rwantare wrote:
> Devices models calling pmbus_send_string can't be relied upon to
> send a non-zero pointer. This logs an error and doesn't segfault.

Yes, a good idea.

Acked-by: Corey Minyard 

> 
> Reviewed-by: Patrick Venture 
> Signed-off-by: Titus Rwantare 
> ---
>  hw/i2c/pmbus_device.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index bb42e410b4..18e629eaac 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -94,6 +94,13 @@ void pmbus_send64(PMBusDevice *pmdev, uint64_t data)
>  
>  void pmbus_send_string(PMBusDevice *pmdev, const char *data)
>  {
> +if (!data) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: %s: uninitialised read from 0x%02x\n",
> +  __func__, DEVICE(pmdev)->canonical_path, pmdev->code);
> +return;
> +}
> +
>  size_t len = strlen(data);
>  g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN);
>  pmdev->out_buf[len + pmdev->out_buf_len] = len;
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
> 



Re: [PATCH 3/5] hw/i2c: pmbus: add fan support

2023-03-30 Thread Corey Minyard
Empty description, but the code itself looks ok.

Acked-by: Corey Minyard 

On Wed, Mar 22, 2023 at 05:55:11PM +, Titus Rwantare wrote:
> Reviewed-by: Stephen Longfield 
> Signed-off-by: Titus Rwantare 
> ---
>  hw/i2c/pmbus_device.c | 176 ++
>  include/hw/i2c/pmbus_device.h |   1 +
>  2 files changed, 177 insertions(+)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index 02647769cd..bb42e410b4 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -490,6 +490,54 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  }
>  break;
>  
> +case PMBUS_FAN_CONFIG_1_2:/* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].fan_config_1_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_1: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_1);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_2: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_CONFIG_3_4:/* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].fan_config_3_4);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_3: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_3);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_FAN_COMMAND_4: /* R/W word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].fan_command_4);
> +} else {
> +goto passthough;
> +}
> +break;
> +
>  case PMBUS_VOUT_OV_FAULT_LIMIT:   /* R/W word */
>  if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
>  pmbus_send16(pmdev, pmdev->pages[index].vout_ov_fault_limit);
> @@ -800,6 +848,22 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  pmbus_send8(pmdev, pmdev->pages[index].status_mfr_specific);
>  break;
>  
> +case PMBUS_STATUS_FANS_1_2:   /* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].status_fans_1_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_STATUS_FANS_3_4:   /* R/W byte */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send8(pmdev, pmdev->pages[index].status_fans_3_4);
> +} else {
> +goto passthough;
> +}
> +break;
> +
>  case PMBUS_READ_EIN:  /* Read-Only block 5 bytes */
>  if (pmdev->pages[index].page_flags & PB_HAS_EIN) {
>  pmbus_send(pmdev, pmdev->pages[index].read_ein, 5);
> @@ -872,6 +936,54 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
>  }
>  break;
>  
> +case PMBUS_READ_FAN_SPEED_1:  /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_1);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_READ_FAN_SPEED_2:  /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_2);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_READ_FAN_SPEED_3:  /* Read-Only word */
> +if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
> +pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_3);
> +} else {
> +goto passthough;
> +}
> +break;
> +
> +case PMBUS_READ_FAN_SPEED_4:  /* Read-

Re: [PATCH 2/5] hw/i2c: pmbus: add vout mode bitfields

2023-03-30 Thread Corey Minyard
I almost never say this, as patches are usually too large :), but it
would be nice if you combined this with the patch that uses the
structure so we can see what it's used for.  Especially since that patch
is several patches down the line.

-corey

On Wed, Mar 22, 2023 at 05:55:10PM +, Titus Rwantare wrote:
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 
> ---
>  include/hw/i2c/pmbus_device.h | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> index 7dc00cc4d9..2e95164aa1 100644
> --- a/include/hw/i2c/pmbus_device.h
> +++ b/include/hw/i2c/pmbus_device.h
> @@ -444,6 +444,14 @@ typedef struct PMBusCoefficients {
>  int32_t R; /* exponent */
>  } PMBusCoefficients;
>  
> +/**
> + * VOUT_Mode bit fields
> + */
> +typedef struct PMBusVoutMode {
> +uint8_t  mode:3;
> +int8_t   exp:5;
> +} PMBusVoutMode;
> +
>  /**
>   * Convert sensor values to direct mode format
>   *
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
> 



Re: [PATCH 1/5] hw/i2c: pmbus add support for block receive

2023-03-30 Thread Corey Minyard
It's generally frowned upon to have empty descriptions, some rationale
would be helpful.  For instance, you remove a length check from the send
string, why did you do that?

Any why is this being added?  What's it supporting?

-corey

On Wed, Mar 22, 2023 at 05:55:09PM +, Titus Rwantare wrote:
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 
> ---
>  hw/i2c/pmbus_device.c | 30 +-
>  include/hw/i2c/pmbus_device.h |  7 +++
>  2 files changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index c3d6046784..02647769cd 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -95,7 +95,6 @@ void pmbus_send64(PMBusDevice *pmdev, uint64_t data)
>  void pmbus_send_string(PMBusDevice *pmdev, const char *data)
>  {
>  size_t len = strlen(data);
> -g_assert(len > 0);
>  g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN);
>  pmdev->out_buf[len + pmdev->out_buf_len] = len;
>  
> @@ -105,6 +104,35 @@ void pmbus_send_string(PMBusDevice *pmdev, const char 
> *data)
>  pmdev->out_buf_len += len + 1;
>  }
>  
> +uint8_t pmbus_receive_block(PMBusDevice *pmdev, uint8_t *dest, size_t len)
> +{
> +/* dest may contain data from previous writes */
> +memset(dest, 0, len);
> +
> +/* Exclude command code from return value */
> +pmdev->in_buf++;
> +pmdev->in_buf_len--;
> +
> +/* The byte after the command code denotes the length */
> +uint8_t sent_len = pmdev->in_buf[0];
> +
> +if (sent_len != pmdev->in_buf_len - 1) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: length mismatch. Expected %d bytes, got %d 
> bytes\n",
> +  __func__, sent_len, pmdev->in_buf_len - 1);
> +}
> +
> +/* exclude length byte */
> +pmdev->in_buf++;
> +pmdev->in_buf_len--;
> +
> +if (pmdev->in_buf_len < len) {
> +len = pmdev->in_buf_len;
> +}
> +memcpy(dest, pmdev->in_buf, len);
> +return len;
> +}
> +
>  
>  static uint64_t pmbus_receive_uint(PMBusDevice *pmdev)
>  {
> diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
> index 93f5d57c9d..7dc00cc4d9 100644
> --- a/include/hw/i2c/pmbus_device.h
> +++ b/include/hw/i2c/pmbus_device.h
> @@ -501,6 +501,13 @@ void pmbus_send64(PMBusDevice *state, uint64_t data);
>   */
>  void pmbus_send_string(PMBusDevice *state, const char *data);
>  
> +/**
> + * @brief Receive data sent with Block Write.
> + * @param dest - memory with enough capacity to receive the write
> + * @param len - the capacity of dest
> + */
> +uint8_t pmbus_receive_block(PMBusDevice *pmdev, uint8_t *dest, size_t len);
> +
>  /**
>   * @brief Receive data over PMBus
>   * These methods help track how much data is being received over PMBus
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
> 



Re: [PATCH v2 4/7] hw/ipmi: Refactor IPMI interface

2023-03-27 Thread Corey Minyard
On Mon, Mar 27, 2023 at 10:08:37AM -0700, Hao Wu wrote:
> Thanks, I think breaking them up makes sense but it might take a while
> since it takes some effort to make each one pass. I could do it in a few
> weeks and send another patch out with  the breakup.

I understand.  In case you haven't done this before, keeping the old
branch and then using "git diff" against it as you break it up in a new
branch will help make sure you haven't changed anything when you break
it up.

-corey

> 
> On Sat, Mar 25, 2023 at 4:51 PM Corey Minyard  wrote:
> 
> > On Fri, Mar 24, 2023 at 04:09:01PM -0700, Hao Wu wrote:
> > > This patch refactors the IPMI interface so that it can be used by both
> > > the BMC side and core-side simulation.
> >
> > This patch is hard to review because it does so many different things
> > and they are all mixed up.  It looks ok, but it's hard to tell.  I know
> > it's a pain (I've done it many times) but can you split this up into
> > separate patches that each make one change?  The list you have below
> > tells me that 5 patches might be appropriate.
> >
> > If I really had to a full review this myself I would break it into
> > multiple patches just to review it.  But that should really be your job.
> >
> > Thanks,
> >
> > -corey
> >
> > >
> > > Detail changes:
> > > (1) Split IPMIInterface into IPMIInterfaceHost (for host side
> > > simulation) and IPMIInterfaceClient (for BMC side simulation).
> > > (2) rename handle_rsp -> handle_msg so the name fits both BMC side and
> > > Core side.
> > > (3) Add a new class IPMICore. This class represents a simulator/external
> > > connection for both BMC and Core side emulation.
> > > (4) Change the original IPMIBmc to IPMIBmcHost, representing host side
> > > simulation.
> > > (5) Add a new type IPMIBmcClient representing BMC side simulation.
> > > (6) Appy the changes to  the entire IPMI library.
> > >
> > > Signed-off-by: Hao Wu 
> > > ---
> > >  hw/acpi/ipmi.c |   4 +-
> > >  hw/ipmi/ipmi.c |  60 +
> > >  hw/ipmi/ipmi_bmc_extern.c  |  67 ++
> > >  hw/ipmi/ipmi_bmc_sim.c |  78 -
> > >  hw/ipmi/ipmi_bt.c  |  33 +
> > >  hw/ipmi/ipmi_kcs.c |  31 +
> > >  hw/ipmi/isa_ipmi_bt.c  |  18 ++---
> > >  hw/ipmi/isa_ipmi_kcs.c |  13 ++--
> > >  hw/ipmi/pci_ipmi_bt.c  |   8 +--
> > >  hw/ipmi/pci_ipmi_kcs.c |   8 +--
> > >  hw/ipmi/smbus_ipmi.c   |  26 +++
> > >  hw/ppc/pnv.c   |   4 +-
> > >  hw/ppc/pnv_bmc.c   |  22 +++---
> > >  hw/smbios/smbios_type_38.c |  11 +--
> > >  include/hw/ipmi/ipmi.h | 135 ++---
> > >  include/hw/ipmi/ipmi_bt.h  |   2 +-
> > >  include/hw/ipmi/ipmi_kcs.h |   2 +-
> > >  include/hw/ppc/pnv.h   |  12 ++--
> > >  18 files changed, 332 insertions(+), 202 deletions(-)
> > >
> > > diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
> > > index a20e57d465..e6d2cd790b 100644
> > > --- a/hw/acpi/ipmi.c
> > > +++ b/hw/acpi/ipmi.c
> > > @@ -66,8 +66,8 @@ void build_ipmi_dev_aml(AcpiDevAmlIf *adev, Aml *scope)
> > >  {
> > >  Aml *dev;
> > >  IPMIFwInfo info = {};
> > > -IPMIInterface *ii = IPMI_INTERFACE(adev);
> > > -IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> > > +IPMIInterfaceHost *ii = IPMI_INTERFACE_HOST(adev);
> > > +IPMIInterfaceHostClass *iic = IPMI_INTERFACE_HOST_GET_CLASS(ii);
> > >  uint16_t version;
> > >
> > >  iic->get_fwinfo(ii, &info);
> > > diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
> > > index bbb07b151e..1be923ffb8 100644
> > > --- a/hw/ipmi/ipmi.c
> > > +++ b/hw/ipmi/ipmi.c
> > > @@ -38,7 +38,7 @@ uint32_t ipmi_next_uuid(void)
> > >  return ipmi_current_uuid++;
> > >  }
> > >
> > > -static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int
> > checkonly)
> > > +static int ipmi_do_hw_op(IPMIInterfaceHost *s, enum ipmi_op op, int
> > checkonly)
> > >  {
> > >  switch (op) {
> > >  case IPMI_RESET_CHASSIS:
> > > @@ -78,9 +78,9 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum
> > ipmi_op op, int checkonly)
> > >  }
> > >  }
> > >
> > > -static void ipmi_

Re: [PATCH v2 4/7] hw/ipmi: Refactor IPMI interface

2023-03-27 Thread Corey Minyard
On Mon, Mar 27, 2023 at 10:11:50AM -0700, Hao Wu wrote:
> Hi, Cedric
> 
> The naming scheme is suggested by Corey in a previous review:
> 
> https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg02691.html
> 
> I originally kept "IpmIBmc" for the host side code talking to BMC but it
> might also cause confusion as well. I'm not sure which name is the best
> here. Maybe Corey can shed some light on this one? Thank you!

I agree with Cédric here, Bmc and BmcClient sound more clear than what I
proposed earlier.

-corey

> 
> Best Regards,
> 
> On Mon, Mar 27, 2023 at 5:34 AM Cédric Le Goater  wrote:
> 
> > Hello Hao,
> >
> > On 3/25/23 00:09, Hao Wu wrote:
> > > This patch refactors the IPMI interface so that it can be used by both
> > > the BMC side and core-side simulation.
> > >
> > > Detail changes:
> > > (1) Split IPMIInterface into IPMIInterfaceHost (for host side
> > >  simulation) and IPMIInterfaceClient (for BMC side simulation).
> > > (2) rename handle_rsp -> handle_msg so the name fits both BMC side and
> > >  Core side.
> > > (3) Add a new class IPMICore. This class represents a simulator/external
> > >  connection for both BMC and Core side emulation.
> > > (4) Change the original IPMIBmc to IPMIBmcHost, representing host side
> > >  simulation.
> > > (5) Add a new type IPMIBmcClient representing BMC side simulation.
> > > (6) Appy the changes to  the entire IPMI library.
> >
> > 'IPMIBmcHost' is a BMC object model (internal or external) and
> > 'IPMIBmcClient' is a host object model ?
> >
> > [ ... ]
> >
> > > @@ -267,15 +267,15 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
> > >* Instantiate the machine BMC. PowerNV uses the QEMU internal
> > >* simulator but it could also be external.
> > >*/
> > > -IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
> > > +IPMIBmcHost *pnv_bmc_create(PnvPnor *pnor)
> > >   {
> > >   Object *obj;
> > >
> > >   obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
> > >   qdev_realize(DEVICE(obj), NULL, &error_fatal);
> > > -pnv_bmc_set_pnor(IPMI_BMC(obj), pnor);
> > > +pnv_bmc_set_pnor(IPMI_BMC_HOST(obj), pnor);
> > >
> > > -return IPMI_BMC(obj);
> > > +return IPMI_BMC_HOST(obj);
> >
> > QEMU PowerNV machines model the host side of OpenPOWER systems which
> > have an Aspeed SoC based BMC for management. The routine above creates
> > an Aspeed *BMC* object model for the PowerNV *host* machine. I find
> > 'IPMIBmcHost' confusing. It shouldn't have a 'Host' suffix I think.
> >
> > 'IPMIBmcClient' sounds ok, or 'IPMIBmcPeer' maybe.
> >
> > Thanks,
> >
> > C.
> >
> >



Re: [PATCH v2 2/7] docs/specs: IPMI device emulation: main processor

2023-03-25 Thread Corey Minyard
On Fri, Mar 24, 2023 at 04:08:59PM -0700, Hao Wu wrote:
> From: Havard Skinnemoen 
> 
> This document is an attempt to briefly document the existing IPMI
> emulation support on the main processor. It provides the necessary
> background for the BMC-side IPMI emulation proposed by the next patch.
> 
> Signed-off-by: Havard Skinnemoen 
> Signed-off-by: Hao Wu 
> ---
> +* An external BMC simulator or emulator, connected over a chardev
> +  (``ipmi-bmc-extern``). `ipmi_sim
> +  
> `_

Nit, you have a double slash above.

Other than that, this does a good job of explaining things.  I'm good
with these docs.

-corey



Re: [PATCH v2 4/7] hw/ipmi: Refactor IPMI interface

2023-03-25 Thread Corey Minyard
On Fri, Mar 24, 2023 at 04:09:01PM -0700, Hao Wu wrote:
> This patch refactors the IPMI interface so that it can be used by both
> the BMC side and core-side simulation.

This patch is hard to review because it does so many different things
and they are all mixed up.  It looks ok, but it's hard to tell.  I know
it's a pain (I've done it many times) but can you split this up into
separate patches that each make one change?  The list you have below
tells me that 5 patches might be appropriate.

If I really had to a full review this myself I would break it into
multiple patches just to review it.  But that should really be your job.

Thanks,

-corey

> 
> Detail changes:
> (1) Split IPMIInterface into IPMIInterfaceHost (for host side
> simulation) and IPMIInterfaceClient (for BMC side simulation).
> (2) rename handle_rsp -> handle_msg so the name fits both BMC side and
> Core side.
> (3) Add a new class IPMICore. This class represents a simulator/external
> connection for both BMC and Core side emulation.
> (4) Change the original IPMIBmc to IPMIBmcHost, representing host side
> simulation.
> (5) Add a new type IPMIBmcClient representing BMC side simulation.
> (6) Appy the changes to  the entire IPMI library.
> 
> Signed-off-by: Hao Wu 
> ---
>  hw/acpi/ipmi.c |   4 +-
>  hw/ipmi/ipmi.c |  60 +
>  hw/ipmi/ipmi_bmc_extern.c  |  67 ++
>  hw/ipmi/ipmi_bmc_sim.c |  78 -
>  hw/ipmi/ipmi_bt.c  |  33 +
>  hw/ipmi/ipmi_kcs.c |  31 +
>  hw/ipmi/isa_ipmi_bt.c  |  18 ++---
>  hw/ipmi/isa_ipmi_kcs.c |  13 ++--
>  hw/ipmi/pci_ipmi_bt.c  |   8 +--
>  hw/ipmi/pci_ipmi_kcs.c |   8 +--
>  hw/ipmi/smbus_ipmi.c   |  26 +++
>  hw/ppc/pnv.c   |   4 +-
>  hw/ppc/pnv_bmc.c   |  22 +++---
>  hw/smbios/smbios_type_38.c |  11 +--
>  include/hw/ipmi/ipmi.h | 135 ++---
>  include/hw/ipmi/ipmi_bt.h  |   2 +-
>  include/hw/ipmi/ipmi_kcs.h |   2 +-
>  include/hw/ppc/pnv.h   |  12 ++--
>  18 files changed, 332 insertions(+), 202 deletions(-)
> 
> diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
> index a20e57d465..e6d2cd790b 100644
> --- a/hw/acpi/ipmi.c
> +++ b/hw/acpi/ipmi.c
> @@ -66,8 +66,8 @@ void build_ipmi_dev_aml(AcpiDevAmlIf *adev, Aml *scope)
>  {
>  Aml *dev;
>  IPMIFwInfo info = {};
> -IPMIInterface *ii = IPMI_INTERFACE(adev);
> -IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> +IPMIInterfaceHost *ii = IPMI_INTERFACE_HOST(adev);
> +IPMIInterfaceHostClass *iic = IPMI_INTERFACE_HOST_GET_CLASS(ii);
>  uint16_t version;
>  
>  iic->get_fwinfo(ii, &info);
> diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
> index bbb07b151e..1be923ffb8 100644
> --- a/hw/ipmi/ipmi.c
> +++ b/hw/ipmi/ipmi.c
> @@ -38,7 +38,7 @@ uint32_t ipmi_next_uuid(void)
>  return ipmi_current_uuid++;
>  }
>  
> -static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
> +static int ipmi_do_hw_op(IPMIInterfaceHost *s, enum ipmi_op op, int 
> checkonly)
>  {
>  switch (op) {
>  case IPMI_RESET_CHASSIS:
> @@ -78,9 +78,9 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, 
> int checkonly)
>  }
>  }
>  
> -static void ipmi_interface_class_init(ObjectClass *class, void *data)
> +static void ipmi_interface_host_class_init(ObjectClass *class, void *data)
>  {
> -IPMIInterfaceClass *ik = IPMI_INTERFACE_CLASS(class);
> +IPMIInterfaceHostClass *ik = IPMI_INTERFACE_HOST_CLASS(class);
>  
>  ik->do_hw_op = ipmi_do_hw_op;
>  }
> @@ -89,27 +89,48 @@ static const TypeInfo ipmi_interface_type_info = {
>  .name = TYPE_IPMI_INTERFACE,
>  .parent = TYPE_INTERFACE,
>  .class_size = sizeof(IPMIInterfaceClass),
> -.class_init = ipmi_interface_class_init,
> +};
> +
> +static const TypeInfo ipmi_interface_host_type_info = {
> +.name = TYPE_IPMI_INTERFACE_HOST,
> +.parent = TYPE_IPMI_INTERFACE,
> +.class_size = sizeof(IPMIInterfaceHostClass),
> +.class_init = ipmi_interface_host_class_init,
> +};
> +
> +static const TypeInfo ipmi_interface_client_type_info = {
> +.name = TYPE_IPMI_INTERFACE_CLIENT,
> +.parent = TYPE_IPMI_INTERFACE,
> +.class_size = sizeof(IPMIInterfaceClientClass),
> +};
> +
> +static const TypeInfo ipmi_core_type_info = {
> +.name = TYPE_IPMI_CORE,
> +.parent = TYPE_DEVICE,
> +.instance_size = sizeof(IPMICore),
> +.class_size = sizeof(IPMICoreClass),
> +.abstract = true,
>  };
>  
>  static void isa_ipmi_bmc_check(const Object *obj, const char *name,
> Object *val, Error **errp)
>  {
> -IPMIBmc *bmc = IPMI_BMC(val);
> +IPMICore *ic = IPMI_CORE(val);
>  
> -if (bmc->intf)
> +if (ic->intf) {
>  error_setg(errp, "BMC object is already in use");
> +}
>  }
>  
>  void ipmi_bmc_find_and_link(Object *obj, Object **bmc)
>  {
> -object_property_add_link(obj, "bm

Re: [RFC PATCH v1] hw/misc: add i2c slave device that passes i2c ops outside

2023-03-23 Thread Corey Minyard
On Thu, Mar 23, 2023 at 10:09:02AM +, Karol Nowak wrote:
> Hi,
> 
> There is a feature I prepared which may be practical for some QEMU users.
> 
> The feature provides a new I2C slave device
> that prepares a message depending what i2c-slave callback was called
> and sends it outside of QEMU through the character device to a client
> that receives that message, processes it and send back a response.
> Thanks to that feature,
> a user can emulate a logic of I2C device outside of QEMU.
> The message contains 3 bytes ended with CRLF: BBB\r\l
> Basically, the I2C slave does 4 steps in each i2c-slave callback:
> * encode
> * send
> * receive
> * decode
> 
> I put more details in esp32_i2c_tcp_slave.c
> and also provided a demo client in python that uses TCP.
> 
> The feature still needs some improvements, but the question is:
> * Do you find the feature useful?

Someone else has proposed this before with a patch, and it was actually
pretty complete and mostly ok, but I pointed out an issue and never
heard back from them.  This feature is something that might be nice.  As
you say, this needs some improvements.  Some I would point out:

Obviously this can't be named esp32, it needs to be general.

All the I/O (reading and writing) has to be non-blocking.  I/O handling
in qemu is single-threaded, if you block anywhere you basically stop
qemu.  You need to implement something where whatever you do (like
handling a NAK, for instance) it doesn't block qemu.

The protocol you have implemented is basically an extension of the QEMU
protocol.  That's probably not ideal, it would be best to think about a
general protocol for extending I2C over a TCP connection.  A lot of the
details of the QEMU implementation is probably not necessary over a TCP
connection.

-corey

> 
> 
> NOTE:
> The feature originally was prepared for espressif/qemu
> that's why there are references to esp32
> 
> 
> Signed-off-by: Karol Nowak 
> ---
>  hw/misc/esp32_i2c_tcp_slave.c | 288 ++
>  include/hw/misc/esp32_i2c_tcp_slave.h |  19 ++
>  tests/i2c-tcp-demo/i2c-tcp-demo.py| 133 
>  3 files changed, 440 insertions(+)
>  create mode 100644 hw/misc/esp32_i2c_tcp_slave.c
>  create mode 100644 include/hw/misc/esp32_i2c_tcp_slave.h
>  create mode 100644 tests/i2c-tcp-demo/i2c-tcp-demo.py
> 
> diff --git a/hw/misc/esp32_i2c_tcp_slave.c b/hw/misc/esp32_i2c_tcp_slave.c
> new file mode 100644
> index 00..db3b6d366a
> --- /dev/null
> +++ b/hw/misc/esp32_i2c_tcp_slave.c
> @@ -0,0 +1,288 @@
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/log.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/irq.h"
> +#include "hw/misc/esp32_i2c_tcp_slave.h"
> +#include "qemu/module.h"
> +
> +#include "qapi/qmp/json-writer.h"
> +#include "chardev/char-fe.h"
> +#include "io/channel-socket.h"
> +#include "chardev/char-io.h"
> +#include "chardev/char-socket.h"
> +#include "qapi/error.h"
> +
> +/*
> + * Description:
> + * To allow to emulate a I2C slave device which is not supported by QEMU,
> + * a new I2C slave device was created that encapsulates I2C operations
> + * and passes them through a selected chardev to the host
> + * where a client resides that implements a logic of emulated device.
> + *
> + *
> + * Architecture:
> + *---
> + *| QEMU|
> + *| | ---
> + *|  ESP32 Firmware writes  | | |
> + *|  to I2C Slave   | | I2C Slave Emulation |
> + *| | | |
> + *|  ---&-& |
> + *|  | I2C Slave at 0x7F&   tcp   & recv msg|
> + *|  ---&-& process msg |
> + *| | | send respone|
> + *| | | |
> + *| | | |
> + *--- |--
> + *
> + *
> + * Syntax & protocol:
> + *  QEMU I2C Slave sends a msg in following format: BBB\r\n
> + *  where each 'B' represents a single byte 0-255
> + *  QEMU I2C Slave expects a respone message in the same format as fast 
> as possible
> + *  Example:
> + * req: 0x45 0x01 0x00 \r\n
> + *resp: 0x45 0x01 0x00 \r\n
> + *
> + *  The format BBB\r\n
> + *first 'B' is a message type
> + *second 'B' is a data value
> + *third 'B' is an error value (not used at the moment)
> + *
> + *  There are three types of message
> + *'E' or 0x45 - Event:
> + *'S' or 0x53 - Send: byte sent to emulated I2C Slave
> + *'R' or 0x52 - Recv: byte to be received by I2C Master
> + *
> + *
> + *  'E' message
> + *second byte is an event type:
> + * 0x0: I2C_START_RECV
> + * 

Re: [PATCH RESEND v2] hw/i2c: Enable an id for the pca954x devices

2023-03-22 Thread Corey Minyard
On Wed, Mar 22, 2023 at 10:21:36AM -0700, Patrick Venture wrote:
> This allows the devices to be more readily found and specified.
> Without setting the name field, they can only be found by device type
> name, which doesn't let you specify the second of the same device type
> behind a bus.
> 
> Tested: Verified that by default the device was findable with the name
> 'pca954x[77]', for an instance attached at that address.

This looks good to me.

Acked-by: Corey Minyard 

if you are taking this in through another tree.  Or do you want me to
take this?

-corey

> 
> Signed-off-by: Patrick Venture 
> Reviewed-by: Hao Wu 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
> v2: s/id/name/g to use name as the identifier field. left 'id' in subject for 
> email chain.
> ---
>  hw/i2c/i2c_mux_pca954x.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> index 3945de795c..76e69bebc5 100644
> --- a/hw/i2c/i2c_mux_pca954x.c
> +++ b/hw/i2c/i2c_mux_pca954x.c
> @@ -20,6 +20,7 @@
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_slave.h"
>  #include "hw/qdev-core.h"
> +#include "hw/qdev-properties.h"
>  #include "hw/sysbus.h"
>  #include "qemu/log.h"
>  #include "qemu/module.h"
> @@ -43,6 +44,8 @@ typedef struct Pca954xState {
>  
>  bool enabled[PCA9548_CHANNEL_COUNT];
>  I2CBus *bus[PCA9548_CHANNEL_COUNT];
> +
> +char *name;
>  } Pca954xState;
>  
>  /*
> @@ -181,6 +184,17 @@ static void pca9548_class_init(ObjectClass *klass, void 
> *data)
>  s->nchans = PCA9548_CHANNEL_COUNT;
>  }
>  
> +static void pca954x_realize(DeviceState *dev, Error **errp)
> +{
> +Pca954xState *s = PCA954X(dev);
> +DeviceState *d = DEVICE(s);
> +if (s->name) {
> +d->id = g_strdup(s->name);
> +} else {
> +d->id = g_strdup_printf("pca954x[%x]", s->parent.i2c.address);
> +}
> +}
> +
>  static void pca954x_init(Object *obj)
>  {
>  Pca954xState *s = PCA954X(obj);
> @@ -197,6 +211,11 @@ static void pca954x_init(Object *obj)
>  }
>  }
>  
> +static Property pca954x_props[] = {
> +DEFINE_PROP_STRING("nane", Pca954xState, name),
> +DEFINE_PROP_END_OF_LIST()
> +};
> +
>  static void pca954x_class_init(ObjectClass *klass, void *data)
>  {
>  I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
> @@ -209,9 +228,12 @@ static void pca954x_class_init(ObjectClass *klass, void 
> *data)
>  rc->phases.enter = pca954x_enter_reset;
>  
>  dc->desc = "Pca954x i2c-mux";
> +dc->realize = pca954x_realize;
>  
>  k->write_data = pca954x_write_data;
>  k->receive_byte = pca954x_read_byte;
> +
> +device_class_set_props(dc, pca954x_props);
>  }
>  
>  static const TypeInfo pca954x_info[] = {
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
> 


smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH RESEND] hw/i2c: Enable an id for the pca954x devices

2023-03-22 Thread Corey Minyard
On Wed, Mar 22, 2023 at 10:03:27AM -0700, Patrick Venture wrote:
> On Tue, Mar 21, 2023 at 6:41 PM Corey Minyard  wrote:
> 
> > On Tue, Mar 21, 2023 at 11:27:44AM -0700, Patrick Venture wrote:
> > > This allows the devices to be more readily found and specified.
> > > Without setting the id field, they can only be found by device type
> > > name, which doesn't let you specify the second of the same device type
> > > behind a bus.
> >
> > So basically, this helps you find a specific device if you have more
> > than one of them.  Yeah, probably a good idea in this case.
> >
> > >
> > > Tested: Verified that by default the device was findable with the id
> > > 'pca954x[77]', for an instance attached at that address.
> > >
> > > Signed-off-by: Patrick Venture 
> > > Reviewed-by: Hao Wu 
> > > Reviewed-by: Philippe Mathieu-Daudé 
> > > ---
> > >  hw/i2c/i2c_mux_pca954x.c | 22 ++
> > >  1 file changed, 22 insertions(+)
> > >
> > > diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> > > index a9517b612a..4f8c2d6ae1 100644
> > > --- a/hw/i2c/i2c_mux_pca954x.c
> > > +++ b/hw/i2c/i2c_mux_pca954x.c
> > > @@ -20,6 +20,7 @@
> > >  #include "hw/i2c/i2c_mux_pca954x.h"
> > >  #include "hw/i2c/smbus_slave.h"
> > >  #include "hw/qdev-core.h"
> > > +#include "hw/qdev-properties.h"
> > >  #include "hw/sysbus.h"
> > >  #include "qemu/log.h"
> > >  #include "qemu/module.h"
> > > @@ -43,6 +44,8 @@ typedef struct Pca954xState {
> > >
> > >  bool enabled[PCA9548_CHANNEL_COUNT];
> > >  I2CBus *bus[PCA9548_CHANNEL_COUNT];
> > > +
> > > +char *id;
> > >  } Pca954xState;
> > >
> > >  /*
> > > @@ -181,6 +184,17 @@ static void pca9548_class_init(ObjectClass *klass,
> > void *data)
> > >  s->nchans = PCA9548_CHANNEL_COUNT;
> > >  }
> > >
> > > +static void pca954x_realize(DeviceState *dev, Error **errp)
> > > +{
> > > +Pca954xState *s = PCA954X(dev);
> > > +DeviceState *d = DEVICE(s);
> > > +if (s->id) {
> > > +d->id = g_strdup(s->id);
> > > +} else {
> > > +d->id = g_strdup_printf("pca954x[%x]", s->parent.i2c.address);
> > > +}
> > > +}
> > > +
> > >  static void pca954x_init(Object *obj)
> > >  {
> > >  Pca954xState *s = PCA954X(obj);
> > > @@ -197,6 +211,11 @@ static void pca954x_init(Object *obj)
> > >  }
> > >  }
> > >
> > > +static Property pca954x_props[] = {
> > > +DEFINE_PROP_STRING("id", Pca954xState, id),
> > > +DEFINE_PROP_END_OF_LIST()
> > > +};
> >
> > There is already an "id=" thing in qemu for doing links between front
> > ends and back ends.  That's probably not the best name to use.  Several
> > devices, like network devices, use "name" for identification in the
> > monitor.
> >
> 
> So I should change it to name? I'm ok with that. I think bus would be
> slightly confusing.  "id" was short and easy.  Will send a v2.

Yes, "name" would be more consistent with other usage.

-corey

> 
> 
> >
> > -corey
> >
> > > +
> > >  static void pca954x_class_init(ObjectClass *klass, void *data)
> > >  {
> > >  I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
> > > @@ -209,9 +228,12 @@ static void pca954x_class_init(ObjectClass *klass,
> > void *data)
> > >  rc->phases.enter = pca954x_enter_reset;
> > >
> > >  dc->desc = "Pca954x i2c-mux";
> > > +dc->realize = pca954x_realize;
> > >
> > >  k->write_data = pca954x_write_data;
> > >  k->receive_byte = pca954x_read_byte;
> > > +
> > > +device_class_set_props(dc, pca954x_props);
> > >  }
> > >
> > >  static const TypeInfo pca954x_info[] = {
> > > --
> > > 2.35.1.894.gb6a874cedc-goog
> > >
> >



Re: [PATCH RESEND] hw/i2c: Enable an id for the pca954x devices

2023-03-21 Thread Corey Minyard
On Tue, Mar 21, 2023 at 11:27:44AM -0700, Patrick Venture wrote:
> This allows the devices to be more readily found and specified.
> Without setting the id field, they can only be found by device type
> name, which doesn't let you specify the second of the same device type
> behind a bus.

So basically, this helps you find a specific device if you have more
than one of them.  Yeah, probably a good idea in this case.

> 
> Tested: Verified that by default the device was findable with the id
> 'pca954x[77]', for an instance attached at that address.
> 
> Signed-off-by: Patrick Venture 
> Reviewed-by: Hao Wu 
> Reviewed-by: Philippe Mathieu-Daudé 
> ---
>  hw/i2c/i2c_mux_pca954x.c | 22 ++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> index a9517b612a..4f8c2d6ae1 100644
> --- a/hw/i2c/i2c_mux_pca954x.c
> +++ b/hw/i2c/i2c_mux_pca954x.c
> @@ -20,6 +20,7 @@
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_slave.h"
>  #include "hw/qdev-core.h"
> +#include "hw/qdev-properties.h"
>  #include "hw/sysbus.h"
>  #include "qemu/log.h"
>  #include "qemu/module.h"
> @@ -43,6 +44,8 @@ typedef struct Pca954xState {
>  
>  bool enabled[PCA9548_CHANNEL_COUNT];
>  I2CBus *bus[PCA9548_CHANNEL_COUNT];
> +
> +char *id;
>  } Pca954xState;
>  
>  /*
> @@ -181,6 +184,17 @@ static void pca9548_class_init(ObjectClass *klass, void 
> *data)
>  s->nchans = PCA9548_CHANNEL_COUNT;
>  }
>  
> +static void pca954x_realize(DeviceState *dev, Error **errp)
> +{
> +Pca954xState *s = PCA954X(dev);
> +DeviceState *d = DEVICE(s);
> +if (s->id) {
> +d->id = g_strdup(s->id);
> +} else {
> +d->id = g_strdup_printf("pca954x[%x]", s->parent.i2c.address);
> +}
> +}
> +
>  static void pca954x_init(Object *obj)
>  {
>  Pca954xState *s = PCA954X(obj);
> @@ -197,6 +211,11 @@ static void pca954x_init(Object *obj)
>  }
>  }
>  
> +static Property pca954x_props[] = {
> +DEFINE_PROP_STRING("id", Pca954xState, id),
> +DEFINE_PROP_END_OF_LIST()
> +};

There is already an "id=" thing in qemu for doing links between front
ends and back ends.  That's probably not the best name to use.  Several
devices, like network devices, use "name" for identification in the
monitor.

-corey

> +
>  static void pca954x_class_init(ObjectClass *klass, void *data)
>  {
>  I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
> @@ -209,9 +228,12 @@ static void pca954x_class_init(ObjectClass *klass, void 
> *data)
>  rc->phases.enter = pca954x_enter_reset;
>  
>  dc->desc = "Pca954x i2c-mux";
> +dc->realize = pca954x_realize;
>  
>  k->write_data = pca954x_write_data;
>  k->receive_byte = pca954x_read_byte;
> +
> +device_class_set_props(dc, pca954x_props);
>  }
>  
>  static const TypeInfo pca954x_info[] = {
> -- 
> 2.35.1.894.gb6a874cedc-goog
> 


smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH 0/2] hw/i2c: Reset fixes

2023-03-20 Thread Corey Minyard
On Mon, Mar 20, 2023 at 10:14:17PM +, Joe Komlodi wrote:
> Hi all,
> 
> This series fixes some I2C state variables not being reset when a reset
> would happen.
> 
> These stale variables would infrequently cause issues, something around
> the order of 5/1000 runs, since the machine would have to be reset at a
> point where they would be in a state that would cause problems.

These look good to me.  Definitely a missing needed function.  Looking
through the way it's handled, I think the proper things are being reset
and the proper ones are being left alone.  There's no checking of the
reset type, but there's only one reset type right now, so I guess any
changes due to reset type will have to come when new types come.

Acked-by: Corey Minyard 

for another tree, or I can take them.

Thanks,

-corey

> 
> Thanks!
> Joe
> 
> Joe Komlodi (2):
>   hw/i2c: smbus_slave: Reset state on reset
>   hw/i2c: core: Add reset
> 
>  hw/i2c/core.c| 25 ++---
>  hw/i2c/smbus_slave.c |  9 +
>  2 files changed, 31 insertions(+), 3 deletions(-)
> 
> -- 
> 2.40.0.rc2.332.ga46443480c-goog
> 


smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH 05/12] hw/i2c/smbus_ich9: Inline ich9_smb_init() and remove it

2023-02-27 Thread Corey Minyard
On Mon, Feb 27, 2023 at 12:53:23PM +0100, Philippe Mathieu-Daudé wrote:
> On 19/2/23 15:21, Corey Minyard wrote:
> > On Sun, Feb 19, 2023 at 02:45:44PM +0100, Philippe Mathieu-Daudé wrote:
> > > On 18/2/23 21:25, Corey Minyard wrote:
> > > > On Mon, Feb 13, 2023 at 06:30:26PM +0100, Bernhard Beschow wrote:
> > > > > ich9_smb_init() is a legacy init function, so modernize the code.
> > > > > 
> > > > > Note that the smb_io_base parameter was unused.
> > > > 
> > > > Acked-by: Corey Minyard 
> > > > 
> > > > > 
> > > > > Signed-off-by: Bernhard Beschow 
> > > > > ---
> > > > >include/hw/i386/ich9.h |  1 -
> > > > >hw/i2c/smbus_ich9.c| 13 +++--
> > > > >hw/i386/pc_q35.c   | 11 ---
> > > > >3 files changed, 11 insertions(+), 14 deletions(-)
> > > > > 
> > > > > diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
> > > > > index 05464f6965..52ea116f44 100644
> > > > > --- a/include/hw/i386/ich9.h
> > > > > +++ b/include/hw/i386/ich9.h
> > > > > @@ -9,7 +9,6 @@
> > > > >#include "qom/object.h"
> > > > >void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
> > > > > -I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
> > > > >void ich9_generate_smi(void);
> > > > > diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
> > > > > index d29c0f6ffa..f0dd3cb147 100644
> > > > > --- a/hw/i2c/smbus_ich9.c
> > > > > +++ b/hw/i2c/smbus_ich9.c
> > > > > @@ -105,6 +105,9 @@ static void ich9_smbus_realize(PCIDevice *d, 
> > > > > Error **errp)
> > > > >pm_smbus_init(&d->qdev, &s->smb, false);
> > > > >pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, 
> > > > > PCI_BASE_ADDRESS_SPACE_IO,
> > > > > &s->smb.io);
> > > > > +
> > > > > +s->smb.set_irq = ich9_smb_set_irq;
> > > > > +s->smb.opaque = s;
> > > 
> > > Corey, shouldn't we expand pm_smbus_init() to take set_irq / opaque
> > > arguments?
> > 
> > That would be nice, but the other two user of this function,
> > hw/isa/vt82c686.c and hw/acpi/piix4.c, don't use these fields.
> > I doubt we are getting any new users.  I'm fine either way, but the
> > value is not large.
> 
> The value is in enforcing stricter APIs (providing good examples).

I agree, and the change would be good, but IMHO it's beyond the scope of
this change and would slow things down.

I'll prepare a patch that does this.

Thanks,

-corey

> 
> Reviewed-by: Philippe Mathieu-Daudé 
> 
> 



Re: [PATCH 05/12] hw/i2c/smbus_ich9: Inline ich9_smb_init() and remove it

2023-02-19 Thread Corey Minyard
On Sun, Feb 19, 2023 at 02:45:44PM +0100, Philippe Mathieu-Daudé wrote:
> On 18/2/23 21:25, Corey Minyard wrote:
> > On Mon, Feb 13, 2023 at 06:30:26PM +0100, Bernhard Beschow wrote:
> > > ich9_smb_init() is a legacy init function, so modernize the code.
> > > 
> > > Note that the smb_io_base parameter was unused.
> > 
> > Acked-by: Corey Minyard 
> > 
> > > 
> > > Signed-off-by: Bernhard Beschow 
> > > ---
> > >   include/hw/i386/ich9.h |  1 -
> > >   hw/i2c/smbus_ich9.c| 13 +++--
> > >   hw/i386/pc_q35.c   | 11 ---
> > >   3 files changed, 11 insertions(+), 14 deletions(-)
> > > 
> > > diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
> > > index 05464f6965..52ea116f44 100644
> > > --- a/include/hw/i386/ich9.h
> > > +++ b/include/hw/i386/ich9.h
> > > @@ -9,7 +9,6 @@
> > >   #include "qom/object.h"
> > >   void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
> > > -I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
> > >   void ich9_generate_smi(void);
> > > diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
> > > index d29c0f6ffa..f0dd3cb147 100644
> > > --- a/hw/i2c/smbus_ich9.c
> > > +++ b/hw/i2c/smbus_ich9.c
> > > @@ -105,6 +105,9 @@ static void ich9_smbus_realize(PCIDevice *d, Error 
> > > **errp)
> > >   pm_smbus_init(&d->qdev, &s->smb, false);
> > >   pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, 
> > > PCI_BASE_ADDRESS_SPACE_IO,
> > >&s->smb.io);
> > > +
> > > +s->smb.set_irq = ich9_smb_set_irq;
> > > +s->smb.opaque = s;
> 
> Corey, shouldn't we expand pm_smbus_init() to take set_irq / opaque
> arguments?

That would be nice, but the other two user of this function,
hw/isa/vt82c686.c and hw/acpi/piix4.c, don't use these fields.
I doubt we are getting any new users.  I'm fine either way, but the
value is not large.

-corey

> 
> > >   }
> 



Re: [PATCH 05/12] hw/i2c/smbus_ich9: Inline ich9_smb_init() and remove it

2023-02-18 Thread Corey Minyard
On Mon, Feb 13, 2023 at 06:30:26PM +0100, Bernhard Beschow wrote:
> ich9_smb_init() is a legacy init function, so modernize the code.
> 
> Note that the smb_io_base parameter was unused.

Acked-by: Corey Minyard 

> 
> Signed-off-by: Bernhard Beschow 
> ---
>  include/hw/i386/ich9.h |  1 -
>  hw/i2c/smbus_ich9.c| 13 +++--
>  hw/i386/pc_q35.c   | 11 ---
>  3 files changed, 11 insertions(+), 14 deletions(-)
> 
> diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
> index 05464f6965..52ea116f44 100644
> --- a/include/hw/i386/ich9.h
> +++ b/include/hw/i386/ich9.h
> @@ -9,7 +9,6 @@
>  #include "qom/object.h"
>  
>  void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
> -I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
>  
>  void ich9_generate_smi(void);
>  
> diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
> index d29c0f6ffa..f0dd3cb147 100644
> --- a/hw/i2c/smbus_ich9.c
> +++ b/hw/i2c/smbus_ich9.c
> @@ -105,6 +105,9 @@ static void ich9_smbus_realize(PCIDevice *d, Error **errp)
>  pm_smbus_init(&d->qdev, &s->smb, false);
>  pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
>   &s->smb.io);
> +
> +s->smb.set_irq = ich9_smb_set_irq;
> +s->smb.opaque = s;
>  }
>  
>  static void build_ich9_smb_aml(AcpiDevAmlIf *adev, Aml *scope)
> @@ -137,16 +140,6 @@ static void ich9_smb_class_init(ObjectClass *klass, void 
> *data)
>  adevc->build_dev_aml = build_ich9_smb_aml;
>  }
>  
> -I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
> -{
> -PCIDevice *d =
> -pci_create_simple_multifunction(bus, devfn, true, 
> TYPE_ICH9_SMB_DEVICE);
> -ICH9SMBState *s = ICH9_SMB_DEVICE(d);
> -s->smb.set_irq = ich9_smb_set_irq;
> -s->smb.opaque = s;
> -return s->smb.smbus;
> -}
> -
>  static const TypeInfo ich9_smb_info = {
>  .name   = TYPE_ICH9_SMB_DEVICE,
>  .parent = TYPE_PCI_DEVICE,
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index 4af8474f31..85ba8ed951 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -316,10 +316,15 @@ static void pc_q35_init(MachineState *machine)
>  }
>  
>  if (pcms->smbus_enabled) {
> +PCIDevice *smb;
> +
>  /* TODO: Populate SPD eeprom data.  */
> -pcms->smbus = ich9_smb_init(host_bus,
> -PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),
> -0xb100);
> +smb = pci_create_simple_multifunction(host_bus,
> +  PCI_DEVFN(ICH9_SMB_DEV,
> +ICH9_SMB_FUNC),
> +  true, TYPE_ICH9_SMB_DEVICE);
> +pcms->smbus = I2C_BUS(qdev_get_child_bus(DEVICE(smb), "i2c"));
> +
>  smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
>  }
>  
> -- 
> 2.39.1
> 
> 



Re: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander

2023-02-06 Thread Corey Minyard
On Mon, Feb 06, 2023 at 07:49:34PM +, Titus Rwantare wrote:
> This is a simple i2c device that allows i2c capable devices to have
> GPIOs.
> 
> Reviewed-by: Hao Wu 
> Signed-off-by: Titus Rwantare 
> ---
>  hw/arm/Kconfig  |   1 +
>  hw/gpio/meson.build |   1 +
>  hw/gpio/pca_i2c_gpio.c  | 362 
>  hw/gpio/trace-events|   5 +
>  hw/i2c/Kconfig  |   4 +
>  include/hw/gpio/pca_i2c_gpio.h  |  72 +++
>  tests/qtest/meson.build |   1 +
>  tests/qtest/pca_i2c_gpio-test.c | 169 +++
>  8 files changed, 615 insertions(+)
>  create mode 100644 hw/gpio/pca_i2c_gpio.c
>  create mode 100644 include/hw/gpio/pca_i2c_gpio.h
>  create mode 100644 tests/qtest/pca_i2c_gpio-test.c
> 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 2d157de9b8..1b533ddd76 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -418,6 +418,7 @@ config NPCM7XX
>  select SSI
>  select UNIMP
>  select PCA954X
> +select PCA_I2C_GPIO
>  
>  config FSL_IMX25
>  bool
> diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
> index b726e6d27a..1e5b602002 100644
> --- a/hw/gpio/meson.build
> +++ b/hw/gpio/meson.build
> @@ -12,3 +12,4 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: 
> files('omap_gpio.c'))
>  softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
>  softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
>  softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
> +softmmu_ss.add(when: 'CONFIG_PCA_I2C_GPIO', if_true: files('pca_i2c_gpio.c'))
> diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c
> new file mode 100644
> index 00..afae497a22
> --- /dev/null
> +++ b/hw/gpio/pca_i2c_gpio.c
> @@ -0,0 +1,362 @@
> +/*
> + * NXP PCA I2C GPIO Expanders
> + *
> + * Low-voltage translating 16-bit I2C/SMBus GPIO expander with interrupt 
> output,
> + * reset, and configuration registers
> + *
> + * Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf
> + *
> + * Copyright 2023 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * These devices, by default, are configured to input only. The 
> configuration is

Yout initial email set they are output only by default.

> + * settable through qom/qmp, or i2c.To set some pins as inputs before boot, 
> use
> + * the following in the board file of the machine:
> + *  object_property_set_uint(Object *obj, const char *name,
> + *   uint64_t value, Error **errp);
> + * specifying name as "gpio_config" and the value as a bitfield of the inputs
> + * e.g. for the pca6416, a value of 0xFFF0, sets pins 0-3 as outputs and
> + * 4-15 as inputs.
> + * This value can also be set at runtime through qmp externally, or by
> + * writing to the config register using i2c.

When the real hardware comes up, can it be configured in some way
before the software access it through I2C?  It seems odd to me that you
have a qemu configuration for something that wouldn't normally be
configurable by something at power up time.

Philippe mentioned some things, too, but this looks good to me beyond
that.

-corey

> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/gpio/pca_i2c_gpio.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "migration/vmstate.h"
> +#include "qapi/visitor.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "trace.h"
> +
> +/*
> + * compare new_output to curr_output and update irq to match new_output
> + *
> + * The Input port registers (registers 0 and 1) reflect the incoming logic
> + * levels of the pins, regardless of whether the pin is defined as an input 
> or
> + * an output by the Configuration register.
> + */
> +static void pca_i2c_update_irqs(PCAGPIOState *ps)
> +{
> +PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(ps);
> +uint16_t out_diff = ps->new_output ^ ps->curr_output;
> +uint16_t in_diff = ps->new_input ^ ps->curr_input;
> +uint16_t mask, pin_i;
> +
> +if (in_diff || out_diff) {
> +for (int i = 0; i < pc->num_pins; i++) {
> +mask = BIT(i);
> +/* pin must be configured as an output to be set here */
> +if (out_diff & ~ps->config & mask) {
> +pin_i = mask & ps->new_output;
> +qemu_set_irq(ps->output[i], pin_i > 0);
> +ps->curr_output &= ~mask;
> +ps->curr_output |= pin_i;
> +}
> +
> +if (in_diff & mask) {
> +ps->curr_input &= ~mask;
> +ps->curr_input |= mask & ps->new_input;
> +}
> +}
> +/* make diff = 0 */
> +ps->new_input = ps->curr_input;
> +}
> +}
> +
> +static void pca_i2c_irq_handler(void *opaque, int n, int level)
> +{
> +PCAGPIOState *ps = opaque;
> +PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(opaque);
> +uint16_t mask = BIT(n);
> +
> + 

Re: [PATCH v4 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-25 Thread Corey Minyard
On Tue, Jan 17, 2023 at 06:42:14PM -0800, Peter Delevoryas wrote:
> EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
> I would expect the I2C state machine to be reset to default values, but I
> wouldn't really expect the memory to change at all.

Yes, I agree, I was actually wondering about this reviewing earlier
changes.  Thanks for fixing this.

Reviewed-by: Corey Minyard 

> 
> The current implementation of the at24c EEPROM resets its internal memory on
> reset. This matches the specification in docs/devel/reset.rst:
> 
>   Cold reset is supported by every resettable object. In QEMU, it means we 
> reset
>   to the initial state corresponding to the start of QEMU; this might differ
>   from what is a real hardware cold reset. It differs from other resets (like
>   warm or bus resets) which may keep certain parts untouched.
> 
> But differs from my intuition. For example, if someone writes some information
> to an EEPROM, then AC power cycles their board, they would expect the EEPROM 
> to
> retain that information. It's very useful to be able to test things like this
> in QEMU as well, to verify software instrumentation like determining the cause
> of a reboot.
> 
> Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Joel Stanley 
> ---
>  hw/nvram/eeprom_at24c.c | 22 ++
>  1 file changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index f8d751fa278d..5074776bff04 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c.c
> @@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
> **errp)
>  }
>  
>  ee->mem = g_malloc0(ee->rsize);
> -
> -}
> -
> -static
> -void at24c_eeprom_reset(DeviceState *state)
> -{
> -EEPROMState *ee = AT24C_EE(state);
> -
> -ee->changed = false;
> -ee->cur = 0;
> -ee->haveaddr = 0;
> -
>  memset(ee->mem, 0, ee->rsize);
>  
>  if (ee->init_rom) {
> @@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
>  }
>  }
>  
> +static
> +void at24c_eeprom_reset(DeviceState *state)
> +{
> +EEPROMState *ee = AT24C_EE(state);
> +
> +ee->changed = false;
> +ee->cur = 0;
> +ee->haveaddr = 0;
> +}
> +
>  static Property at24c_eeprom_props[] = {
>  DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
>  DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
> -- 
> 2.39.0
> 
> 



Re: [PATCH v4 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-25 Thread Corey Minyard
On Tue, Jan 17, 2023 at 06:42:13PM -0800, Peter Delevoryas wrote:
> - Create aspeed_eeprom.c and aspeed_eeprom.h
> - Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
> - Include aspeed_eeprom.h in aspeed.c
> - Add fby35_bmc_fruid data
> - Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with 
> data
>   from aspeed_eeprom.c

Reviewed-by: Corey Minyard 

> 
> wget 
> https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
> qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
> ...
> user: root
> pass: 0penBmc
> ...
> root@bmc-oob:~# fruid-util bb
> 
> FRU Information   : Baseboard
> ---   : --
> Chassis Type  : Rack Mount Chassis
> Chassis Part Number   : N/A
> Chassis Serial Number : N/A
> Board Mfg Date: Fri Jan  7 10:30:00 2022
> Board Mfg : XX
> Board Product : Management Board wBMC
> Board Serial  : X
> Board Part Number : XX
> Board FRU ID  : 1.0
> Board Custom Data 1   : X
> Board Custom Data 2   : XX
> Product Manufacturer  : XX
> Product Name  : Yosemite V3.5 EVT2
> Product Part Number   : XX
> Product Version   : EVT2
> Product Serial: X
> Product Asset Tag : XXX
> Product FRU ID: 1.0
> Product Custom Data 1 : X
> Product Custom Data 2 : N/A
> root@bmc-oob:~# fruid-util bmc
> 
> FRU Information   : BMC
> ---   : --
> Board Mfg Date: Mon Jan 10 21:42:00 2022
> Board Mfg : XX
> Board Product : BMC Storage Module
> Board Serial  : X
> Board Part Number : XX
> Board FRU ID  : 1.0
> Board Custom Data 1   : X
> Board Custom Data 2   : XX
> Product Manufacturer  : XX
> Product Name  : Yosemite V3.5 EVT2
> Product Part Number   : XX
> Product Version   : EVT2
> Product Serial: X
> Product Asset Tag : XXX
> Product FRU ID: 1.0
> Product Custom Data 1 : X
> Product Custom Data 2 : Config A
> root@bmc-oob:~# fruid-util nic
> 
> FRU Information   : NIC
> ---   : --
> Board Mfg Date: Tue Nov  2 08:51:00 2021
> Board Mfg : 
> Board Product : Mellanox ConnectX-6 DX OCP3.0
> Board Serial  : 
> Board Part Number : X
> Board FRU ID  : FRU Ver 0.02
> Product Manufacturer  : 
> Product Name  : Mellanox ConnectX-6 DX OCP3.0
> Product Part Number   : X
> Product Version   : A9
> Product Serial: 
> Product Custom Data 3 : ConnectX-6 DX
> 
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Cédric Le Goater 
> Reviewed-by: Joel Stanley 
> ---
>  hw/arm/aspeed.c| 10 --
>  hw/arm/aspeed_eeprom.c | 78 ++
>  hw/arm/aspeed_eeprom.h | 16 +
>  hw/arm/meson.build |  1 +
>  4 files changed, 102 insertions(+), 3 deletions(-)
>  create mode 100644 hw/arm/aspeed_eeprom.c
>  create mode 100644 hw/arm/aspeed_eeprom.h
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index c929c61d582a..382965f82c38 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -14,6 +14,7 @@
>  #include "hw/arm/boot.h"
>  #include "hw/arm/aspeed.h"
>  #include "hw/arm/aspeed_soc.h"
> +#include "hw/arm/aspeed_eeprom.h"
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/misc/pca9552.h"
> @@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
>  
>  at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
>  at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
> -at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
> -at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
> -at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
> +at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
> +  sizeof(fby35_nic_fruid));
> +at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
> +  sizeof(fby35_bb_fruid));
> +at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
> +

Re: [PATCH v4 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-25 Thread Corey Minyard
On Tue, Jan 17, 2023 at 06:42:10PM -0800, Peter Delevoryas wrote:
> This helper is useful in board initialization because lets users initialize 
> and
> realize an EEPROM on an I2C bus with a single function call.

This is a good improvement.

Reviewed-by: Corey Minyard 

> 
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Cédric Le Goater 
> Reviewed-by: Joel Stanley 
> ---
>  hw/arm/aspeed.c | 10 +-
>  hw/arm/npcm7xx_boards.c | 20 +---
>  hw/nvram/eeprom_at24c.c | 12 
>  include/hw/nvram/eeprom_at24c.h | 23 +++
>  4 files changed, 41 insertions(+), 24 deletions(-)
>  create mode 100644 include/hw/nvram/eeprom_at24c.h
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 55f114ef729f..1f9799d4321e 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -17,6 +17,7 @@
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/misc/pca9552.h"
> +#include "hw/nvram/eeprom_at24c.h"
>  #include "hw/sensor/tmp105.h"
>  #include "hw/misc/led.h"
>  #include "hw/qdev-properties.h"
> @@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
>  arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
>  }
>  
> -static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
> -{
> -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> -DeviceState *dev = DEVICE(i2c_dev);
> -
> -qdev_prop_set_uint32(dev, "rom-size", rsize);
> -i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
> -}
> -
>  static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
>  {
>  AspeedSoCState *soc = &bmc->soc;
> diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
> index 6bc6f5d2fe29..9b31207a06e9 100644
> --- a/hw/arm/npcm7xx_boards.c
> +++ b/hw/arm/npcm7xx_boards.c
> @@ -21,6 +21,7 @@
>  #include "hw/i2c/i2c_mux_pca954x.h"
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/loader.h"
> +#include "hw/nvram/eeprom_at24c.h"
>  #include "hw/qdev-core.h"
>  #include "hw/qdev-properties.h"
>  #include "qapi/error.h"
> @@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
> uint32_t num)
>  return I2C_BUS(qdev_get_child_bus(DEVICE(&soc->smbus[num]), "i2c-bus"));
>  }
>  
> -static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
> -  uint32_t rsize)
> -{
> -I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
> -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> -DeviceState *dev = DEVICE(i2c_dev);
> -
> -qdev_prop_set_uint32(dev, "rom-size", rsize);
> -i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
> -}
> -
>  static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
>NPCM7xxState *soc, const int 
> *fan_counts)
>  {
> @@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
>  
> -at24c_eeprom_init(soc, 9, 0x55, 8192);
> -at24c_eeprom_init(soc, 10, 0x55, 8192);
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
>  
>  /*
>   * i2c-11:
> @@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
>  
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
>  
> -at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
>  
>  i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
>TYPE_PCA9548, 0x77);
> @@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
>  i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
>  i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
>  
> -at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
> +at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
>  
>  /* TODO: Add remaining i2c devices. */
>  }
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index 2d4d8b952f38..98857e3626b9 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c

Re: [PATCH v4 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-25 Thread Corey Minyard
On Tue, Jan 17, 2023 at 06:42:11PM -0800, Peter Delevoryas wrote:
> aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Reviewed-by: Corey Minyard 
> 
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Cédric Le Goater 
> Reviewed-by: Philippe Mathieu-Daudé 
> Reviewed-by: Joel Stanley 
> ---
>  hw/arm/aspeed.c | 95 ++---
>  1 file changed, 43 insertions(+), 52 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 1f9799d4321e..c929c61d582a 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
>eeprom_buf);
>  }
>  
> -static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
> -{
> -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> -DeviceState *dev = DEVICE(i2c_dev);
> -
> -qdev_prop_set_uint32(dev, "rom-size", rsize);
> -i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
> -}
> -
>  static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
>  {
>  AspeedSoCState *soc = &bmc->soc;
> @@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>  AspeedSoCState *soc = &bmc->soc;
>  I2CSlave *i2c_mux;
>  
> -aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 0), 0x51, 32 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 0), 0x51, 32 * KiB);
>  
>  create_pca9552(soc, 3, 0x61);
>  
> @@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>   0x4a);
>  i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4),
>"pca9546", 0x70);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
>  create_pca9552(soc, 4, 0x60);
>  
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
> @@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>  create_pca9552(soc, 5, 0x61);
>  i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5),
>"pca9546", 0x70);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
>  
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
>   0x48);
> @@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState 
> *bmc)
>   0x4b);
>  i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6),
>"pca9546", 0x70);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
> -aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
> +at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
>  
>  create_pca9552(soc, 7, 0x30);
>  create_pca9552(soc, 7, 0x31);
> @@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState 
> *bmc)
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), TYPE_TMP105,
>   0x48);
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "max31785", 
> 0x52);
> -aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x50, 64 * KiB);
> -aspeed_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x51, 64 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x50, 64 * KiB);
> +at24c_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 7), 0x51, 64 * KiB);
>  
>  i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->

Re: [PATCH v4 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-25 Thread Corey Minyard
On Tue, Jan 17, 2023 at 06:42:12PM -0800, Peter Delevoryas wrote:
> Allows users to specify binary data to initialize an EEPROM, allowing users to
> emulate data programmed at manufacturing time.
> 
> - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
> - Added at24c_eeprom_init_rom helper function to initialize attributes
> - If -drive property is provided, it overrides init_rom data
> 
> Signed-off-by: Peter Delevoryas 
> Reviewed-by: Joel Stanley 
> ---
>  hw/nvram/eeprom_at24c.c | 37 -
>  include/hw/nvram/eeprom_at24c.h | 16 ++
>  2 files changed, 48 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index 98857e3626b9..f8d751fa278d 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c.c
> @@ -50,6 +50,9 @@ struct EEPROMState {
>  uint8_t *mem;
>  
>  BlockBackend *blk;
> +
> +const uint8_t *init_rom;
> +uint32_t init_rom_size;
>  };
>  
>  static
> @@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
>  
>  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
>  {
> -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> -DeviceState *dev = DEVICE(i2c_dev);
> +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> +}
> +
> +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> rom_size,
> +const uint8_t *init_rom, uint32_t 
> init_rom_size)
> +{
> +EEPROMState *s;
> +
> +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> +
> +qdev_prop_set_uint8(DEVICE(s), "address", address);

Why did you switch from using i2c_slave_new()?  Using it is more
documentation and future-proofing than convenience.

Other than that, looks good to me.

Reviewed-by: Corey Minyard 

> +qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
>  
> -qdev_prop_set_uint32(dev, "rom-size", rom_size);
> -i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
> +/* TODO: Model init_rom with QOM properties. */
> +s->init_rom = init_rom;
> +s->init_rom_size = init_rom_size;
>  
> -return i2c_dev;
> +i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, &error_abort);
> +
> +return I2C_SLAVE(s);
>  }
>  
>  static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
>  {
>  EEPROMState *ee = AT24C_EE(dev);
>  
> +if (ee->init_rom_size > ee->rsize) {
> +error_setg(errp, "%s: init rom is larger than rom: %u > %u",
> +   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
> +return;
> +}
> +
>  if (ee->blk) {
>  int64_t len = blk_getlength(ee->blk);
>  
> @@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
> **errp)
>  }
>  
>  ee->mem = g_malloc0(ee->rsize);
> +
>  }
>  
>  static
> @@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
>  
>  memset(ee->mem, 0, ee->rsize);
>  
> +if (ee->init_rom) {
> +memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
> +}
> +
>  if (ee->blk) {
>  int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
>  
> diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
> index 196db309d451..acb9857b2add 100644
> --- a/include/hw/nvram/eeprom_at24c.h
> +++ b/include/hw/nvram/eeprom_at24c.h
> @@ -20,4 +20,20 @@
>   */
>  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
>  
> +
> +/*
> + * Create and realize an AT24C EEPROM device on the heap with initial data.
> + * @bus: I2C bus to put it on
> + * @address: I2C address of the EEPROM slave when put on a bus
> + * @rom_size: size of the EEPROM
> + * @init_rom: Array of bytes to initialize EEPROM memory with
> + * @init_rom_size: Size of @init_rom, must be less than or equal to @rom_size
> + *
> + * Create the device state structure, initialize it, put it on the specified
> + * @bus, and drop the reference to it (the device is realized). Copies the 
> data
> + * from @init_rom to the beginning of the EEPROM memory buffer.
> + */
> +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> rom_size,
> +const uint8_t *init_rom, uint32_t 
> init_rom_size);
> +
>  #endif
> -- 
> 2.39.0
> 
> 



Re: [PATCH v3 0/5] hw/i2c/bitbang_i2c: Housekeeping

2023-01-12 Thread Corey Minyard
On Wed, Jan 11, 2023 at 09:50:11AM +0100, Philippe Mathieu-Daudé wrote:
> Series fully reviewed.

These all look good to me

Acked-by: Corey Minyard 

You mentioned the ARM tree, is this going in through there?

-corey

> 
> Since v2:
> - Use array of const pointers to const (Richard)
> 
> Since v1:
> - Fixed overwritten RECEIVING_BIT7 entry (Richard)
> - Picked R-b tags
> 
> - Remove unused dummy MemoryRegion
> - Convert DPRINTF() to using trace events
> 
> (series used as base for follow-up, better if merged via ARM tree)
> 
> Philippe Mathieu-Daudé (5):
>   hw/i2c/bitbang_i2c: Define TYPE_GPIO_I2C in public header
>   hw/i2c/bitbang_i2c: Remove unused dummy MemoryRegion
>   hw/i2c/bitbang_i2c: Change state calling bitbang_i2c_set_state()
> helper
>   hw/i2c/bitbang_i2c: Trace state changes
>   hw/i2c/bitbang_i2c: Convert DPRINTF() to trace events
> 
>  hw/arm/musicpal.c|  3 +-
>  hw/i2c/bitbang_i2c.c | 80 ++--
>  hw/i2c/trace-events  |  7 
>  include/hw/i2c/bitbang_i2c.h |  2 +
>  4 files changed, 61 insertions(+), 31 deletions(-)
> 
> -- 
> 2.38.1
> 
> 



Re: [PATCH RFC 2/3] hw/i2c: add mctp core

2022-11-16 Thread Corey Minyard
On Wed, Nov 16, 2022 at 09:43:11AM +0100, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add an abstract MCTP over I2C endpoint model. This implements MCTP
> control message handling as well as handling the actual I2C transport
> (packetization).
> 
> Devices are intended to derive from this and implement the class
> methods.
> 
> Parts of this implementation is inspired by code[1] previously posted by
> Jonathan Cameron.

I have some comments inline, mostly about buffer handling.  Buffer
handling is scary to me, so you might see some paranoia here :-).

> 
>   [1]: 
> https://lore.kernel.org/qemu-devel/20220520170128.4436-1-jonathan.came...@huawei.com/
> 
> Signed-off-by: Klaus Jensen 
> ---
>  hw/arm/Kconfig |   1 +
>  hw/i2c/Kconfig |   4 +
>  hw/i2c/mctp.c  | 365 +
>  hw/i2c/meson.build |   1 +
>  hw/i2c/trace-events|  12 ++
>  include/hw/i2c/mctp.h  |  83 ++
>  include/hw/misc/mctp.h |  43 +
>  7 files changed, 509 insertions(+)
>  create mode 100644 hw/i2c/mctp.c
>  create mode 100644 include/hw/i2c/mctp.h
>  create mode 100644 include/hw/misc/mctp.h
> 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 17fcde8e1ccc..3233bdc193d7 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -444,6 +444,7 @@ config ASPEED_SOC
>  select DS1338
>  select FTGMAC100
>  select I2C
> +select MCTP_I2C
>  select DPS310
>  select PCA9552
>  select SERIAL
> diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
> index 9bb8870517f8..5dd43d550c32 100644
> --- a/hw/i2c/Kconfig
> +++ b/hw/i2c/Kconfig
> @@ -41,3 +41,7 @@ config PCA954X
>  config PMBUS
>  bool
>  select SMBUS
> +
> +config MCTP_I2C
> +bool
> +select I2C
> diff --git a/hw/i2c/mctp.c b/hw/i2c/mctp.c
> new file mode 100644
> index ..46376de95a98
> --- /dev/null
> +++ b/hw/i2c/mctp.c
> @@ -0,0 +1,365 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * SPDX-FileCopyrightText: Copyright (c) 2022 Samsung Electronics Co., Ltd.
> + * SPDX-FileContributor: Klaus Jensen 
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/main-loop.h"
> +
> +#include "hw/qdev-properties.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/i2c/mctp.h"
> +
> +#include "trace.h"
> +
> +static uint8_t crc8(uint16_t data)
> +{
> +#define POLY (0x1070U << 3)
> +int i;
> +
> +for (i = 0; i < 8; i++) {
> +if (data & 0x8000) {
> +data = data ^ POLY;
> +}
> +
> +data = data << 1;
> +}
> +
> +return (uint8_t)(data >> 8);
> +#undef POLY
> +}
> +
> +static uint8_t i2c_smbus_pec(uint8_t crc, uint8_t *buf, size_t len)
> +{
> +int i;
> +
> +for (i = 0; i < len; i++) {
> +crc = crc8((crc ^ buf[i]) << 8);
> +}
> +
> +return crc;
> +}

The PEC calculation probably belongs in it's own smbus.c file, since
it's generic, so someone looking will find it.

> +
> +void i2c_mctp_schedule_send(MCTPI2CEndpoint *mctp)
> +{
> +I2CBus *i2c = I2C_BUS(qdev_get_parent_bus(DEVICE(mctp)));
> +
> +mctp->tx.state = I2C_MCTP_STATE_TX_START_SEND;
> +
> +i2c_bus_master(i2c, mctp->tx.bh);
> +}
> +
> +static void i2c_mctp_tx(void *opaque)
> +{
> +DeviceState *dev = DEVICE(opaque);
> +I2CBus *i2c = I2C_BUS(qdev_get_parent_bus(dev));
> +I2CSlave *slave = I2C_SLAVE(dev);
> +MCTPI2CEndpoint *mctp = MCTP_I2C_ENDPOINT(dev);
> +MCTPI2CEndpointClass *mc = MCTP_I2C_ENDPOINT_GET_CLASS(mctp);
> +MCTPI2CPacket *pkt = (MCTPI2CPacket *)mctp->buffer;
> +uint8_t flags = 0;
> +
> +switch (mctp->tx.state) {
> +case I2C_MCTP_STATE_TX_SEND_BYTE:
> +if (mctp->pos < mctp->len) {
> +uint8_t byte = mctp->buffer[mctp->pos];
> +
> +trace_i2c_mctp_tx_send_byte(mctp->pos, byte);
> +
> +/* send next byte */
> +i2c_send_async(i2c, byte);
> +
> +mctp->pos++;
> +
> +break;
> +}
> +
> +/* packet sent */
> +i2c_end_transfer(i2c);
> +
> +/* fall through */
> +
> +case I2C_MCTP_STATE_TX_START_SEND:
> +if (mctp->tx.is_control) {
> +/* packet payload is already in buffer */
> +flags |= MCTP_H_FLAGS_SOM | MCTP_H_FLAGS_EOM;
> +} else {
> +/* get message bytes from derived device */
> +mctp->len = mc->get_message_bytes(mctp, pkt->mctp.payload,
> +  I2C_MCTP_MAXMTU, &flags);
> +}
> +
> +if (!mctp->len) {
> +trace_i2c_mctp_tx_done();
> +
> +/* no more packets needed; release the bus */
> +i2c_bus_release(i2c);
> +
> +mctp->state = I2C_MCTP_STATE_IDLE;
> +mctp->tx.is_control = false;
> +
> +break;
> +}
> +
> +mctp->state = I2C_MCTP_STATE_TX;
> +
> +pkt->i2c = (MCTPI2CPacketHeader) {
> +.dest = mctp->tx.addr & ~0x1,
> +.prot = 0xf,
> +.byte_c

Re: [PATCH maybe-7.2 1/3] hw/i2c: only schedule pending master when bus is idle

2022-11-16 Thread Corey Minyard
On Wed, Nov 16, 2022 at 09:43:10AM +0100, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> It is not given that the current master will release the bus after a
> transfer ends. Only schedule a pending master if the bus is idle.
> 

Yes, I think this is correct.

Acked-by: Corey Minyard 

Is there a reason you are thinking this is needed for 7.2?  There's no
code in qemu proper that uses this yet.  I had assumed that was coming
soon after the patch.

-corey

> Fixes: 37fa5ca42623 ("hw/i2c: support multiple masters")
> Signed-off-by: Klaus Jensen 
> ---
>  hw/i2c/aspeed_i2c.c  |  2 ++
>  hw/i2c/core.c| 37 ++---
>  include/hw/i2c/i2c.h |  2 ++
>  3 files changed, 26 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
> index c166fd20fa11..1f071a3811f7 100644
> --- a/hw/i2c/aspeed_i2c.c
> +++ b/hw/i2c/aspeed_i2c.c
> @@ -550,6 +550,8 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, 
> uint64_t value)
>  }
>  SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_STOP_CMD, 0);
>  aspeed_i2c_set_state(bus, I2CD_IDLE);
> +
> +i2c_schedule_pending_master(bus->bus);
>  }
>  
>  if (aspeed_i2c_bus_pkt_mode_en(bus)) {
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index d4ba8146bffb..bed594fe599b 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -185,22 +185,39 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, 
> bool is_recv)
>  
>  void i2c_bus_master(I2CBus *bus, QEMUBH *bh)
>  {
> +I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
> +node->bh = bh;
> +
> +QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
> +}
> +
> +void i2c_schedule_pending_master(I2CBus *bus)
> +{
> +I2CPendingMaster *node;
> +
>  if (i2c_bus_busy(bus)) {
> -I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
> -node->bh = bh;
> -
> -QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
> +/* someone is already controlling the bus; wait for it to release it 
> */
> +return;
> +}
>  
> +if (QSIMPLEQ_EMPTY(&bus->pending_masters)) {
>  return;
>  }
>  
> -bus->bh = bh;
> +node = QSIMPLEQ_FIRST(&bus->pending_masters);
> +bus->bh = node->bh;
> +
> +QSIMPLEQ_REMOVE_HEAD(&bus->pending_masters, entry);
> +g_free(node);
> +
>  qemu_bh_schedule(bus->bh);
>  }
>  
>  void i2c_bus_release(I2CBus *bus)
>  {
>  bus->bh = NULL;
> +
> +i2c_schedule_pending_master(bus);
>  }
>  
>  int i2c_start_recv(I2CBus *bus, uint8_t address)
> @@ -234,16 +251,6 @@ void i2c_end_transfer(I2CBus *bus)
>  g_free(node);
>  }
>  bus->broadcast = false;
> -
> -if (!QSIMPLEQ_EMPTY(&bus->pending_masters)) {
> -I2CPendingMaster *node = QSIMPLEQ_FIRST(&bus->pending_masters);
> -bus->bh = node->bh;
> -
> -QSIMPLEQ_REMOVE_HEAD(&bus->pending_masters, entry);
> -g_free(node);
> -
> -qemu_bh_schedule(bus->bh);
> -}
>  }
>  
>  int i2c_send(I2CBus *bus, uint8_t data)
> diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
> index 9b9581d23097..2a3abacd1ba6 100644
> --- a/include/hw/i2c/i2c.h
> +++ b/include/hw/i2c/i2c.h
> @@ -141,6 +141,8 @@ int i2c_start_send(I2CBus *bus, uint8_t address);
>   */
>  int i2c_start_send_async(I2CBus *bus, uint8_t address);
>  
> +void i2c_schedule_pending_master(I2CBus *bus);
> +
>  void i2c_end_transfer(I2CBus *bus);
>  void i2c_nack(I2CBus *bus);
>  void i2c_ack(I2CBus *bus);
> -- 
> 2.38.1
> 
> 



[PULL] IPMI bug fixes

2022-08-01 Thread Corey Minyard
Not a huge deal, but probably makes mainainers lives a little easier.

Add a change to make Coverity happy.


Corey Minyard (1):
  ipmi:smbus: Add a check around a memcpy

 hw/ipmi/smbus_ipmi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
cminyard@t560:/personal/git/qemu/Z$ git request-pull master origin 
tags/for-qemu-2022-08-01
The following changes since commit cc42559ab129a15554cc485ea9265e34dde7ab5b:

  Merge tag 'pull-ppc-20220728' of https://gitlab.com/danielhb/qemu into 
staging (2022-07-28 15:06:42 -0700)

are available in the Git repository at:

  g...@github.com:cminyard/qemu.git tags/for-qemu-2022-08-01

for you to fetch changes up to 3fde641e7286f9b968bdb3b4b922c6465f2a9abc:

  ipmi:smbus: Add a check around a memcpy (2022-08-01 06:40:50 -0500)


Add a change to make Coverity happy.

----
Corey Minyard (1):
  ipmi:smbus: Add a check around a memcpy

 hw/ipmi/smbus_ipmi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)




[PATCH] ipmi:smbus: Add a check around a memcpy

2022-07-31 Thread minyard
From: Corey Minyard 

In one case:

  memcpy(sid->inmsg + sid->inlen, buf, len);

if len == 0 then sid->inmsg + sig->inlen can point to one past the inmsg
array if the array is full.  We have to allow len == 0 due to some
vagueness in the spec, but we don't have to call memcpy.

Found by Coverity.  This is not a problem in practice, but the results
are technically (maybe) undefined.  So make Coverity happy.

Reported-by: Peter Maydell 
Signed-off-by: Corey Minyard 
---
 hw/ipmi/smbus_ipmi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

I think this should do it.

diff --git a/hw/ipmi/smbus_ipmi.c b/hw/ipmi/smbus_ipmi.c
index 9ef9112dd5..d0991ab7f9 100644
--- a/hw/ipmi/smbus_ipmi.c
+++ b/hw/ipmi/smbus_ipmi.c
@@ -281,7 +281,9 @@ static int ipmi_write_data(SMBusDevice *dev, uint8_t *buf, 
uint8_t len)
  */
 send = true;
 }
-memcpy(sid->inmsg + sid->inlen, buf, len);
+if (len > 0) {
+memcpy(sid->inmsg + sid->inlen, buf, len);
+}
 sid->inlen += len;
 break;
 }
-- 
2.25.1




Re: [PATCH 12/15] ipmi: Add an SMBus IPMI interface

2022-07-29 Thread Corey Minyard
On Tue, Jun 28, 2022 at 05:21:44PM +0100, Peter Maydell wrote:
> On Thu, 19 Sept 2019 at 22:39,  wrote:
> >
> > From: Corey Minyard 
> >
> > Signed-off-by: Corey Minyard 
> > ---
> 

Thank you for the ping.  Comments inline...

> Very old patch, but Coverity has decided it doesn't like something
> in this function that's still basically the same in the current codebase
> (CID 1487146):
> 
> > +static int ipmi_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len)
> > +{
> > +SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
> > +bool send = false;
> > +uint8_t cmd;
> > +int ret = 0;
> > +
> > +/* length is guaranteed to be >= 1. */
> > +cmd = *buf++;
> > +len--;
> > +
> > +/* Handle read request, which don't have any data in the write part. */
> > +switch (cmd) {
> > +case SSIF_IPMI_RESPONSE:
> > +sid->currblk = 0;
> > +ret = ipmi_load_readbuf(sid);
> > +break;
> > +
> > +case SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE:
> > +sid->currblk++;
> > +ret = ipmi_load_readbuf(sid);
> > +break;
> > +
> > +case SSIF_IPMI_MULTI_PART_RETRY:
> > +if (len >= 1) {
> > +sid->currblk = buf[0];
> > +ret = ipmi_load_readbuf(sid);
> > +} else {
> > +ret = -1;
> > +}
> > +break;
> > +
> > +default:
> > +break;
> > +}
> > +
> > +/* This should be a message write, make the length is there and 
> > correct. */
> > +if (len >= 1) {
> > +if (*buf != len - 1 || *buf > MAX_SSIF_IPMI_MSG_CHUNK) {
> > +return -1; /* Bogus message */
> > +}
> > +buf++;
> > +len--;
> > +}
> 
> After all of this preamble, len can be zero...
> 
> > +
> > +switch (cmd) {
> > +case SSIF_IPMI_REQUEST:
> > +send = true;
> > +/* FALLTHRU */
> > +case SSIF_IPMI_MULTI_PART_REQUEST_START:
> > +if (len < 2) {
> > +return -1; /* Bogus. */
> > +}
> > +memcpy(sid->inmsg, buf, len);
> > +sid->inlen = len;
> > +break;
> > +
> > +case SSIF_IPMI_MULTI_PART_REQUEST_END:
> > +send = true;
> > +/* FALLTHRU */
> > +case SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE:
> > +if (!sid->inlen) {
> > +return -1; /* Bogus. */
> > +}
> > +if (sid->inlen + len > MAX_SSIF_IPMI_MSG_SIZE) {
> > +sid->inlen = 0; /* Discard the message. */
> > +return -1; /* Bogus. */
> > +}
> 
> ...this error checking on the values of the 'middle' request
> means that after one 'middle' request we can end up with
> sid->inlen == MAX_SSIF_IPMI_MSG_SIZE (ie we filled the
> entire sid->inmsg[] array).
> 
> But then if we get another 'middle' request with len == 0,
> that will pass this error checking because (sid->inlen + len == MSG_SIZE)
> and fall through into...
> 
> > +if (len < 32) {
> > +/*
> > + * Special hack, a multi-part middle that is less than 32 bytes
> > + * marks the end of a message.  The specification is fairly
> > + * confusing, so some systems to this, even sending a zero
> > + * length end message to mark the end.
> > + */
> > +send = true;
> > +}
> > +memcpy(sid->inmsg + sid->inlen, buf, len);
> 
> ...calling memcpy() with argument 1 being a pointer that points
> one past the end of the array. Even though len will be 0 and
> we won't memcpy() anything, this is (depending on how you choose
> to intepret things the C standard doesn't come right out and state
> explicitly) undefined behaviour, because memcpy() wants to be passed
> valid pointers, even if you ask it to do no work with a zero len.
> 
> This isn't going to be a visible bug in practical terms, but it would
> make Coverity happy if we either (a) rejected a request with an empty
> length or else (b) skipped the memcpy(). I don't know enough about
> IPMI to know which is better.

Hmm.  In some cases you have to accept a zero-length packet (as
described in the comments), but if you said:

  if (len > 0)
  memcpy(sid->inmsg + sid->inlen, buf, len);

would that make Coverity happy?  I was under the impression that if you
passed zero into len, you could pass anything into the data on a memcpy.
But apparently not; I can make this change.

-corey

> 
> > +sid->inlen += len;
> > +break;
> > +}
> > +
> > +if (send && sid->inlen) {
> > +smbus_ipmi_send_msg(sid);
> > +}
> > +
> > +return ret;
> > +}
> 
> thanks
> -- PMM
> 



Re: [PATCH v2 1/9] hw/i2c/pca954x: Add method to get channels

2022-07-05 Thread Corey Minyard
On Tue, Jul 05, 2022 at 12:13:52PM -0700, Peter Delevoryas wrote:
> I added this helper in the Aspeed machine file a while ago to help
> initialize fuji-bmc i2c devices. This moves it to the official pca954x
> file so that other files can use it.
> 
> This does something very similar to pca954x_i2c_get_bus, but I think
> this is useful when you have a very complicated dts with a lot of
> switches, like the fuji dts.
> 
> This convenience method lets you write code that produces a flat array
> of I2C buses that matches the naming in the dts. After that you can just
> add individual sensors using the flat array of I2C buses.

This is an improvment, I think.  But it really needs to be two patches,
one with the I2C portion, and one with the aspeed portion.

Also, the name is a little misleading, you might want to name it 
pca954x_i2c_create_get_channels

-corey

> 
> See fuji_bmc_i2c_init to understand this point further.
> 
> The fuji dts is here for reference:
> 
> https://github.com/torvalds/linux/blob/40cb6373b46/arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts
> 
> Signed-off-by: Peter Delevoryas 
> ---
>  hw/arm/aspeed.c  | 29 +
>  hw/i2c/i2c_mux_pca954x.c | 10 ++
>  include/hw/i2c/i2c_mux_pca954x.h | 13 +
>  3 files changed, 32 insertions(+), 20 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 6fe9b13548..bee8a748ec 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -793,15 +793,6 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>  create_pca9552(soc, 15, 0x60);
>  }
>  
> -static void get_pca9548_channels(I2CBus *bus, uint8_t mux_addr,
> - I2CBus **channels)
> -{
> -I2CSlave *mux = i2c_slave_create_simple(bus, "pca9548", mux_addr);
> -for (int i = 0; i < 8; i++) {
> -channels[i] = pca954x_i2c_get_bus(mux, i);
> -}
> -}
> -
>  #define TYPE_LM75 TYPE_TMP105
>  #define TYPE_TMP75 TYPE_TMP105
>  #define TYPE_TMP422 "tmp422"
> @@ -814,20 +805,18 @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
>  for (int i = 0; i < 16; i++) {
>  i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
>  }
> -I2CBus *i2c180 = i2c[2];
> -I2CBus *i2c480 = i2c[8];
> -I2CBus *i2c600 = i2c[11];
>  
> -get_pca9548_channels(i2c180, 0x70, &i2c[16]);
> -get_pca9548_channels(i2c480, 0x70, &i2c[24]);
> +pca954x_i2c_get_channels(i2c[2], 0x70, "pca9548", &i2c[16]);
> +pca954x_i2c_get_channels(i2c[8], 0x70, "pca9548", &i2c[24]);
>  /* NOTE: The device tree skips [32, 40) in the alias numbering */
> -get_pca9548_channels(i2c600, 0x77, &i2c[40]);
> -get_pca9548_channels(i2c[24], 0x71, &i2c[48]);
> -get_pca9548_channels(i2c[25], 0x72, &i2c[56]);
> -get_pca9548_channels(i2c[26], 0x76, &i2c[64]);
> -get_pca9548_channels(i2c[27], 0x76, &i2c[72]);
> +pca954x_i2c_get_channels(i2c[11], 0x77, "pca9548", &i2c[40]);
> +pca954x_i2c_get_channels(i2c[24], 0x71, "pca9548", &i2c[48]);
> +pca954x_i2c_get_channels(i2c[25], 0x72, "pca9548", &i2c[56]);
> +pca954x_i2c_get_channels(i2c[26], 0x76, "pca9548", &i2c[64]);
> +pca954x_i2c_get_channels(i2c[27], 0x76, "pca9548", &i2c[72]);
>  for (int i = 0; i < 8; i++) {
> -get_pca9548_channels(i2c[40 + i], 0x76, &i2c[80 + i * 8]);
> +pca954x_i2c_get_channels(i2c[40 + i], 0x76, "pca9548",
> + &i2c[80 + i * 8]);
>  }
>  
>  i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4c);
> diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> index 3945de795c..6b07804546 100644
> --- a/hw/i2c/i2c_mux_pca954x.c
> +++ b/hw/i2c/i2c_mux_pca954x.c
> @@ -169,6 +169,16 @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t 
> channel)
>  return pca954x->bus[channel];
>  }
>  
> +void pca954x_i2c_get_channels(I2CBus *bus, uint8_t address,
> +  const char *type_name, I2CBus **channels)
> +{
> +I2CSlave *mux = i2c_slave_create_simple(bus, type_name, address);
> +Pca954xClass *pc = PCA954X_GET_CLASS(mux);
> +Pca954xState *pca954x = PCA954X(mux);
> +
> +memcpy(channels, pca954x->bus, pc->nchans * sizeof(channels[0]));
> +}
> +
>  static void pca9546_class_init(ObjectClass *klass, void *data)
>  {
>  Pca954xClass *s = PCA954X_CLASS(klass);
> diff --git a/include/hw/i2c/i2c_mux_pca954x.h 
> b/include/hw/i2c/i2c_mux_pca954x.h
> index 3dd25ec983..3a676a30a9 100644
> --- a/include/hw/i2c/i2c_mux_pca954x.h
> +++ b/include/hw/i2c/i2c_mux_pca954x.h
> @@ -16,4 +16,17 @@
>   */
>  I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel);
>  
> +/**
> + * Creates an i2c mux and retrieves all of the channels associated with it.
> + *
> + * @bus: the i2c bus where the i2c mux resides.
> + * @address: the address of the i2c mux on the aforementioned i2c bus.
> + * @type_name: name of the i2c mux type to create.
> + * @channels: an output parameter specifying where to return the chan

Re: [RFC PATCH v2 4/6] hw/i2c: add asynchronous send

2022-06-01 Thread Corey Minyard
On Wed, Jun 01, 2022 at 11:08:29PM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add an asynchronous version of i2c_send() that requires the slave to
> explicitly acknowledge on the bus with i2c_ack().
> 
> The current master must use the new i2c_start_send_async() to indicate
> that it wants to do an asynchronous transfer. This allows the i2c core
> to check if the target slave supports this or not. This approach relies
> on adding a new enum i2c_event member, which is why a bunch of other
> devices needs changes in their event handling switches.

This would be easier to read if you split out the default return of -1
in all the devices to a separate patch.

You've already pointed out the lack of nack support.

I think this is ok outside of that.

-corey

> 
> Signed-off-by: Klaus Jensen 
> ---
>  hw/arm/pxa2xx.c|  2 ++
>  hw/display/sii9022.c   |  2 ++
>  hw/display/ssd0303.c   |  2 ++
>  hw/i2c/core.c  | 36 +++-
>  hw/i2c/smbus_slave.c   |  4 
>  hw/i2c/trace-events|  2 ++
>  hw/misc/ibm-cffps.c|  2 ++
>  hw/misc/ir35221.c  |  2 ++
>  hw/nvram/eeprom_at24c.c|  2 ++
>  hw/sensor/lsm303dlhc_mag.c |  2 ++
>  include/hw/i2c/i2c.h   | 16 
>  11 files changed, 71 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index f4f687df68ef..93dda83d7aa9 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -1305,6 +1305,8 @@ static int pxa2xx_i2c_event(I2CSlave *i2c, enum 
> i2c_event event)
>  case I2C_NACK:
>  s->status |= 1 << 1; /* set ACKNAK */
>  break;
> +default:
> +return -1;
>  }
>  pxa2xx_i2c_update(s);
>  
> diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c
> index b591a5878901..664fd4046d82 100644
> --- a/hw/display/sii9022.c
> +++ b/hw/display/sii9022.c
> @@ -76,6 +76,8 @@ static int sii9022_event(I2CSlave *i2c, enum i2c_event 
> event)
>  break;
>  case I2C_NACK:
>  break;
> +default:
> +return -1;
>  }
>  
>  return 0;
> diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c
> index aeae22da9c29..d67b0ad7b529 100644
> --- a/hw/display/ssd0303.c
> +++ b/hw/display/ssd0303.c
> @@ -196,6 +196,8 @@ static int ssd0303_event(I2CSlave *i2c, enum i2c_event 
> event)
>  case I2C_NACK:
>  /* Nothing to do.  */
>  break;
> +default:
> +return -1;
>  }
>  
>  return 0;
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index 145dce60782a..d4ba8146bffb 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -161,7 +161,8 @@ static int i2c_do_start_transfer(I2CBus *bus, uint8_t 
> address,
> start condition.  */
>  
>  if (sc->event) {
> -trace_i2c_event("start", s->address);
> +trace_i2c_event(event == I2C_START_SEND ? "start" : 
> "start_async",
> +s->address);
>  rv = sc->event(s, event);
>  if (rv && !bus->broadcast) {
>  if (bus_scanned) {
> @@ -212,6 +213,11 @@ int i2c_start_send(I2CBus *bus, uint8_t address)
>  return i2c_do_start_transfer(bus, address, I2C_START_SEND);
>  }
>  
> +int i2c_start_send_async(I2CBus *bus, uint8_t address)
> +{
> +return i2c_do_start_transfer(bus, address, I2C_START_SEND_ASYNC);
> +}
> +
>  void i2c_end_transfer(I2CBus *bus)
>  {
>  I2CSlaveClass *sc;
> @@ -261,6 +267,23 @@ int i2c_send(I2CBus *bus, uint8_t data)
>  return ret ? -1 : 0;
>  }
>  
> +int i2c_send_async(I2CBus *bus, uint8_t data)
> +{
> +I2CNode *node = QLIST_FIRST(&bus->current_devs);
> +I2CSlave *slave = node->elt;
> +I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(slave);
> +
> +if (!sc->send_async) {
> +return -1;
> +}
> +
> +trace_i2c_send_async(slave->address, data);
> +
> +sc->send_async(slave, data);
> +
> +return 0;
> +}
> +
>  uint8_t i2c_recv(I2CBus *bus)
>  {
>  uint8_t data = 0xff;
> @@ -297,6 +320,17 @@ void i2c_nack(I2CBus *bus)
>  }
>  }
>  
> +void i2c_ack(I2CBus *bus)
> +{
> +if (!bus->bh) {
> +return;
> +}
> +
> +trace_i2c_ack();
> +
> +qemu_bh_schedule(bus->bh);
> +}
> +
>  static int i2c_slave_post_load(void *opaque, int version_id)
>  {
>  I2CSlave *dev = opaque;
> diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c
> index 5d10e27664db..feb3ec633350 100644
> --- a/hw/i2c/smbus_slave.c
> +++ b/hw/i2c/smbus_slave.c
> @@ -143,6 +143,10 @@ static int smbus_i2c_event(I2CSlave *s, enum i2c_event 
> event)
>  dev->mode = SMBUS_CONFUSED;
>  break;
>  }
> +break;
> +
> +default:
> +return -1;
>  }
>  
>  return 0;
> diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
> index 209275ed2dc8..af181d43ee64 100644
> --- a/hw/i2c/trace-events
> +++ b/hw/i2c/trace-events
> @@ -4,7 +4,9 @@
>  
>  i2c_event(const char *event, uint8_t address) "

Re: [RFC PATCH v2 3/6] hw/i2c: support multiple masters

2022-06-01 Thread Corey Minyard
On Wed, Jun 01, 2022 at 11:08:28PM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Allow slaves to master the bus by registering a bottom halve. If the bus
> is busy, the bottom halve is queued up. When a slave has succesfully
  ^ half
> mastered the bus, the bottom halve is scheduled.
   ^ half

"halve" is a verb that means to split something into two pieces.  Yes,
English is a strange language :).

Also, technically from an I2C point of view, masters master the bus and
slaves only respond.  The way it's phrased here and elsewhere sounds a
little strange from that point of view.

I'm ok with this patch.  It's straightforward.

> 
> Signed-off-by: Klaus Jensen 
> ---
>  hw/i2c/core.c| 34 +-
>  include/hw/i2c/i2c.h | 14 ++
>  2 files changed, 47 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index d0cb2d32fa44..145dce60782a 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -13,6 +13,7 @@
>  #include "migration/vmstate.h"
>  #include "qapi/error.h"
>  #include "qemu/module.h"
> +#include "qemu/main-loop.h"
>  #include "trace.h"
>  
>  #define I2C_BROADCAST 0x00
> @@ -62,6 +63,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
>  
>  bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
>  QLIST_INIT(&bus->current_devs);
> +QSIMPLEQ_INIT(&bus->pending_masters);
>  vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
>  return bus;
>  }
> @@ -74,7 +76,7 @@ void i2c_slave_set_address(I2CSlave *dev, uint8_t address)
>  /* Return nonzero if bus is busy.  */
>  int i2c_bus_busy(I2CBus *bus)
>  {
> -return !QLIST_EMPTY(&bus->current_devs);
> +return !QLIST_EMPTY(&bus->current_devs) || bus->bh;
>  }
>  
>  bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
> @@ -180,6 +182,26 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, 
> bool is_recv)
> : I2C_START_SEND);
>  }
>  
> +void i2c_bus_master(I2CBus *bus, QEMUBH *bh)
> +{
> +if (i2c_bus_busy(bus)) {
> +I2CPendingMaster *node = g_new(struct I2CPendingMaster, 1);
> +node->bh = bh;
> +
> +QSIMPLEQ_INSERT_TAIL(&bus->pending_masters, node, entry);
> +
> +return;
> +}
> +
> +bus->bh = bh;
> +qemu_bh_schedule(bus->bh);
> +}
> +
> +void i2c_bus_release(I2CBus *bus)
> +{
> +bus->bh = NULL;
> +}
> +
>  int i2c_start_recv(I2CBus *bus, uint8_t address)
>  {
>  return i2c_do_start_transfer(bus, address, I2C_START_RECV);
> @@ -206,6 +228,16 @@ void i2c_end_transfer(I2CBus *bus)
>  g_free(node);
>  }
>  bus->broadcast = false;
> +
> +if (!QSIMPLEQ_EMPTY(&bus->pending_masters)) {
> +I2CPendingMaster *node = QSIMPLEQ_FIRST(&bus->pending_masters);
> +bus->bh = node->bh;
> +
> +QSIMPLEQ_REMOVE_HEAD(&bus->pending_masters, entry);
> +g_free(node);
> +
> +qemu_bh_schedule(bus->bh);
> +}
>  }
>  
>  int i2c_send(I2CBus *bus, uint8_t data)
> diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
> index 5ca3b708c0be..be8bb8b78a60 100644
> --- a/include/hw/i2c/i2c.h
> +++ b/include/hw/i2c/i2c.h
> @@ -69,13 +69,25 @@ struct I2CNode {
>  QLIST_ENTRY(I2CNode) next;
>  };
>  
> +typedef struct I2CPendingMaster I2CPendingMaster;
> +
> +struct I2CPendingMaster {
> +QEMUBH *bh;
> +QSIMPLEQ_ENTRY(I2CPendingMaster) entry;
> +};
> +
>  typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList;
> +typedef QSIMPLEQ_HEAD(I2CPendingMasters, I2CPendingMaster) I2CPendingMasters;
>  
>  struct I2CBus {
>  BusState qbus;
>  I2CNodeList current_devs;
> +I2CPendingMasters pending_masters;
>  uint8_t saved_address;
>  bool broadcast;
> +
> +/* Set from slave currently mastering the bus. */
> +QEMUBH *bh;
>  };
>  
>  I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
> @@ -117,6 +129,8 @@ int i2c_start_send(I2CBus *bus, uint8_t address);
>  
>  void i2c_end_transfer(I2CBus *bus);
>  void i2c_nack(I2CBus *bus);
> +void i2c_bus_master(I2CBus *bus, QEMUBH *bh);
> +void i2c_bus_release(I2CBus *bus);
>  int i2c_send(I2CBus *bus, uint8_t data);
>  uint8_t i2c_recv(I2CBus *bus);
>  bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
> -- 
> 2.36.1
> 


smime.p7s
Description: S/MIME Cryptographic Signature


Re: [RFC PATCH 2/2] arm/virt: Add aspeed-i2c controller and MCTP EP to enable MCTP testing

2022-05-24 Thread Corey Minyard
On Tue, May 24, 2022 at 05:50:43PM +0100, Jonathan Cameron wrote:
> On Tue, 24 May 2022 09:36:44 -0700
> Ben Widawsky  wrote:
> 
> > On 22-05-20 18:01:28, Jonathan Cameron wrote:
> > > As the only I2C emulation in QEMU that supports being both
> > > a master and a slave, suitable for MCTP over i2c is aspeed-i2c
> > > add this controller to the arm virt model and hook up our new
> > > i2c_mctp_cxl_fmapi device.
> > > 
> > > The current Linux driver for aspeed-i2c has a hard requirement on
> > > a reset controller.  Throw down the simplest reset controller
> > > I could find so as to avoid need to make any chance to the kernel
> > > code.  
> > 
> > s/chance/change
> oops :)
> > 
> > > 
> > > Patch also builds appropriate device tree.  Unfortunately for CXL
> > > we need to use ACPI (no DT bindings yet defined). Enabling this will
> > > either require appropriate support for MCTP on an i2c master that
> > > has ACPI bindings, or modifications of the kernel driver to support
> > > ACPI with aspeed-i2c (which might be a little controversial ;)  
> > 
> > I'm naive to what DT defines, but I assume what's there already is 
> > insufficient
> > to make the bindings for CXL. I say this because I believe it wouldn't be 
> > too
> > bad at all to make a cxl_dt.ko, and it's certainly less artificial than
> > providing ACPI support for things which don't naturally have ACPI support.
> 
> It wouldn't be that hard to work out a CXL dt binding, but it's not
> of sufficient interest to me that I'd want to do it (I'll review if someone
> else sends patches). Platforms I'm interested in CXL with are all strictly
> ACPI only.
> 
> The trick here I think, is going to be adding ACPI support for a suitable I2C 
> controller
> which supports the requirement for supporting master and and I2C EP needed
> for MCTP. Either I find one that already has ACPI bindings and add enough
> emulation for this functionality, or work around the lack of ACPI bindings 
> for the
> aspeed-i2c controller.
> 
> Based on a really quick check of I2C masters for which I have docs and that
> definitely have ACPI bindings, it's not a particularly common feature set.

Ben already got my comments.

It's not common, but it's something you are using, so it obviously
exists.  What hardware do you have?  The most natural thing might be to
add your controller.

-corey

> 
> Jonathan
> 
> 
> 
> > 
> > > 
> > > Signed-off-by: Jonathan Cameron 
> > > ---
> > >  hw/arm/Kconfig|  1 +
> > >  hw/arm/virt.c | 77 +++
> > >  include/hw/arm/virt.h |  2 ++
> > >  3 files changed, 80 insertions(+)
> > > 
> > > diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> > > index 219262a8da..4a733298cd 100644
> > > --- a/hw/arm/Kconfig
> > > +++ b/hw/arm/Kconfig
> > > @@ -30,6 +30,7 @@ config ARM_VIRT
> > >  select ACPI_VIOT
> > >  select VIRTIO_MEM_SUPPORTED
> > >  select ACPI_CXL
> > > +select I2C_MCTP_CXL_FMAPI
> > >  
> > >  config CHEETAH
> > >  bool
> > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> > > index d818131b57..ea04279515 100644
> > > --- a/hw/arm/virt.c
> > > +++ b/hw/arm/virt.c
> > > @@ -80,6 +80,9 @@
> > >  #include "hw/char/pl011.h"
> > >  #include "hw/cxl/cxl.h"
> > >  #include "qemu/guest-random.h"
> > > +#include "hw/i2c/i2c.h"
> > > +#include "hw/i2c/aspeed_i2c.h"
> > > +#include "hw/misc/i2c_mctp_cxl_fmapi.h"
> > >  
> > >  #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
> > >  static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
> > > @@ -156,6 +159,8 @@ static const MemMapEntry base_memmap[] = {
> > >  [VIRT_PVTIME] = { 0x090a, 0x0001 },
> > >  [VIRT_SECURE_GPIO] ={ 0x090b, 0x1000 },
> > >  [VIRT_MMIO] =   { 0x0a00, 0x0200 },
> > > +[VIRT_I2C] ={ 0x0b00, 0x4000 },
> > > +[VIRT_RESET_FAKE] = { 0x0b004000, 0x0010 },
> > >  /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that 
> > > size */
> > >  [VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
> > >  [VIRT_SECURE_MEM] = { 0x0e00, 0x0100 },
> > > @@ -192,6 +197,7 @@ static const int a15irqmap[] = {
> > >  [VIRT_GPIO] = 7,
> > >  [VIRT_SECURE_UART] = 8,
> > >  [VIRT_ACPI_GED] = 9,
> > > +[VIRT_I2C] = 10,
> > >  [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
> > >  [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
> > >  [VIRT_SMMU] = 74,/* ...to 74 + NUM_SMMU_IRQS - 1 */
> > > @@ -1996,6 +2002,75 @@ static void virt_cpu_post_init(VirtMachineState 
> > > *vms, MemoryRegion *sysmem)
> > >  }
> > >  }
> > >  
> > > +static void create_mctp_test(MachineState *ms)
> > > +{
> > > +VirtMachineState *vms = VIRT_MACHINE(ms);
> > > +MemoryRegion *sysmem = get_system_memory();
> > > +AspeedI2CState *aspeedi2c;
> > > +struct DeviceState  *dev;
> > > +char *nodename_i2c_master;
> > > +

Re: [RFC PATCH 0/4] hw/i2c: i2c slave mode support

2022-04-01 Thread Corey Minyard
On Fri, Apr 01, 2022 at 08:29:03AM +0200, Klaus Jensen wrote:
> On Mar 31 15:32, Corey Minyard wrote:
> > On Thu, Mar 31, 2022 at 06:57:33PM +0200, Klaus Jensen wrote:
> > > From: Klaus Jensen 
> > > 
> > > Hi all,
> > > 
> > > This RFC series adds I2C "slave mode" support for the Aspeed I2C
> > > controller as well as the necessary infrastructure in the i2c core to
> > > support this.
> > 
> > I've been wondering when this would happen :).  I had put some thought
> > into how this would work, but hadn't come up with anything good.
> > 
> > The big disadvantage of this is you are adding an interface that is
> > incompatible with the current masters and slaves.  So you are using the
> > same I2C bus, but slaves written this way cannot talk to existing
> > masters, and masters written this way cannot talk to existing slave.
> > You could adapt the masters to be able to work either way, and I suppose
> > some slaves that could do it could have both an async send and a normal
> > send. 
> 
> Would it make sense to introduce a QOM Interface to differentiate
> between the slave/master types?

Yes, that would be a good idea, as Damien said.  You will have a type
that is capable of both for both sync and async for the master and the
slave, then types that are capable of one sync and async so the code
can sort out what can talk to what.

> 
> > But you could not adapt a slave device for the Aspeed to do both.
> 
> Exactly, the Aspeed must be able to defer the ack, so it cannot
> implement send(). Even if it buffered up the write, I don't think it
> would be correct to Ack the transfer until the host has Acked it.
> 
> > But that said, I don't know of a better way to handle this.
> > 
> > You don't have the ability to nack a byte in what you have currently.
> > That's probably something that will be needed.
> 
> True. Didn't consider that. Since the ack is basically defined as the
> scheduling of the bh, I guess I have to come up with something where I
> can also pass a "return value".
> 
> > 
> > This is obviously not something useful by itself.  How do you plan to
> > tie this in to something else that would use it?
> > 
> 
> This is specifically for implementing an NVMe-MI device which uses MCTP
> transactions (in which both requests and replies are master->slave
> transfers). I just wanted to get a feel for how you maintaines would
> envision this begin done before posting that. The NVMe-MI device will
> function exactly like the example i2c echo device (i.e. receive an MCTP
> transaction using the normal i2c slave interface, parse the
> transaction/request, master the bus and start a new transfer).

Ok, so you aren't planning to add some sort of interface that would
allow a net connection to hook up as an I2C master.

Someone submitted something a while ago for doing an I2C slave that way,
but there were some issues and nothing came of it.  It's tricky to do
because it has to be non-blocking.

IIRC, there was also some work that allowed two emulations to go on at a
time in a qemu instance, that could allow a BMC and a main processor to
run together.  This might be useful in that scenario.  My question was
really just more curiousity, wondering what else is coming in the
future.

Thanks,

-corey



Re: [RFC PATCH 0/4] hw/i2c: i2c slave mode support

2022-03-31 Thread Corey Minyard
On Thu, Mar 31, 2022 at 06:57:33PM +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Hi all,
> 
> This RFC series adds I2C "slave mode" support for the Aspeed I2C
> controller as well as the necessary infrastructure in the i2c core to
> support this.

I've been wondering when this would happen :).  I had put some thought
into how this would work, but hadn't come up with anything good.

The big disadvantage of this is you are adding an interface that is
incompatible with the current masters and slaves.  So you are using the
same I2C bus, but slaves written this way cannot talk to existing
masters, and masters written this way cannot talk to existing slave.
You could adapt the masters to be able to work either way, and I suppose
some slaves that could do it could have both an async send and a normal
send.  But you could not adapt a slave device for the Aspeed to do both.

But that said, I don't know of a better way to handle this.

You don't have the ability to nack a byte in what you have currently.
That's probably something that will be needed.

This is obviously not something useful by itself.  How do you plan to
tie this in to something else that would use it?

-corey

> 
> Background
> ~~
> We are working on an emulated NVM Express Management Interface[1] for
> testing and validation purposes. NVMe-MI is based on the MCTP
> protocol[2] which may use a variety of underlying transports. The one we
> are interested in is I2C[3].
> 
> The first general trickery here is that all MCTP transactions are based
> on the SMBus Block Write bus protocol[4]. This means that the slave must
> be able to master the bus to communicate. As you know, hw/i2c/core.c
> currently does not support this use case.
> 
> The second issue is how to interact with these mastering devices. Jeremy
> and Matt (CC'ed) have been working on an MCTP stack for the Linux Kernel
> (already upstream) and an I2C binding driver[5] is currently under
> review. This binding driver relies on I2C slave mode support in the I2C
> controller.
> 
> This series
> ~~~
> Patch 1 adds support for multiple masters in the i2c core, allowing
> slaves to master the bus and safely issue i2c_send/recv(). Patch 2 adds
> an asynchronous send i2c_send_async(I2CBus *, uint8) on the bus that
> must be paired with an explicit ack using i2c_ack(I2CBus *).
> 
> Patch 3 adds the slave mode functionality to the emulated Aspeed I2C
> controller. The implementation is probably buggy since I had to rely on
> the implementation of the kernel driver to reverse engineer the behavior
> of the controller slave mode (I do not have access to a spec sheet for
> the Aspeed, but maybe someone can help me out with that?).
> 
> Finally, patch 4 adds an example device using this new API. The device
> is a simple "echo" device that upon being sent a set of bytes uses the
> first byte as the address of the slave to echo to.
> 
> With this combined I am able to boot up Linux on an emulated Aspeed 2600
> evaluation board and have the i2c echo device write into a Linux slave
> EEPROM. Assuming the echo device is on address 0x42:
> 
>   # echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-15/new_device
>   i2c i2c-15: new_device: Instantiated device slave-24c02 at 0x64
>   # i2cset -y 15 0x42 0x64 0x00 0xaa i
>   # hexdump /sys/bus/i2c/devices/15-1064/slave-eeprom
>   000 ffaa       
>   010        
>   *
>   100
> 
>   [1]: https://nvmexpress.org/developers/nvme-mi-specification/
>   [2]: 
> https://www.dmtf.org/sites/default/files/standards/documents/DSP0236_1.3.1.pdf
>   [3]: 
> https://www.dmtf.org/sites/default/files/standards/documents/DSP0237_1.2.0.pdf
>   [4]: http://www.smbus.org/specs/SMBus_3_1_20180319.pdf
>   [5]: 
> https://lore.kernel.org/linux-i2c/20220218055106.1944485-1-m...@codeconstruct.com.au/
> 
> Klaus Jensen (4):
>   hw/i2c: support multiple masters
>   hw/i2c: add async send
>   hw/i2c: add slave mode for aspeed_i2c
>   hw/misc: add a toy i2c echo device
> 
>  hw/i2c/aspeed_i2c.c |  95 +---
>  hw/i2c/core.c   |  57 +-
>  hw/i2c/trace-events |   2 +-
>  hw/misc/i2c-echo.c  | 144 
>  hw/misc/meson.build |   2 +
>  include/hw/i2c/aspeed_i2c.h |   8 ++
>  include/hw/i2c/i2c.h|  19 +
>  7 files changed, 316 insertions(+), 11 deletions(-)
>  create mode 100644 hw/misc/i2c-echo.c
> 
> -- 
> 2.35.1
> 
> 



Re: [PATCH v3 0/9] This patch series contains updates to PMBus in QEMU along with some PMBus device models for Renesas regulators. I have also added myself to MAINTAINERS as this code is in use daily,

2022-03-08 Thread Corey Minyard
On Mon, Mar 07, 2022 at 01:00:02AM +0100, Philippe Mathieu-Daudé wrote:
> On 5/3/22 00:42, Titus Rwantare wrote:
> > On Fri, 4 Mar 2022 at 13:43, Corey Minyard  wrote:
> > > 
> > > On Tue, Mar 01, 2022 at 05:50:44PM -0800, Titus Rwantare wrote:
> > > > v2:
> > > >- split PMBus commit with updates into individual fixes
> > > >- renamed isl_pmbus[.ch] adding _vr for voltage regulators
> > > > 
> > > > v3:
> > > >- split uint refactor commit and removed commit renaming files
> > > >- rename rolled into preceding commits
> > > >- update commit description for uint refactoring change
> > > 
> > > This all looks good to me:
> > > 
> > > Acked-by: Corey Minyard 
> > > 
> > > Do you have a plan for getting this in to qemu?  Like through the ARM
> > > tree?  I could take it into an I2C tree, but there's really not much
> > > activity or work there.
> > > 
> > > -corey
> > 
> > In general PMBus is more specific to i2c than ARM, but I'm not sure of
> > the QEMU implications.
> 
> Titus, could you address my comments?
> 
> Corey, if you are busy, I can take care of this series.

It's not a "too busy" sort of thing, the i2c tree doesn't get much
traffic.  I can take it, but it's not much different than just pulling
it directly.

So it's probably best if you take it.

Thanks,

-corey

> 
> Regards,
> 
> Phil.
> 



Re: [PATCH v3 0/9] This patch series contains updates to PMBus in QEMU along with some PMBus device models for Renesas regulators. I have also added myself to MAINTAINERS as this code is in use daily,

2022-03-04 Thread Corey Minyard
On Tue, Mar 01, 2022 at 05:50:44PM -0800, Titus Rwantare wrote:
> v2:
>   - split PMBus commit with updates into individual fixes
>   - renamed isl_pmbus[.ch] adding _vr for voltage regulators
> 
> v3:
>   - split uint refactor commit and removed commit renaming files
>   - rename rolled into preceding commits
>   - update commit description for uint refactoring change

This all looks good to me:

Acked-by: Corey Minyard 

Do you have a plan for getting this in to qemu?  Like through the ARM
tree?  I could take it into an I2C tree, but there's really not much
activity or work there.

-corey

> 
> Shengtan Mao (1):
>   hw/i2c: Added linear mode translation for pmbus devices
> 
> Titus Rwantare (8):
>   hw/i2c: pmbus: add registers
>   hw/i2c: pmbus: guard against out of range accesses
>   hw/i2c: pmbus: add PEC unsupported warning
>   hw/i2c: pmbus: refactor uint handling
>   hw/i2c: pmbus: update MAINTAINERS
>   hw/sensor: add Intersil ISL69260 device model
>   hw/sensor: add Renesas raa229004 PMBus device
>   hw/sensor: add Renesas raa228000 device
> 
>  MAINTAINERS  |  13 +
>  hw/arm/Kconfig   |   1 +
>  hw/i2c/pmbus_device.c| 106 ++-
>  hw/sensor/Kconfig|   5 +
>  hw/sensor/isl_pmbus_vr.c | 279 ++
>  hw/sensor/meson.build|   1 +
>  include/hw/i2c/pmbus_device.h|  23 +-
>  include/hw/sensor/isl_pmbus_vr.h |  52 
>  tests/qtest/isl_pmbus_vr-test.c  | 474 +++
>  tests/qtest/meson.build  |   1 +
>  10 files changed, 944 insertions(+), 11 deletions(-)
>  create mode 100644 hw/sensor/isl_pmbus_vr.c
>  create mode 100644 include/hw/sensor/isl_pmbus_vr.h
>  create mode 100644 tests/qtest/isl_pmbus_vr-test.c
> 
> -- 
> 2.35.1.616.g0bdcbb4464-goog
> 



Re: [PATCH v2 4/9] hw/i2c: pmbus: refactor uint handling and update MAINTAINERS

2022-03-01 Thread Corey Minyard
On Tue, Mar 01, 2022 at 04:23:02PM -0800, Titus Rwantare wrote:
> Signed-off-by: Titus Rwantare 
> ---
>  MAINTAINERS   | 10 ++
>  hw/i2c/pmbus_device.c | 18 +-
>  2 files changed, 19 insertions(+), 9 deletions(-)

This makes sense, but can you split it into two patches and give a bit
more explaination about the uint handling.  Usually patches without
explaination are frowned upon, even if it's kind of obvious.

-corey

> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fa8adc2618..3601984b5d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3135,6 +3135,16 @@ F: include/hw/i2c/smbus_master.h
>  F: include/hw/i2c/smbus_slave.h
>  F: include/hw/i2c/smbus_eeprom.h
>  
> +PMBus
> +M: Titus Rwantare 
> +S: Maintained
> +F: hw/i2c/pmbus_device.c
> +F: hw/sensor/adm1272.c
> +F: hw/sensor/max34451.c
> +F: include/hw/i2c/pmbus_device.h
> +F: tests/qtest/adm1272-test.c
> +F: tests/qtest/max34451-test.c
> +
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
>  R: Daniel P. Berrange 
> diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
> index 6eeb0731d7..3beb02afad 100644
> --- a/hw/i2c/pmbus_device.c
> +++ b/hw/i2c/pmbus_device.c
> @@ -89,16 +89,16 @@ void pmbus_send_string(PMBusDevice *pmdev, const char 
> *data)
>  }
>  
>  
> -static uint64_t pmbus_receive_uint(const uint8_t *buf, uint8_t len)
> +static uint64_t pmbus_receive_uint(PMBusDevice *pmdev)
>  {
>  uint64_t ret = 0;
>  
>  /* Exclude command code from return value */
> -buf++;
> -len--;
> +pmdev->in_buf++;
> +pmdev->in_buf_len--;
>  
> -for (int i = len - 1; i >= 0; i--) {
> -ret = ret << 8 | buf[i];
> +for (int i = pmdev->in_buf_len - 1; i >= 0; i--) {
> +ret = ret << 8 | pmdev->in_buf[i];
>  }
>  return ret;
>  }
> @@ -110,7 +110,7 @@ uint8_t pmbus_receive8(PMBusDevice *pmdev)
>"%s: length mismatch. Expected 1 byte, got %d bytes\n",
>__func__, pmdev->in_buf_len - 1);
>  }
> -return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
> +return pmbus_receive_uint(pmdev);
>  }
>  
>  uint16_t pmbus_receive16(PMBusDevice *pmdev)
> @@ -120,7 +120,7 @@ uint16_t pmbus_receive16(PMBusDevice *pmdev)
>"%s: length mismatch. Expected 2 bytes, got %d 
> bytes\n",
>__func__, pmdev->in_buf_len - 1);
>  }
> -return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
> +return pmbus_receive_uint(pmdev);
>  }
>  
>  uint32_t pmbus_receive32(PMBusDevice *pmdev)
> @@ -130,7 +130,7 @@ uint32_t pmbus_receive32(PMBusDevice *pmdev)
>"%s: length mismatch. Expected 4 bytes, got %d 
> bytes\n",
>__func__, pmdev->in_buf_len - 1);
>  }
> -return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
> +return pmbus_receive_uint(pmdev);
>  }
>  
>  uint64_t pmbus_receive64(PMBusDevice *pmdev)
> @@ -140,7 +140,7 @@ uint64_t pmbus_receive64(PMBusDevice *pmdev)
>"%s: length mismatch. Expected 8 bytes, got %d 
> bytes\n",
>__func__, pmdev->in_buf_len - 1);
>  }
> -return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
> +return pmbus_receive_uint(pmdev);
>  }
>  
>  static uint8_t pmbus_out_buf_pop(PMBusDevice *pmdev)
> -- 
> 2.35.1.616.g0bdcbb4464-goog
> 



Re: [PATCH v2 9/9] hw/sensor: rename isl_pmbus to isl_pmbus_vr

2022-03-01 Thread Corey Minyard
On Tue, Mar 01, 2022 at 04:23:07PM -0800, Titus Rwantare wrote:
> Signed-off-by: Titus Rwantare 

Two things:

* Why do you want to rename this?

* This patch doesn't really add anything, it just renames things in a
  previous patch.  Can it be folded in to the patch that added these
  fields?

-corey

> ---
>  MAINTAINERS   |   6 +-
>  hw/arm/Kconfig|   2 +-
>  hw/sensor/Kconfig |   2 +-
>  hw/sensor/{isl_pmbus.c => isl_pmbus_vr.c} |  77 ++---
>  hw/sensor/meson.build |   2 +-
>  .../hw/sensor/{isl_pmbus.h => isl_pmbus_vr.h} |   4 +-
>  .../{isl_pmbus-test.c => isl_pmbus_vr-test.c} | 263 +-
>  tests/qtest/meson.build   |   2 +-
>  8 files changed, 180 insertions(+), 178 deletions(-)
>  rename hw/sensor/{isl_pmbus.c => isl_pmbus_vr.c} (80%)
>  rename include/hw/sensor/{isl_pmbus.h => isl_pmbus_vr.h} (96%)
>  rename tests/qtest/{isl_pmbus-test.c => isl_pmbus_vr-test.c} (55%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3df8e938e0..364a844045 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3140,13 +3140,13 @@ M: Titus Rwantare 
>  S: Maintained
>  F: hw/i2c/pmbus_device.c
>  F: hw/sensor/adm1272.c
> -F: hw/sensor/isl_pmbus.c
> +F: hw/sensor/isl_pmbus_vr.c
>  F: hw/sensor/max34451.c
>  F: include/hw/i2c/pmbus_device.h
> -F: include/hw/sensor/isl_pmbus.h
> +F: include/hw/sensor/isl_pmbus_vr.h
>  F: tests/qtest/adm1272-test.c
>  F: tests/qtest/max34451-test.c
> -F: tests/qtest/isl_pmbus-test.c
> +F: tests/qtest/isl_pmbus_vr-test.c
>  
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 8047ad6378..97f3b38019 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -400,7 +400,7 @@ config NPCM7XX
>  select SMBUS
>  select AT24C  # EEPROM
>  select MAX34451
> -select ISL_PMBUS
> +select ISL_PMBUS_VR
>  select PL310  # cache controller
>  select PMBUS
>  select SERIAL
> diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
> index 70fb335789..a834d2f814 100644
> --- a/hw/sensor/Kconfig
> +++ b/hw/sensor/Kconfig
> @@ -31,7 +31,7 @@ config LSM303DLHC_MAG
>  depends on I2C
>  default y if I2C_DEVICES
>  
> -config ISL_PMBUS
> +config ISL_PMBUS_VR
>  bool
>  depends on I2C
>  
> diff --git a/hw/sensor/isl_pmbus.c b/hw/sensor/isl_pmbus_vr.c
> similarity index 80%
> rename from hw/sensor/isl_pmbus.c
> rename to hw/sensor/isl_pmbus_vr.c
> index e3b42b119e..df7c003ea6 100644
> --- a/hw/sensor/isl_pmbus.c
> +++ b/hw/sensor/isl_pmbus_vr.c
> @@ -7,13 +7,13 @@
>   */
>  
>  #include "qemu/osdep.h"
> -#include "hw/sensor/isl_pmbus.h"
> +#include "hw/sensor/isl_pmbus_vr.h"
>  #include "hw/qdev-properties.h"
>  #include "qapi/visitor.h"
>  #include "qemu/log.h"
>  #include "qemu/module.h"
>  
> -static uint8_t isl_pmbus_read_byte(PMBusDevice *pmdev)
> +static uint8_t isl_pmbus_vr_read_byte(PMBusDevice *pmdev)
>  {
>  qemu_log_mask(LOG_GUEST_ERROR,
>"%s: reading from unsupported register: 0x%02x\n",
> @@ -21,7 +21,7 @@ static uint8_t isl_pmbus_read_byte(PMBusDevice *pmdev)
>  return 0xFF;
>  }
>  
> -static int isl_pmbus_write_data(PMBusDevice *pmdev, const uint8_t *buf,
> +static int isl_pmbus_vr_write_data(PMBusDevice *pmdev, const uint8_t *buf,
>uint8_t len)
>  {
>  qemu_log_mask(LOG_GUEST_ERROR,
> @@ -31,13 +31,13 @@ static int isl_pmbus_write_data(PMBusDevice *pmdev, const 
> uint8_t *buf,
>  }
>  
>  /* TODO: Implement coefficients support in pmbus_device.c for qmp */
> -static void isl_pmbus_get(Object *obj, Visitor *v, const char *name,
> +static void isl_pmbus_vr_get(Object *obj, Visitor *v, const char *name,
>   void *opaque, Error **errp)
>  {
>  visit_type_uint16(v, name, (uint16_t *)opaque, errp);
>  }
>  
> -static void isl_pmbus_set(Object *obj, Visitor *v, const char *name,
> +static void isl_pmbus_vr_set(Object *obj, Visitor *v, const char *name,
>   void *opaque, Error **errp)
>  {
>  PMBusDevice *pmdev = PMBUS_DEVICE(obj);
> @@ -51,7 +51,7 @@ static void isl_pmbus_set(Object *obj, Visitor *v, const 
> char *name,
>  pmbus_check_limits(pmdev);
>  }
>  
> -static void isl_pmbus_exit_reset(Object *obj)
> +static void isl_pmbus_vr_exit_reset(Object *obj)
>  {
>  PMBusDevice *pmdev = PMBUS_DEVICE(obj);
>  
> @@ -92,7 +92,7 @@ static void isl_pmbus_exit_reset(Object *obj)
>  /* The raa228000 uses different direct mode coefficents from most isl 
> devices */
>  static void raa228000_exit_reset(Object *obj)
>  {
> -isl_pmbus_exit_reset(obj);
> +isl_pmbus_vr_exit_reset(obj);
>  
>  PMBusDevice *pmdev = PMBUS_DEVICE(obj);
>  
> @@ -107,70 +107,70 @@ static void raa228000_exit_reset(Object *obj)
>  pmdev->pages[0].read_temperature_3 = 0;
>  }
>  
> -static void isl_pmbus_add_props(Obje

Re: [PATCH v2 15/22] hw/ipmi/isa_ipmi_bt: Disuse isa_init_irq()

2022-02-26 Thread Corey Minyard
On Tue, Feb 22, 2022 at 08:34:39PM +0100, Bernhard Beschow wrote:
> isa_init_irq() has become a trivial one-line wrapper for isa_get_irq().
> Use the original instead such that isa_init_irq() can be removed
> eventually.

Looking at the rest of the patch series, this looks lik a good idea.
This is obviously trivial here, but:

Acked-by: Corey Minyard 

For this and the KCS patch.

-corey

> 
> Signed-off-by: Bernhard Beschow 
> ---
>  hw/ipmi/isa_ipmi_bt.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c
> index 02625eb94e..88aa734e9e 100644
> --- a/hw/ipmi/isa_ipmi_bt.c
> +++ b/hw/ipmi/isa_ipmi_bt.c
> @@ -92,7 +92,7 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error 
> **errp)
>  }
>  
>  if (iib->isairq > 0) {
> -isa_init_irq(isadev, &iib->irq, iib->isairq);
> +iib->irq = isa_get_irq(isadev, iib->isairq);
>  iib->bt.use_irq = 1;
>  iib->bt.raise_irq = isa_ipmi_bt_raise_irq;
>  iib->bt.lower_irq = isa_ipmi_bt_lower_irq;
> -- 
> 2.35.1
> 



Re: [PATCH 0/5] Fixups for PMBus and new sensors

2022-02-24 Thread Corey Minyard
On Thu, Feb 24, 2022 at 10:58:52AM -0800, Patrick Venture wrote:
> On Thu, Jan 6, 2022 at 3:09 PM Titus Rwantare  wrote:
> 
> > This patch series contains updates to PMBus in QEMU along with some PMBus
> > device models for Renesas regulators.
> > I have also added myself to MAINTAINERS as this code is in use daily,
> > where I am responsible for it.
> >
> > Shengtan Mao (1):
> >   hw/i2c: Added linear mode translation for pmbus devices
> >
> > Titus Rwantare (4):
> >   hw/i2c: pmbus updates
> >   hw/sensor: add Intersil ISL69260 device model
> >   hw/sensor: add Renesas raa229004 PMBus device
> >   hw/misc: add Renesas raa228000 device
> >
> >  MAINTAINERS   |  15 +-
> >  hw/arm/Kconfig|   1 +
> >  hw/i2c/pmbus_device.c | 106 +++-
> >  hw/sensor/Kconfig |   5 +
> >  hw/sensor/isl_pmbus.c | 278 
> >  hw/sensor/meson.build |   1 +
> >  include/hw/i2c/pmbus_device.h |  23 +-
> >  include/hw/sensor/isl_pmbus.h |  52 
> >  tests/qtest/isl_pmbus-test.c  | 460 ++
> >  tests/qtest/meson.build   |   1 +
> >  10 files changed, 930 insertions(+), 12 deletions(-)
> >  create mode 100644 hw/sensor/isl_pmbus.c
> >  create mode 100644 include/hw/sensor/isl_pmbus.h
> >  create mode 100644 tests/qtest/isl_pmbus-test.c
> >
> >
> Friendly ping - I believe I saw some of these have picked up Reviewer tags,
> but ideally this will get into 7.0 before next month's soft-freeze.

Did you split up patch 1 as Peter requested?

-corey

> 
> 
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >
> >



Re: [PATCH 0/2] Adds designware i2c module and adds it to virt arm

2022-02-22 Thread Corey Minyard
On Mon, Feb 21, 2022 at 09:47:27AM -0800, Chris Rauer wrote:
> Hi Phil,
> 
> > What about using virtio-gpio & bitbang I2C?
> >
> > - virtio-gpio
> > https://lore.kernel.org/qemu-devel/20201127182917.2387-5-i...@metux.net/
> >
> > - bitbang I2C already in: hw/i2c/bitbang_i2c.c
> Sorry for the delay.
> 
> That looks like it might be doable with a bit more work creating the ACPI
> entries for the bitbang I2C.  This definitely seems more appropriate on the
> ARM_VIRT platform instead of putting a specific controller in.

I would think the efficiency of this would be horrible.

> 
> For my uses, I will have to stick with the designware controller since it
> matches the system I'm emulating a little more closely.  We can hold back
> the designware stuff until another SoC platform is interested in using this
> controller (since it seems like it is a common one).  Hopefully someone
> will find another use for the controller patches someday.

I should have chimed in sooner.

The i.MX i2c device has ACPI and OF support, I believe, and it's already
available in qemu.  I don't think the Intel smbus device would work.

The designware one is a pretty common and general one, it's a little
suprising that it hasn't already been done on qemu.  I would be ok with
this but Peter has the big picture here.

-corey

> 
> Thanks again for looking at our patches.
> 
> -Chris
> 
> 
> On Wed, Jan 26, 2022 at 3:42 PM Philippe Mathieu-Daudé 
> wrote:
> 
> > +Enrico Weigelt
> >
> > On 26/1/22 19:03, Peter Maydell wrote:
> > > On Wed, 26 Jan 2022 at 17:12, Chris Rauer  wrote:
> > >>
> > >>> I need to see a pretty strong justification for why we should be
> > >>> adding new kinds of devices to the virt machine,
> > >>
> > >> The designware i2c controller is a very common controller on many
> > >>   ARM SoCs.  It has device tree bindings and ACPI bindings which
> > >> makes it ideal for this platform.
> > >
> > > No, I mean, why do we need an i2c controller on the virt
> > > board at all ?
> > >
> > >>> Forgot to mention, but my prefered approach for providing
> > >>> an i2c controller on the virt board would be to have a
> > >>> PCI i2c controller: that way users who do need it can plug it
> > >>> in with a -device command line option, and users who don't
> > >>> need it never have to worry about it.
> > >
> > >>> (We seem to have an ICH9-SMB PCI device already; I have no idea if
> > it's suitable.)
> > >> I didn't find that device suitable because it is part of the Intel
> > >> Southbridge, which may have some Intel platform quirks, and
> > >> we don't need all the things in that IO hub.
> > >
> > > That's a pity. Is there a different PCI I2C controller we could model ?
> >
> > What about using virtio-gpio & bitbang I2C?
> >
> > - virtio-gpio
> > https://lore.kernel.org/qemu-devel/20201127182917.2387-5-i...@metux.net/
> >
> > - bitbang I2C already in: hw/i2c/bitbang_i2c.c
> >
> > Regards,
> >
> > Phil.
> >



Re: [PATCH] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-27 Thread Corey Minyard
On Thu, Jan 27, 2022 at 03:18:43PM -0800, Patrick Venture wrote:
> On Thu, Jan 27, 2022 at 10:20 AM Hao Wu  wrote:
> 
> >
> > On Thu, Jan 27, 2022 at 6:55 AM Corey Minyard  wrote:
> >
> >> On Wed, Jan 26, 2022 at 04:09:03PM -0800, Hao Wu wrote:
> >> > Hi,
> >> >
> >> > Sorry for the late reply. I'm not sure what "auto-increment" means here.
> >>
> >> The question is: When a value is read, does the address automatically
> >> increment.  I2C devices very often do this.  If you do a multi-byte
> >> read, they often will read the value from address 0, then from address
> >> 1, etc.  Same for writes.
> >>
> > The datasheet does not suggest such behavior could happen.
> >
> >>
> >> > The kernel driver at
> >> > https://lkml.org/lkml/2020/12/11/968
> >> > only has byte-size read/write operations, so I don't see a problem here.
> >> > The values are extracted
> >> > from the datasheet.
> >>
> >> The *Linux* kernel driver my only do byte-size operations, but other
> >> kernels may work different, and the Linux kernel may change.  You have
> >> to implement from the datasheet, not the device driver.
> >>
> > The implementation is already according to the datasheet.
> >
> >> Thanks,
> >>
> >> -corey
> >>
> >>
> I have to send out a new patchset to include my signature block since I'm
> sending a patch Hao wrote.  Laurent pointed this out to me in a different
> patch series.
> 
> From this exchange, I don't think there are other changes for v2.  Please
> let me know if that's false.

Yes, we are good.  It's a little surprising, hopefully we don't have to
fix it in the future if it works that way the datasheet didn't say so.

Acked-by: Corey Minyard 

> 
> Thanks,
> Patrick
> 
> 
> > >
> >> > On Tue, Jan 18, 2022 at 9:10 AM Patrick Venture 
> >> wrote:
> >> >
> >> > >
> >> > >
> >> > > On Mon, Jan 17, 2022 at 6:05 AM Corey Minyard 
> >> wrote:
> >> > >
> >> > >> On Sun, Jan 09, 2022 at 06:17:34PM -0800, Patrick Venture wrote:
> >> > >> > On Fri, Jan 7, 2022 at 7:04 PM Patrick Venture  >> >
> >> > >> wrote:
> >> > >> >
> >> > >> > > From: Hao Wu 
> >> > >> > >
> >> > >> > > SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
> >> > >> > > interface that reports AMD SoC's Ttcl (normalized temperature),
> >> > >> > > and resembles a typical 8-pin remote temperature sensor's I2C
> >> > >> interface
> >> > >> > > to BMC.
> >> > >> > >
> >> > >> > > This patch implements a basic AMD SB-TSI sensor that is
> >> > >> > > compatible with the open-source data sheet from AMD and Linux
> >> > >> > > kernel driver.
> >> > >> > >
> >> > >> > > Reference:
> >> > >> > > Linux kernel driver:
> >> > >> > > https://lkml.org/lkml/2020/12/11/968
> >> > >> > > Register Map:
> >> > >> > > https://developer.amd.com/wp-content/resources/56255_3_03.PDF
> >> > >> > > (Chapter 6)
> >> > >> > >
> >> > >> > > Signed-off-by: Hao Wu 
> >> > >> > > Reviewed-by: Doug Evans 
> >> > >> > > ---
> >> > >> > >  hw/sensor/Kconfig|   4 +
> >> > >> > >  hw/sensor/meson.build|   1 +
> >> > >> > >  hw/sensor/tmp_sbtsi.c| 393
> >> > >> +++
> >> > >> > >  hw/sensor/trace-events   |   5 +
> >> > >> > >  hw/sensor/trace.h|   1 +
> >> > >> > >  meson.build  |   1 +
> >> > >> > >  tests/qtest/meson.build  |   1 +
> >> > >> > >  tests/qtest/tmp_sbtsi-test.c | 180 
> >> > >> > >  8 files changed, 586 insertions(+)
> >> > >> > >  create mode 100644 hw/sensor/tmp_sbtsi.c
> >> > >> > >  create mode 100644 hw/sensor/trace-events
> >> > >> > >  create m

Re: [PATCH] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-27 Thread Corey Minyard
On Wed, Jan 26, 2022 at 04:09:03PM -0800, Hao Wu wrote:
> Hi,
> 
> Sorry for the late reply. I'm not sure what "auto-increment" means here.

The question is: When a value is read, does the address automatically
increment.  I2C devices very often do this.  If you do a multi-byte
read, they often will read the value from address 0, then from address
1, etc.  Same for writes.

> The kernel driver at
> https://lkml.org/lkml/2020/12/11/968
> only has byte-size read/write operations, so I don't see a problem here.
> The values are extracted
> from the datasheet.

The *Linux* kernel driver my only do byte-size operations, but other
kernels may work different, and the Linux kernel may change.  You have
to implement from the datasheet, not the device driver.

Thanks,

-corey

> 
> On Tue, Jan 18, 2022 at 9:10 AM Patrick Venture  wrote:
> 
> >
> >
> > On Mon, Jan 17, 2022 at 6:05 AM Corey Minyard  wrote:
> >
> >> On Sun, Jan 09, 2022 at 06:17:34PM -0800, Patrick Venture wrote:
> >> > On Fri, Jan 7, 2022 at 7:04 PM Patrick Venture 
> >> wrote:
> >> >
> >> > > From: Hao Wu 
> >> > >
> >> > > SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
> >> > > interface that reports AMD SoC's Ttcl (normalized temperature),
> >> > > and resembles a typical 8-pin remote temperature sensor's I2C
> >> interface
> >> > > to BMC.
> >> > >
> >> > > This patch implements a basic AMD SB-TSI sensor that is
> >> > > compatible with the open-source data sheet from AMD and Linux
> >> > > kernel driver.
> >> > >
> >> > > Reference:
> >> > > Linux kernel driver:
> >> > > https://lkml.org/lkml/2020/12/11/968
> >> > > Register Map:
> >> > > https://developer.amd.com/wp-content/resources/56255_3_03.PDF
> >> > > (Chapter 6)
> >> > >
> >> > > Signed-off-by: Hao Wu 
> >> > > Reviewed-by: Doug Evans 
> >> > > ---
> >> > >  hw/sensor/Kconfig|   4 +
> >> > >  hw/sensor/meson.build|   1 +
> >> > >  hw/sensor/tmp_sbtsi.c| 393
> >> +++
> >> > >  hw/sensor/trace-events   |   5 +
> >> > >  hw/sensor/trace.h|   1 +
> >> > >  meson.build  |   1 +
> >> > >  tests/qtest/meson.build  |   1 +
> >> > >  tests/qtest/tmp_sbtsi-test.c | 180 
> >> > >  8 files changed, 586 insertions(+)
> >> > >  create mode 100644 hw/sensor/tmp_sbtsi.c
> >> > >  create mode 100644 hw/sensor/trace-events
> >> > >  create mode 100644 hw/sensor/trace.h
> >> > >  create mode 100644 tests/qtest/tmp_sbtsi-test.c
> >> > >
> >> > > diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
> >> > > index 9c8a049b06..27f6f79c84 100644
> >> > > --- a/hw/sensor/Kconfig
> >> > > +++ b/hw/sensor/Kconfig
> >> > > @@ -21,3 +21,7 @@ config ADM1272
> >> > >  config MAX34451
> >> > >  bool
> >> > >  depends on I2C
> >> > > +
> >> > > +config AMDSBTSI
> >> > > +bool
> >> > > +depends on I2C
> >> > > diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
> >> > > index 059c4ca935..f7b0e645eb 100644
> >> > > --- a/hw/sensor/meson.build
> >> > > +++ b/hw/sensor/meson.build
> >> > > @@ -4,3 +4,4 @@ softmmu_ss.add(when: 'CONFIG_DPS310', if_true:
> >> > > files('dps310.c'))
> >> > >  softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
> >> > >  softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
> >> > >  softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
> >> > > +softmmu_ss.add(when: 'CONFIG_AMDSBTSI', if_true:
> >> files('tmp_sbtsi.c'))
> >> > > diff --git a/hw/sensor/tmp_sbtsi.c b/hw/sensor/tmp_sbtsi.c
> >> > > new file mode 100644
> >> > > index 00..b68c7ebf61
> >> > > --- /dev/null
> >> > > +++ b/hw/sensor/tmp_sbtsi.c
> >> > > @@ -0,0 +1,393 @@
> >> > > +/*
> >> > > + * AMD SBI Tem

Re: [PATCH v2 1/2] Mark remaining global TypeInfo instances as const

2022-01-17 Thread Corey Minyard
On Mon, Jan 17, 2022 at 03:58:04PM +0100, Bernhard Beschow wrote:
> More than 1k of TypeInfo instances are already marked as const. Mark the
> remaining ones, too.
> 
> This commit was created with:
>   git grep -z -l 'static TypeInfo' -- '*.c' | \
>   xargs -0 sed -i 's/static TypeInfo/static const TypeInfo/'
> 
> Signed-off-by: Bernhard Beschow 
> ---
>  hw/core/generic-loader.c   | 2 +-
>  hw/core/guest-loader.c | 2 +-
>  hw/display/bcm2835_fb.c| 2 +-
>  hw/display/i2c-ddc.c   | 2 +-
>  hw/display/macfb.c | 4 ++--
>  hw/display/virtio-vga.c| 2 +-
>  hw/dma/bcm2835_dma.c   | 2 +-
>  hw/i386/pc_piix.c  | 2 +-
>  hw/i386/sgx-epc.c  | 2 +-
>  hw/intc/bcm2835_ic.c   | 2 +-
>  hw/intc/bcm2836_control.c  | 2 +-
>  hw/ipmi/ipmi.c | 4 ++--

For IPMI portions:

Acked-by: Corey Minyard 

>  hw/mem/nvdimm.c| 2 +-
>  hw/mem/pc-dimm.c   | 2 +-
>  hw/misc/bcm2835_mbox.c | 2 +-
>  hw/misc/bcm2835_powermgt.c | 2 +-
>  hw/misc/bcm2835_property.c | 2 +-
>  hw/misc/bcm2835_rng.c  | 2 +-
>  hw/misc/pvpanic-isa.c  | 2 +-
>  hw/misc/pvpanic-pci.c  | 2 +-
>  hw/net/fsl_etsec/etsec.c   | 2 +-
>  hw/ppc/prep_systemio.c | 2 +-
>  hw/ppc/spapr_iommu.c   | 2 +-
>  hw/s390x/s390-pci-bus.c| 2 +-
>  hw/s390x/sclp.c| 2 +-
>  hw/s390x/tod-kvm.c | 2 +-
>  hw/s390x/tod-tcg.c | 2 +-
>  hw/s390x/tod.c | 2 +-
>  hw/scsi/lsi53c895a.c   | 2 +-
>  hw/sd/allwinner-sdhost.c   | 2 +-
>  hw/sd/aspeed_sdhci.c   | 2 +-
>  hw/sd/bcm2835_sdhost.c | 2 +-
>  hw/sd/cadence_sdhci.c  | 2 +-
>  hw/sd/npcm7xx_sdhci.c  | 2 +-
>  hw/usb/dev-mtp.c   | 2 +-
>  hw/usb/host-libusb.c   | 2 +-
>  hw/vfio/igd.c  | 2 +-
>  hw/virtio/virtio-pmem.c| 2 +-
>  qom/object.c   | 4 ++--
>  39 files changed, 42 insertions(+), 42 deletions(-)
> 
> diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
> index 9a24ffb880..eaafc416f4 100644
> --- a/hw/core/generic-loader.c
> +++ b/hw/core/generic-loader.c
> @@ -207,7 +207,7 @@ static void generic_loader_class_init(ObjectClass *klass, 
> void *data)
>  set_bit(DEVICE_CATEGORY_MISC, dc->categories);
>  }
>  
> -static TypeInfo generic_loader_info = {
> +static const TypeInfo generic_loader_info = {
>  .name = TYPE_GENERIC_LOADER,
>  .parent = TYPE_DEVICE,
>  .instance_size = sizeof(GenericLoaderState),
> diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c
> index d3f9d1a06e..391c875a29 100644
> --- a/hw/core/guest-loader.c
> +++ b/hw/core/guest-loader.c
> @@ -129,7 +129,7 @@ static void guest_loader_class_init(ObjectClass *klass, 
> void *data)
>  set_bit(DEVICE_CATEGORY_MISC, dc->categories);
>  }
>  
> -static TypeInfo guest_loader_info = {
> +static const TypeInfo guest_loader_info = {
>  .name = TYPE_GUEST_LOADER,
>  .parent = TYPE_DEVICE,
>  .instance_size = sizeof(GuestLoaderState),
> diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
> index 2be77bdd3a..088fc3d51c 100644
> --- a/hw/display/bcm2835_fb.c
> +++ b/hw/display/bcm2835_fb.c
> @@ -454,7 +454,7 @@ static void bcm2835_fb_class_init(ObjectClass *klass, 
> void *data)
>  dc->vmsd = &vmstate_bcm2835_fb;
>  }
>  
> -static TypeInfo bcm2835_fb_info = {
> +static const TypeInfo bcm2835_fb_info = {
>  .name  = TYPE_BCM2835_FB,
>  .parent= TYPE_SYS_BUS_DEVICE,
>  .instance_size = sizeof(BCM2835FBState),
> diff --git a/hw/display/i2c-ddc.c b/hw/display/i2c-ddc.c
> index 13eb529fc1..146489518c 100644
> --- a/hw/display/i2c-ddc.c
> +++ b/hw/display/i2c-ddc.c
> @@ -113,7 +113,7 @@ static void i2c_ddc_class_init(ObjectClass *oc, void 
> *data)
>  isc->send = i2c_ddc_tx;
>  }
>  
> -static TypeInfo i2c_ddc_info = {
> +static const TypeInfo i2c_ddc_info = {
>  .name = TYPE_I2CDDC,
>  .parent = TYPE_I2C_SLAVE,
>  .instance_size = sizeof(I2CDDCState),
> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
> index 4bd7c3ad6a..69c2ea2b6e 100644
> --- a/hw/display/macfb.c
> +++ b/hw/display/macfb.c
> @@ -783,14 +783,14 @@ static void macfb_nubus_class_init(ObjectClass *klass, 
> void *data)
>  device_class_set_props(dc, macfb_nubus_properties);
>  }
>  
> -static TypeInfo macfb_sysbus_info = {
> +static const TypeInfo macfb_sysbus_info = {
>  .name  = TYPE_MACFB,
>  .parent= TYPE_SYS_BUS_DEVICE,
>  .instance_size = sizeof(MacfbSysBusState),
>  .class_init= macfb_sysbus_class_init,
>  };
>  
> -static TypeInfo macfb_nubu

Re: [PATCH] hw/sensor: Add SB-TSI Temperature Sensor Interface

2022-01-17 Thread Corey Minyard
On Sun, Jan 09, 2022 at 06:17:34PM -0800, Patrick Venture wrote:
> On Fri, Jan 7, 2022 at 7:04 PM Patrick Venture  wrote:
> 
> > From: Hao Wu 
> >
> > SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible
> > interface that reports AMD SoC's Ttcl (normalized temperature),
> > and resembles a typical 8-pin remote temperature sensor's I2C interface
> > to BMC.
> >
> > This patch implements a basic AMD SB-TSI sensor that is
> > compatible with the open-source data sheet from AMD and Linux
> > kernel driver.
> >
> > Reference:
> > Linux kernel driver:
> > https://lkml.org/lkml/2020/12/11/968
> > Register Map:
> > https://developer.amd.com/wp-content/resources/56255_3_03.PDF
> > (Chapter 6)
> >
> > Signed-off-by: Hao Wu 
> > Reviewed-by: Doug Evans 
> > ---
> >  hw/sensor/Kconfig|   4 +
> >  hw/sensor/meson.build|   1 +
> >  hw/sensor/tmp_sbtsi.c| 393 +++
> >  hw/sensor/trace-events   |   5 +
> >  hw/sensor/trace.h|   1 +
> >  meson.build  |   1 +
> >  tests/qtest/meson.build  |   1 +
> >  tests/qtest/tmp_sbtsi-test.c | 180 
> >  8 files changed, 586 insertions(+)
> >  create mode 100644 hw/sensor/tmp_sbtsi.c
> >  create mode 100644 hw/sensor/trace-events
> >  create mode 100644 hw/sensor/trace.h
> >  create mode 100644 tests/qtest/tmp_sbtsi-test.c
> >
> > diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
> > index 9c8a049b06..27f6f79c84 100644
> > --- a/hw/sensor/Kconfig
> > +++ b/hw/sensor/Kconfig
> > @@ -21,3 +21,7 @@ config ADM1272
> >  config MAX34451
> >  bool
> >  depends on I2C
> > +
> > +config AMDSBTSI
> > +bool
> > +depends on I2C
> > diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
> > index 059c4ca935..f7b0e645eb 100644
> > --- a/hw/sensor/meson.build
> > +++ b/hw/sensor/meson.build
> > @@ -4,3 +4,4 @@ softmmu_ss.add(when: 'CONFIG_DPS310', if_true:
> > files('dps310.c'))
> >  softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
> >  softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
> >  softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
> > +softmmu_ss.add(when: 'CONFIG_AMDSBTSI', if_true: files('tmp_sbtsi.c'))
> > diff --git a/hw/sensor/tmp_sbtsi.c b/hw/sensor/tmp_sbtsi.c
> > new file mode 100644
> > index 00..b68c7ebf61
> > --- /dev/null
> > +++ b/hw/sensor/tmp_sbtsi.c
> > @@ -0,0 +1,393 @@
> > +/*
> > + * AMD SBI Temperature Sensor Interface (SB-TSI)
> > + *
> > + * Copyright 2021 Google LLC
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU General Public License as published by the
> > + * Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> > + * for more details.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/i2c/smbus_slave.h"
> > +#include "hw/irq.h"
> > +#include "migration/vmstate.h"
> > +#include "qapi/error.h"
> > +#include "qapi/visitor.h"
> > +#include "qemu/log.h"
> > +#include "qemu/module.h"
> > +#include "trace.h"
> > +
> > +#define TYPE_SBTSI "sbtsi"
> > +#define SBTSI(obj) OBJECT_CHECK(SBTSIState, (obj), TYPE_SBTSI)
> > +
> > +/**
> > + * SBTSIState:
> > + * temperatures are in units of 0.125 degrees
> > + * @temperature: Temperature
> > + * @limit_low: Lowest temperature
> > + * @limit_high: Highest temperature
> > + * @status: The status register
> > + * @config: The config register
> > + * @alert_config: The config for alarm_l output.
> > + * @addr: The address to read/write for the next cmd.
> > + * @alarm: The alarm_l output pin (GPIO)
> > + */
> > +typedef struct SBTSIState {
> > +SMBusDevice parent;
> > +
> > +uint32_t temperature;
> > +uint32_t limit_low;
> > +uint32_t limit_high;
> > +uint8_t status;
> > +uint8_t config;
> > +uint8_t alert_config;
> > +uint8_t addr;
> > +qemu_irq alarm;
> > +} SBTSIState;
> > +
> > +/*
> > + * SB-TSI registers only support SMBus byte data access. "_INT" registers
> > are
> > + * the integer part of a temperature value or limit, and "_DEC" registers
> > are
> > + * corresponding decimal parts.
> > + */
> > +#define SBTSI_REG_TEMP_INT  0x01 /* RO */
> > +#define SBTSI_REG_STATUS0x02 /* RO */
> > +#define SBTSI_REG_CONFIG0x03 /* RO */
> > +#define SBTSI_REG_TEMP_HIGH_INT 0x07 /* RW */
> > +#define SBTSI_REG_TEMP_LOW_INT  0x08 /* RW */
> > +#define SBTSI_REG_CONFIG_WR 0x09 /* RW */
> > +#define SBTSI_REG_TEMP_DEC  0x10 /* RO */
> > +#define SBTSI_REG_TEMP_HIGH_DEC 0x13 /* RW */
> > +#define SBTSI_REG_TEMP_LOW_DEC  0x14 /* RW */
> > +#define SBTSI_REG_ALERT_CONFIG  0xBF /* RW */
> > +#de

Re: [PATCH v2 2/7] hw/i2c: Read FIFO during RXF_CTL change in NPCM7XX SMBus

2021-10-21 Thread Corey Minyard
On Thu, Oct 21, 2021 at 11:39:51AM -0700, Hao Wu wrote:
> Originally we read in from SMBus when RXF_STS is cleared. However,
> the driver clears RXF_STS before setting RXF_CTL, causing the SM bus
> module to read incorrect amount of bytes in FIFO mode when the number
> of bytes read changed. This patch fixes this issue.
> 
> Signed-off-by: Hao Wu 
> Reviewed-by: Titus Rwantare 

This looks ok.  I assume you can take this in with the rest of the
patches.

Acked-by: Corey Minyard 

> ---
>  hw/i2c/npcm7xx_smbus.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
> index f18e311556..1435daea94 100644
> --- a/hw/i2c/npcm7xx_smbus.c
> +++ b/hw/i2c/npcm7xx_smbus.c
> @@ -637,9 +637,6 @@ static void npcm7xx_smbus_write_rxf_sts(NPCM7xxSMBusState 
> *s, uint8_t value)
>  {
>  if (value & NPCM7XX_SMBRXF_STS_RX_THST) {
>  s->rxf_sts &= ~NPCM7XX_SMBRXF_STS_RX_THST;
> -if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
> -npcm7xx_smbus_recv_fifo(s);
> -}
>  }
>  }
>  
> @@ -651,6 +648,9 @@ static void npcm7xx_smbus_write_rxf_ctl(NPCM7xxSMBusState 
> *s, uint8_t value)
>  new_ctl = KEEP_OLD_BIT(s->rxf_ctl, new_ctl, NPCM7XX_SMBRXF_CTL_LAST);
>  }
>  s->rxf_ctl = new_ctl;
> +if (s->status == NPCM7XX_SMBUS_STATUS_RECEIVING) {
> +npcm7xx_smbus_recv_fifo(s);
> +}
>  }
>  
>  static uint64_t npcm7xx_smbus_read(void *opaque, hwaddr offset, unsigned 
> size)
> -- 
> 2.33.0.1079.g6e70778dc9-goog
> 
> 



Re: [PATCH] hw: Add a 'Sensor devices' qdev category

2021-09-27 Thread Corey Minyard
On Mon, Sep 27, 2021 at 12:15:18AM +0200, Philippe Mathieu-Daudé wrote:
> Sensors models are listed in the 'Misc devices' category.
> Move them to their own category.
> 
> For the devices in the hw/sensor/ directory, the category
> is obvious.
> 
> hw/arm/z2.c models the AER915 model which is described
> on [*] as:
> 
>   The 14-pin chip marked AER915 just below the expansion
>   port is a 80C51-type microcontroller, similar to Philips
>   P89LPC915. It has an 8-bit A/D which is used to determine
>   which of six buttons are pressed on the resistor-network
>   wired remote.  It communicates with the main cpu via I2C.
> 
> It was introduced in commit 3bf11207c06 ("Add support for
> Zipit Z2 machine") with this comment:
> 
>   248 static uint8_t aer915_recv(I2CSlave *slave)
>   249 {
>   ...
>   253 switch (s->buf[0]) {
>   254 /* Return hardcoded battery voltage,
>   255  * 0xf0 means ~4.1V
>   256  */
>   257 case 0x02:
>   258 retval = 0xf0;
>   259 break;
> 
> For QEMU the AER915 is a very simple sensor model.
> 
> [*] https://www.bealecorner.org/best/measure/z2/index.html
> 
> Signed-off-by: Philippe Mathieu-Daudé 

This makes sense to me.  I'd like to hear from others on this.

-corey

> ---
>  include/hw/qdev-core.h | 1 +
>  hw/arm/z2.c| 1 +
>  hw/sensor/adm1272.c| 1 +
>  hw/sensor/dps310.c | 1 +
>  hw/sensor/emc141x.c| 1 +
>  hw/sensor/max34451.c   | 2 ++
>  hw/sensor/tmp105.c | 1 +
>  hw/sensor/tmp421.c | 1 +
>  softmmu/qdev-monitor.c | 1 +
>  9 files changed, 10 insertions(+)
> 
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 34c8a7506a1..f6241212247 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -26,6 +26,7 @@ typedef enum DeviceCategory {
>  DEVICE_CATEGORY_SOUND,
>  DEVICE_CATEGORY_MISC,
>  DEVICE_CATEGORY_CPU,
> +DEVICE_CATEGORY_SENSOR,
>  DEVICE_CATEGORY_MAX
>  } DeviceCategory;
>  
> diff --git a/hw/arm/z2.c b/hw/arm/z2.c
> index 9c1e876207b..62db9741106 100644
> --- a/hw/arm/z2.c
> +++ b/hw/arm/z2.c
> @@ -288,6 +288,7 @@ static void aer915_class_init(ObjectClass *klass, void 
> *data)
>  k->recv = aer915_recv;
>  k->send = aer915_send;
>  dc->vmsd = &vmstate_aer915_state;
> +set_bit(DEVICE_CATEGORY_SENSOR, dc->categories);
>  }
>  
>  static const TypeInfo aer915_info = {
> diff --git a/hw/sensor/adm1272.c b/hw/sensor/adm1272.c
> index 7310c769be2..2942ac75f90 100644
> --- a/hw/sensor/adm1272.c
> +++ b/hw/sensor/adm1272.c
> @@ -518,6 +518,7 @@ static void adm1272_class_init(ObjectClass *klass, void 
> *data)
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
>  
> +set_bit(DEVICE_CATEGORY_SENSOR, dc->categories);
>  dc->desc = "Analog Devices ADM1272 Hot Swap controller";
>  dc->vmsd = &vmstate_adm1272;
>  k->write_data = adm1272_write_data;
> diff --git a/hw/sensor/dps310.c b/hw/sensor/dps310.c
> index d60a18ac41b..1e24a499b38 100644
> --- a/hw/sensor/dps310.c
> +++ b/hw/sensor/dps310.c
> @@ -208,6 +208,7 @@ static void dps310_class_init(ObjectClass *klass, void 
> *data)
>  k->send = dps310_tx;
>  dc->reset = dps310_reset;
>  dc->vmsd = &vmstate_dps310;
> +set_bit(DEVICE_CATEGORY_SENSOR, dc->categories);
>  }
>  
>  static const TypeInfo dps310_info = {
> diff --git a/hw/sensor/emc141x.c b/hw/sensor/emc141x.c
> index 7ce8f4e9794..4202d8f185a 100644
> --- a/hw/sensor/emc141x.c
> +++ b/hw/sensor/emc141x.c
> @@ -270,6 +270,7 @@ static void emc141x_class_init(ObjectClass *klass, void 
> *data)
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
>  
> +set_bit(DEVICE_CATEGORY_SENSOR, dc->categories);
>  dc->reset = emc141x_reset;
>  k->event = emc141x_event;
>  k->recv = emc141x_rx;
> diff --git a/hw/sensor/max34451.c b/hw/sensor/max34451.c
> index a91d8bd487c..8300bf4ff43 100644
> --- a/hw/sensor/max34451.c
> +++ b/hw/sensor/max34451.c
> @@ -751,6 +751,8 @@ static void max34451_class_init(ObjectClass *klass, void 
> *data)
>  ResettableClass *rc = RESETTABLE_CLASS(klass);
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
> +
> +set_bit(DEVICE_CATEGORY_SENSOR, dc->categories);
>  dc->desc = "Maxim MAX34451 16-Channel V/I monitor";
>  dc->vmsd = &vmstate_max34451;
>  k->write_data = max34451_write_data;
> diff --git a/hw/sensor/tmp105.c b/hw/sensor/tmp105.c
> index 20564494899..43d79b9eeec 100644
> --- a/hw/sensor/tmp105.c
> +++ b/hw/sensor/tmp105.c
> @@ -305,6 +305,7 @@ static void tmp105_class_init(ObjectClass *klass, void 
> *data)
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
>  
> +set_bit(DEVICE_CATEGORY_SENSOR, dc->categories);
>  dc->realize = tmp105_realize;
>  k->event = tmp105_event;
>  k->recv = tmp105_rx;
> diff --git a/hw/sensor/tmp421.c b/hw/sensor/tmp42

Re: [PATCH 5/6] qbus: Rename qbus_create() to qbus_new()

2021-09-23 Thread Corey Minyard
On Thu, Sep 23, 2021 at 01:11:52PM +0100, Peter Maydell wrote:
> Rename the "allocate and return" qbus creation function to
> qbus_new(), to bring it into line with our _init vs _new convention.

This looks like a good idea to me.

Reviewed-by: Corey Minyard 

> 
> Signed-off-by: Peter Maydell 
> ---
>  include/hw/qdev-core.h  | 2 +-
>  hw/core/bus.c   | 2 +-
>  hw/hyperv/vmbus.c   | 2 +-
>  hw/i2c/core.c   | 2 +-
>  hw/isa/isa-bus.c| 2 +-
>  hw/misc/auxbus.c| 2 +-
>  hw/nubus/mac-nubus-bridge.c | 2 +-
>  hw/pci/pci.c| 2 +-
>  hw/ppc/spapr_vio.c  | 2 +-
>  hw/s390x/ap-bridge.c| 2 +-
>  hw/s390x/css-bridge.c   | 2 +-
>  hw/s390x/s390-pci-bus.c | 2 +-
>  hw/ssi/ssi.c| 2 +-
>  hw/xen/xen-bus.c| 2 +-
>  hw/xen/xen-legacy-backend.c | 2 +-
>  15 files changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index ebca8cf9fca..4ff19c714bd 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -680,7 +680,7 @@ typedef int (qdev_walkerfn)(DeviceState *dev, void 
> *opaque);
>  
>  void qbus_init(void *bus, size_t size, const char *typename,
> DeviceState *parent, const char *name);
> -BusState *qbus_create(const char *typename, DeviceState *parent, const char 
> *name);
> +BusState *qbus_new(const char *typename, DeviceState *parent, const char 
> *name);
>  bool qbus_realize(BusState *bus, Error **errp);
>  void qbus_unrealize(BusState *bus);
>  
> diff --git a/hw/core/bus.c b/hw/core/bus.c
> index cec49985024..c7831b5293b 100644
> --- a/hw/core/bus.c
> +++ b/hw/core/bus.c
> @@ -159,7 +159,7 @@ void qbus_init(void *bus, size_t size, const char 
> *typename,
>  qbus_init_internal(bus, parent, name);
>  }
>  
> -BusState *qbus_create(const char *typename, DeviceState *parent, const char 
> *name)
> +BusState *qbus_new(const char *typename, DeviceState *parent, const char 
> *name)
>  {
>  BusState *bus;
>  
> diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
> index c9887d5a7bc..dbce3b35fba 100644
> --- a/hw/hyperv/vmbus.c
> +++ b/hw/hyperv/vmbus.c
> @@ -2729,7 +2729,7 @@ static void vmbus_bridge_realize(DeviceState *dev, 
> Error **errp)
>  return;
>  }
>  
> -bridge->bus = VMBUS(qbus_create(TYPE_VMBUS, dev, "vmbus"));
> +bridge->bus = VMBUS(qbus_new(TYPE_VMBUS, dev, "vmbus"));
>  }
>  
>  static char *vmbus_bridge_ofw_unit_address(const SysBusDevice *dev)
> diff --git a/hw/i2c/core.c b/hw/i2c/core.c
> index 416372ad00c..0e7d2763b9e 100644
> --- a/hw/i2c/core.c
> +++ b/hw/i2c/core.c
> @@ -60,7 +60,7 @@ I2CBus *i2c_init_bus(DeviceState *parent, const char *name)
>  {
>  I2CBus *bus;
>  
> -bus = I2C_BUS(qbus_create(TYPE_I2C_BUS, parent, name));
> +bus = I2C_BUS(qbus_new(TYPE_I2C_BUS, parent, name));
>  QLIST_INIT(&bus->current_devs);
>  vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_i2c_bus, bus);
>  return bus;
> diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
> index cffaa35e9cf..6c31398dda6 100644
> --- a/hw/isa/isa-bus.c
> +++ b/hw/isa/isa-bus.c
> @@ -64,7 +64,7 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion* 
> address_space,
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
>  }
>  
> -isabus = ISA_BUS(qbus_create(TYPE_ISA_BUS, dev, NULL));
> +isabus = ISA_BUS(qbus_new(TYPE_ISA_BUS, dev, NULL));
>  isabus->address_space = address_space;
>  isabus->address_space_io = address_space_io;
>  return isabus;
> diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
> index 434ff8d910d..8a8012f5f08 100644
> --- a/hw/misc/auxbus.c
> +++ b/hw/misc/auxbus.c
> @@ -65,7 +65,7 @@ AUXBus *aux_bus_init(DeviceState *parent, const char *name)
>  AUXBus *bus;
>  Object *auxtoi2c;
>  
> -bus = AUX_BUS(qbus_create(TYPE_AUX_BUS, parent, name));
> +bus = AUX_BUS(qbus_new(TYPE_AUX_BUS, parent, name));
>  auxtoi2c = object_new_with_props(TYPE_AUXTOI2C, OBJECT(bus), "i2c",
>   &error_abort, NULL);
>  
> diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c
> index 7c329300b82..148979dab13 100644
> --- a/hw/nubus/mac-nubus-bridge.c
> +++ b/hw/nubus/mac-nubus-bridge.c
> @@ -16,7 +16,7 @@ static void mac_nubus_bridge_init(Object *obj)
>  MacNubusState *s = MAC_NUBUS_BRIDGE(obj);
>  SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
>  
> -s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL));
> +s-&g

Re: [PATCH 7/8] hw/ipmi: Add an IPMI external host device

2021-09-09 Thread Corey Minyard
On Thu, Sep 09, 2021 at 04:06:19PM -0700, Hao Wu wrote:
> The IPMI external host device works for Baseband Management Controller
> (BMC) emulations. It works as a representation of a host class that
> connects to a given BMC.  It can connect to a real host hardware or a
> emulated or simulated host device. In particular it can connect to a
> host QEMU instance with device ipmi-bmc-extern.

This is reasonable, I think.

The terminology here is confusing, though.  I'm not sure exactly what to
do about it.  So we have right now:

  host interfaces - KCS, BT, SSIF
  bmc - either an emulated or extern BMC the host talks to

And what you are proposing is:

  core - anything that supplies IPMI message for processing by
the code in the VM.  So this is the internal/external BMC
and the bmc-side of things.
  bmc - either an emulated or extern BMC the host talks to
  bmc-side - Receives messages from a host running ipmi_bmc_extern
  interfaces - KCS, BT, SSIF, and the interface to the bmc-side
VM.

What I would propose is something like:

  core - anything that supplies IPMI message for processing by
the code in the VM.  So this is the internal/external BMC
and the bmc-side of things.
  bmc-host - either an emulated or extern BMC the host talks to
  bmc-client - Receives messages from a host running ipmi_bmc_extern
  interfaces - All IPMI interfaces
  interfaces-host - KCS, BT, SSIF
  interfaces-client - the interface to the bmc-side VM.

I'm not too excited about the name "client", though.  But I think a
class hierarchy like above would be more clear about what things are,
and it's not that different than what you are proposing.

I'm really just thinking out loud, though.

-corey

> 
> For more details of IPMI host device in BMC emulation, see
> docs/specs/ipmi.rst.
> 
> Signed-off-by: Hao Wu 
> ---
>  configs/devices/arm-softmmu/default.mak |   2 +
>  hw/ipmi/Kconfig |   5 +
>  hw/ipmi/ipmi_extern.c   |  18 ++-
>  hw/ipmi/ipmi_host_extern.c  | 170 
>  hw/ipmi/meson.build |   1 +
>  5 files changed, 194 insertions(+), 2 deletions(-)
>  create mode 100644 hw/ipmi/ipmi_host_extern.c
> 
> diff --git a/configs/devices/arm-softmmu/default.mak 
> b/configs/devices/arm-softmmu/default.mak
> index 6985a25377..82f0c6f8c3 100644
> --- a/configs/devices/arm-softmmu/default.mak
> +++ b/configs/devices/arm-softmmu/default.mak
> @@ -25,6 +25,8 @@ CONFIG_GUMSTIX=y
>  CONFIG_SPITZ=y
>  CONFIG_TOSA=y
>  CONFIG_Z2=y
> +CONFIG_IPMI=y
> +CONFIG_IPMI_HOST=y
>  CONFIG_NPCM7XX=y
>  CONFIG_COLLIE=y
>  CONFIG_ASPEED_SOC=y
> diff --git a/hw/ipmi/Kconfig b/hw/ipmi/Kconfig
> index 9befd4f422..6722b1fbb0 100644
> --- a/hw/ipmi/Kconfig
> +++ b/hw/ipmi/Kconfig
> @@ -11,6 +11,11 @@ config IPMI_EXTERN
>  default y
>  depends on IPMI
>  
> +config IPMI_HOST
> +bool
> +default y
> +depends on IPMI
> +
>  config ISA_IPMI_KCS
>  bool
>  depends on ISA_BUS
> diff --git a/hw/ipmi/ipmi_extern.c b/hw/ipmi/ipmi_extern.c
> index 97dfed085f..0952dc5992 100644
> --- a/hw/ipmi/ipmi_extern.c
> +++ b/hw/ipmi/ipmi_extern.c
> @@ -145,11 +145,25 @@ void ipmi_extern_handle_command(IPMIExtern *ibe,
>  if (err) {
>  IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  unsigned char rsp[3];
> +
>  rsp[0] = cmd[0] | 0x04;
>  rsp[1] = cmd[1];
>  rsp[2] = err;
> -ibe->waiting_rsp = false;
> -k->handle_msg(s, msg_id, rsp, 3);
> +
> +if (ibe->bmc_side) {
> +/* For BMC Side, send out an error message. */
> +addchar(ibe, msg_id);
> +for (i = 0; i < 3; ++i) {
> +addchar(ibe, rsp[i]);
> +}
> +csum = ipmb_checksum(&msg_id, 1, 0);
> +addchar(ibe, -ipmb_checksum(rsp, 3, csum));
> +continue_send(ibe);
> +} else {
> +/* For Core side, handle an error message. */
> +ibe->waiting_rsp = false;
> +k->handle_msg(s, msg_id, rsp, 3);
> +}
>  goto out;
>  }
>  
> diff --git a/hw/ipmi/ipmi_host_extern.c b/hw/ipmi/ipmi_host_extern.c
> new file mode 100644
> index 00..4530631901
> --- /dev/null
> +++ b/hw/ipmi/ipmi_host_extern.c
> @@ -0,0 +1,170 @@
> +/*
> + * IPMI Host external connection
> + *
> + * Copyright 2021 Google LLC
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * for more details.
> + */
> +
> +/*
> + * This is designed to connect to a host QE

Re: [PATCH 5/8] hw/ipmi: Take out common from ipmi_bmc_extern.c

2021-09-09 Thread Corey Minyard
t;outbuf[ibe->outlen] = VM_CMD_CHAR;
> -ibe->outlen++;
> -ibe->sending_cmd = false;
> -continue_send(ibe);
> -break;
> -
> -case CHR_EVENT_CLOSED:
> -if (!ibe->connected) {
> -return;
> -}
> -ibe->connected = false;
> -/*
> - * Don't hang the OS trying to handle the ATN bit, other end will
> - * resend on a reconnect.
> - */
> -k->set_atn(s, 0, 0);
> -if (ibe->waiting_rsp) {
> -ibe->waiting_rsp = false;
> -ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
> -ibe->inbuf[2] = ibe->outbuf[2];
> -ibe->inbuf[3] = IPMI_CC_BMC_INIT_IN_PROGRESS;
> -k->handle_msg(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
> -}
> -break;
> +IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
>  
> -case CHR_EVENT_BREAK:
> -case CHR_EVENT_MUX_IN:
> -case CHR_EVENT_MUX_OUT:
> -/* Ignore */
> -break;
> +if (!qdev_realize(DEVICE(&ibe->conn), NULL, errp)) {
> +return;
>  }
>  }
>  
> @@ -456,42 +141,14 @@ static void ipmi_bmc_extern_handle_reset(IPMIBmc *b)
>  IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(b);
>  
>  ibe->send_reset = true;
> -continue_send(ibe);
> -}
> -
> -static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
> -{
> -IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);
> -
> -if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
> -error_setg(errp, "IPMI external bmc requires chardev attribute");
> -return;
> -}
> -
> -qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
> - chr_event, NULL, ibe, NULL, true);
> +continue_send_bmc(ibe);
>  }
>  
>  static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)
>  {
> -IPMIBmcExtern *ibe = opaque;
> -
> -/*
> - * We don't directly restore waiting_rsp, Instead, we return an
> - * error on the interface if a response was being waited for.
> - */
> -if (ibe->waiting_rsp) {
> -IPMICore *ic = opaque;
> -IPMIInterface *ii = ic->intf;
> -IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> -
> -ibe->waiting_rsp = false;
> -ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
> -ibe->inbuf[2] = ibe->outbuf[2];
> -ibe->inbuf[3] = IPMI_CC_BMC_INIT_IN_PROGRESS;
> -iic->handle_msg(ii, ibe->outbuf[0], ibe->inbuf + 1, 3);
> -}
> -return 0;
> +IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(opaque);
> +
> +return ipmi_extern_post_migrate(&ibe->conn, version_id);
>  }
>  
>  static const VMStateDescription vmstate_ipmi_bmc_extern = {
> @@ -501,28 +158,24 @@ static const VMStateDescription vmstate_ipmi_bmc_extern 
> = {
>  .post_load = ipmi_bmc_extern_post_migrate,
>  .fields  = (VMStateField[]) {
>  VMSTATE_BOOL(send_reset, IPMIBmcExtern),
> -VMSTATE_BOOL(waiting_rsp, IPMIBmcExtern),
> +VMSTATE_BOOL(conn.waiting_rsp, IPMIBmcExtern),
>  VMSTATE_END_OF_LIST()
>  }
>  };
>  
>  static void ipmi_bmc_extern_init(Object *obj)
>  {
> +IPMICore *ic = IPMI_CORE(obj);
>  IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
>  
> -ibe->extern_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, extern_timeout, 
> ibe);
> +object_initialize_child(obj, "extern", &ibe->conn,
> +TYPE_IPMI_EXTERN);
> +ibe->conn.core = ic;
>  vmstate_register(NULL, 0, &vmstate_ipmi_bmc_extern, ibe);
>  }
>  
> -static void ipmi_bmc_extern_finalize(Object *obj)
> -{
> -IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
> -
> -timer_free(ibe->extern_timer);
> -}
> -
>  static Property ipmi_bmc_extern_properties[] = {
> -DEFINE_PROP_CHR("chardev", IPMIBmcExtern, chr),
> +DEFINE_PROP_CHR("chardev", IPMIBmcExtern, conn.chr),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>  
> @@ -530,9 +183,11 @@ static void ipmi_bmc_extern_class_init(ObjectClass *oc, 
> void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(oc);
>  IPMIBmcClass *bk = IPMI_BMC_CLASS(oc);
> +IPMICoreClass *ck = IPMI_CORE_CLASS(oc);
>  
>  bk->handle_command = ipmi_bmc_extern_handle_command;
>  bk->handle_reset = ipmi_bmc_extern_handle_reset;
> +ck->handle_hw_op = ipmi_bmc_handle_hw_op;
>  dc->hotpluggable = false;
>  dc->realize = ipmi_bmc_extern_realize;
>  device_class_set_pr

Re: [PATCH 4/8] hw/ipmi: Refactor IPMI interface

2021-09-09 Thread Corey Minyard
On Thu, Sep 09, 2021 at 04:06:16PM -0700, Hao Wu wrote:
> This patch refactors the IPMI interface so that it can be used by both
> the BMC side and core-side simulation.
> 
> Detail changes:
> (1) rename handle_rsp -> handle_msg so the name fits both BMC side and
> Core side.
> (2) Add a new class IPMICore. This class represents a simulator/external
> connection for both BMC and Core side emulation. The old IPMIBmc is
> a sub-class of IPMICore.
> (3) Change all ibe->parent.intf in hw/ipmi/ipmi_bmc_*.c to use type
> cast to IPMICore. Directly accessing parent QOM is against QEMU
> guide and by using type casting the code can fit both core side and
> BMC side emulation.

I think I'm ok with this.  It fixes some fundamental issues (maybe that
should be separate patches, but I think it's ok here).

I was kind of against this at first, I was thinking a completely
separate code for the BMC-side hardware emulation.  But I can see that
so much code would be duplicated that it would be silly.

It would be better if there was an ipmi_bmc.[ch] that had the
BMC-specific things, split out from the ipmi.[ch] code.  I'm not 100%
sure how important that is, but it would be less confusing.  Do you
agree?

A couple of comments inline...

-corey

> 
> Signed-off-by: Hao Wu 
> ---
>  hw/ipmi/ipmi.c| 15 +++---
>  hw/ipmi/ipmi_bmc_extern.c | 37 +--
>  hw/ipmi/ipmi_bmc_sim.c| 41 ++-
>  hw/ipmi/ipmi_bt.c |  2 +-
>  hw/ipmi/ipmi_kcs.c|  2 +-
>  hw/ipmi/isa_ipmi_bt.c |  4 +++-
>  hw/ipmi/isa_ipmi_kcs.c|  4 +++-
>  hw/ipmi/pci_ipmi_bt.c |  4 +++-
>  hw/ipmi/pci_ipmi_kcs.c|  4 +++-
>  hw/ipmi/smbus_ipmi.c  |  6 --
>  include/hw/ipmi/ipmi.h| 40 ++
>  11 files changed, 111 insertions(+), 48 deletions(-)
> 
> diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
> index 8d35c9fdd6..7da1b36fab 100644
> --- a/hw/ipmi/ipmi.c
> +++ b/hw/ipmi/ipmi.c
> @@ -92,13 +92,21 @@ static TypeInfo ipmi_interface_type_info = {
>  .class_init = ipmi_interface_class_init,
>  };
>  
> +static TypeInfo ipmi_core_type_info = {
> +.name = TYPE_IPMI_CORE,
> +.parent = TYPE_DEVICE,
> +.instance_size = sizeof(IPMICore),
> +.abstract = true,
> +};
> +
>  static void isa_ipmi_bmc_check(const Object *obj, const char *name,
> Object *val, Error **errp)
>  {
> -IPMIBmc *bmc = IPMI_BMC(val);
> +IPMICore *ic = IPMI_CORE(val);
>  
> -if (bmc->intf)
> +if (ic->intf) {
>  error_setg(errp, "BMC object is already in use");
> +}
>  }
>  
>  void ipmi_bmc_find_and_link(Object *obj, Object **bmc)
> @@ -122,7 +130,7 @@ static void bmc_class_init(ObjectClass *oc, void *data)
>  
>  static TypeInfo ipmi_bmc_type_info = {
>  .name = TYPE_IPMI_BMC,
> -.parent = TYPE_DEVICE,
> +.parent = TYPE_IPMI_CORE,
>  .instance_size = sizeof(IPMIBmc),
>  .abstract = true,
>  .class_size = sizeof(IPMIBmcClass),
> @@ -132,6 +140,7 @@ static TypeInfo ipmi_bmc_type_info = {
>  static void ipmi_register_types(void)
>  {
>  type_register_static(&ipmi_interface_type_info);
> +type_register_static(&ipmi_core_type_info);
>  type_register_static(&ipmi_bmc_type_info);
>  }
>  
> diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
> index acf2bab35f..a0c3a40e7c 100644
> --- a/hw/ipmi/ipmi_bmc_extern.c
> +++ b/hw/ipmi/ipmi_bmc_extern.c
> @@ -147,8 +147,9 @@ static void continue_send(IPMIBmcExtern *ibe)
>  
>  static void extern_timeout(void *opaque)
>  {
> +IPMICore *ic = opaque;
>  IPMIBmcExtern *ibe = opaque;

Shouldn't the above be a cast from ic?

> -IPMIInterface *s = ibe->parent.intf;
> +IPMIInterface *s = ic->intf;
>  
>  if (ibe->connected) {
>  if (ibe->waiting_rsp && (ibe->outlen == 0)) {
> @@ -158,7 +159,7 @@ static void extern_timeout(void *opaque)
>  ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
>  ibe->inbuf[2] = ibe->outbuf[2];
>  ibe->inbuf[3] = IPMI_CC_TIMEOUT;
> -k->handle_rsp(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
> +k->handle_msg(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
>  } else {
>  continue_send(ibe);
>  }
> @@ -186,8 +187,9 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
> unsigned int max_cmd_len,
> uint8_t msg_id)
>  {
> +IPMICore *ic = IPMI_CORE(b);
>  IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(b);
> -IPMIInterface *s = ibe->parent.intf;
> +IPMIInterface *s = ic->intf;
>  uint8_t err = 0, csum;
>  unsigned int i;
>  
> @@ -213,7 +215,7 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
>  rsp[1] = cmd[1];
>  rsp[2] = err;
>  ibe->waiting_rsp = false;
> -k->handle_rsp(s, msg_id, rsp, 3);
> +k->handle_msg(s, msg_i

Re: [PATCH 2/8] docs/specs: IPMI device emulation: main processor

2021-09-09 Thread Corey Minyard
On Thu, Sep 09, 2021 at 04:06:14PM -0700, Hao Wu wrote:
> From: Havard Skinnemoen 
> 
> This document is an attempt to briefly document the existing IPMI
> emulation support on the main processor. It provides the necessary
> background for the BMC-side IPMI emulation proposed by the next patch.

I'm good with this for the most part.  One nit inline below.

This block diagrams depend on the previous patch.

> 
> Signed-off-by: Havard Skinnemoen 
> Signed-off-by: Hao Wu 
> ---
>  docs/specs/index.rst |   1 +
>  docs/specs/ipmi.rst  | 100 +++
>  2 files changed, 101 insertions(+)
>  create mode 100644 docs/specs/ipmi.rst
> 
> diff --git a/docs/specs/index.rst b/docs/specs/index.rst
> index 65e9663916..1b5d177d53 100644
> --- a/docs/specs/index.rst
> +++ b/docs/specs/index.rst
> @@ -11,6 +11,7 @@ guest hardware that is specific to QEMU.
> ppc-spapr-xive
> ppc-spapr-numa
> acpi_hw_reduced_hotplug
> +   ipmi
> tpm
> acpi_hest_ghes
> acpi_cpu_hotplug
> diff --git a/docs/specs/ipmi.rst b/docs/specs/ipmi.rst
> new file mode 100644
> index 00..adb098b53d
> --- /dev/null
> +++ b/docs/specs/ipmi.rst
> @@ -0,0 +1,100 @@
> +=
> +IPMI device emulation
> +=
> +
> +QEMU supports emulating many types of machines. This includes machines that 
> may
> +serve as the main processor in an IPMI system, e.g. x86 or POWER server
> +processors, as well as machines emulating ARM-based Baseband Management
> +Controllers (BMCs), e.g. AST2xxx or NPCM7xxx systems-on-chip.
> +
> +Main processor emulation
> +
> +
> +A server platform may include one of the following system interfaces for
> +communicating with a BMC:
> +
> +* A Keyboard Controller Style (KCS) Interface, accessible via ISA
> +  (``isa-ipmi-kcs``) or PCI (``pci-ipmi-kcs``).
> +* A Block Transfer (BT) Interface, accessible via ISA (``isa-ipmi-bt``) or 
> PCI
> +  (``pci-ipmi-bt``).
> +* An SMBus System Interface (SSIF; ``smbus-ipmi``).
> +
> +These interfaces can all be emulated by QEMU. To emulate the behavior of the
> +BMC, the messaging interface emulators use one of the following backends:
> +
> +* A BMC simulator running within the QEMU process (``ipmi-bmc-sim``).
> +* An external BMC simulator or emulator, connected over a chardev
> +  (``ipmi-bmc-extern``). `ipmi_sim
> +  
> `_

Here, and in the other reference below, can you reference the official
repository instead of your own?

> +  from OpenIPMI is an example external BMC emulator.
> +
> +The following diagram shows how these entities relate to each other.
> +
> +.. blockdiag::
> +
> +blockdiag main_processor_ipmi {
> +orientation = portrait
> +default_group_color = "none";
> +class msgif [color = lightblue];
> +class bmc [color = salmon];
> +
> +ipmi_sim [color="aquamarine", label="External BMC"]
> +ipmi-bmc-extern <-> ipmi_sim [label="chardev"];
> +
> +group {
> +orientation = portrait
> +
> +ipmi-interface <-> ipmi-bmc;
> +
> +group {
> +orientation = portrait
> +
> +ipmi-interface [class = "msgif"];
> +isa-ipmi-kcs [class="msgif", stacked];
> +
> +ipmi-interface <- isa-ipmi-kcs [hstyle = generalization];
> +}
> +
> +
> +group {
> +orientation = portrait
> +
> +ipmi-bmc [class = "bmc"];
> +ipmi-bmc-sim [class="bmc"];
> +ipmi-bmc-extern [class="bmc"];
> +
> +ipmi-bmc <- ipmi-bmc-sim [hstyle = generalization];
> +ipmi-bmc <- ipmi-bmc-extern [hstyle = generalization];
> +}
> +
> +}
> +}
> +
> +IPMI System Interfaces
> +--
> +
> +The system software running on the main processor may use a *system 
> interface*
> +to communicate with the BMC. These are hardware devices attached to an ISA, 
> PCI
> +or i2c bus, and in QEMU, they all need to implement ``ipmi-interface``.
> +This allows a BMC implementation to interact with the system interface in a
> +standard way.
> +
> +IPMI BMC
> +
> +
> +The system interface devices delegate emulation of BMC behavior to a BMC
> +device, that is a subclass of ``ipmi-bmc``. This type of device is called
> +a BMC because that's what it looks like to the main processor guest software.
> +
> +The BMC behavior may be simulated within the qemu process (``ipmi-bmc-sim``) 
> or
> +further delegated to an external emulator, or a real BMC. The
> +``ipmi-bmc-extern`` device has a required ``chardev`` property which 
> specifies
> +the communications channel to the external BMC.
> +
> +Wire protocol
> +=
> +
> +The wire protocol used between ``ipmi-bmc-extern`` and the external BMC
> +emulator is defined by `README.vm
> +

Re: [PATCH 1/8] docs: enable sphinx blockdiag extension

2021-09-09 Thread Corey Minyard
On Thu, Sep 09, 2021 at 04:06:13PM -0700, Hao Wu wrote:
> From: Havard Skinnemoen 
> 

Can you add some reason for this?  I also can't approve this, you'll
need permission from whoever is responsible for this file.

-corey

> Signed-off-by: Havard Skinnemoen 
> Signed-off-by: Hao Wu 
> ---
>  docs/conf.py | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/conf.py b/docs/conf.py
> index ff6e92c6e2..ecd0be66a5 100644
> --- a/docs/conf.py
> +++ b/docs/conf.py
> @@ -71,7 +71,11 @@
>  # Add any Sphinx extension module names here, as strings. They can be
>  # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
>  # ones.
> -extensions = ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc']
> +extensions = ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc',
> +'sphinxcontrib.blockdiag']
> +
> +# Fontpath for blockdiag (truetype font)
> +blockdiag_fontpath = 
> '/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf'
>  
>  # Add any paths that contain templates here, relative to this directory.
>  templates_path = ['_templates']
> -- 
> 2.33.0.309.g3052b89438-goog
> 



Re: [PATCH for-6.2 3/4] tests/qtest/ipmi-bt-test: Zero-initialize sockaddr struct

2021-08-14 Thread Corey Minyard
On Fri, Aug 13, 2021 at 04:05:05PM +0100, Peter Maydell wrote:
> Zero-initialize the sockaddr_in struct that we're about to fill in
> and pass to bind(), to ensure we don't leave possible
> implementation-defined extension fields as uninitialized garbage.
> 
> Signed-off-by: Peter Maydell 

Looks good to me.  Thanks, Peter.  I looked through all the other
patches, too, and reviewed those.

Reviewed-by: Corey Minyard 

> ---
>  tests/qtest/ipmi-bt-test.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/ipmi-bt-test.c b/tests/qtest/ipmi-bt-test.c
> index 8492f02a9c3..19612e9405a 100644
> --- a/tests/qtest/ipmi-bt-test.c
> +++ b/tests/qtest/ipmi-bt-test.c
> @@ -378,7 +378,7 @@ static void test_enable_irq(void)
>   */
>  static void open_socket(void)
>  {
> -struct sockaddr_in myaddr;
> +struct sockaddr_in myaddr = {};
>  socklen_t addrlen;
>  
>  myaddr.sin_family = AF_INET;
> -- 
> 2.20.1
> 



Re: [PATCH v4 0/2] Add remote I2C device to support external I2C device

2021-08-13 Thread Corey Minyard
On Fri, Aug 13, 2021 at 10:37:00AM -0400, Shengtan Mao wrote:
> Hi Corey,
> Thank you so much for your feedback. I took some time to discuss these
> points with my team.
> 
> 1. Blocking QEMU I/O
> Thanks for bringing this to our attention. We acknowledge it as a drawback,
> but we hope that by indicating this clearly in an updated docs, the user
> will accept these drawbacks when they use it. In short, we hope that you
> will consider merging this patch despite this drawback.

I understand the complexity this will add.  I'm not sure of the general
QEMU policy on this.  Everything that I know of that relies on remote
responses is done with async I/O.  The way you have proposed it would be
ok for testing, I suppose, but I don't think it would be ok in a
production system.  Things like this have a way of sneaking in to more
uses than you imagined.  (Hey, we can use this to tie in to a real
TPM!).

So I don't know.  I'll add Peter to the To: and see if he can speak to
this.

> 
> 2. Error Handling
> We will add them for the next version.
> 
> 3. Remote end NACK
> It  would be helpful to have a bit more information on this. The remote I2C
> in QEMU redirects the return value (which can indicate NACK / ACK) from the
> external device, so the remote end should be able to NACK if prompted by
> the external device. If you are saying that the remote I2C should be able
> to NACK independently, then no, it doesn't support that, but we can take
> steps to add it.

I believe you will eventually need the ability to get a remote NACK.
You may also need the ability to signal an interrupt from the remote
device (though that will require async input).  The information back
from the remote needs some sort of tag to make it extensible.

> 
> I am leaving google, so I will be passing this project to my team. Thank
> you again for your feedback.

Well, bummer.  This is a good idea hopefully we can see it through.

Thanks,

-corey


> 
> best,
> Shengtan
> 
> On Fri, Aug 6, 2021 at 9:55 PM Corey Minyard  wrote:
> 
> > On Fri, Aug 06, 2021 at 11:49:16PM +, Shengtan Mao wrote:
> > > This patch implements the remote I2C device.  The remote I2C device
> > allows an
> > > external I2C device to communicate with the I2C controller in QEMU
> > through the
> > > remote I2C protocol.  Users no longer have to directly modify QEMU to
> > add new
> > > I2C devices and can instead implement the emulated device externally and
> > > connect it to the remote I2C device.
> >
> > I got to spend some time on this today, and I like the concept, but
> > there is one major issue.  When you do a read, you are blocking the
> > entire qemu I/O system until the read returns, which may result in
> > issues.  At least that's may understanding of how the qemu I/O system
> > works, which may be dated or wrong.
> >
> > If you look at the IPMI code, it as an external BMC that can handle
> > async I/O from the chardev.  But the IPMI subsystem is designed to
> > handle this sort of thing.
> >
> > Unfortunately, the I2C code really isn't set up to handle async
> > operations.  I'm not sure how hard it would be to modify the I2C core to
> > handle this, but it doesn't look trivial.  Well, the changes to the core
> > wouldn't be terrible, but all the host devices are set up for
> > synchronous operation.  You could add a separate asynchronous interface,
> > and only host devices that were modified could use it, and your device
> > would only work on those host devices.
> >
> > Another issue is that you aren't handling errors from the chr read/write
> > calls.  If the remote connection dies, this isn't going to be good.  You
> > have to do error handling.
> >
> > There is also no way for the remote end to return a NACK.  That's pretty
> > important, I think.  It will, unfortunately, complicate your nice simple
> > protocol.
> >
> > Sorry to be the bearer of bad news.  Maybe I'm wrong about the blocking
> > thing, I'd be happy to be wrong.
> >
> > -corey
> >
> > >
> > > Previous work by Wolfram Sang
> > > (
> > https://git.kernel.org/pub/scm/virt/qemu/wsa/qemu.git/commit/?h=i2c-passthrough
> > )
> > > was referenced.  It shares the similar idea of redirecting the actual
> > I2C device
> > > functionalities, but Sang focuses on physical devices, and we focus on
> > emulated devices.
> > > The work by Sang mainly utilizes file descriptors while ours utilizes
> > character
> > > devices, which offers better support for emulated devices. The work by
> >

Re: [PATCH 09/10] hw/misc: Add Infineon DPS310 sensor model

2021-08-10 Thread Corey Minyard
On Mon, Aug 09, 2021 at 03:15:55PM +0200, Cédric Le Goater wrote:
> From: Joel Stanley 
> 
> This contains some hardcoded register values that were obtained from the
> hardware after reading the temperature.
> 
> It does enough to test the Linux kernel driver. The FIFO mode, IRQs and
> operation modes other than the default as used by Linux are not modelled.
> 
> Signed-off-by: Joel Stanley 
> [ clg: Fix sequential reading ]
> Message-Id: <20210616073358.750472-2-j...@jms.id.au>
> Signed-off-by: Cédric Le Goater 
> Message-Id: <20210629142336.750058-4-...@kaod.org>
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/misc/dps310.c| 227 

Can this go into hw/sensor?

-corey

>  hw/arm/Kconfig  |   1 +
>  hw/misc/Kconfig |   4 +
>  hw/misc/meson.build |   1 +
>  4 files changed, 233 insertions(+)
>  create mode 100644 hw/misc/dps310.c
> 
> diff --git a/hw/misc/dps310.c b/hw/misc/dps310.c
> new file mode 100644
> index ..893521ab8516
> --- /dev/null
> +++ b/hw/misc/dps310.c
> @@ -0,0 +1,227 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2017-2021 Joel Stanley , IBM Corporation
> + *
> + * Infineon DPS310 temperature and humidity sensor
> + *
> + * 
> https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps310/
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "hw/hw.h"
> +#include "hw/i2c/i2c.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +#include "migration/vmstate.h"
> +
> +#define NUM_REGISTERS   0x33
> +
> +typedef struct DPS310State {
> +/*< private >*/
> +I2CSlave i2c;
> +
> +/*< public >*/
> +uint8_t regs[NUM_REGISTERS];
> +
> +uint8_t len;
> +uint8_t pointer;
> +
> +} DPS310State;
> +
> +#define TYPE_DPS310 "dps310"
> +#define DPS310(obj) OBJECT_CHECK(DPS310State, (obj), TYPE_DPS310)
> +
> +#define DPS310_PRS_B2   0x00
> +#define DPS310_PRS_B1   0x01
> +#define DPS310_PRS_B0   0x02
> +#define DPS310_TMP_B2   0x03
> +#define DPS310_TMP_B1   0x04
> +#define DPS310_TMP_B0   0x05
> +#define DPS310_PRS_CFG  0x06
> +#define DPS310_TMP_CFG  0x07
> +#define  DPS310_TMP_RATE_BITS   (0x70)
> +#define DPS310_MEAS_CFG 0x08
> +#define  DPS310_MEAS_CTRL_BITS  (0x07)
> +#define   DPS310_PRESSURE_ENBIT(0)
> +#define   DPS310_TEMP_ENBIT(1)
> +#define   DPS310_BACKGROUND BIT(2)
> +#define  DPS310_PRS_RDY BIT(4)
> +#define  DPS310_TMP_RDY BIT(5)
> +#define  DPS310_SENSOR_RDY  BIT(6)
> +#define  DPS310_COEF_RDYBIT(7)
> +#define DPS310_CFG_REG  0x09
> +#define DPS310_RESET0x0c
> +#define  DPS310_RESET_MAGIC (BIT(0) | BIT(3))
> +#define DPS310_COEF_BASE0x10
> +#define DPS310_COEF_LAST0x21
> +#define DPS310_COEF_SRC 0x28
> +
> +static void dps310_reset(DeviceState *dev)
> +{
> +DPS310State *s = DPS310(dev);
> +
> +static const uint8_t regs_reset_state[] = {
> +0xfe, 0x2f, 0xee, 0x02, 0x69, 0xa6, 0x00, 0x80, 0xc7, 0x00, 0x00, 
> 0x00,
> +0x00, 0x10, 0x00, 0x00, 0x0e, 0x1e, 0xdd, 0x13, 0xca, 0x5f, 0x21, 
> 0x52,
> +0xf9, 0xc6, 0x04, 0xd1, 0xdb, 0x47, 0x00, 0x5b, 0xfb, 0x3a, 0x00, 
> 0x00,
> +0x20, 0x49, 0x4e, 0xa5, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
> 0x00,
> +0x60, 0x15, 0x02
> +};
> +
> +QEMU_BUILD_BUG_ON(sizeof(regs_reset_state) != sizeof(s->regs));
> +
> +memcpy(s->regs, regs_reset_state, sizeof(s->regs));
> +s->pointer = 0;
> +
> +/* TODO: assert these after some timeout ? */
> +s->regs[DPS310_MEAS_CFG] = DPS310_COEF_RDY | DPS310_SENSOR_RDY
> +| DPS310_TMP_RDY | DPS310_PRS_RDY;
> +}
> +
> +static uint8_t dps310_read(DPS310State *s, uint8_t reg)
> +{
> +if (reg >= sizeof(s->regs)) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: register 0x%02x out of bounds\n",
> +  __func__, s->pointer);
> +return 0xFF;
> +}
> +
> +switch (reg) {
> +case DPS310_PRS_B2:
> +case DPS310_PRS_B1:
> +case DPS310_PRS_B0:
> +case DPS310_TMP_B2:
> +case DPS310_TMP_B1:
> +case DPS310_TMP_B0:
> +case DPS310_PRS_CFG:
> +case DPS310_TMP_CFG:
> +case DPS310_MEAS_CFG:
> +case DPS310_CFG_REG:
> +case DPS310_COEF_BASE...DPS310_COEF_LAST:
> +case DPS310_COEF_SRC:
> +case 0x32: /* Undocumented register to indicate workaround not required 
> */
> +return s->regs[reg];
> +default:
> +qemu_log_mask(LOG_UNIMP, "%s: register 0x%02x unimplemented\n",
> +  __func__, reg);
> +return 0xFF;
> +}
> +}
> +
> +static void dps310_write(DPS310State *s, uint8_t reg, uint8_t data)
> +{
> +if (reg >= sizeof(s->regs)) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: register %d out of bounds\n",
> +  __func__, s->pointer);
> +return;
> +}
> +
> +switch (reg) {
>

Re: [PATCH v4 0/2] Add remote I2C device to support external I2C device

2021-08-06 Thread Corey Minyard
On Fri, Aug 06, 2021 at 11:49:16PM +, Shengtan Mao wrote:
> This patch implements the remote I2C device.  The remote I2C device allows an
> external I2C device to communicate with the I2C controller in QEMU through the
> remote I2C protocol.  Users no longer have to directly modify QEMU to add new
> I2C devices and can instead implement the emulated device externally and
> connect it to the remote I2C device.

I got to spend some time on this today, and I like the concept, but
there is one major issue.  When you do a read, you are blocking the
entire qemu I/O system until the read returns, which may result in
issues.  At least that's may understanding of how the qemu I/O system
works, which may be dated or wrong.

If you look at the IPMI code, it as an external BMC that can handle
async I/O from the chardev.  But the IPMI subsystem is designed to
handle this sort of thing.

Unfortunately, the I2C code really isn't set up to handle async
operations.  I'm not sure how hard it would be to modify the I2C core to
handle this, but it doesn't look trivial.  Well, the changes to the core
wouldn't be terrible, but all the host devices are set up for
synchronous operation.  You could add a separate asynchronous interface,
and only host devices that were modified could use it, and your device
would only work on those host devices.

Another issue is that you aren't handling errors from the chr read/write
calls.  If the remote connection dies, this isn't going to be good.  You
have to do error handling.

There is also no way for the remote end to return a NACK.  That's pretty
important, I think.  It will, unfortunately, complicate your nice simple
protocol.

Sorry to be the bearer of bad news.  Maybe I'm wrong about the blocking
thing, I'd be happy to be wrong.

-corey

> 
> Previous work by Wolfram Sang
> (https://git.kernel.org/pub/scm/virt/qemu/wsa/qemu.git/commit/?h=i2c-passthrough)
> was referenced.  It shares the similar idea of redirecting the actual I2C 
> device
> functionalities, but Sang focuses on physical devices, and we focus on 
> emulated devices.
> The work by Sang mainly utilizes file descriptors while ours utilizes 
> character
> devices, which offers better support for emulated devices. The work by Sang is
> not meant to offer full I2C device support; it only implements the receive
> functionality.  Our work implements full support for I2C devices: send, recv,
> and event (match_and_add is not applicable for external devices).
> 
> v1 -> v2
> fixed terminology errors in the description comments.
> v2 -> v3
> corrected patch set emailing errors.
> v3 -> v4
> added remote I2C protocol description in docs/specs
> 
> Shengtan Mao (2):
>   hw/i2c: add remote I2C device
>   docs/specs: add remote i2c docs
> 
>  docs/specs/index.rst  |   1 +
>  docs/specs/remote-i2c.rst |  51 
>  hw/arm/Kconfig|   1 +
>  hw/i2c/Kconfig|   4 +
>  hw/i2c/meson.build|   1 +
>  hw/i2c/remote-i2c.c   | 117 ++
>  tests/qtest/meson.build   |   1 +
>  tests/qtest/remote-i2c-test.c | 216 ++
>  8 files changed, 392 insertions(+)
>  create mode 100644 docs/specs/remote-i2c.rst
>  create mode 100644 hw/i2c/remote-i2c.c
>  create mode 100644 tests/qtest/remote-i2c-test.c
> 
> -- 
> 2.32.0.605.g8dce9f2422-goog
> 



Re: [PATCH v2 0/1] Add remote I2C device to support external I2C device

2021-08-03 Thread Corey Minyard
On Mon, Aug 02, 2021 at 11:03:22PM +, Shengtan Mao wrote:
> This patch implements the remote I2C device.
> The remote I2C device allows an external I2C device to communicate with the 
> I2C controller in QEMU through the remote I2C protocol.
> Users no longer have to directly modify QEMU to add new I2C devices and can 
> instead implement the emulated device externally and connect it to the remote 
> I2C device.

I apologise, I haven't had time to look at this, and I'm going to be
really busy for a little while.

I looked it over a bit, and is there some description of the protocol?
Could you add a reference to it in the code?

-corey

> 
> Previous work by Wolfram Sang 
> (https://git.kernel.org/pub/scm/virt/qemu/wsa/qemu.git/commit/?h=i2c-passthrough)
>  was referenced.
> It shares the similar idea of redirecting the actual I2C device 
> functionalities, but Sang focuses on physical devices, and we focus on 
> emulated devices.
> The work by Sang mainly utilizes file descriptors while ours utilizes 
> character devices, which offers better support for emulated devices.
> The work by Sang is not meant to offer full I2C device support; it only 
> implements the receive functionality.
> Our work implements full support for I2C devices: send, recv, and event 
> (match_and_add is not applicable for external devices).
> 
> Shengtan Mao (1):
>   hw/i2c: add remote I2C device
> 
>  hw/arm/Kconfig|   1 +
>  hw/i2c/Kconfig|   4 +
>  hw/i2c/meson.build|   1 +
>  hw/i2c/remote-i2c.c   | 117 ++
>  tests/qtest/meson.build   |   1 +
>  tests/qtest/remote-i2c-test.c | 216 ++
>  6 files changed, 340 insertions(+)
>  create mode 100644 hw/i2c/remote-i2c.c
>  create mode 100644 tests/qtest/remote-i2c-test.c
> 
> -- 
> 2.32.0.554.ge1b32706d8-goog
> 



Re: QEMU question: upstreaming I2C device with unpublished datasheet

2021-07-27 Thread Corey Minyard
On Tue, Jul 27, 2021 at 10:23:26AM +0100, Peter Maydell wrote:
> On Wed, 21 Jul 2021 at 22:06, Shengtan Mao  wrote:
> >
> > Hi everyone,
> > we are hoping to upstream a MAX I2C device to QEMU. The device's datasheet 
> > is not public, and we are contacting the Maxim company to get their 
> > permission. If Maxim is okay with upstreaming the device with an 
> > unpublished datasheet, will this still be an issue with QEMU?
> 
> It's not inherently a blocker, but the difficulty is code review.
> Without knowing how the device should behave, it's hard to tell
> whether the model is doing the right thing. Ideally Maxim should
> just publish their datasheet, so if you/your company has any
> leverage with them you should push them to do that :-)
> 
> That said, we do have other device models in the tree which
> don't have public datasheets, and as long as the device is not
> too complicated we should be OK as long as you can also submit
> enough test cases that we could refactor the device in future
> without worrying too much that we're breaking it because we don't
> know how it's supposed to behave.

Thanks Peter.

I will add that you need to be sure you have the legal right to publish
the software.  If you have a non-public datasheet, that probably means
you had to sign NDA or something like that to see it.  That may limit
what you can do.

-corey



  1   2   3   4   5   6   7   8   9   10   >