hw/pxa2xx.c: Fix handling of pxa2xx_i2c variable offset within region
commit14dd5faa7e168d70760902c269dc68f3104b8ed6
authorPeter Maydell <peter.maydell@linaro.org>
Wed, 14 Mar 2012 15:37:53 +0000 (14 15:37 +0000)
committerPeter Maydell <peter.maydell@linaro.org>
Fri, 16 Mar 2012 18:09:55 +0000 (16 18:09 +0000)
tree9146aa0edaed9bb51974edd926645e66f6949a09
parent27424dcc6804e630602a61229e57e42b14050869
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>
hw/pxa2xx.c