|
|
1.1.1.2 root 1: /*
2: * QEMU NVRAM emulation for DS1225Y chip
3: *
1.1.1.8 ! root 4: * Copyright (c) 2007-2008 Hervé Poussineau
1.1.1.2 root 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:
1.1.1.6 root 25: #include "sysbus.h"
26: #include "trace.h"
1.1.1.2 root 27:
1.1.1.6 root 28: typedef struct {
29: DeviceState qdev;
1.1.1.8 ! root 30: MemoryRegion iomem;
1.1.1.2 root 31: uint32_t chip_size;
1.1.1.6 root 32: char *filename;
1.1.1.7 root 33: FILE *file;
1.1.1.2 root 34: uint8_t *contents;
1.1.1.6 root 35: } NvRamState;
1.1.1.2 root 36:
1.1.1.8 ! root 37: static uint64_t nvram_read(void *opaque, target_phys_addr_t addr, unsigned size)
1.1.1.2 root 38: {
1.1.1.6 root 39: NvRamState *s = opaque;
1.1.1.2 root 40: uint32_t val;
41:
42: val = s->contents[addr];
1.1.1.6 root 43: trace_nvram_read(addr, val);
1.1.1.2 root 44: return val;
45: }
46:
1.1.1.8 ! root 47: static void nvram_write(void *opaque, target_phys_addr_t addr, uint64_t val,
! 48: unsigned size)
1.1.1.2 root 49: {
1.1.1.6 root 50: NvRamState *s = opaque;
1.1.1.2 root 51:
1.1.1.6 root 52: val &= 0xff;
53: trace_nvram_write(addr, s->contents[addr], val);
1.1.1.2 root 54:
1.1.1.6 root 55: s->contents[addr] = val;
1.1.1.2 root 56: if (s->file) {
1.1.1.7 root 57: fseek(s->file, addr, SEEK_SET);
58: fputc(val, s->file);
59: fflush(s->file);
1.1.1.2 root 60: }
61: }
62:
1.1.1.8 ! root 63: static const MemoryRegionOps nvram_ops = {
! 64: .read = nvram_read,
! 65: .write = nvram_write,
! 66: .impl = {
! 67: .min_access_size = 1,
! 68: .max_access_size = 1,
! 69: },
! 70: .endianness = DEVICE_LITTLE_ENDIAN,
1.1.1.2 root 71: };
72:
1.1.1.6 root 73: static int nvram_post_load(void *opaque, int version_id)
74: {
75: NvRamState *s = opaque;
76:
77: /* Close file, as filename may has changed in load/store process */
78: if (s->file) {
1.1.1.7 root 79: fclose(s->file);
1.1.1.6 root 80: }
81:
82: /* Write back nvram contents */
1.1.1.7 root 83: s->file = fopen(s->filename, "wb");
1.1.1.6 root 84: if (s->file) {
85: /* Write back contents, as 'wb' mode cleaned the file */
1.1.1.7 root 86: if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) {
87: printf("nvram_post_load: short write\n");
88: }
89: fflush(s->file);
1.1.1.6 root 90: }
91:
92: return 0;
93: }
94:
95: static const VMStateDescription vmstate_nvram = {
96: .name = "nvram",
97: .version_id = 0,
98: .minimum_version_id = 0,
99: .minimum_version_id_old = 0,
100: .post_load = nvram_post_load,
101: .fields = (VMStateField[]) {
102: VMSTATE_VARRAY_UINT32(contents, NvRamState, chip_size, 0,
103: vmstate_info_uint8, uint8_t),
104: VMSTATE_END_OF_LIST()
105: }
1.1.1.2 root 106: };
107:
1.1.1.6 root 108: typedef struct {
109: SysBusDevice busdev;
110: NvRamState nvram;
111: } SysBusNvRamState;
112:
113: static int nvram_sysbus_initfn(SysBusDevice *dev)
1.1.1.2 root 114: {
1.1.1.6 root 115: NvRamState *s = &FROM_SYSBUS(SysBusNvRamState, dev)->nvram;
1.1.1.7 root 116: FILE *file;
1.1.1.2 root 117:
1.1.1.7 root 118: s->contents = g_malloc0(s->chip_size);
1.1.1.6 root 119:
1.1.1.8 ! root 120: memory_region_init_io(&s->iomem, &nvram_ops, s, "nvram", s->chip_size);
! 121: sysbus_init_mmio(dev, &s->iomem);
1.1.1.2 root 122:
123: /* Read current file */
1.1.1.7 root 124: file = fopen(s->filename, "rb");
1.1.1.2 root 125: if (file) {
126: /* Read nvram contents */
1.1.1.7 root 127: if (fread(s->contents, s->chip_size, 1, file) != 1) {
128: printf("nvram_sysbus_initfn: short read\n");
129: }
130: fclose(file);
1.1.1.2 root 131: }
1.1.1.6 root 132: nvram_post_load(s, 0);
133:
134: return 0;
135: }
136:
1.1.1.8 ! root 137: static Property nvram_sysbus_properties[] = {
! 138: DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000),
! 139: DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename),
! 140: DEFINE_PROP_END_OF_LIST(),
! 141: };
! 142:
! 143: static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
! 144: {
! 145: DeviceClass *dc = DEVICE_CLASS(klass);
! 146: SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
! 147:
! 148: k->init = nvram_sysbus_initfn;
! 149: dc->vmsd = &vmstate_nvram;
! 150: dc->props = nvram_sysbus_properties;
! 151: }
! 152:
! 153: static TypeInfo nvram_sysbus_info = {
! 154: .name = "ds1225y",
! 155: .parent = TYPE_SYS_BUS_DEVICE,
! 156: .instance_size = sizeof(SysBusNvRamState),
! 157: .class_init = nvram_sysbus_class_init,
1.1.1.6 root 158: };
1.1.1.2 root 159:
1.1.1.8 ! root 160: static void nvram_register_types(void)
1.1.1.6 root 161: {
1.1.1.8 ! root 162: type_register_static(&nvram_sysbus_info);
1.1.1.2 root 163: }
1.1.1.6 root 164:
1.1.1.8 ! root 165: type_init(nvram_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.