bcm2835_aux (raspi3) fails when the receive FIFO fills up
Host environment
- Operating system: Linux
- OS/kernel version: Linux 5.4.0-77-generic x86_64 GNU/Linux
- Architecture: x86_64
- QEMU flavor: qemu-system-aarch64
- QEMU version: QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.16)
- QEMU command line:
echo abcdefgh | qemu-system-aarch64 -M raspi3 -kernel kernel8.elf -serial null -serial stdio
Emulated/Virtualized environment
- Operating system: bare-metal see below
- Architecture: aarch64
Description of problem
When a bare-metal application on the raspi3
board reads the AUX_MU_STAT_REG
MMIO register while the device's buffer is at full receive FIFO capacity (i.e. s->read_count == BCM2835_AUX_RX_FIFO_LEN
) the assertion assert(s->read_count < BCM2835_AUX_RX_FIFO_LEN)
fails.
The assertion in question is currently in line 141 of hw/char/bcm2835_aux.c
: https://gitlab.com/qemu-project/qemu/-/blob/9c2647f75004c4f7d64c9c0ec55f8c6f0739a8b1/hw/char/bcm2835_aux.c#L141
but in my current QEMU version, it seems that it was in line 140, but I don't think that has any implication on this error. If the below steps to reproduce are followed, the full output of a normal QEMU (no debugging output or anything) is simply:
$ echo abcdefgh | qemu-system-aarch64 -M raspi3 -kernel kernel8.elf -serial null -serial stdio
qemu-system-aarch64: /build/qemu-71DV4m/qemu-4.2/hw/char/bcm2835_aux.c:140: bcm2835_aux_read: Assertion `s->read_count < BCM2835_AUX_RX_FIFO_LEN' failed.
Aborted (core dumped)
Notice, that there is nothing really wrong with the implementation, if for instance an application that uses the AUX_MU_LSR_REG
instead to check whether input is available, everything works as expected. It really seems that just this assertion is wrong. Also notice that the BCM2835 manual (page 18) explicitly allows values inclusive 8.
Steps to reproduce
- write a minimal bare-metal application for aarch64 using below main file
- compile it with a decent aarch64 compiler, linker script and entry assembly as
kernel8.elf
echo abcdefgh | qemu-system-aarch64 -M raspi3 -kernel kernel8.elf -serial null -serial stdio
- QEMU crashes with the above state assertion error
Additional information
Minimal bare-metal application (main.c
):
#define MMIO_BASE 0x3F000000
#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064))
void main() {
while (1) {
// Just read STAT register to trigger the assertion error
*AUX_MU_STAT;
}
}
Also see kernel8.elf.zip for a precompiled version of the above application.