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

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

  ViewVC Help
Powered by ViewVC 1.1.26