The CFI entry for sector length must be set to sector length per device.
This is important for boards using multiple devices like the ARM
Vexpress board (width = 4, device-width = 2).
Linux and u-boots calculate the size ratio by dividing both values:
size_ratio = info->portwidth / info->chipwidth;
After that the sector length will be multiplied by the size_ratio, thus
the CFI entry for sector length is doubled. When Linux or u-boot send a
sector erase, they expect to erase the doubled sector length, but QEMU
only erases the board specified sector length.
This patch fixes the sector length in the CFI table to match the length
per device, equal to blocks_per_device.
Signed-off-by: David Engraf <david.eng...@sysgo.com>
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 5f0ee9d..8bb61e4 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -703,7 +703,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
pflash_t *pfl = CFI_PFLASH01(dev);
uint64_t total_len;
int ret;
- uint64_t blocks_per_device, device_len;
+ uint64_t blocks_per_device, sector_len_per_device, device_len;
int num_devices;
Error *local_err = NULL;
@@ -727,7 +727,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
*/
num_devices = pfl->device_width ? (pfl->bank_width / pfl->device_width) : 1;
blocks_per_device = pfl->nb_blocs / num_devices;
- device_len = pfl->sector_len * blocks_per_device;
+ sector_len_per_device = pfl->sector_len / num_devices;
+ device_len = sector_len_per_device * blocks_per_device;
/* XXX: to be fixed */
#if 0
@@ -839,8 +840,8 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
/* Erase block region 1 */
pfl->cfi_table[0x2D] = blocks_per_device - 1;
pfl->cfi_table[0x2E] = (blocks_per_device - 1) >> 8;
- pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
- pfl->cfi_table[0x30] = pfl->sector_len >> 16;
+ pfl->cfi_table[0x2F] = sector_len_per_device >> 8;
+ pfl->cfi_table[0x30] = sector_len_per_device >> 16;
/* Extended */
pfl->cfi_table[0x31] = 'P';