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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 dpavlin 4 /*
2     * Cisco 3725 simulation platform.
3     * Copyright (c) 2006 Christophe Fillot (cf@utc.fr)
4     *
5     * This is very similar to c2691.
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11     #include <unistd.h>
12     #include <sys/types.h>
13     #include <termios.h>
14     #include <fcntl.h>
15     #include <pthread.h>
16    
17     #include "ptask.h"
18 dpavlin 7 #include "cpu.h"
19     #include "vm.h"
20 dpavlin 4 #include "dynamips.h"
21     #include "memory.h"
22     #include "device.h"
23     #include "dev_vtty.h"
24     #include "nmc93c46.h"
25     #include "dev_c3725.h"
26    
27     /* Debugging flags */
28     #define DEBUG_UNKNOWN 1
29     #define DEBUG_ACCESS 0
30    
31     /* Definitions for Mainboard EEPROM */
32     #define EEPROM_MB_DOUT 3
33     #define EEPROM_MB_DIN 2
34     #define EEPROM_MB_CLK 1
35     #define EEPROM_MB_CS 0
36    
37     /* Definitions for Network Modules EEPROM */
38     #define EEPROM_NM_DOUT 7
39     #define EEPROM_NM_DIN 6
40     #define EEPROM_NM_CLK 2
41     #define EEPROM_NM_CS 4
42    
43     #define C3725_NET_IRQ_CLEARING_DELAY 16
44    
45     /* IO FPGA structure */
46     struct iofpga_data {
47     vm_obj_t vm_obj;
48     struct vdevice dev;
49     c3725_t *router;
50    
51     /*
52     * Used to introduce a "delay" before clearing the network interrupt
53     * on 3620/3640 platforms. Added due to a packet loss when using an
54     * Ethernet NM on these platforms.
55     *
56     * Anyway, we should rely on the device information with appropriate IRQ
57     * routing.
58     */
59     int net_irq_clearing_count;
60    
61     /* Interrupt mask*/
62     m_uint16_t intr_mask;
63     };
64    
65     /* Mainboard EEPROM definition */
66     static const struct nmc93c46_eeprom_def eeprom_mb_def = {
67     EEPROM_MB_CLK, EEPROM_MB_CS,
68     EEPROM_MB_DIN, EEPROM_MB_DOUT,
69     };
70    
71     /* Mainboard EEPROM */
72     static const struct nmc93c46_group eeprom_mb_group = {
73     1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
74     };
75    
76     /* NM EEPROM definition */
77     static const struct nmc93c46_eeprom_def eeprom_nm_def = {
78     EEPROM_NM_CLK, EEPROM_NM_CS,
79     EEPROM_NM_DIN, EEPROM_NM_DOUT,
80     };
81    
82     /* NM EEPROM */
83     static const struct nmc93c46_group eeprom_nm_group = {
84     1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
85     };
86    
87     /*
88     * dev_c3725_iofpga_access()
89     */
90     static void *
91 dpavlin 7 dev_c3725_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
92 dpavlin 4 m_uint32_t offset,u_int op_size,u_int op_type,
93     m_uint64_t *data)
94     {
95     struct iofpga_data *d = dev->priv_data;
96    
97     if (op_type == MTS_READ)
98     *data = 0x0;
99    
100     #if DEBUG_ACCESS
101     if (op_type == MTS_READ) {
102     cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
103 dpavlin 7 offset,cpu_get_pc(cpu),op_size);
104 dpavlin 4 } else {
105     cpu_log(cpu,"IO_FPGA",
106     "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
107 dpavlin 7 offset,cpu_get_pc(cpu),*data,op_size);
108 dpavlin 4 }
109     #endif
110    
111     switch(offset) {
112     /*
113     * Platform type ?
114 dpavlin 5 * 0x04 and 0x05 seem to work.
115 dpavlin 4 */
116     case 0x36:
117     if (op_type == MTS_READ)
118 dpavlin 5 *data = 0x04 << 5;
119 dpavlin 4 break;
120    
121     /* Mainboard EEPROM */
122     case 0x0e:
123     if (op_type == MTS_WRITE)
124     nmc93c46_write(&d->router->mb_eeprom_group,(u_int)(*data));
125     else
126     *data = nmc93c46_read(&d->router->mb_eeprom_group);
127     break;
128    
129     case 0x12:
130     /*
131     * Bit 0: 1=No WIC in slot 0 ?
132     * Bit 1: 1=No WIC in slot 1 ?
133     * Bit 2: 1=No WIC in slot 2 ?
134     */
135     if (op_type == MTS_READ)
136     *data = 0x0007;
137     break;
138    
139     case 0x14:
140     if (op_type == MTS_READ)
141     *data = 0xFFFF;
142     break;
143    
144     case 0x18:
145     if (op_type == MTS_READ)
146     *data = 0xFFFF;
147     break;
148    
149     /* wic/vwic related */
150     case 0x40:
151     if (op_type == MTS_READ)
152     *data = 0x0004;
153     break;
154    
155     /* WIC related: 16-bit data */
156     case 0x42:
157     break;
158    
159     /* NM Slot 1 EEPROM */
160     case 0x44:
161     if (op_type == MTS_WRITE)
162     nmc93c46_write(&d->router->nm_eeprom_group[0],(u_int)(*data));
163     else
164     *data = nmc93c46_read(&d->router->nm_eeprom_group[0]);
165     break;
166    
167     /* NM Slot 2 EEPROM */
168     case 0x46:
169     if (op_type == MTS_WRITE)
170     nmc93c46_write(&d->router->nm_eeprom_group[1],(u_int)(*data));
171     else
172     *data = nmc93c46_read(&d->router->nm_eeprom_group[1]);
173     break;
174    
175     /* AIM EEPROM #0 */
176     case 0x48:
177     if (op_type == MTS_READ)
178     *data = 0xFFFF;
179     break;
180    
181     /* AIM EEPROM #1 */
182     case 0x4a:
183     if (op_type == MTS_READ)
184     *data = 0xFFFF;
185     break;
186    
187     /*
188     * NM Presence.
189     *
190     * Bit 7: 0=NM present in slot 1.
191     * Bit 11: 0=NM present in slot 2.
192     * Other bits unknown.
193     */
194     case 0x20:
195     if (op_type == MTS_READ) {
196     *data = 0xFFFF;
197    
198     if (c3725_nm_check_eeprom(d->router,1))
199     *data &= ~0x0008;
200    
201     if (c3725_nm_check_eeprom(d->router,2))
202     *data &= ~0x0800;
203     }
204     break;
205    
206     /* ??? */
207     case 0x24:
208     break;
209    
210     /* Intr Mask (sh platform) */
211     case 0x30:
212     if (op_type == MTS_READ)
213     *data = d->intr_mask;
214     else
215     d->intr_mask = *data;
216     break;
217    
218     /*
219     * Network interrupt status.
220     *
221     * Bit 0: 0 = GT96100 Ethernet ports.
222     * Other bits unknown.
223     */
224     case 0x26:
225     if (op_type == MTS_READ)
226     *data = 0xFFFE;
227     break;
228    
229     /*
230     * Network interrupt status.
231     *
232     * Bit 0: 0 = NM in Slot 1.
233     * Bit 8: 0 = NM in Slot 2.
234     * Other bits unknown.
235     */
236     case 0x28:
237     if (op_type == MTS_READ) {
238     *data = 0xFFEE;
239    
240     if (++d->net_irq_clearing_count == C3725_NET_IRQ_CLEARING_DELAY) {
241     vm_clear_irq(d->router->vm,C3725_NETIO_IRQ);
242     d->net_irq_clearing_count = 0;
243     }
244     }
245     break;
246    
247     case 0x2c:
248     if (op_type == MTS_READ)
249     *data = 0xFFFF;
250     break;
251    
252     /* OIR interrupt but not supported (IRQ 6) */
253     case 0x2e:
254     if (op_type == MTS_READ)
255     *data = 0xFFFF;
256     break;
257    
258     /*
259     * Environmental monitor, determined with "sh env all".
260     *
261     * Bit 0: 1 = Fan Error
262     * Bit 1: 1 = Fan Error
263     * Bit 2: 1 = Over-temperature
264     * Bit 3: ???
265     * Bit 4: 0 = RPS present.
266     * Bit 5: 0 = Input Voltage status failure.
267     * Bit 6: 1 = Thermal status failure.
268     * Bit 7: 1 = DC Output Voltage status failure.
269     */
270     case 0x3a:
271     if (op_type == MTS_READ)
272     *data = 0x0020;
273     break;
274    
275     /*
276     * Bit 0: Slot0 Compact Flash presence.
277     * Bit 1: System Compact Flash presence.
278     */
279     case 0x3c:
280     if (op_type == MTS_READ) {
281     *data = 0xFFFF;
282    
283     /* System Flash ? */
284     if (cpu->vm->pcmcia_disk_size[0])
285     *data &= ~0x02;
286    
287     /* Slot0 Flash ? */
288     if (cpu->vm->pcmcia_disk_size[1])
289     *data &= ~0x01;
290     }
291     break;
292    
293     #if DEBUG_UNKNOWN
294     default:
295     if (op_type == MTS_READ) {
296     cpu_log(cpu,"IO_FPGA",
297     "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
298 dpavlin 7 offset,cpu_get_pc(cpu),op_size);
299 dpavlin 4 } else {
300     cpu_log(cpu,"IO_FPGA",
301     "write to unknown addr 0x%x, value=0x%llx, "
302 dpavlin 7 "pc=0x%llx (size=%u)\n",
303     offset,*data,cpu_get_pc(cpu),op_size);
304 dpavlin 4 }
305     #endif
306     }
307    
308     return NULL;
309     }
310    
311     /* Initialize EEPROM groups */
312     void c3725_init_eeprom_groups(c3725_t *router)
313     {
314     /* Initialize Mainboard EEPROM */
315     router->mb_eeprom_group = eeprom_mb_group;
316     router->mb_eeprom_group.eeprom[0] = &router->mb_eeprom;
317     router->mb_eeprom.data = NULL;
318     router->mb_eeprom.len = 0;
319    
320     /* EEPROM for NM slot 1 */
321     router->nm_eeprom_group[0] = eeprom_nm_group;
322     router->nm_eeprom_group[0].eeprom[0] = &router->nm_bay[1].eeprom;
323    
324     /* EEPROM for NM slot 2 */
325     router->nm_eeprom_group[1] = eeprom_nm_group;
326     router->nm_eeprom_group[1].eeprom[0] = &router->nm_bay[2].eeprom;
327     }
328    
329     /* Shutdown the IO FPGA device */
330     void dev_c3725_iofpga_shutdown(vm_instance_t *vm,struct iofpga_data *d)
331     {
332     if (d != NULL) {
333     /* Remove the device */
334     dev_remove(vm,&d->dev);
335    
336     /* Free the structure itself */
337     free(d);
338     }
339     }
340    
341     /*
342     * dev_c3725_iofpga_init()
343     */
344     int dev_c3725_iofpga_init(c3725_t *router,m_uint64_t paddr,m_uint32_t len)
345     {
346     vm_instance_t *vm = router->vm;
347     struct iofpga_data *d;
348    
349     /* Allocate private data structure */
350     if (!(d = malloc(sizeof(*d)))) {
351     fprintf(stderr,"IO_FPGA: out of memory\n");
352     return(-1);
353     }
354    
355     memset(d,0,sizeof(*d));
356     d->router = router;
357    
358     vm_object_init(&d->vm_obj);
359     d->vm_obj.name = "io_fpga";
360     d->vm_obj.data = d;
361     d->vm_obj.shutdown = (vm_shutdown_t)dev_c3725_iofpga_shutdown;
362    
363     /* Set device properties */
364     dev_init(&d->dev);
365     d->dev.name = "io_fpga";
366     d->dev.phys_addr = paddr;
367     d->dev.phys_len = len;
368     d->dev.priv_data = d;
369     d->dev.handler = dev_c3725_iofpga_access;
370    
371     /* Map this device to the VM */
372     vm_bind_device(router->vm,&d->dev);
373     vm_object_add(vm,&d->vm_obj);
374     return(0);
375     }

  ViewVC Help
Powered by ViewVC 1.1.26