/[dynamips]/upstream/dynamips-0.2.7-RC1/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 /upstream/dynamips-0.2.7-RC1/dev_flash.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 7031 byte(s)
dynamips-0.2.7-RC1

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 dpavlin 7 #include "cpu.h"
16     #include "vm.h"
17 dpavlin 4 #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 dpavlin 7 void *dev_flash_access(cpu_gen_t *cpu,struct vdevice *dev,
39 dpavlin 4 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 dpavlin 7 offset,cpu_get_pc(cpu),d->state);
49 dpavlin 4 } else {
50     cpu_log(cpu,dev->name,
51     "write access to vaddr=0x%x, pc=0x%llx, val=0x%llx (state=%d)\n",
52 dpavlin 7 offset,cpu_get_pc(cpu),*data,d->state);
53 dpavlin 4 }
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