/[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 5 - (hide annotations)
Sat Oct 6 16:08:03 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC4/dev_c3725_iofpga.c
File MIME type: text/plain
File size: 9153 byte(s)
dynamips-0.2.6-RC4

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

  ViewVC Help
Powered by ViewVC 1.1.26