aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2012-03-14 15:37:53 +0000
committerPeter Maydell <peter.maydell@linaro.org>2012-03-16 18:09:55 +0000
commit14dd5faa7e168d70760902c269dc68f3104b8ed6 (patch)
tree9146aa0edaed9bb51974edd926645e66f6949a09
parent27424dcc6804e630602a61229e57e42b14050869 (diff)
hw/pxa2xx.c: Fix handling of pxa2xx_i2c variable offset within region
The pxa2xx I2C controller can have its registers at an arbitrary offset within the MemoryRegion it creates. We use this to create two controllers, one which covers a region of size 0x10000 with registers starting at an offset 0x1600 into that region, and a second one which covers a region of size just 0x100 with the registers starting at the base of the region. The implementation of this offsetting uses two qdev properties, "offset" (which sets the offset which must be subtracted from the address to get the offset into the actual register bank) and "size", which is the size of the MemoryRegion. We were actually using "offset" for two purposes: firstly the required one of handling the registers not being at the base of the MemoryRegion, and secondly as a workaround for a deficiency of QEMU. Until commit 5312bd8b3, if a MemoryRegion was mapped at a non-page boundary, the address passed into the read and write functions would be the offset from the start of the page, not the offset from the start of the MemoryRegion. So when calculating the value to set the "offset" qdev property we included a rounding to a page boundary. Following commit 5312bd8b3 MemoryRegion read/write functions are now correctly passed the offset from the base of the region, and our workaround now means we're subtracting too much from addresses, resulting in warnings like "pxa2xx_i2c_read: Bad register 0xffffff90". The fix for this is simply to remove the rounding to a page boundary; this allows us to slightly simplify the expression since base - (base & (~region_size)) == base & region_size The qdev property "offset" itself must remain because it is still performing its primary job of handling register banks not being at the base of the MemoryRegion. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Andreas Färber <afaerber@suse.de>
-rw-r--r--hw/pxa2xx.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index f55287774..1d5c35f17 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1507,8 +1507,7 @@ PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
i2c_dev = sysbus_from_qdev(qdev_create(NULL, "pxa2xx_i2c"));
qdev_prop_set_uint32(&i2c_dev->qdev, "size", region_size + 1);
- qdev_prop_set_uint32(&i2c_dev->qdev, "offset",
- base - (base & (~region_size) & TARGET_PAGE_MASK));
+ qdev_prop_set_uint32(&i2c_dev->qdev, "offset", base & region_size);
qdev_init_nofail(&i2c_dev->qdev);