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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (12 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 8528 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26