/[dynamips]/upstream/dynamips-0.2.7-RC2/dev_flash.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7-RC2/dev_flash.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 7031 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco Simulation Platform.
3 * Copyright (c) 2006 Christophe Fillot. All rights reserved.
4 *
5 * 23-Oct-2006: only basic code at this time.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <errno.h>
13 #include <unistd.h>
14
15 #include "cpu.h"
16 #include "vm.h"
17 #include "dynamips.h"
18 #include "memory.h"
19 #include "device.h"
20
21 #define DEBUG_ACCESS 0
22 #define DEBUG_WRITE 0
23
24 /* Flash private data */
25 struct flash_data {
26 vm_obj_t vm_obj;
27 struct vdevice dev;
28 m_uint32_t state;
29 u_int sector_size;
30 char *filename;
31 };
32
33 #define BPTR(d,offset) (((char *)d->dev.host_addr) + offset)
34
35 /*
36 * dev_bootflash_access()
37 */
38 void *dev_flash_access(cpu_gen_t *cpu,struct vdevice *dev,
39 m_uint32_t offset,u_int op_size,u_int op_type,
40 m_uint64_t *data)
41 {
42 struct flash_data *d = dev->priv_data;
43
44 #if DEBUG_ACCESS
45 if (op_type == MTS_READ) {
46 cpu_log(cpu,dev->name,
47 "read access to offset=0x%x, pc=0x%llx (state=%u)\n",
48 offset,cpu_get_pc(cpu),d->state);
49 } else {
50 cpu_log(cpu,dev->name,
51 "write access to vaddr=0x%x, pc=0x%llx, val=0x%llx (state=%d)\n",
52 offset,cpu_get_pc(cpu),*data,d->state);
53 }
54 #endif
55
56 if (op_type == MTS_READ) {
57 switch(d->state) {
58 case 0:
59 return(BPTR(d,offset));
60 default:
61 cpu_log(cpu,dev->name,"read: unhandled state %d\n",d->state);
62 }
63
64 return NULL;
65 }
66
67 /* Write mode */
68 #if DEBUG_WRITE
69 cpu_log(cpu,dev->name,"write to offset 0x%x, data=0x%llx\n",offset,*data);
70 #endif
71
72 switch(d->state) {
73 /* Initial Cycle */
74 case 0:
75 switch(offset) {
76 case 0xAAA:
77 if (*data == 0xAA)
78 d->state = 1;
79 break;
80 default:
81 switch(*data) {
82 case 0xB0:
83 /* Erase/Program Suspend */
84 d->state = 0;
85 break;
86 case 0x30:
87 /* Erase/Program Resume */
88 d->state = 0;
89 break;
90 case 0xF0:
91 /* Product ID Exit */
92 break;
93 }
94 }
95 break;
96
97 /* Cycle 1 was: 0xAAA, 0xAA */
98 case 1:
99 if ((offset != 0x555) && (*data != 0x55))
100 d->state = 0;
101 else
102 d->state = 2;
103 break;
104
105 /* Cycle 1 was: 0xAAA, 0xAA, Cycle 2 was: 0x555, 0x55 */
106 case 2:
107 d->state = 0;
108
109 if (offset == 0xAAA) {
110 switch(*data) {
111 case 0x80:
112 d->state = 3;
113 break;
114 case 0xA0:
115 /* Byte/Word program */
116 d->state = 4;
117 break;
118 case 0xF0:
119 /* Product ID Exit */
120 break;
121 case 0xC0:
122 /* Program Protection Register / Lock Protection Register */
123 d->state = 5;
124 break;
125 case 0x90:
126 /* Product ID Entry / Status of Block B protection */
127 d->state = 6;
128 break;
129 case 0xD0:
130 /* Set configuration register */
131 d->state = 7;
132 break;
133 }
134 }
135 break;
136
137 /*
138 * Cycle 1 was 0xAAA, 0xAA
139 * Cycle 2 was 0x555, 0x55
140 * Cycle 3 was 0xAAA, 0x80
141 */
142 case 3:
143 if ((offset != 0xAAA) && (*data != 0xAA))
144 d->state = 0;
145 else
146 d->state = 8;
147 break;
148
149 /*
150 * Cycle 1 was 0xAAA, 0xAA
151 * Cycle 2 was 0x555, 0x55
152 * Cycle 3 was 0xAAA, 0x80
153 * Cycle 4 was 0xAAA, 0xAA
154 */
155 case 8:
156 if ((offset != 0x555) && (*data != 0x55))
157 d->state = 0;
158 else
159 d->state = 9;
160 break;
161
162 /*
163 * Cycle 1 was 0xAAA, 0xAA
164 * Cycle 2 was 0x555, 0x55
165 * Cycle 3 was 0xAAA, 0x80
166 * Cycle 4 was 0xAAA, 0xAA
167 * Cycle 5 was 0x555, 0x55
168 */
169 case 9:
170 d->state = 0;
171
172 switch(*data) {
173 case 0x10:
174 /* Chip Erase */
175 memset(BPTR(d,offset),0,d->dev.phys_len);
176 break;
177
178 case 0x30:
179 /* Sector Erase */
180 memset(BPTR(d,offset),0,d->sector_size);
181 break;
182
183 case 0xA0:
184 /* Enter Single Pulse Program Mode */
185 break;
186
187 case 0x60:
188 /* Sector Lockdown */
189 break;
190 }
191 break;
192
193 /* Byte/Word Program */
194 case 4:
195 d->state = 0;
196 *(m_uint8_t *)(BPTR(d,offset)) = *data;
197 break;
198
199 default:
200 cpu_log(cpu,dev->name,"write: unhandled state %d\n",d->state);
201 }
202
203 return NULL;
204 }
205
206 /* Copy data directly to a flash device */
207 int dev_flash_copy_data(vm_obj_t *obj,m_uint32_t offset,
208 u_char *ptr,ssize_t len)
209 {
210 struct flash_data *d = obj->data;
211 u_char *p;
212
213 if (!d || !d->dev.host_addr)
214 return(-1);
215
216 p = (u_char *)d->dev.host_addr + offset;
217 memcpy(p,ptr,len);
218 return(0);
219 }
220
221 /* Shutdown a flash device */
222 void dev_flash_shutdown(vm_instance_t *vm,struct flash_data *d)
223 {
224 if (d != NULL) {
225 /* Remove the device */
226 dev_remove(vm,&d->dev);
227
228 /* We don't remove the file, since it used as permanent storage */
229 if (d->filename)
230 free(d->filename);
231
232 /* Free the structure itself */
233 free(d);
234 }
235 }
236
237 /* Create a Flash device */
238 vm_obj_t *dev_flash_init(vm_instance_t *vm,char *name,
239 m_uint64_t paddr,m_uint32_t len)
240 {
241 struct flash_data *d;
242 u_char *ptr;
243
244 /* Allocate the private data structure */
245 if (!(d = malloc(sizeof(*d)))) {
246 fprintf(stderr,"Flash: unable to create device.\n");
247 return NULL;
248 }
249
250 memset(d,0,sizeof(*d));
251 d->sector_size = 0x4000;
252
253 vm_object_init(&d->vm_obj);
254 d->vm_obj.name = name;
255 d->vm_obj.data = d;
256 d->vm_obj.shutdown = (vm_shutdown_t)dev_flash_shutdown;
257
258 if (!(d->filename = vm_build_filename(vm,name))) {
259 fprintf(stderr,"Flash: unable to create filename.\n");
260 goto err_filename;
261 }
262
263 dev_init(&d->dev);
264 d->dev.name = name;
265 d->dev.priv_data = d;
266 d->dev.phys_addr = paddr;
267 d->dev.phys_len = len;
268 d->dev.handler = dev_flash_access;
269 d->dev.fd = memzone_create_file(d->filename,d->dev.phys_len,&ptr);
270 d->dev.host_addr = (m_iptr_t)ptr;
271 d->dev.flags = VDEVICE_FLAG_NO_MTS_MMAP;
272
273 if (d->dev.fd == -1) {
274 fprintf(stderr,"Flash: unable to map file '%s'\n",d->filename);
275 goto err_fd_create;
276 }
277
278 /* Map this device to the VM */
279 vm_bind_device(vm,&d->dev);
280 vm_object_add(vm,&d->vm_obj);
281 return(&d->vm_obj);
282
283 err_fd_create:
284 free(d->filename);
285 err_filename:
286 free(d);
287 return NULL;
288 }

  ViewVC Help
Powered by ViewVC 1.1.26