/[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 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_c2691_iofpga.c
File MIME type: text/plain
File size: 8463 byte(s)
dynamips-0.2.6-RC5

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

  ViewVC Help
Powered by ViewVC 1.1.26