/[dynamips]/upstream/dynamips-0.2.5/dev_bootflash.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.5/dev_bootflash.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Sat Oct 6 16:01:44 2007 UTC (14 years, 10 months ago) by dpavlin
File MIME type: text/plain
File size: 5766 byte(s)
import 0.2.5 from upstream

1 dpavlin 1 /*
2     * Cisco C7200 (Predator) Bootflash.
3     * Copyright (c) 2006 Christophe Fillot. All rights reserved.
4     *
5     * Intel Flash SIMM emulation (28F008SA/28F016SA)
6     *
7     * Intelligent ID Codes:
8     * 28F008SA: 0x89A2 (1 Mb)
9     * 28F016SA: 0x89A0 (2 Mb)
10     *
11     * Manuals:
12     * http://www.ortodoxism.ro/datasheets/Intel/mXvsysv.pdf
13     *
14     * This code is working but is far from perfect. The four assembled circuits
15     * should be managed independently.
16     *
17     * Here, we emulate a group of four 28F016SA, for a total size of 8 Mb.
18     * If you need to change this, the Flash SIMM register must also be changed.
19     * (TODO: a CLI option + generic code).
20     */
21    
22     #include <stdio.h>
23     #include <stdlib.h>
24     #include <string.h>
25     #include <time.h>
26     #include <errno.h>
27    
28     #include "mips64.h"
29     #include "dynamips.h"
30     #include "memory.h"
31     #include "device.h"
32    
33     #define DEBUG_ACCESS 0
34     #define DEBUG_WRITE 0
35    
36     /* Bootflash private data */
37     struct bootflash_data {
38     vm_obj_t vm_obj;
39     struct vdevice dev;
40     m_uint32_t cui_cmd,blk_cmd;
41     m_uint32_t status;
42     char *filename;
43     };
44    
45     #define BPTR(d,offset) (((char *)d->dev.host_addr) + offset)
46    
47     /*
48     * dev_bootflash_access()
49     */
50     void *dev_bootflash_access(cpu_mips_t *cpu,struct vdevice *dev,
51     m_uint32_t offset,u_int op_size,u_int op_type,
52     m_uint64_t *data)
53     {
54     struct bootflash_data *d = dev->priv_data;
55    
56     #if DEBUG_ACCESS
57     if (op_type == MTS_READ)
58     cpu_log(cpu,dev->name,"read access to offset = 0x%x, pc = 0x%llx "
59     "(stat=%u,cui_cmd=0x%x)\n",
60     offset,cpu->pc,d->status,d->cui_cmd);
61     else
62     cpu_log(cpu,dev->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
63     "val = 0x%llx\n",offset,cpu->pc,*data);
64     #endif
65    
66     if (op_type == MTS_READ) {
67     /* Read Array mode */
68     if (d->status == 0)
69     return(BPTR(d,offset));
70    
71     switch(d->cui_cmd) {
72     /* Intelligent identifier */
73     case 0x90909090:
74     switch(offset) {
75     case 0x00:
76     *data = 0x89898989; /* manufacturer code */
77     return NULL;
78     case 0x04:
79     *data = 0xA0A0A0A0; /* device code */
80     return NULL;
81     default:
82     cpu_log(cpu,dev->name,
83     "Reading Intelligent ID Code at offset = 0x%x ?\n",
84     offset);
85     *data = 0x00000000;
86     return NULL;
87     }
88     break;
89    
90     /* Read Status Register */
91     case 0x70707070:
92     *data = 0x80808080;
93     return NULL;
94     }
95    
96     /* Default: status register */
97     *data = 0x80808080;
98     return NULL;
99     }
100    
101     /* write mode */
102     if (d->blk_cmd == 0x40404040) {
103     #if DEBUG_WRITE
104     cpu_log(cpu,dev->name,"Writing 0x%llx at offset=0x%x\n",*data,offset);
105     #endif
106     d->blk_cmd = 0;
107     d->cui_cmd = 0;
108     d->status = 1;
109     return(BPTR(d,offset));
110     }
111    
112     switch(*data) {
113     /* Erase Setup */
114     case 0x20202020:
115     d->blk_cmd = *data;
116     break;
117    
118     /* Erase Confirm */
119     case 0xd0d0d0d0:
120     if ((d->blk_cmd == 0x20202020) && !(offset & 0x3FFFF)) {
121     memset(BPTR(d,offset),0xFF,0x40000);
122     d->blk_cmd = 0;
123     d->cui_cmd = 0;
124     d->status = 1;
125     }
126     break;
127    
128     /* Byte Write Setup (XXX ugly hack) */
129     case 0x40404040:
130     case 0x40ffffff:
131     case 0x4040ffff:
132     case 0x404040ff:
133     case 0xff404040:
134     case 0xffff4040:
135     case 0xffffff40:
136     d->blk_cmd = 0x40404040;
137     break;
138    
139     /* Reset */
140     case 0xffffffff:
141     d->status = 0;
142     break;
143    
144     /* Intelligent Identifier and Read Status register */
145     case 0x90909090:
146     case 0x70707070:
147     d->status = 1;
148     d->cui_cmd = *data;
149     break;
150    
151     default:
152     cpu_log(cpu,dev->name,
153     "default write case at offset=0x%7.7x, val=0x%llx\n",
154     offset,*data);
155     }
156    
157     return NULL;
158     }
159    
160     /* Shutdown a bootflash device */
161     void dev_bootflash_shutdown(vm_instance_t *vm,struct bootflash_data *d)
162     {
163     if (d != NULL) {
164     /* Remove the device */
165     dev_remove(vm,&d->dev);
166    
167     /* We don't remove the file, since it used as permanent storage */
168     if (d->filename)
169     free(d->filename);
170    
171     /* Free the structure itself */
172     free(d);
173     }
174     }
175    
176     /* Create a 8 Mb bootflash */
177     int dev_bootflash_init(vm_instance_t *vm,char *name,
178     m_uint64_t paddr,m_uint32_t len)
179     {
180     struct bootflash_data *d;
181     u_char *ptr;
182    
183     /* Allocate the private data structure */
184     if (!(d = malloc(sizeof(*d)))) {
185     fprintf(stderr,"Bootflash: unable to create device.\n");
186     return(-1);
187     }
188    
189     memset(d,0,sizeof(*d));
190    
191     vm_object_init(&d->vm_obj);
192     d->vm_obj.name = name;
193     d->vm_obj.data = d;
194     d->vm_obj.shutdown = (vm_shutdown_t)dev_bootflash_shutdown;
195    
196     if (!(d->filename = vm_build_filename(vm,name))) {
197     fprintf(stderr,"Bootflash: unable to create filename.\n");
198     goto err_filename;
199     }
200    
201     dev_init(&d->dev);
202     d->dev.name = name;
203     d->dev.priv_data = d;
204     d->dev.phys_addr = paddr;
205     d->dev.phys_len = len;
206     d->dev.handler = dev_bootflash_access;
207     d->dev.fd = memzone_create_file(d->filename,d->dev.phys_len,&ptr);
208     d->dev.host_addr = (m_iptr_t)ptr;
209     d->dev.flags = VDEVICE_FLAG_NO_MTS_MMAP;
210    
211     if (d->dev.fd == -1) {
212     fprintf(stderr,"Bootflash: unable to map file '%s'\n",d->filename);
213     goto err_fd_create;
214     }
215    
216     /* Map this device to the VM */
217     vm_bind_device(vm,&d->dev);
218     vm_object_add(vm,&d->vm_obj);
219     return(0);
220    
221     err_fd_create:
222     free(d->filename);
223     err_filename:
224     free(d);
225     return(-1);
226     }

  ViewVC Help
Powered by ViewVC 1.1.26