On Mon, Mar 14, 2022 at 2:12 PM Patrick Venture wrote: > Tested: Verified at24c02 driver happy and contents matched > expectations. > > Signed-off-by: Patrick Venture > Reviewed-by: Hao Wu > --- > hw/nvram/eeprom_at24c.c | 52 +++++++++++++++++++++++++++-------------- > 1 file changed, 35 insertions(+), 17 deletions(-) > > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c > index 01a3093600..abf9898f94 100644 > --- a/hw/nvram/eeprom_at24c.c > +++ b/hw/nvram/eeprom_at24c.c > @@ -45,6 +45,8 @@ struct EEPROMState { > bool changed; > /* during WRITE, # of address bytes transfered */ > uint8_t haveaddr; > + /* whether it's 8-bit addressed or 16-bit */ > + bool eightbit; > > uint8_t *mem; > > @@ -85,7 +87,7 @@ uint8_t at24c_eeprom_recv(I2CSlave *s) > EEPROMState *ee = AT24C_EE(s); > uint8_t ret; > > - if (ee->haveaddr == 1) { > + if (ee->haveaddr == 1 && !ee->eightbit) { > return 0xff; > } > > @@ -102,26 +104,35 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data) > { > EEPROMState *ee = AT24C_EE(s); > > - if (ee->haveaddr < 2) { > - ee->cur <<= 8; > - ee->cur |= data; > + if (ee->haveaddr < 1) { > + ee->cur = data; > ee->haveaddr++; > - if (ee->haveaddr == 2) { > - ee->cur %= ee->rsize; > + if (ee->eightbit) { > DPRINTK("Set pointer %04x\n", ee->cur); > } > + return 0; > + } else if (ee->haveaddr < 2) { > + if (!ee->eightbit) { > + ee->cur <<= 8; > + ee->cur |= data; > + ee->haveaddr++; > + if (ee->haveaddr == 2) { > + ee->cur %= ee->rsize; > + DPRINTK("Set pointer %04x\n", ee->cur); > + } > > - } else { > - if (ee->writable) { > - DPRINTK("Send %02x\n", data); > - ee->mem[ee->cur] = data; > - ee->changed = true; > - } else { > - DPRINTK("Send error %02x read-only\n", data); > + return 0; > } > - ee->cur = (ee->cur + 1u) % ee->rsize; > + } > > + if (ee->writable) { > + DPRINTK("Send %02x\n", data); > + ee->mem[ee->cur] = data; > + ee->changed = true; > + } else { > + DPRINTK("Send error %02x read-only\n", data); > } > + ee->cur = (ee->cur + 1u) % ee->rsize; > > return 0; > } > @@ -131,12 +142,16 @@ static void at24c_eeprom_realize(DeviceState *dev, > Error **errp) > EEPROMState *ee = AT24C_EE(dev); > > if (ee->blk) { > + /* blk length is a minimum of 1 sector. */ > int64_t len = blk_getlength(ee->blk); > > if (len != ee->rsize) { > - error_setg(errp, "%s: Backing file size %" PRId64 " != %u", > - TYPE_AT24C_EE, len, ee->rsize); > - return; > + /* for the at24c01 and at24c02, they are smaller than a > sector. */ > + if (ee->rsize >= BDRV_SECTOR_SIZE) { > + error_setg(errp, "%s: Backing file size %" PRId64 " != > %u", > + TYPE_AT24C_EE, len, ee->rsize); > + return; > + } > } > > if (blk_set_perm(ee->blk, BLK_PERM_CONSISTENT_READ | > BLK_PERM_WRITE, > @@ -148,6 +163,9 @@ static void at24c_eeprom_realize(DeviceState *dev, > Error **errp) > } > } > > + if (ee->rsize < 512) { > + ee->eightbit = true; > + } > Why 512? The eeprom sizes for the parts seem to grow exponentially, so c01 is 128, then c02 is 256, then 512. So I check for the two smaller effectively. Might warrant a comment. > ee->mem = g_malloc0(ee->rsize); > } > > -- > 2.35.1.723.g4982287a31-goog > >