diff options
Diffstat (limited to 'hw/ds1225y.c')
-rw-r--r-- | hw/ds1225y.c | 152 |
1 files changed, 77 insertions, 75 deletions
diff --git a/hw/ds1225y.c b/hw/ds1225y.c index b1c52321fe..662d7b5166 100644 --- a/hw/ds1225y.c +++ b/hw/ds1225y.c @@ -22,31 +22,24 @@ * THE SOFTWARE. */ -#include "hw.h" -#include "mips.h" -#include "nvram.h" +#include "sysbus.h" +#include "trace.h" -//#define DEBUG_NVRAM - -typedef struct ds1225y_t -{ +typedef struct { + DeviceState qdev; uint32_t chip_size; + char *filename; QEMUFile *file; uint8_t *contents; - uint8_t protection; -} ds1225y_t; - +} NvRamState; static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr) { - ds1225y_t *s = opaque; + NvRamState *s = opaque; uint32_t val; val = s->contents[addr]; - -#ifdef DEBUG_NVRAM - printf("nvram: read 0x%x at " TARGET_FMT_lx "\n", val, addr); -#endif + trace_nvram_read(addr, val); return val; } @@ -70,13 +63,12 @@ static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr) static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t val) { - ds1225y_t *s = opaque; + NvRamState *s = opaque; -#ifdef DEBUG_NVRAM - printf("nvram: write 0x%x at " TARGET_FMT_lx "\n", val, addr); -#endif + val &= 0xff; + trace_nvram_write(addr, s->contents[addr], val); - s->contents[addr] = val & 0xff; + s->contents[addr] = val; if (s->file) { qemu_fseek(s->file, addr, SEEK_SET); qemu_put_byte(s->file, (int)val); @@ -98,34 +90,6 @@ static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t val) nvram_writeb(opaque, addr + 3, (val >> 24) & 0xff); } -static void nvram_writeb_protected (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - ds1225y_t *s = opaque; - - if (s->protection != 7) { -#ifdef DEBUG_NVRAM - printf("nvram: prevent write of 0x%x at " TARGET_FMT_lx "\n", val, addr); -#endif - return; - } - - nvram_writeb(opaque, addr, val); -} - -static void nvram_writew_protected (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - nvram_writeb_protected(opaque, addr, val & 0xff); - nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void nvram_writel_protected (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - nvram_writeb_protected(opaque, addr, val & 0xff); - nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff); - nvram_writeb_protected(opaque, addr + 2, (val >> 16) & 0xff); - nvram_writeb_protected(opaque, addr + 3, (val >> 24) & 0xff); -} - static CPUReadMemoryFunc * const nvram_read[] = { &nvram_readb, &nvram_readw, @@ -138,45 +102,83 @@ static CPUWriteMemoryFunc * const nvram_write[] = { &nvram_writel, }; -static CPUWriteMemoryFunc * const nvram_write_protected[] = { - &nvram_writeb_protected, - &nvram_writew_protected, - &nvram_writel_protected, +static int nvram_post_load(void *opaque, int version_id) +{ + NvRamState *s = opaque; + + /* Close file, as filename may has changed in load/store process */ + if (s->file) { + qemu_fclose(s->file); + } + + /* Write back nvram contents */ + s->file = qemu_fopen(s->filename, "wb"); + if (s->file) { + /* Write back contents, as 'wb' mode cleaned the file */ + qemu_put_buffer(s->file, s->contents, s->chip_size); + qemu_fflush(s->file); + } + + return 0; +} + +static const VMStateDescription vmstate_nvram = { + .name = "nvram", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = nvram_post_load, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(contents, NvRamState, chip_size, 0, + vmstate_info_uint8, uint8_t), + VMSTATE_END_OF_LIST() + } }; -/* Initialisation routine */ -void *ds1225y_init(target_phys_addr_t mem_base, const char *filename) +typedef struct { + SysBusDevice busdev; + NvRamState nvram; +} SysBusNvRamState; + +static int nvram_sysbus_initfn(SysBusDevice *dev) { - ds1225y_t *s; - int mem_indexRW, mem_indexRP; + NvRamState *s = &FROM_SYSBUS(SysBusNvRamState, dev)->nvram; QEMUFile *file; + int s_io; - s = qemu_mallocz(sizeof(ds1225y_t)); - s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */ s->contents = qemu_mallocz(s->chip_size); - s->protection = 7; + + s_io = cpu_register_io_memory(nvram_read, nvram_write, s, + DEVICE_NATIVE_ENDIAN); + sysbus_init_mmio(dev, s->chip_size, s_io); /* Read current file */ - file = qemu_fopen(filename, "rb"); + file = qemu_fopen(s->filename, "rb"); if (file) { /* Read nvram contents */ qemu_get_buffer(file, s->contents, s->chip_size); qemu_fclose(file); } - s->file = qemu_fopen(filename, "wb"); - if (s->file) { - /* Write back contents, as 'wb' mode cleaned the file */ - qemu_put_buffer(s->file, s->contents, s->chip_size); - qemu_fflush(s->file); - } + nvram_post_load(s, 0); + + return 0; +} + +static SysBusDeviceInfo nvram_sysbus_info = { + .qdev.name = "ds1225y", + .qdev.size = sizeof(SysBusNvRamState), + .qdev.vmsd = &vmstate_nvram, + .init = nvram_sysbus_initfn, + .qdev.props = (Property[]) { + DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000), + DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename), + DEFINE_PROP_END_OF_LIST(), + }, +}; - /* Read/write memory */ - mem_indexRW = cpu_register_io_memory(nvram_read, nvram_write, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW); - /* Read/write protected memory */ - mem_indexRP = cpu_register_io_memory(nvram_read, nvram_write_protected, s, - DEVICE_NATIVE_ENDIAN); - cpu_register_physical_memory(mem_base + s->chip_size, s->chip_size, mem_indexRP); - return s; +static void nvram_register(void) +{ + sysbus_register_withprop(&nvram_sysbus_info); } + +device_init(nvram_register) |