/[dynamips]/upstream/dynamips-0.2.7-RC1/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.7-RC1/dev_bootflash.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: 5812 byte(s)
dynamips-0.2.7-RC1

1 dpavlin 1 /*
2 dpavlin 7 * Cisco router simulation platform.
3 dpavlin 1 * 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 dpavlin 7 #include "cpu.h"
29     #include "vm.h"
30 dpavlin 1 #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 dpavlin 7 void *dev_bootflash_access(cpu_gen_t *cpu,struct vdevice *dev,
52 dpavlin 1 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 dpavlin 7 offset,cpu_get_pc(cpu),d->status,d->cui_cmd);
62 dpavlin 1 else
63     cpu_log(cpu,dev->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
64 dpavlin 7 "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);
65 dpavlin 1 #endif
66    
67     if (op_type == MTS_READ) {
68 dpavlin 7 *data = 0;
69    
70 dpavlin 1 /* 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