Re: [PATCH] fix BCM2835_I2C_CLKT
Philippe Mathieu-Daudé <[email protected]> Mon, 27 Jul 2026 13:54:49 +0200
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 27/7/26 12:04, Peter Maydell wrote: > On Fri, 24 Jul 2026 at 13:51, botszhuang <[email protected]> wrote: >> >> hw/i2c/bcm2835_i2c: Correct CLKT register offset >> >> The Clock Stretch Timeout (CLKT) register for the BCM2835 I2C controller is actually located at offset 0x1c, not 0x20. >> >> The previous incorrect value caused the guest OS to read from and write to the wrong memory address when configuring the I2C timeout, which could lead to unexpected controller behavior. >> >> Update the BCM2835_I2C_CLKT macro to match the hardware specification. > > Checking the datasheet, this is definitely the wrong value, > so the fix is correct. I'm a bit confused by your commit message, > though. The value here in QEMU can't cause the guest OS to write > to the wrong memory address, because the guest OS doesn't ever > see what we have defined here. It has the offset hardcoded into > its own source code. > > It looks to me like the effect of getting this wrong is that when > the guest writes to CLKT (at its actual 0x1c offset) we will log > a guest error and give read-as-zero behaviour. That's not correct, > but I expect for most guest OSes it'll be pretty harmless because > the guest probably doesn't write the value it wants to configure > and then read it back to check. (QEMU ignores the value written > anyway.) > > I've applied this to target-arm.next. Should we also reduce the region size? -- >8 -- diff --git a/hw/i2c/bcm2835_i2c.c b/hw/i2c/bcm2835_i2c.c index 34de1f36e5b..5f6093087dd 100644 --- a/hw/i2c/bcm2835_i2c.c +++ b/hw/i2c/bcm2835_i2c.c @@ -222,7 +222,7 @@ static void bcm2835_i2c_realize(DeviceState *dev, Error **errp) s->bus = i2c_init_bus(dev, NULL); memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_i2c_ops, s, - TYPE_BCM2835_I2C, 0x24); + TYPE_BCM2835_I2C, 0x20); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); } ---