qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ds1225y.c (4898B)


      1 /*
      2  * QEMU NVRAM emulation for DS1225Y chip
      3  *
      4  * Copyright (c) 2007-2008 Hervé Poussineau
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22  * THE SOFTWARE.
     23  */
     24 
     25 #include "qemu/osdep.h"
     26 #include "hw/qdev-properties.h"
     27 #include "hw/sysbus.h"
     28 #include "migration/vmstate.h"
     29 #include "trace.h"
     30 #include "qemu/error-report.h"
     31 #include "qemu/module.h"
     32 #include "qom/object.h"
     33 
     34 typedef struct {
     35     MemoryRegion iomem;
     36     uint32_t chip_size;
     37     char *filename;
     38     FILE *file;
     39     uint8_t *contents;
     40 } NvRamState;
     41 
     42 static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
     43 {
     44     NvRamState *s = opaque;
     45     uint32_t val;
     46 
     47     val = s->contents[addr];
     48     trace_nvram_read(addr, val);
     49     return val;
     50 }
     51 
     52 static void nvram_write(void *opaque, hwaddr addr, uint64_t val,
     53                         unsigned size)
     54 {
     55     NvRamState *s = opaque;
     56 
     57     val &= 0xff;
     58     trace_nvram_write(addr, s->contents[addr], val);
     59 
     60     s->contents[addr] = val;
     61     if (s->file) {
     62         fseek(s->file, addr, SEEK_SET);
     63         fputc(val, s->file);
     64         fflush(s->file);
     65     }
     66 }
     67 
     68 static const MemoryRegionOps nvram_ops = {
     69     .read = nvram_read,
     70     .write = nvram_write,
     71     .impl = {
     72         .min_access_size = 1,
     73         .max_access_size = 1,
     74     },
     75     .endianness = DEVICE_LITTLE_ENDIAN,
     76 };
     77 
     78 static int nvram_post_load(void *opaque, int version_id)
     79 {
     80     NvRamState *s = opaque;
     81 
     82     /* Close file, as filename may has changed in load/store process */
     83     if (s->file) {
     84         fclose(s->file);
     85     }
     86 
     87     /* Write back nvram contents */
     88     s->file = s->filename ? fopen(s->filename, "wb") : NULL;
     89     if (s->file) {
     90         /* Write back contents, as 'wb' mode cleaned the file */
     91         if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) {
     92             printf("nvram_post_load: short write\n");
     93         }
     94         fflush(s->file);
     95     }
     96 
     97     return 0;
     98 }
     99 
    100 static const VMStateDescription vmstate_nvram = {
    101     .name = "nvram",
    102     .version_id = 0,
    103     .minimum_version_id = 0,
    104     .post_load = nvram_post_load,
    105     .fields = (VMStateField[]) {
    106         VMSTATE_VARRAY_UINT32(contents, NvRamState, chip_size, 0,
    107                               vmstate_info_uint8, uint8_t),
    108         VMSTATE_END_OF_LIST()
    109     }
    110 };
    111 
    112 #define TYPE_DS1225Y "ds1225y"
    113 OBJECT_DECLARE_SIMPLE_TYPE(SysBusNvRamState, DS1225Y)
    114 
    115 struct SysBusNvRamState {
    116     SysBusDevice parent_obj;
    117 
    118     NvRamState nvram;
    119 };
    120 
    121 static void nvram_sysbus_realize(DeviceState *dev, Error **errp)
    122 {
    123     SysBusNvRamState *sys = DS1225Y(dev);
    124     NvRamState *s = &sys->nvram;
    125     FILE *file;
    126 
    127     s->contents = g_malloc0(s->chip_size);
    128 
    129     memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s,
    130                           "nvram", s->chip_size);
    131     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
    132 
    133     /* Read current file */
    134     file = s->filename ? fopen(s->filename, "rb") : NULL;
    135     if (file) {
    136         /* Read nvram contents */
    137         if (fread(s->contents, s->chip_size, 1, file) != 1) {
    138             error_report("nvram_sysbus_realize: short read");
    139         }
    140         fclose(file);
    141     }
    142     nvram_post_load(s, 0);
    143 }
    144 
    145 static Property nvram_sysbus_properties[] = {
    146     DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000),
    147     DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename),
    148     DEFINE_PROP_END_OF_LIST(),
    149 };
    150 
    151 static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
    152 {
    153     DeviceClass *dc = DEVICE_CLASS(klass);
    154 
    155     dc->realize = nvram_sysbus_realize;
    156     dc->vmsd = &vmstate_nvram;
    157     device_class_set_props(dc, nvram_sysbus_properties);
    158 }
    159 
    160 static const TypeInfo nvram_sysbus_info = {
    161     .name          = TYPE_DS1225Y,
    162     .parent        = TYPE_SYS_BUS_DEVICE,
    163     .instance_size = sizeof(SysBusNvRamState),
    164     .class_init    = nvram_sysbus_class_init,
    165 };
    166 
    167 static void nvram_register_types(void)
    168 {
    169     type_register_static(&nvram_sysbus_info);
    170 }
    171 
    172 type_init(nvram_register_types)