|
|
1.1.1.2 root 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 "hw.h"
26: #include "mips.h"
27: #include "nvram.h"
28:
29: //#define DEBUG_NVRAM
30:
31: typedef struct ds1225y_t
32: {
33: uint32_t chip_size;
34: QEMUFile *file;
35: uint8_t *contents;
36: uint8_t protection;
37: } ds1225y_t;
38:
39:
40: static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
41: {
42: ds1225y_t *s = opaque;
43: uint32_t val;
44:
45: val = s->contents[addr];
46:
47: #ifdef DEBUG_NVRAM
48: printf("nvram: read 0x%x at " TARGET_FMT_lx "\n", val, addr);
49: #endif
50: return val;
51: }
52:
53: static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
54: {
55: uint32_t v;
56: v = nvram_readb(opaque, addr);
57: v |= nvram_readb(opaque, addr + 1) << 8;
58: return v;
59: }
60:
61: static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
62: {
63: uint32_t v;
64: v = nvram_readb(opaque, addr);
65: v |= nvram_readb(opaque, addr + 1) << 8;
66: v |= nvram_readb(opaque, addr + 2) << 16;
67: v |= nvram_readb(opaque, addr + 3) << 24;
68: return v;
69: }
70:
71: static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
72: {
73: ds1225y_t *s = opaque;
74:
75: #ifdef DEBUG_NVRAM
76: printf("nvram: write 0x%x at " TARGET_FMT_lx "\n", val, addr);
77: #endif
78:
79: s->contents[addr] = val & 0xff;
80: if (s->file) {
81: qemu_fseek(s->file, addr, SEEK_SET);
82: qemu_put_byte(s->file, (int)val);
83: qemu_fflush(s->file);
84: }
85: }
86:
87: static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
88: {
89: nvram_writeb(opaque, addr, val & 0xff);
90: nvram_writeb(opaque, addr + 1, (val >> 8) & 0xff);
91: }
92:
93: static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
94: {
95: nvram_writeb(opaque, addr, val & 0xff);
96: nvram_writeb(opaque, addr + 1, (val >> 8) & 0xff);
97: nvram_writeb(opaque, addr + 2, (val >> 16) & 0xff);
98: nvram_writeb(opaque, addr + 3, (val >> 24) & 0xff);
99: }
100:
101: static void nvram_writeb_protected (void *opaque, target_phys_addr_t addr, uint32_t val)
102: {
103: ds1225y_t *s = opaque;
104:
105: if (s->protection != 7) {
106: #ifdef DEBUG_NVRAM
107: printf("nvram: prevent write of 0x%x at " TARGET_FMT_lx "\n", val, addr);
108: #endif
109: return;
110: }
111:
112: nvram_writeb(opaque, addr, val);
113: }
114:
115: static void nvram_writew_protected (void *opaque, target_phys_addr_t addr, uint32_t val)
116: {
117: nvram_writeb_protected(opaque, addr, val & 0xff);
118: nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff);
119: }
120:
121: static void nvram_writel_protected (void *opaque, target_phys_addr_t addr, uint32_t val)
122: {
123: nvram_writeb_protected(opaque, addr, val & 0xff);
124: nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff);
125: nvram_writeb_protected(opaque, addr + 2, (val >> 16) & 0xff);
126: nvram_writeb_protected(opaque, addr + 3, (val >> 24) & 0xff);
127: }
128:
129: static CPUReadMemoryFunc *nvram_read[] = {
130: &nvram_readb,
131: &nvram_readw,
132: &nvram_readl,
133: };
134:
135: static CPUWriteMemoryFunc *nvram_write[] = {
136: &nvram_writeb,
137: &nvram_writew,
138: &nvram_writel,
139: };
140:
141: static CPUWriteMemoryFunc *nvram_write_protected[] = {
142: &nvram_writeb_protected,
143: &nvram_writew_protected,
144: &nvram_writel_protected,
145: };
146:
147: /* Initialisation routine */
148: void *ds1225y_init(target_phys_addr_t mem_base, const char *filename)
149: {
150: ds1225y_t *s;
151: int mem_indexRW, mem_indexRP;
152: QEMUFile *file;
153:
154: s = qemu_mallocz(sizeof(ds1225y_t));
155: s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */
156: s->contents = qemu_mallocz(s->chip_size);
157: s->protection = 7;
158:
159: /* Read current file */
160: file = qemu_fopen(filename, "rb");
161: if (file) {
162: /* Read nvram contents */
163: qemu_get_buffer(file, s->contents, s->chip_size);
164: qemu_fclose(file);
165: }
166: s->file = qemu_fopen(filename, "wb");
167: if (s->file) {
168: /* Write back contents, as 'wb' mode cleaned the file */
169: qemu_put_buffer(s->file, s->contents, s->chip_size);
170: qemu_fflush(s->file);
171: }
172:
173: /* Read/write memory */
1.1.1.3 ! root 174: mem_indexRW = cpu_register_io_memory(nvram_read, nvram_write, s);
1.1.1.2 root 175: cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW);
176: /* Read/write protected memory */
1.1.1.3 ! root 177: mem_indexRP = cpu_register_io_memory(nvram_read, nvram_write_protected, s);
1.1.1.2 root 178: cpu_register_physical_memory(mem_base + s->chip_size, s->chip_size, mem_indexRP);
179: return s;
180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.