qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC 0/3] Add Generic SPI GPIO model


From: Peter Delevoryas
Subject: Re: [RFC 0/3] Add Generic SPI GPIO model
Date: Sat, 30 Jul 2022 15:06:36 -0700

On Sat, Jul 30, 2022 at 11:18:33PM +0200, Cédric Le Goater wrote:
> On 7/29/22 19:30, Peter Delevoryas wrote:
> > On Fri, Jul 29, 2022 at 03:25:55PM +0200, Cédric Le Goater wrote:
> > > Hello Iris,
> > > 
> > > On 7/29/22 01:23, Iris Chen wrote:
> > > > Hey everyone,
> > > > 
> > > > I have been working on a project to add support for SPI-based TPMs in 
> > > > QEMU.
> > > > Currently, most of our vboot platforms using a SPI-based TPM use the 
> > > > Linux
> > > > SPI-GPIO driver to "bit-bang" the SPI protocol. This is because the 
> > > > Aspeed
> > > > SPI controller (modeled in QEMU under hw/ssi/aspeed_smc.c) has an 
> > > > implementation
> > > > deficiency that prevents bi-directional operations.
> > > aspeed_smc models the Aspeed FMC/SPI controllers which have a well defined
> > > HW interface. Your model proposal adds support for a new SPI controller
> > > using bitbang GPIOs. These are really two differents models. I don't see
> > > how you could reuse aspeed_smc for this purpose.
> > > 
> > > or you mean that Linux is using the SPI-GPIO driver because the Linux
> > > Aspeed SMC driver doesn't match the need ? It is true that the Linux
> > > driver is not generic, it deals with flash devices only. But that's
> > > another problem.
> > > 
> > > > Thus, in order to connect
> > > > a TPM to this bus, my patch implements a QEMU SPI-GPIO driver (as the 
> > > > QEMU
> > > > counterpart of the Linux SPI-GPIO driver).
> > > > 
> > > > As we use SPI-based TPMs on many of our BMCs for the secure-boot 
> > > > implementation,
> > > > I have already tested this implementation locally with our 
> > > > Yosemite-v3.5 platform
> > > > and Facebook-OpenBMC. This model was tested by connecting a generic 
> > > > SPI-NOR (m25p80
> > > > for example) to the Yosemite-v3.5 SPI bus containing the TPM.
> > > > 
> > > > This patch is an RFC because I have several questions about design. 
> > > > Although the
> > > > model is working, I understand there are many areas where the design 
> > > > decision
> > > > is not deal (ie. abstracting hard coded GPIO values). Below are some 
> > > > details of the
> > > > patch and specific areas where I would appreciate feedback on how to 
> > > > make this better:
> > > > hw/arm/aspeed.c:
> > > > I am not sure where the best place is to instantiate the spi_gpio 
> > > > besides the
> > > > aspeed_machine_init.
> > > 
> > > The SPI GPIO device would be a platform device and not a SoC device.
> > > Hence, it should be instantiated at the machine level, like the I2C
> > > device are, using properties to let the model know about the GPIOs
> > > that should be driven to implement the SPI protocol.
> > 
> > Agreed, should be like an I2C device.
> > 
> > > 
> > > Ideally, the state of the GPIO controller pins and the SPI GPIO state
> > > should be shared. I think that's what you are trying to do that with
> > > attribute 'controller_state' in your patch ? But, the way it is done
> > > today, is too tightly coupled (names) with the Aspeed GPIO model to
> > > be generic.
> > > 
> > > I think we need an intermediate QOM interface, or a base class, to
> > > implement an abstract SPI GPIO model and an Aspeed SPI GPIO model
> > > on top which would be linked to the Aspeed GPIO model of the SoC
> > > in use.
> > 
> > Disagree, I feel like we can accomplish this without inheritance.
> > 
> > > 
> > > Or we could introduce some kind of generic GPIO controller that
> > > we would link the SPI GPIO model with (using a property). The
> > > Aspeed GPIO model would be of that kind and the SPI GPIO model
> > > would be able to drive the pins using a common interface.
> > > That's another way to do it.
> > 
> > Agree, I would like to go in this direction if at all possible.
> Let's give it a try then. I would introduce a new QOM interface,
> something like  :
> 
>     #define TYPE_GPIO_INTERFACE "gpio-interface"
>     #define GPIO_INTERFACE(obj)                                     \
>         INTERFACE_CHECK(GpioInterface, (obj), TYPE_GPIO_INTERFACE)
>     typedef struct GpioInterfaceClass GpioInterfaceClass;
>     DECLARE_CLASS_CHECKERS(GpioInterfaceClass, GPIO_INTERFACE,
>                            TYPE_GPIO_INTERFACE)
>     struct GpioInterfaceClass {
>         InterfaceClass parent;
>         int (*get)(GpioInterface *gi, ...);
>         int (*set)(GpioInterface *gi, ...);
>         ...
>     };
> 
> and implement the interface handlers under the AspeedGPIO model.
> The SPI GPIO model would have a link to such an interface to drive
> the GPIO pins.
> 
> See IPMI and XIVE for some more complete models.

