hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper
Allows users to specify binary data to initialize an EEPROM, allowing users to emulate data programmed at manufacturing time. - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE - Added at24c_eeprom_init_rom helper function to initialize attributes - If -drive property is provided, it overrides init_rom data Signed-off-by: Peter Delevoryas <peter@pjd.dev> Reviewed-by: Joel Stanley <joel@jms.id.au> Reviewed-by: Corey Minyard <cminyard@mvista.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Tested-by: Ninad Palsule <ninadpalsule@us.ibm.com> Link: https://lore.kernel.org/r/20230128060543.95582-4-peter@pjd.dev Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
9077e09a13
commit
9f782e9e82
|
@ -50,6 +50,9 @@ struct EEPROMState {
|
||||||
uint8_t *mem;
|
uint8_t *mem;
|
||||||
|
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
|
|
||||||
|
const uint8_t *init_rom;
|
||||||
|
uint32_t init_rom_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -131,19 +134,37 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
|
||||||
|
|
||||||
I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
|
I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
|
||||||
{
|
{
|
||||||
I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
|
return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
|
||||||
DeviceState *dev = DEVICE(i2c_dev);
|
}
|
||||||
|
|
||||||
qdev_prop_set_uint32(dev, "rom-size", rom_size);
|
I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t rom_size,
|
||||||
i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
|
const uint8_t *init_rom, uint32_t init_rom_size)
|
||||||
|
{
|
||||||
|
EEPROMState *s;
|
||||||
|
|
||||||
return i2c_dev;
|
s = AT24C_EE(i2c_slave_new(TYPE_AT24C_EE, address));
|
||||||
|
|
||||||
|
qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
|
||||||
|
|
||||||
|
/* TODO: Model init_rom with QOM properties. */
|
||||||
|
s->init_rom = init_rom;
|
||||||
|
s->init_rom_size = init_rom_size;
|
||||||
|
|
||||||
|
i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, &error_abort);
|
||||||
|
|
||||||
|
return I2C_SLAVE(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
|
static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
EEPROMState *ee = AT24C_EE(dev);
|
EEPROMState *ee = AT24C_EE(dev);
|
||||||
|
|
||||||
|
if (ee->init_rom_size > ee->rsize) {
|
||||||
|
error_setg(errp, "%s: init rom is larger than rom: %u > %u",
|
||||||
|
TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ee->blk) {
|
if (ee->blk) {
|
||||||
int64_t len = blk_getlength(ee->blk);
|
int64_t len = blk_getlength(ee->blk);
|
||||||
|
|
||||||
|
@ -163,6 +184,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
ee->mem = g_malloc0(ee->rsize);
|
ee->mem = g_malloc0(ee->rsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -176,6 +198,10 @@ void at24c_eeprom_reset(DeviceState *state)
|
||||||
|
|
||||||
memset(ee->mem, 0, ee->rsize);
|
memset(ee->mem, 0, ee->rsize);
|
||||||
|
|
||||||
|
if (ee->init_rom) {
|
||||||
|
memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
|
||||||
|
}
|
||||||
|
|
||||||
if (ee->blk) {
|
if (ee->blk) {
|
||||||
int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
|
int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
|
||||||
|
|
||||||
|
|
|
@ -20,4 +20,20 @@
|
||||||
*/
|
*/
|
||||||
I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
|
I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create and realize an AT24C EEPROM device on the heap with initial data.
|
||||||
|
* @bus: I2C bus to put it on
|
||||||
|
* @address: I2C address of the EEPROM slave when put on a bus
|
||||||
|
* @rom_size: size of the EEPROM
|
||||||
|
* @init_rom: Array of bytes to initialize EEPROM memory with
|
||||||
|
* @init_rom_size: Size of @init_rom, must be less than or equal to @rom_size
|
||||||
|
*
|
||||||
|
* Create the device state structure, initialize it, put it on the specified
|
||||||
|
* @bus, and drop the reference to it (the device is realized). Copies the data
|
||||||
|
* from @init_rom to the beginning of the EEPROM memory buffer.
|
||||||
|
*/
|
||||||
|
I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t rom_size,
|
||||||
|
const uint8_t *init_rom, uint32_t init_rom_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue