aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/block/pflash_cfi02.c8
-rw-r--r--tests/pflash-cfi02-test.c12
2 files changed, 17 insertions, 3 deletions
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index e64dc69c6c..4be3837be5 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -281,11 +281,13 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
}
offset &= pfl->chip_len - 1;
- boff = offset & (pfl->sector_len - 1);
+ boff = offset;
if (pfl->width == 2)
boff = boff >> 1;
else if (pfl->width == 4)
boff = boff >> 2;
+ /* Only the least-significant 11 bits are used in most cases. */
+ boff &= 0x7FF;
switch (pfl->wcycle) {
case 0:
/* Set the device in I/O access mode if required */
@@ -538,6 +540,10 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
}
}
+ /* Only 11 bits are used in the comparison. */
+ pfl->unlock_addr0 &= 0x7FF;
+ pfl->unlock_addr1 &= 0x7FF;
+
pflash_setup_mappings(pfl);
pfl->rom_mode = 1;
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
diff --git a/tests/pflash-cfi02-test.c b/tests/pflash-cfi02-test.c
index e7e16a8dd8..e090b2e3a0 100644
--- a/tests/pflash-cfi02-test.c
+++ b/tests/pflash-cfi02-test.c
@@ -21,8 +21,8 @@
#define FLASH_WIDTH 2
#define CFI_ADDR (FLASH_WIDTH * 0x55)
-#define UNLOCK0_ADDR (FLASH_WIDTH * 0x5555)
-#define UNLOCK1_ADDR (FLASH_WIDTH * 0x2AAA)
+#define UNLOCK0_ADDR (FLASH_WIDTH * 0x555)
+#define UNLOCK1_ADDR (FLASH_WIDTH * 0x2AA)
#define CFI_CMD 0x98
#define UNLOCK0_CMD 0xAA
@@ -190,6 +190,14 @@ static void test_flash(void)
g_assert_cmphex(flash_read(6), ==, 0xCDEF);
g_assert_cmphex(flash_read(8), ==, 0xFFFF);
+ /* Test ignored high order bits of address. */
+ flash_write(FLASH_WIDTH * 0x5555, UNLOCK0_CMD);
+ flash_write(FLASH_WIDTH * 0x2AAA, UNLOCK1_CMD);
+ flash_write(FLASH_WIDTH * 0x5555, AUTOSELECT_CMD);
+ g_assert_cmpint(flash_read(FLASH_WIDTH * 0x0000), ==, 0x00BF);
+ g_assert_cmpint(flash_read(FLASH_WIDTH * 0x0001), ==, 0x236D);
+ reset();
+
qtest_quit(global_qtest);
}