This sounds good, but I just want to clarify first:

Is it necessary to introduce a GPIO interface?

Or, could we connect the IRQ's just using the existing
QOM/sysbus/object/IRQ infrastructure?

I'll investigate if we can connect the IRQ's without introducing a new
interface. We can continue with this design for now though.

> 
> > > > Could we add the ability to instantiate it on the command line?
> > > 
> > > It might be complex to identify the QOM object to use as the GPIO
> > > controller from the command line since it is on the SoC and not
> > > a platform device. In that case, an Aspeed SPI GPIO model would
> > > be a better approach. we  would have to peek in the machine/soc to
> > > get a link on the Aspeed GPIO model in the realize routine of the
> > > Aspeed SPI GPIO model.
> > 
> > Hrrrm perhaps, I feel like it shouldn't be that hard though.
> > 
> > - Get a pointer to the QOM object that holds the GPIO's using object
> >    path or ID. Something similar to '-device ftgmac100,netdev=<id>'
> >    right?
> 
> yes. something like that.

+1

> 
> > - Get the GPIO's by name from the QOM object.
> 
> yes.

+1

> 
> > In this situation, I think we should be able to get the GPIO controller
> > object, and then get the IRQ's by the "sysbus-irq[126]"/etc name.
> > 
> > We could refactor the aspeed_gpio.c model to name the IRQ's like the
> > properties,.  to use "gpioX4" instead of "sysbus-irq[*]".
> 
> we could use qdev_init_gpio_out_named() instead of sysbus_init_irq()
> to name them.
>

+1, I actually suggested to Iris offline that this change might be
useful regardless.

> 
> > > > m25p80_transfer8_ex in hw/block/m25p80.c:
> > > > Existing SPI model assumed that the output byte is fully formed, can be 
> > > > passed to
> > > > the SPI device, and the input byte can be returned, all in one 
> > > > operation. With
> > > > SPI-GPIO we don't have the input byte until all 8 bits of the output 
> > > > have been
> > > > shifted out, so we have to prime the MISO with bogus values (0xFF).
> > > 
> > > That's fine I think. We do something similar for dummies.
> > > 
> > > > MOSI pin in spi_gpio: the mosi pin is not included and we poll the 
> > > > realtime value
> > > > of the gpio for input bits to prevent bugs with caching the mosi value. 
> > > > It was discovered
> > > > during testing that when using the mosi pin as the input pin, the mosi 
> > > > value was not
> > > > being updated due to a kernel and aspeed_gpio model optimization.
> > > 
> > > ah. We need help from Andrew ! the model should have a mosi pin .
> > 
> > Not sure if this was clear, but Iris is just saying that she used object
> > properties to read and write the mosi, miso, and clk pins, rather than
> > the IRQ's.
> 
> The IRQ line is not raised ?

Something like that, yes. She was having trouble following the IRQ level
purely through edge changes. Perhaps this is due to a bug in
aspeed_gpio.c.

> 
> > Certainly we'd like to use IRQ's instead, but she ran into correctness
> > problems. Maybe we can investigate that further and fix it.
> 
> So much is happening in that mode. We need more trace events in the Aspeed
> GPIO model at least an extra in aspeed_gpio_update()

+1

> 
> Thanks,
> 
> C.
> 
> > 
> > > 
> > > Thanks,
> > > 
> > > C.
> > > 
> > > > Thus, here we are
> > > > reading the value directly from the gpio controller instead of waiting 
> > > > for the push.
> > > > 
> > > > I realize there are Aspeed specifics in the spi_gpio model. To make 
> > > > this extensible,
> > > > is it preferred to make this into a base class and have our Aspeed SPI 
> > > > GPIO extend
> > > > this or we could set up params to pass in the constructor?
> > > > 
> > > > Thanks for your review and any direction here would be helpful :)
> > > > 
> > > > Iris Chen (3):
> > > >     hw: m25p80: add prereading ability in transfer8
> > > >     hw: spi_gpio: add spi gpio model
> > > >     hw: aspeed: hook up the spi gpio model
> > > > 
> > > >    hw/arm/Kconfig            |   1 +
> > > >    hw/arm/aspeed.c           |   5 ++
> > > >    hw/block/m25p80.c         |  29 ++++++-
> > > >    hw/ssi/Kconfig            |   4 +
> > > >    hw/ssi/meson.build        |   1 +
> > > >    hw/ssi/spi_gpio.c         | 166 
> > > > ++++++++++++++++++++++++++++++++++++++
> > > >    hw/ssi/ssi.c              |   4 -
> > > >    include/hw/ssi/spi_gpio.h |  38 +++++++++
> > > >    include/hw/ssi/ssi.h      |   5 ++
> > > >    9 files changed, 248 insertions(+), 5 deletions(-)
> > > >    create mode 100644 hw/ssi/spi_gpio.c
> > > >    create mode 100644 include/hw/ssi/spi_gpio.h
> > > > 
> > > 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]