On Tue, Sep 22, 2026 at 09:43:52AM -0600, Mathieu Poirier wrote:
> On Wed, Sep 16, 2026 at 11:10:57PM +0200, Francesco Valla wrote:
> > Add rings for multiple vdevs, as well as the required virtio nodes for
> > I2C, SPI and GPIO functionalities. On top of that, add example
> > peripherals using all of them.
> > 
> > NOTE: this is a Proof-Of-Concept, not meant to be integrated!
> > 
> > Signed-off-by: Francesco Valla <[email protected]>
> > ---
> >  arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts | 128 
> > +++++++++++++++++++--
> >  1 file changed, 119 insertions(+), 9 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts 
> > b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
> > index bd14ba28690c..dfa3b122ac5f 100644
> > --- a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
> > @@ -53,6 +53,32 @@ button-k3 {
> >             };
> >     };
> >  
> > +   gpio-keys-virtio {
> > +           compatible = "gpio-keys-polled";
> > +           poll-interval = <100>;
> > +
> > +           button-v1 {
> > +                   label = "Button V1";
> > +                   linux,code = <BTN_3>;
> > +                   gpios = <&v_gpio 23 GPIO_ACTIVE_LOW>;
> > +           };
> > +
> > +           button-v2 {
> > +                   label = "Button V2";
> > +                   linux,code = <BTN_4>;
> > +                   gpios = <&v_gpio 24 GPIO_ACTIVE_LOW>;
> > +           };
> > +   };
> > +
> > +   leds {
> > +           compatible = "gpio-leds";
> > +
> > +           led {
> > +                   gpios = <&v_gpio 18 GPIO_ACTIVE_HIGH>;
> > +                   label = "LED V";
> > +           };
> > +   };
> > +
> >     reg_usdhc2_vmmc: regulator-usdhc2 {
> >             compatible = "regulator-fixed";
> >             off-on-delay-us = <12000>;
> > @@ -89,11 +115,6 @@ linux,cma {
> >                     linux,cma-default;
> >             };
> >  
> > -           rsc_table: rsc-table@2021e000 {
> > -                   reg = <0 0x2021e000 0 0x1000>;
> > -                   no-map;
> > -           };
> > -
> 
> Why is the resource table removed?  There is no mention of that in the
> changelog...
>

You are obviously right, the commit message here should have been a
poem, not a form of hermetic poetry. My bad.

The resource table here is causing problems with how Zephyr is managing
it at its side. If it is kept in a separate memory location and copied
there at runtime by the remote processor firmware during its startup
(which is the current Zephyr behavior), then there might be a race
condition when the aforesaid firmware is loaded and started by Linux
*and* at least one of the vdev drivers (here including rpmsg_bus) is
built-in. In this case, the copy of the resource table done by the
remote processor might - depending on the async execution of the two
processors - overwrite the status bit set by the Linux driver:

  Firmware load and startup (echo start > /sys/.../state)
                           |
                           |
                           V
  The vdev devices get registered (by register_virtio_device())
                           |
                           |
                           V
  If a driver is built-in, it probes and sets the vdev status
  inside the resource table @rsc-table.
                           .
                           . (in the mean time)
                           .
  The remote processor starts up and copies the resource table from its
  dedicated section to @rsc-table.

Depending on the system load and the complexity of the firmware, the two
operations can happen in whatever sequence, causing a race condition.

This is somewhat masked if vdev drivers are built as modules, as the
devices does not probe immediately but only after the modules have been
loaded, giving the remote processor time to start. Note that this is not
a solution! but a workaround.

If the rsc-table node is not there, the startup logic falls back to the
classic rproc_elf_find_loaded_rsc_table().

This is specific to i.MX platforms [1] and is probably not normally an
issue because - as stated in [1] - the offical SDK from NXP seems not
to check the status inside the resource table.

> >             vdev0vring0: vdev0vring0@a4000000 {
> >                     reg = <0 0xa4000000 0 0x8000>;
> >                     no-map;
> > @@ -105,12 +126,42 @@ vdev0vring1: vdev0vring1@a4008000 {
> >             };
> >  
> >             vdev1vring0: vdev1vring0@a4010000 {
> > -                   reg = <0 0xa4010000 0 0x8000>;
> > +                   reg = <0 0xa4010000 0 0x1000>;
> > +                   no-map;
> > +           };
> > +
> > +           vdev2vring0: vdev2vring0@a4011000 {
> > +                   reg = <0 0xa4011000 0 0x2000>;
> > +                   no-map;
> > +           };
> > +
> > +           vdev2vring1: vdev2vring1@a4013000 {
> > +                   reg = <0 0xa4013000 0 0x2000>;
> > +                   no-map;
> > +           };
> > +
> > +           vdev3vring0: vdev3vring0@a4015000 {
> > +                   reg = <0 0xa4015000 0 0x2000>;
> > +                   no-map;
> > +           };
> > +
> > +           vdev4vring0: vdev4vring0@a4017000 {
> > +                   reg = <0 0xa4017000 0 0x4000>;
> > +                   no-map;
> > +           };
> > +
> > +           vdev5vring0: vdev5vring0@a401B000 {
> > +                   reg = <0 0xa401B000 0 0x2000>;
> > +                   no-map;
> > +           };
> > +
> > +           vdev5vring1: vdev5vring1@a401D000 {
> > +                   reg = <0 0xa401D000 0 0x2000>;
> >                     no-map;
> >             };
> >  
> > -           vdev1vring1: vdev1vring1@a4018000 {
> > -                   reg = <0 0xa4018000 0 0x8000>;
> > +           vdev5vring2: vdev5vring2@a401F000 {
> > +                   reg = <0 0xa401F000 0 0x1000>;
> >                     no-map;
> >             };
> >  
> > @@ -149,8 +200,67 @@ &cm33 {
> >              <&mu1 3 1>;
> >     mbox-names = "tx", "rx", "rxdb";
> >     memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
> > -                   <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
> > +                   <&vdev1vring0>, <&vdev2vring0>, <&vdev2vring1>,
> > +                   <&vdev3vring0>, <&vdev4vring0>,
> > +                   <&vdev5vring0>, <&vdev5vring1>, <&vdev5vring2>;
> 
> Who is using vdev5 vrings?  
> 

Another thing that should have been in the commit message. Vdevs are
defined, in the Zephyr application I am using as PoC, as follows:

 - vdev0: RPMSG (tx and rx vrings)
 - vdev1: entropy (single request vring)
 - vdev2: GPIO (request and event vrings)
 - vdev3: I2C (single request vring)
 - vdev4: SPI (single request vring)
 - vdev5: CAN (tx, rx and control vrings)

vdev5 is not represented inside the devicetree because the can-virtio
driver registers a single CAN network device and has thus no need for
such representation.

> >     status = "okay";
> > +
> > +   virtio {
> > +           #address-cells = <1>;
> > +           #size-cells = <0>;
> > +
> > +           vdev@2 {
> > +                   reg = <2>;
> > +
> > +                   v_gpio: gpio {
> > +                           compatible = "virtio,device29";
> > +                           gpio-controller;
> > +                           #gpio-cells = <2>;
> > +                           interrupt-controller;
> > +                           #interrupt-cells = <2>;
> > +                   };
> > +           };
> > +
> > +           vdev@3 {
> > +                   reg = <3>;
> > +
> > +                   i2c {
> > +                           compatible = "virtio,device22";
> > +                           #address-cells = <1>;
> > +                           #size-cells = <0>;
> > +
> > +                           eeprom@50 {
> > +                                   compatible = "atmel,24c1025";
> > +                                   reg = <0x50>;
> > +                           };
> > +                   };
> > +           };
> > +
> > +           vdev@4 {
> > +                   reg = <4>;
> > +
> > +                   spi {
> > +                           compatible = "virtio,device2d";
> > +                           #address-cells = <1>;
> > +                           #size-cells = <0>;
> > +
> > +                           sram@0 {
> > +                                   compatible = "microchip,mchp23k256";
> > +                                   reg = <0>;
> > +                                   spi-max-frequency = <20000000>;
> > +                           };
> > +
> > +                           lcd@1 {
> > +                                   compatible = "adafruit,yx240qv29", 
> > "ilitek,ili9341";
> > +                                   reg = <1>;
> > +                                   spi-max-frequency = <10000000>;
> > +                                   dc-gpios = <&v_gpio 21 
> > GPIO_ACTIVE_HIGH>;
> > +                                   reset-gpios = <&v_gpio 20 
> > GPIO_ACTIVE_HIGH>;
> > +                                   rotation = <90>;
> > +                           };
> > +                   };
> > +           };
> > +   };
> >  };
> >  
> >  &eqos {
> > 
> > -- 
> > 2.55.0
> >

Thank you!

Regards,
Francesco


[1] https://lore.kernel.org/all/[email protected]/

Reply via email to