/[dynamips]/upstream/dynamips-0.2.7-RC2/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

Contents of /upstream/dynamips-0.2.7-RC2/dev_bootflash.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: 5812 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
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 "cpu.h"
29 #include "vm.h"
30 #include "dynamips.h"
31 #include "memory.h"
32 #include "device.h"
33
34 #define DEBUG_ACCESS 0
35 #define DEBUG_WRITE 0
36
37 /* Bootflash private data */
38 struct bootflash_data {
39 vm_obj_t vm_obj;
40 struct vdevice dev;
41 m_uint32_t cui_cmd,blk_cmd;
42 m_uint32_t status;
43 char *filename;
44 };
45
46 #define BPTR(d,offset) (((char *)d->dev.host_addr) + offset)
47
48 /*
49 * dev_bootflash_access()
50 */
51 void *dev_bootflash_access(cpu_gen_t *cpu,struct vdevice *dev,
52 m_uint32_t offset,u_int op_size,u_int op_type,
53 m_uint64_t *data)
54 {
55 struct bootflash_data *d = dev->priv_data;
56
57 #if DEBUG_ACCESS
58 if (op_type == MTS_READ)
59 cpu_log(cpu,dev->name,"read access to offset = 0x%x, pc = 0x%llx "
60 "(stat=%u,cui_cmd=0x%x)\n",
61 offset,cpu_get_pc(cpu),d->status,d->cui_cmd);
62 else
63 cpu_log(cpu,dev->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
64 "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);
65 #endif
66
67 if (op_type == MTS_READ) {
68 *data = 0;
69
70 /* Read Array mode */
71 if (d->status == 0)
72 return(BPTR(d,offset));
73
74 switch(d->cui_cmd) {
75 /* Intelligent identifier */
76 case 0x90909090:
77 switch(offset) {
78 case 0x00:
79 *data = 0x89898989; /* manufacturer code */
80 return NULL;
81 case 0x04:
82 *data = 0xA0A0A0A0; /* device code */
83 return NULL;
84 default:
85 cpu_log(cpu,dev->name,
86 "Reading Intelligent ID Code at offset = 0x%x ?\n",
87 offset);
88 *data = 0x00000000;
89 return NULL;
90 }
91 break;
92
93 /* Read Status Register */
94 case 0x70707070:
95 *data = 0x80808080;
96 return NULL;
97 }
98
99 /* Default: status register */
100 *data = 0x80808080;
101 return NULL;
102 }
103
104 /* write mode */
105 if (d->blk_cmd == 0x40404040) {
106 #if DEBUG_WRITE
107 cpu_log(cpu,dev->name,"Writing 0x%llx at offset=0x%x\n",*data,offset);
108 #endif
109 d->blk_cmd = 0;
110 d->cui_cmd = 0;
111 d->status = 1;
112 return(BPTR(d,offset));
113 }
114
115 switch(*data) {
116 /* Erase Setup */
117 case 0x20202020:
118 d->blk_cmd = *data;
119 break;
120
121 /* Erase Confirm */
122 case 0xd0d0d0d0:
123 if ((d->blk_cmd == 0x20202020) && !(offset & 0x3FFFF)) {
124 memset(BPTR(d,offset),0xFF,0x40000);
125 d->blk_cmd = 0;
126 d->cui_cmd = 0;
127 d->status = 1;
128 }
129 break;
130
131 /* Byte Write Setup (XXX ugly hack) */
132 case 0x40404040:
133 case 0x40ffffff:
134 case 0x4040ffff:
135 case 0x404040ff:
136 case 0xff404040:
137 case 0xffff4040:
138 case 0xffffff40:
139 d->blk_cmd = 0x40404040;
140 break;
141
142 /* Reset */
143 case 0xffffffff:
144 d->status = 0;
145 break;
146
147 /* Intelligent Identifier and Read Status register */
148 case 0x90909090:
149 case 0x70707070:
150 d->status = 1;
151 d->cui_cmd = *data;
152 break;
153
154 default:
155 cpu_log(cpu,dev->name,
156 "default write case at offset=0x%7.7x, val=0x%llx\n",
157 offset,*data);
158 }
159
160 return NULL;
161 }
162
163 /* Shutdown a bootflash device */
164 void dev_bootflash_shutdown(vm_instance_t *vm,struct bootflash_data *d)
165 {
166 if (d != NULL) {
167 /* Remove the device */
168 dev_remove(vm,&d->dev);
169
170 /* We don't remove the file, since it used as permanent storage */
171 if (d->filename)
172 free(d->filename);
173
174 /* Free the structure itself */
175 free(d);
176 }
177 }
178
179 /* Create a 8 Mb bootflash */
180 int dev_bootflash_init(vm_instance_t *vm,char *name,
181 m_uint64_t paddr,m_uint32_t len)
182 {
183 struct bootflash_data *d;
184 u_char *ptr;
185
186 /* Allocate the private data structure */
187 if (!(d = malloc(sizeof(*d)))) {
188 fprintf(stderr,"Bootflash: unable to create device.\n");
189 return(-1);
190 }
191
192 memset(d,0,sizeof(*d));
193
194 vm_object_init(&d->vm_obj);
195 d->vm_obj.name = name;
196 d->vm_obj.data = d;
197 d->vm_obj.shutdown = (vm_shutdown_t)dev_bootflash_shutdown;
198
199 if (!(d->filename = vm_build_filename(vm,name))) {
200 fprintf(stderr,"Bootflash: unable to create filename.\n");
201 goto err_filename;
202 }
203
204 dev_init(&d->dev);
205 d->dev.name = name;
206 d->dev.priv_data = d;
207 d->dev.phys_addr = paddr;
208 d->dev.phys_len = len;
209 d->dev.handler = dev_bootflash_access;
210 d->dev.fd = memzone_create_file(d->filename,d->dev.phys_len,&ptr);
211 d->dev.host_addr = (m_iptr_t)ptr;
212 d->dev.flags = VDEVICE_FLAG_NO_MTS_MMAP;
213
214 if (d->dev.fd == -1) {
215 fprintf(stderr,"Bootflash: unable to map file '%s'\n",d->filename);
216 goto err_fd_create;
217 }
218
219 /* Map this device to the VM */
220 vm_bind_device(vm,&d->dev);
221 vm_object_add(vm,&d->vm_obj);
222 return(0);
223
224 err_fd_create:
225 free(d->filename);
226 err_filename:
227 free(d);
228 return(-1);
229 }

  ViewVC Help
Powered by ViewVC 1.1.26