/[dynamips]/trunk/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

Annotation of /trunk/dev_flash.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Sat Oct 6 16:06:49 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC3/dev_flash.c
File MIME type: text/plain
File size: 7003 byte(s)
dynamips-0.2.6-RC3

1 dpavlin 4 /*
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