/[dynamips]/upstream/dynamips-0.2.6-RC4/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.6-RC4/dev_flash.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Sat Oct 6 16:08:03 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 7003 byte(s)
dynamips-0.2.6-RC4

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

  ViewVC Help
Powered by ViewVC 1.1.26