22 |
22 |
* THE SOFTWARE.
|
23 |
23 |
*/
|
24 |
24 |
|
25 |
|
#include "hw.h"
|
26 |
|
#include "mips.h"
|
|
25 |
#include "sysbus.h"
|
27 |
26 |
#include "trace.h"
|
28 |
27 |
|
29 |
|
typedef struct ds1225y_t
|
30 |
|
{
|
|
28 |
typedef struct {
|
|
29 |
DeviceState qdev;
|
31 |
30 |
uint32_t chip_size;
|
|
31 |
char *filename;
|
32 |
32 |
QEMUFile *file;
|
33 |
33 |
uint8_t *contents;
|
34 |
|
} ds1225y_t;
|
35 |
|
|
|
34 |
} NvRamState;
|
36 |
35 |
|
37 |
36 |
static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
|
38 |
37 |
{
|
39 |
|
ds1225y_t *s = opaque;
|
|
38 |
NvRamState *s = opaque;
|
40 |
39 |
uint32_t val;
|
41 |
40 |
|
42 |
41 |
val = s->contents[addr];
|
... | ... | |
64 |
63 |
|
65 |
64 |
static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
|
66 |
65 |
{
|
67 |
|
ds1225y_t *s = opaque;
|
|
66 |
NvRamState *s = opaque;
|
68 |
67 |
|
69 |
68 |
val &= 0xff;
|
70 |
69 |
trace_nvram_write(addr, s->contents[addr], val);
|
... | ... | |
103 |
102 |
&nvram_writel,
|
104 |
103 |
};
|
105 |
104 |
|
106 |
|
/* Initialisation routine */
|
107 |
|
void *ds1225y_init(target_phys_addr_t mem_base, const char *filename)
|
|
105 |
static int nvram_post_load(void *opaque, int version_id)
|
108 |
106 |
{
|
109 |
|
ds1225y_t *s;
|
110 |
|
int mem_indexRW;
|
|
107 |
NvRamState *s = opaque;
|
|
108 |
|
|
109 |
/* Close file, as filename may has changed in load/store process */
|
|
110 |
if (s->file) {
|
|
111 |
qemu_fclose(s->file);
|
|
112 |
}
|
|
113 |
|
|
114 |
/* Write back nvram contents */
|
|
115 |
s->file = qemu_fopen(s->filename, "wb");
|
|
116 |
if (s->file) {
|
|
117 |
/* Write back contents, as 'wb' mode cleaned the file */
|
|
118 |
qemu_put_buffer(s->file, s->contents, s->chip_size);
|
|
119 |
qemu_fflush(s->file);
|
|
120 |
}
|
|
121 |
|
|
122 |
return 0;
|
|
123 |
}
|
|
124 |
|
|
125 |
static const VMStateDescription vmstate_nvram = {
|
|
126 |
.name = "nvram",
|
|
127 |
.version_id = 0,
|
|
128 |
.minimum_version_id = 0,
|
|
129 |
.minimum_version_id_old = 0,
|
|
130 |
.post_load = nvram_post_load,
|
|
131 |
.fields = (VMStateField[]) {
|
|
132 |
VMSTATE_VARRAY_UINT32(contents, NvRamState, chip_size, 0,
|
|
133 |
vmstate_info_uint8, uint8_t),
|
|
134 |
VMSTATE_END_OF_LIST()
|
|
135 |
}
|
|
136 |
};
|
|
137 |
|
|
138 |
typedef struct {
|
|
139 |
SysBusDevice busdev;
|
|
140 |
NvRamState nvram;
|
|
141 |
} SysBusNvRamState;
|
|
142 |
|
|
143 |
static int nvram_sysbus_initfn(SysBusDevice *dev)
|
|
144 |
{
|
|
145 |
NvRamState *s = &FROM_SYSBUS(SysBusNvRamState, dev)->nvram;
|
111 |
146 |
QEMUFile *file;
|
|
147 |
int s_io;
|
112 |
148 |
|
113 |
|
s = qemu_mallocz(sizeof(ds1225y_t));
|
114 |
|
s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */
|
115 |
149 |
s->contents = qemu_mallocz(s->chip_size);
|
116 |
150 |
|
|
151 |
s_io = cpu_register_io_memory(nvram_read, nvram_write, s,
|
|
152 |
DEVICE_NATIVE_ENDIAN);
|
|
153 |
sysbus_init_mmio(dev, s->chip_size, s_io);
|
|
154 |
|
117 |
155 |
/* Read current file */
|
118 |
|
file = qemu_fopen(filename, "rb");
|
|
156 |
file = qemu_fopen(s->filename, "rb");
|
119 |
157 |
if (file) {
|
120 |
158 |
/* Read nvram contents */
|
121 |
159 |
qemu_get_buffer(file, s->contents, s->chip_size);
|
122 |
160 |
qemu_fclose(file);
|
123 |
161 |
}
|
124 |
|
s->file = qemu_fopen(filename, "wb");
|
125 |
|
if (s->file) {
|
126 |
|
/* Write back contents, as 'wb' mode cleaned the file */
|
127 |
|
qemu_put_buffer(s->file, s->contents, s->chip_size);
|
128 |
|
qemu_fflush(s->file);
|
129 |
|
}
|
|
162 |
nvram_post_load(s, 0);
|
130 |
163 |
|
131 |
|
/* Read/write memory */
|
132 |
|
mem_indexRW = cpu_register_io_memory(nvram_read, nvram_write, s,
|
133 |
|
DEVICE_NATIVE_ENDIAN);
|
134 |
|
cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW);
|
135 |
|
return s;
|
|
164 |
return 0;
|
136 |
165 |
}
|
|
166 |
|
|
167 |
static SysBusDeviceInfo nvram_sysbus_info = {
|
|
168 |
.qdev.name = "ds1225y",
|
|
169 |
.qdev.size = sizeof(SysBusNvRamState),
|
|
170 |
.qdev.vmsd = &vmstate_nvram,
|
|
171 |
.init = nvram_sysbus_initfn,
|
|
172 |
.qdev.props = (Property[]) {
|
|
173 |
DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000),
|
|
174 |
DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename),
|
|
175 |
DEFINE_PROP_END_OF_LIST(),
|
|
176 |
},
|
|
177 |
};
|
|
178 |
|
|
179 |
static void nvram_register(void)
|
|
180 |
{
|
|
181 |
sysbus_register_withprop(&nvram_sysbus_info);
|
|
182 |
}
|
|
183 |
|
|
184 |
device_init(nvram_register)
|