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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Sat Oct 6 16:26:06 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 10505 byte(s)
dynamips-0.2.7-RC3

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

  ViewVC Help
Powered by ViewVC 1.1.26