diff --git a/hw/xbox/Makefile.objs b/hw/xbox/Makefile.objs index 119750f4e2..8519da60f3 100644 --- a/hw/xbox/Makefile.objs +++ b/hw/xbox/Makefile.objs @@ -1,7 +1,7 @@ obj-y += xbox.o obj-y += chihiro.o obj-y += xbox_pci.o acpi_xbox.o -obj-y += amd_smbus.o smbus_xbox_smc.o smbus_cx25871.o smbus_adm1032.o +obj-y += amd_smbus.o smbus_xbox_smc.o smbus_cx25871.o smbus_adm1032.o smbus_storage.o obj-y += nvnet.o obj-y += mcpx_apu.o mcpx_aci.o obj-y += lpc47m157.o diff --git a/hw/xbox/chihiro.c b/hw/xbox/chihiro.c index 84e95194f1..7c69046860 100644 --- a/hw/xbox/chihiro.c +++ b/hw/xbox/chihiro.c @@ -274,48 +274,6 @@ static void chihiro_ide_interface_init(const char *rom_file, #endif } -/* Placeholder blank eeprom for chihiro: - * Serial number 000000000000 - * Mac address 00:00:00:00:00:00 - * ...etc. - */ - /* FIXME: This should be passed in via machine args, - * please fix when xbox is fixed */ -static const uint8_t eeprom[] = { - 0xA7, 0x65, 0x60, 0x76, 0xB7, 0x2F, 0xFE, 0xD8, - 0x20, 0xBC, 0x8B, 0x15, 0x13, 0xBF, 0x73, 0x9C, - 0x8C, 0x3F, 0xD8, 0x07, 0x75, 0x55, 0x5F, 0x8B, - 0x09, 0xD1, 0x25, 0xD1, 0x1A, 0xA2, 0xD5, 0xB7, - 0x01, 0x7D, 0x9A, 0x31, 0xCD, 0x9C, 0x83, 0x6B, - 0x2C, 0xAB, 0xAD, 0x6F, 0xAC, 0x36, 0xDE, 0xEF, - 0x6F, 0x6E, 0x2F, 0x6F, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - static void chihiro_init(MachineState *machine) { const char *mediaboard_rom_file = object_property_get_str( @@ -326,7 +284,7 @@ static void chihiro_init(MachineState *machine) mediaboard_filesystem_file); ISABus *isa_bus; - xbox_init_common(machine, eeprom, NULL, &isa_bus); + xbox_init_common(machine, NULL, &isa_bus); isa_create_simple(isa_bus, "chihiro-lpc"); } diff --git a/hw/xbox/smbus_storage.c b/hw/xbox/smbus_storage.c new file mode 100644 index 0000000000..f82352e0e8 --- /dev/null +++ b/hw/xbox/smbus_storage.c @@ -0,0 +1,224 @@ +/* + * QEMU SMBus Generic Storage Device + * + * Copyright (c) 2020 Mike Davis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "hw/i2c/i2c.h" +#include "hw/i2c/smbus_slave.h" +#include "smbus.h" +#include "qapi/error.h" +#include "hw/loader.h" +#include "migration/vmstate.h" + +#define TYPE_SMBUS_STORAGE "smbus-storage" +#define SMBUS_STORAGE(obj) OBJECT_CHECK(SMBusStorageDevice, (obj), \ + TYPE_SMBUS_STORAGE) + +//#define DEBUG +#ifdef DEBUG +# define DPRINTF(format, ...) printf(format, ## __VA_ARGS__) +#else +# define DPRINTF(format, ...) do { } while (0) +#endif + +typedef struct SMBusStorageDevice { + SMBusDevice smbusdev; + char* file; + uint8_t *data; + uint32_t size; + uint8_t addr; + uint32_t offset; + bool persist; +} SMBusStorageDevice; + +// FIXME: remove, file should be generated upstream if unspecified +const uint8_t default_eeprom[] = { + 0xe3, 0x1c, 0x5c, 0x23, 0x6a, 0x58, 0x68, 0x37, + 0xb7, 0x12, 0x26, 0x6c, 0x99, 0x11, 0x30, 0xd1, + 0xe2, 0x3e, 0x4d, 0x56, 0xf7, 0x73, 0x2b, 0x73, + 0x85, 0xfe, 0x7f, 0x0a, 0x08, 0xef, 0x15, 0x3c, + 0x77, 0xee, 0x6d, 0x4e, 0x93, 0x2f, 0x28, 0xee, + 0xf8, 0x61, 0xf7, 0x94, 0x17, 0x1f, 0xfc, 0x11, + 0x0b, 0x84, 0x44, 0xed, 0x31, 0x30, 0x35, 0x35, + 0x38, 0x31, 0x31, 0x31, 0x34, 0x30, 0x30, 0x33, + 0x00, 0x50, 0xf2, 0x4f, 0x65, 0x52, 0x00, 0x00, + 0x0a, 0x1e, 0x35, 0x33, 0x71, 0x85, 0x31, 0x4d, + 0x59, 0x12, 0x38, 0x48, 0x1c, 0x91, 0x53, 0x60, + 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x75, 0x61, 0x57, 0xfb, 0x2c, 0x01, 0x00, 0x00, + 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x05, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void smbus_storage_realize(DeviceState *dev, Error **errp) +{ + SMBusStorageDevice *s = SMBUS_STORAGE(dev); + qdev_prop_set_uint8(dev, "address", s->addr); + s->data = g_malloc0(s->size); + s->offset = 0; + + if (s->file) { + int size = get_image_size(s->file); + if (size != s->size) { + error_setg(errp, "%s: file '%s' size of %d, expected %d\n", + __func__, s->file, size, s->size); + return; + } + + int fd = open(s->file, O_RDONLY | O_BINARY); + if (fd < 0) { + error_setg(errp, "%s: file '%s' could not be opened\n", + __func__, s->file); + return; + } + + int rc = read(fd, s->data, s->size); + if (rc != s->size) { + error_setg(errp, "%s: file '%s' read failure\n", __func__, s->file); + close(fd); + return; + } + close(fd); + } else { + // FIXME: remove, file should be generated upstream if unspecified + memcpy(s->data, default_eeprom, MIN(s->size, sizeof(default_eeprom))); + } +} + +static int smbus_storage_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len) +{ + SMBusStorageDevice *s = SMBUS_STORAGE(dev); + + DPRINTF("%s: addr=0x%02x cmd=0x%02x val=0x%02x\n", + __func__, s->addr, buf[0], buf[1]); + + /* len is guaranteed to be > 0 */ + s->offset = buf[0]; + buf++; + len--; + + bool changed = false; + for (; len > 0; len--) { + changed = true; + s->data[s->offset] = *buf++; + DPRINTF("%s: addr=0x%02x off=0x%02x, data=0x%02x\n", + __func__, s->addr, s->offset, s->data[s->offset]); + s->offset = (s->offset + 1) % s->size; + } + + if (changed && s->file && s->persist) { + int fd = open(s->file, O_WRONLY | O_BINARY); + if (fd < 0) { + DPRINTF("%s: file '%s' could not be opened\n", __func__, s->file); + return -1; + } + + int wc = write(fd, s->data, s->size); + if (wc != s->size) { + DPRINTF( "%s: file '%s' write failure\n", __func__, s->file); + close(fd); + return -1; + } + close(fd); + } + + return 0; +} + +static uint8_t smbus_storage_receive_byte(SMBusDevice *dev) +{ + SMBusStorageDevice *s = SMBUS_STORAGE(dev); + + uint8_t val = s->data[s->offset]; + DPRINTF("%s: addr=0x%02x off=0x%02x val=0x%02x\n", + __func__, s->addr, s->offset, val); + s->offset = (s->offset + 1) % s->size; + + return val; +} + +static const VMStateDescription vmstate_smbus_storage = { + .name = "smbus-storage", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_SMBUS_DEVICE(smbusdev, SMBusStorageDevice), + VMSTATE_VBUFFER_UINT32(data, SMBusStorageDevice, 1, NULL, size), + VMSTATE_UINT32(offset, SMBusStorageDevice), + VMSTATE_END_OF_LIST() + } +}; + +// default xbox eeprom with persistence +static Property smbus_storage_props[] = { + DEFINE_PROP_UINT8("addr", SMBusStorageDevice, addr, 0x54), + DEFINE_PROP_UINT32("size", SMBusStorageDevice, size, 256), + DEFINE_PROP_BOOL("persist", SMBusStorageDevice, persist, true), + DEFINE_PROP_STRING("file", SMBusStorageDevice, file), + DEFINE_PROP_END_OF_LIST() +}; + +static void smbus_storage_class_initfn(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_smbus_storage; + dc->realize = smbus_storage_realize; + sc->receive_byte = smbus_storage_receive_byte; + sc->write_data = smbus_storage_write_data; + device_class_set_props(dc, smbus_storage_props); +} + +static TypeInfo smbus_storage_info = { + .name = TYPE_SMBUS_STORAGE, + .parent = TYPE_SMBUS_DEVICE, + .instance_size = sizeof(SMBusStorageDevice), + .class_init = smbus_storage_class_initfn +}; + +static void smbus_storage_register_devices(void) +{ + type_register_static(&smbus_storage_info); +} + +type_init(smbus_storage_register_devices) diff --git a/hw/xbox/xbox.c b/hw/xbox/xbox.c index 1ed7e03077..4cc6c26d3c 100644 --- a/hw/xbox/xbox.c +++ b/hw/xbox/xbox.c @@ -59,43 +59,6 @@ #define MAX_IDE_BUS 2 -// XBOX_TODO: Should be passed in through configuration -/* bunnie's eeprom */ -const uint8_t default_eeprom[] = { - 0xe3, 0x1c, 0x5c, 0x23, 0x6a, 0x58, 0x68, 0x37, - 0xb7, 0x12, 0x26, 0x6c, 0x99, 0x11, 0x30, 0xd1, - 0xe2, 0x3e, 0x4d, 0x56, 0xf7, 0x73, 0x2b, 0x73, - 0x85, 0xfe, 0x7f, 0x0a, 0x08, 0xef, 0x15, 0x3c, - 0x77, 0xee, 0x6d, 0x4e, 0x93, 0x2f, 0x28, 0xee, - 0xf8, 0x61, 0xf7, 0x94, 0x17, 0x1f, 0xfc, 0x11, - 0x0b, 0x84, 0x44, 0xed, 0x31, 0x30, 0x35, 0x35, - 0x38, 0x31, 0x31, 0x31, 0x34, 0x30, 0x30, 0x33, - 0x00, 0x50, 0xf2, 0x4f, 0x65, 0x52, 0x00, 0x00, - 0x0a, 0x1e, 0x35, 0x33, 0x71, 0x85, 0x31, 0x4d, - 0x59, 0x12, 0x38, 0x48, 0x1c, 0x91, 0x53, 0x60, - 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x75, 0x61, 0x57, 0xfb, 0x2c, 0x01, 0x00, 0x00, - 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x05, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - /* FIXME: Clean this up and propagate errors to UI */ static void xbox_flash_init(MemoryRegion *rom_memory) { @@ -233,66 +196,13 @@ static void xbox_memory_init(PCMachineState *pcms, pc_system_flash_cleanup_unused(pcms); } -uint8_t *load_eeprom(void) -{ - char *filename; - int fd; - int rc; - int eeprom_file_size; - const int eeprom_size = 256; - - uint8_t *eeprom_data = g_malloc(eeprom_size); - - const char *eeprom_file = object_property_get_str(qdev_get_machine(), - "eeprom", NULL); - if ((eeprom_file != NULL) && *eeprom_file) { - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, eeprom_file); - assert(filename); - - eeprom_file_size = get_image_size(filename); - if (eeprom_size != eeprom_file_size) { - fprintf(stderr, - "qemu: EEPROM file size != %d bytes. (Is %d bytes)\n", - eeprom_size, eeprom_file_size); - g_free(filename); - exit(1); - return NULL; - } - - fd = open(filename, O_RDONLY | O_BINARY); - if (fd < 0) { - fprintf(stderr, "qemu: EEPROM file '%s' could not be opened.\n", filename); - g_free(filename); - exit(1); - return NULL; - } - - rc = read(fd, eeprom_data, eeprom_size); - if (rc != eeprom_size) { - fprintf(stderr, "qemu: Could not read the full EEPROM file.\n"); - close(fd); - g_free(filename); - exit(1); - return NULL; - } - - close(fd); - g_free(filename); - } else { - memcpy(eeprom_data, default_eeprom, eeprom_size); - } - return eeprom_data; -} - /* PC hardware initialisation */ static void xbox_init(MachineState *machine) { - uint8_t *eeprom_data = load_eeprom(); - xbox_init_common(machine, eeprom_data, NULL, NULL); + xbox_init_common(machine, NULL, NULL); } void xbox_init_common(MachineState *machine, - const uint8_t *eeprom, PCIBus **pci_bus_out, ISABus **isa_bus_out) { @@ -394,10 +304,6 @@ void xbox_init_common(MachineState *machine, } /* smbus devices */ - uint8_t *eeprom_buf = g_malloc0(256); - memcpy(eeprom_buf, eeprom, 256); - smbus_eeprom_init_one(smbus, 0x54, eeprom_buf); - smbus_xbox_smc_init(smbus, 0x10); smbus_cx25871_init(smbus, 0x45); smbus_adm1032_init(smbus, 0x4c); @@ -475,22 +381,6 @@ static void machine_set_bootrom(Object *obj, const char *value, ms->bootrom = g_strdup(value); } -static char *machine_get_eeprom(Object *obj, Error **errp) -{ - XboxMachineState *ms = XBOX_MACHINE(obj); - - return g_strdup(ms->eeprom); -} - -static void machine_set_eeprom(Object *obj, const char *value, - Error **errp) -{ - XboxMachineState *ms = XBOX_MACHINE(obj); - - g_free(ms->eeprom); - ms->eeprom = g_strdup(value); -} - static char *machine_get_avpack(Object *obj, Error **errp) { XboxMachineState *ms = XBOX_MACHINE(obj); @@ -534,11 +424,6 @@ static inline void xbox_machine_initfn(Object *obj) object_property_set_description(obj, "bootrom", "Xbox bootrom file"); - object_property_add_str(obj, "eeprom", machine_get_eeprom, - machine_set_eeprom); - object_property_set_description(obj, "eeprom", - "Xbox EEPROM file"); - object_property_add_str(obj, "avpack", machine_get_avpack, machine_set_avpack); object_property_set_description(obj, "avpack", diff --git a/hw/xbox/xbox.h b/hw/xbox/xbox.h index 0cc27a2a77..bcab3fd0f8 100644 --- a/hw/xbox/xbox.h +++ b/hw/xbox/xbox.h @@ -25,10 +25,7 @@ #define MAX_IDE_BUS 2 -uint8_t *load_eeprom(void); - void xbox_init_common(MachineState *machine, - const uint8_t *eeprom, PCIBus **pci_bus_out, ISABus **isa_bus_out); @@ -46,7 +43,6 @@ typedef struct XboxMachineState { /*< public >*/ char *bootrom; - char *eeprom; char *avpack; bool short_animation; } XboxMachineState; diff --git a/softmmu/vl.c b/softmmu/vl.c index 4223fa6b94..ad91027a50 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2917,25 +2917,45 @@ void qemu_init(int argc, char **argv, char **envp) bootrom_path = ""; } - const char *eeprom_path; - xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, &eeprom_path); - if (strlen(eeprom_path) > 0 && xemu_check_file(eeprom_path)) { - char *msg = g_strdup_printf("Failed to open EEPROM file '%s'. Please check machine settings.", eeprom_path); - xemu_queue_error_message(msg); - g_free(msg); - eeprom_path = ""; - } - int short_animation; xemu_settings_get_bool(XEMU_SETTINGS_SYSTEM_SHORTANIM, &short_animation); - fake_argv[fake_argc++] = g_strdup_printf("xbox%s%s%s%s", + fake_argv[fake_argc++] = g_strdup_printf("xbox%s%s%s", strlen(bootrom_path) > 0 ? g_strdup_printf(",bootrom=%s", bootrom_path) : "", // Leak - strlen(eeprom_path) > 0 ? g_strdup_printf(",eeprom=%s", eeprom_path) : "", // Leak short_animation ? ",short-animation" : "", ",kernel-irqchip=off" ); + const char *eeprom_path; + xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, &eeprom_path); + + // Sanity check EEPROM file + if (strlen(eeprom_path) > 0) { + int eeprom_size = get_image_size(eeprom_path); + if (eeprom_size < 0) { + char *msg = g_strdup_printf("Failed to open EEPROM file '%s'. " + "Please check machine settings.", eeprom_path); + xemu_queue_error_message(msg); + g_free(msg); + eeprom_path = ""; + } else if (eeprom_size != 256) { + char *msg = g_strdup_printf( + "Invalid EEPROM file '%s' size of %d; should be 256 bytes. " + "Please check machine settings.", eeprom_path, eeprom_size); + xemu_queue_error_message(msg); + g_free(msg); + eeprom_path = ""; + } + } + + fake_argv[fake_argc++] = strdup("-device"); + if (strlen(eeprom_path) > 0) { + fake_argv[fake_argc++] = g_strdup_printf("smbus-storage,file=%s", + eeprom_path); + } else { + fake_argv[fake_argc++] = strdup("smbus-storage"); + } + const char *flash_path; xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, &flash_path); autostart = 0; // Do not auto-start the machine without a valid BIOS file