/[dynamips]/trunk/dev_c2691_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_c2691_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations)
Sat Oct 6 16:29:14 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7/dev_c2691_iofpga.c
File MIME type: text/plain
File size: 9843 byte(s)
dynamips-0.2.7

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

  ViewVC Help
Powered by ViewVC 1.1.26