|
@@ -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);
|
|
|
|
- DeviceState *dev = DEVICE(i2c_dev);
|
|
|
|
|
|
+ return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t rom_size,
|
|
|
|
+ const uint8_t *init_rom, uint32_t init_rom_size)
|
|
|
|
+{
|
|
|
|
+ EEPROMState *s;
|
|
|
|
+
|
|
|
|
+ s = AT24C_EE(i2c_slave_new(TYPE_AT24C_EE, address));
|
|
|
|
+
|
|
|
|
+ qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
|
|
|
|
|
|
- qdev_prop_set_uint32(dev, "rom-size", rom_size);
|
|
|
|
- i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
|
|
|
|
|
|
+ /* TODO: Model init_rom with QOM properties. */
|
|
|
|
+ s->init_rom = init_rom;
|
|
|
|
+ s->init_rom_size = init_rom_size;
|
|
|
|
|
|
- return i2c_dev;
|
|
|
|
|
|
+ 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);
|
|
|
|
|