/[dynamips]/trunk/dev_c2600_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_c2600_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 dpavlin 7 /*
2     * Cisco router 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 "cpu.h"
17     #include "vm.h"
18     #include "dynamips.h"
19     #include "memory.h"
20     #include "device.h"
21     #include "dev_vtty.h"
22 dpavlin 8 #include "nmc93cX6.h"
23 dpavlin 7 #include "dev_c2600.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 7
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     #define C2691_NET_IRQ_CLEARING_DELAY 16
43    
44 dpavlin 8 /* Network IRQ distribution */
45     static u_int net_irq_dist[C2600_MAX_NM_BAYS] = {
46     4, /* reg 0x08, bits 4-5 */
47     0, /* reg 0x08, bits 0-3 */
48     };
49    
50 dpavlin 7 /* IO FPGA structure */
51 dpavlin 8 struct c2600_iofpga_data {
52 dpavlin 7 vm_obj_t vm_obj;
53     struct vdevice dev;
54     c2600_t *router;
55    
56 dpavlin 8 /* Network Interrupt status */
57     m_uint8_t net_irq_status;
58 dpavlin 7
59 dpavlin 8 /* Interrupt mask */
60 dpavlin 7 m_uint16_t intr_mask;
61     };
62    
63     /* Mainboard EEPROM definition */
64 dpavlin 8 static const struct nmc93cX6_eeprom_def eeprom_mb_def = {
65 dpavlin 7 EEPROM_MB_CLK, EEPROM_MB_CS,
66     EEPROM_MB_DIN, EEPROM_MB_DOUT,
67     };
68    
69     /* Mainboard EEPROM */
70 dpavlin 8 static const struct nmc93cX6_group eeprom_mb_group = {
71     EEPROM_TYPE_NMC93C46, 1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
72 dpavlin 7 };
73    
74     /* NM EEPROM definition */
75 dpavlin 8 static const struct nmc93cX6_eeprom_def eeprom_nm_def = {
76 dpavlin 7 EEPROM_NM_CLK, EEPROM_NM_CS,
77     EEPROM_NM_DIN, EEPROM_NM_DOUT,
78     };
79    
80     /* NM EEPROM */
81 dpavlin 8 static const struct nmc93cX6_group eeprom_nm_group = {
82     EEPROM_TYPE_NMC93C46, 1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
83 dpavlin 7 };
84    
85 dpavlin 8 /* Update network interrupt status */
86     static inline void dev_c2600_iofpga_net_update_irq(struct c2600_iofpga_data *d)
87     {
88     if (d->net_irq_status) {
89     vm_set_irq(d->router->vm,C2600_NETIO_IRQ);
90     } else {
91     vm_clear_irq(d->router->vm,C2600_NETIO_IRQ);
92     }
93     }
94    
95     /* Trigger a Network IRQ for the specified slot/port */
96     void dev_c2600_iofpga_net_set_irq(struct c2600_iofpga_data *d,
97     u_int slot,u_int port)
98     {
99     #if DEBUG_NET_IRQ
100     vm_log(d->router->vm,"IO_FPGA","setting NetIRQ for slot %u port %u\n",
101     slot,port);
102     #endif
103     d->net_irq_status |= 1 << (net_irq_dist[slot] + port);
104     dev_c2600_iofpga_net_update_irq(d);
105     }
106    
107     /* Clear a Network IRQ for the specified slot/port */
108     void dev_c2600_iofpga_net_clear_irq(struct c2600_iofpga_data *d,
109     u_int slot,u_int port)
110     {
111     #if DEBUG_NET_IRQ
112     vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
113     slot,port);
114     #endif
115     d->net_irq_status &= ~(1 << (net_irq_dist[slot] + port));
116     dev_c2600_iofpga_net_update_irq(d);
117     }
118    
119 dpavlin 7 /*
120     * dev_c2600_iofpga_access()
121     */
122     static void *
123     dev_c2600_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
124     m_uint32_t offset,u_int op_size,u_int op_type,
125     m_uint64_t *data)
126     {
127 dpavlin 8 struct c2600_iofpga_data *d = dev->priv_data;
128 dpavlin 7
129     if (op_type == MTS_READ)
130     *data = 0x0;
131    
132     #if DEBUG_ACCESS
133     if (op_type == MTS_READ) {
134     cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
135     offset,cpu_get_pc(cpu),op_size);
136     } else {
137     cpu_log(cpu,"IO_FPGA",
138     "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
139     offset,cpu_get_pc(cpu),*data,op_size);
140     }
141     #endif
142    
143     switch(offset) {
144     case 0x04:
145     if (op_type == MTS_READ)
146     *data = 0x00;
147     break;
148    
149     /*
150     * Network Interrupt.
151     *
152 dpavlin 8 * Bit 0-3: slot 1.
153 dpavlin 7 * Bit 4: slot 0 (MB), port 0
154     * Bit 5: slot 0 (MB), port 1
155     * Other: AIM ? (error messages displayed)
156     */
157     case 0x08:
158     if (op_type == MTS_READ)
159 dpavlin 8 *data = d->net_irq_status;
160 dpavlin 7 break;
161    
162     case 0x10:
163     case 0x14:
164     if (op_type == MTS_READ)
165     *data = 0xFFFFFFFF;
166     break;
167    
168 dpavlin 8 /*
169     * Flash Related: 0x1y
170     *
171     * Bit 1: card present in slot 0 / WIC 0.
172     * Bit 2: card present in slot 0 / WIC 1.
173     *
174     * Other bits unknown.
175     */
176 dpavlin 7 #if 1
177     case 0x0c:
178     if (op_type == MTS_READ)
179 dpavlin 8 *data = 0x10; //0x10;
180 dpavlin 7 break;
181     #endif
182    
183     /* NM EEPROM */
184     case 0x1c:
185     if (op_type == MTS_WRITE)
186 dpavlin 8 nmc93cX6_write(&d->router->nm_eeprom_group,(u_int)(*data));
187 dpavlin 7 else
188 dpavlin 8 *data = nmc93cX6_read(&d->router->nm_eeprom_group);
189 dpavlin 7 break;
190    
191     #if DEBUG_UNKNOWN
192     default:
193     if (op_type == MTS_READ) {
194     cpu_log(cpu,"IO_FPGA",
195     "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
196     offset,cpu_get_pc(cpu),op_size);
197     } else {
198     cpu_log(cpu,"IO_FPGA",
199     "write to unknown addr 0x%x, value=0x%llx, "
200     "pc=0x%llx (size=%u)\n",
201     offset,*data,cpu_get_pc(cpu),op_size);
202     }
203     #endif
204     }
205    
206     return NULL;
207     }
208    
209     /* Initialize EEPROM groups */
210     void c2600_init_eeprom_groups(c2600_t *router)
211     {
212     /* Initialize Mainboard EEPROM */
213     router->mb_eeprom_group = eeprom_mb_group;
214     router->mb_eeprom_group.eeprom[0] = &router->mb_eeprom;
215     router->mb_eeprom.data = NULL;
216     router->mb_eeprom.len = 0;
217    
218     /* EEPROM for NM slot 1 */
219     router->nm_eeprom_group = eeprom_nm_group;
220     router->nm_eeprom_group.eeprom[0] = &router->nm_bay[1].eeprom;
221     }
222    
223     /* Shutdown the IO FPGA device */
224 dpavlin 8 static void
225     dev_c2600_iofpga_shutdown(vm_instance_t *vm,struct c2600_iofpga_data *d)
226 dpavlin 7 {
227     if (d != NULL) {
228     /* Remove the device */
229     dev_remove(vm,&d->dev);
230    
231     /* Free the structure itself */
232     free(d);
233     }
234     }
235    
236     /*
237     * dev_c2600_iofpga_init()
238     */
239     int dev_c2600_iofpga_init(c2600_t *router,m_uint64_t paddr,m_uint32_t len)
240     {
241     vm_instance_t *vm = router->vm;
242 dpavlin 8 struct c2600_iofpga_data *d;
243 dpavlin 7
244     /* Allocate private data structure */
245     if (!(d = malloc(sizeof(*d)))) {
246     fprintf(stderr,"IO_FPGA: out of memory\n");
247     return(-1);
248     }
249    
250     memset(d,0,sizeof(*d));
251     d->router = router;
252    
253     vm_object_init(&d->vm_obj);
254     d->vm_obj.name = "io_fpga";
255     d->vm_obj.data = d;
256     d->vm_obj.shutdown = (vm_shutdown_t)dev_c2600_iofpga_shutdown;
257    
258     /* Set device properties */
259     dev_init(&d->dev);
260     d->dev.name = "io_fpga";
261     d->dev.phys_addr = paddr;
262     d->dev.phys_len = len;
263     d->dev.priv_data = d;
264     d->dev.handler = dev_c2600_iofpga_access;
265    
266     /* Map this device to the VM */
267     vm_bind_device(router->vm,&d->dev);
268     vm_object_add(vm,&d->vm_obj);
269     return(0);
270     }

  ViewVC Help
Powered by ViewVC 1.1.26