raspi4b I2C and SPI no interrupt

Host environment

  • Operating system: Manjaro 25.0.0 Zetar
  • OS/kernel version: Linux gui-pc 6.12.12-2-MANJARO #1 SMP PREEMPT_DYNAMIC Mon, 03 Feb 2025 16:27:19 +0000 x86_64 GNU/Linux
  • Architecture: x86
  • QEMU flavor: qemu-system-aarch64
  • QEMU version: 9.2.1
  • QEMU command line:
    qemu-system-aarch64 \
     -M raspi4b \
     -m 2G \
     -kernel rtthread.bin \
     -dtb bcm2711-rpi-4-b.dtb \
     -serial mon:stdio \
     -device ds1338,address=0x68,bus=i2c-bus.0 \
     -device m25p80,write-enable=true,drive=flash0,bus=spi \
     	-blockdev node-name=flash0,driver=file,filename=flash.bin

Emulated/Virtualized environment

  • Operating system: RT-Thread
  • OS/kernel version: RT-Thread Smart 5.2.1
  • Architecture: AARCH64

Description of problem

The SPI and I2C interrupts were not injected success.

Steps to reproduce

  1. Add RTC ds1338 to I2C bus0, add m25p80 to SPI bus0.
  2. When type the data, the I2C wait timeout for read RTC date.
  3. The SPI not dont by IRQ when probe the SPI-nor flash.
  4. I tried to add the I2C and SPI irq connect by GIC SPI, then they could work:
--- a/qemu/include/hw/arm/bcm2838_peripherals.h  2025-06-30 13:50:04.166986438 +0800
+++ b/qemu/include/hw/arm/bcm2838_peripherals.h  2025-02-12 05:08:13.000000000 +0800
@@ -22,8 +22,6 @@
 #define GIC_SPI_INTERRUPT_DMA_7_8      87
 #define GIC_SPI_INTERRUPT_DMA_9_10     88
 #define GIC_SPI_INTERRUPT_AUX_UART1    93
+#define GIC_SPI_INTERRUPT_I2C          117
+#define GIC_SPI_INTERRUPT_SPI          118
 #define GIC_SPI_INTERRUPT_SDHOST       120
 #define GIC_SPI_INTERRUPT_UART0        121
 #define GIC_SPI_INTERRUPT_RNG200       125

--- a/qemu/hw/arm/bcm2838.c      2025-06-30 13:50:14.967838852 +0800
+++ b/qemu/hw/arm/bcm2838.c      2025-02-12 05:08:13.000000000 +0800
@@ -184,14 +184,6 @@
     sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->aux), 0,
                        qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_AUX_UART1));
 
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->i2c[0]), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_I2C));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->i2c[1]), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_I2C));
+
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->spi[0]), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_SPI));
+
     /* Connect VC mailbox to the interrupt controller */
     sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->mboxes), 0,
                        qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_MBOX));
Edited by GUI