/[dynamips]/trunk/dev_c3745_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 /trunk/dev_c3745_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (hide annotations)
Sat Oct 6 16:09:07 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC5/dev_c3745_iofpga.c
File MIME type: text/plain
File size: 9518 byte(s)
dynamips-0.2.6-RC5

1 dpavlin 4 /*
2     * Cisco 3745 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_c3745.h"
25    
26     /* Debugging flags */
27     #define DEBUG_UNKNOWN 1
28     #define DEBUG_ACCESS 0
29    
30     /* Definitions for Motherboard EEPROM (0x00) */
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 I/O board EEPROM (0x01) */
37     #define EEPROM_IO_DOUT 3
38     #define EEPROM_IO_DIN 2
39     #define EEPROM_IO_CLK 1
40     #define EEPROM_IO_CS 8
41    
42     /* Definitions for Midplane EEPROM (0x02) */
43     #define EEPROM_MP_DOUT 3
44     #define EEPROM_MP_DIN 2
45     #define EEPROM_MP_CLK 1
46     #define EEPROM_MP_CS 9
47    
48     /* Definitions for Network Modules EEPROM */
49     #define EEPROM_NM_DOUT 7
50     #define EEPROM_NM_DIN 6
51     #define EEPROM_NM_CLK 2
52     #define EEPROM_NM_CS 4
53    
54     #define C3745_NET_IRQ_CLEARING_DELAY 16
55    
56     /* IO FPGA structure */
57     struct iofpga_data {
58     vm_obj_t vm_obj;
59     struct vdevice dev;
60     c3745_t *router;
61    
62     /*
63     * Used to introduce a "delay" before clearing the network interrupt
64     * on 3620/3640 platforms. Added due to a packet loss when using an
65     * Ethernet NM on these platforms.
66     *
67     * Anyway, we should rely on the device information with appropriate IRQ
68     * routing.
69     */
70     int net_irq_clearing_count;
71    
72     /* Interrupt mask */
73     m_uint16_t intr_mask,io_mask2;
74    
75     /* EEPROM select */
76     u_int eeprom_select;
77     };
78    
79     /* Motherboard EEPROM definition */
80     static const struct nmc93c46_eeprom_def eeprom_mb_def = {
81     EEPROM_MB_CLK, EEPROM_MB_CS,
82     EEPROM_MB_DIN, EEPROM_MB_DOUT,
83     };
84    
85     /* I/O board EEPROM definition */
86     static const struct nmc93c46_eeprom_def eeprom_io_def = {
87     EEPROM_IO_CLK, EEPROM_IO_CS,
88     EEPROM_IO_DIN, EEPROM_IO_DOUT,
89     };
90    
91     /* Midplane EEPROM definition */
92     static const struct nmc93c46_eeprom_def eeprom_mp_def = {
93     EEPROM_MP_CLK, EEPROM_MP_CS,
94     EEPROM_MP_DIN, EEPROM_MP_DOUT,
95     };
96    
97     /* System EEPROM group */
98     static const struct nmc93c46_group eeprom_sys_group = {
99     3, 0, "System EEPROM", 0,
100     { &eeprom_mb_def, &eeprom_io_def, &eeprom_mp_def },
101     };
102    
103     /* NM EEPROM definition */
104     static const struct nmc93c46_eeprom_def eeprom_nm_def = {
105     EEPROM_NM_CLK, EEPROM_NM_CS,
106     EEPROM_NM_DIN, EEPROM_NM_DOUT,
107     };
108    
109     /* NM EEPROM */
110     static const struct nmc93c46_group eeprom_nm_group = {
111     1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
112     };
113    
114     /*
115     * dev_c3745_iofpga_access()
116     */
117     static void *
118     dev_c3745_iofpga_access(cpu_mips_t *cpu,struct vdevice *dev,
119     m_uint32_t offset,u_int op_size,u_int op_type,
120     m_uint64_t *data)
121     {
122     struct iofpga_data *d = dev->priv_data;
123     u_int slot;
124    
125     if (op_type == MTS_READ)
126     *data = 0x0;
127    
128     #if DEBUG_ACCESS
129     if (op_type == MTS_READ) {
130     cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
131     offset,cpu->pc,op_size);
132     } else {
133     cpu_log(cpu,"IO_FPGA",
134     "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
135     offset,cpu->pc,*data,op_size);
136     }
137     #endif
138    
139     switch(offset) {
140     /* Unknown */
141     case 0x000000:
142     if (op_type == MTS_READ)
143     *data = 0xFFFF;
144     break;
145    
146     /* Unknown */
147     case 0x000004:
148     if (op_type == MTS_READ)
149     *data = 0xFFFF;
150     break;
151    
152     /*
153     * CompactFlash.
154     *
155     * Bit 0: Slot0 Compact Flash presence.
156     * Bit 1: System Compact Flash presence.
157     */
158     case 0x000012:
159     if (op_type == MTS_READ) {
160     *data = 0xFFFF;
161    
162     /* System Flash ? */
163     if (cpu->vm->pcmcia_disk_size[0])
164     *data &= ~0x02;
165    
166     /* Slot0 Flash ? */
167     if (cpu->vm->pcmcia_disk_size[1])
168     *data &= ~0x01;
169     }
170     break;
171    
172     /* Suppress the "****TDM FPGA download failed.." message */
173     case 0x000014:
174     if (op_type == MTS_READ)
175     *data = 0x00FF;
176     break;
177    
178     /* Power supply status */
179     case 0x00000a:
180     if (op_type == MTS_READ)
181     *data = 0x0000;
182     break;
183    
184     /* Fan status */
185     case 0x00000c:
186     if (op_type == MTS_READ)
187     *data = 0x0000;
188     break;
189    
190     /* System EEPROMs */
191     case 0x00000e:
192     if (op_type == MTS_WRITE)
193     nmc93c46_write(&d->router->sys_eeprom_group,(u_int)(*data));
194     else
195     *data = nmc93c46_read(&d->router->sys_eeprom_group);
196     break;
197    
198     /*
199     * Network interrupt status.
200     *
201     * Bit 0: 0 = GT96100 Ethernet ports.
202     * Bit 8: 0 = AIM slot 0.
203     * Bit 9: 0 = AIM slot 1.
204     */
205     case 0x000020:
206     if (op_type == MTS_READ)
207     *data = 0xFFFE;
208     break;
209    
210     /*
211     * Network interrupt status.
212     *
213     * Bit 0: 0 = Interrupt for slot 1
214     * Bit 4: 0 = Interrupt for slot 2
215     * Bit 8: 0 = Interrupt for slot 3
216     * Bit 12: 0 = Interrupt for slot 4
217     */
218     case 0x000022:
219     if (op_type == MTS_READ)
220     *data = 0x0000;
221     vm_clear_irq(d->router->vm,C3745_NETIO_IRQ);
222     break;
223    
224     /*
225     * Per Slot Intr Mask (seen with "sh platform").
226     * IO Mask 1 is the lower 8-bits.
227     */
228     case 0x00002a:
229     if (op_type == MTS_READ)
230     *data = d->intr_mask;
231     else
232     d->intr_mask = *data;
233     break;
234    
235     /* IO Mask 2 (seen with "sh platform") */
236     case 0x00002c:
237     if (op_type == MTS_READ)
238     *data = d->io_mask2;
239     else
240     d->io_mask2 = *data;
241     break;
242    
243     /* EEPROM in slots 1-4 */
244     case 0x000040:
245     case 0x000042:
246     case 0x000044:
247     case 0x000046:
248     slot = (offset - 0x000040) >> 1;
249    
250     if (op_type == MTS_WRITE)
251     nmc93c46_write(&d->router->nm_eeprom_group[slot],(u_int)(*data));
252     else
253     *data = nmc93c46_read(&d->router->nm_eeprom_group[slot]);
254     break;
255    
256     /* AIM slot 0 EEPROM */
257     case 0x000048:
258     if (op_type == MTS_READ)
259     *data = 0xFFFF;
260     break;
261    
262     /* AIM slot 1 EEPROM */
263     case 0x00004A:
264     if (op_type == MTS_READ)
265     *data = 0xFFFF;
266     break;
267    
268     /*
269     * NM presence.
270     *
271     * Bit 0: 0 = NM present in slot 2 (0x42)
272     * Bit 4: 0 = NM present in slot 4 (0x46)
273     * Bit 8: 0 = NM present in slot 1 (0x40)
274     * Bit 12: 0 = NM present in slot 3 (0x44)
275     */
276     case 0x00004e:
277     if (op_type == MTS_READ) {
278     *data = 0xFFFF;
279    
280     if (c3745_nm_check_eeprom(d->router,1))
281     *data &= ~0x0100;
282    
283     if (c3745_nm_check_eeprom(d->router,2))
284     *data &= ~0x0001;
285    
286     if (c3745_nm_check_eeprom(d->router,3))
287     *data &= ~0x1000;
288    
289     if (c3745_nm_check_eeprom(d->router,4))
290     *data &= ~0x0010;
291     }
292     break;
293    
294     /* VWIC/WIC related */
295     case 0x100004:
296     case 0x100006:
297     case 0x100008:
298     if (op_type == MTS_READ)
299     *data = 0xFFFF;
300     break;
301    
302     #if DEBUG_UNKNOWN
303     default:
304     if (op_type == MTS_READ) {
305     cpu_log(cpu,"IO_FPGA",
306     "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
307     offset,cpu->pc,op_size);
308     } else {
309     cpu_log(cpu,"IO_FPGA",
310     "write to unknown addr 0x%x, value=0x%llx, "
311     "pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size);
312     }
313     #endif
314     }
315    
316     return NULL;
317     }
318    
319     /* Initialize EEPROM groups */
320     void c3745_init_eeprom_groups(c3745_t *router)
321     {
322     int i;
323    
324     /* Initialize Mainboard EEPROM */
325     router->sys_eeprom_group = eeprom_sys_group;
326    
327     for(i=0;i<3;i++) {
328     router->sys_eeprom_group.eeprom[i] = &router->sys_eeprom[i];
329     router->sys_eeprom[i].data = NULL;
330     router->sys_eeprom[i].len = 0;
331     }
332    
333     /* EEPROMs for Network Modules */
334     for(i=1;i<=4;i++) {
335     router->nm_eeprom_group[i-1] = eeprom_nm_group;
336     router->nm_eeprom_group[i-1].eeprom[0] = &router->nm_bay[i].eeprom;
337     }
338     }
339    
340     /* Shutdown the IO FPGA device */
341     void dev_c3745_iofpga_shutdown(vm_instance_t *vm,struct iofpga_data *d)
342     {
343     if (d != NULL) {
344     /* Remove the device */
345     dev_remove(vm,&d->dev);
346    
347     /* Free the structure itself */
348     free(d);
349     }
350     }
351    
352     /*
353     * dev_c3745_iofpga_init()
354     */
355     int dev_c3745_iofpga_init(c3745_t *router,m_uint64_t paddr,m_uint32_t len)
356     {
357     vm_instance_t *vm = router->vm;
358     struct iofpga_data *d;
359    
360     /* Allocate private data structure */
361     if (!(d = malloc(sizeof(*d)))) {
362     fprintf(stderr,"IO_FPGA: out of memory\n");
363     return(-1);
364     }
365    
366     memset(d,0,sizeof(*d));
367     d->router = router;
368    
369     vm_object_init(&d->vm_obj);
370     d->vm_obj.name = "io_fpga";
371     d->vm_obj.data = d;
372     d->vm_obj.shutdown = (vm_shutdown_t)dev_c3745_iofpga_shutdown;
373    
374     /* Set device properties */
375     dev_init(&d->dev);
376     d->dev.name = "io_fpga";
377     d->dev.phys_addr = paddr;
378     d->dev.phys_len = len;
379     d->dev.priv_data = d;
380     d->dev.handler = dev_c3745_iofpga_access;
381    
382     /* Map this device to the VM */
383     vm_bind_device(router->vm,&d->dev);
384     vm_object_add(vm,&d->vm_obj);
385     return(0);
386     }

  ViewVC Help
Powered by ViewVC 1.1.26