/[dynamips]/upstream/dynamips-0.2.7-RC2/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

Contents of /upstream/dynamips-0.2.7-RC2/dev_c3725_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (12 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 10505 byte(s)
dynamips-0.2.7-RC2

1 /*
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 #include "cpu.h"
19 #include "vm.h"
20 #include "dynamips.h"
21 #include "memory.h"
22 #include "device.h"
23 #include "dev_vtty.h"
24 #include "nmc93cX6.h"
25 #include "dev_c3725.h"
26
27 /* Debugging flags */
28 #define DEBUG_UNKNOWN 1
29 #define DEBUG_ACCESS 0
30 #define DEBUG_NET_IRQ 0
31
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 /* Network IRQ distribution */
45 struct net_irq_distrib {
46 u_int reg;
47 u_int offset;
48 };
49
50 static struct net_irq_distrib net_irq_dist[C3725_MAX_NM_BAYS] = {
51 { 0, 0 }, /* Slot 0: reg 0x26, 0x000000XX */
52 { 1, 0 }, /* Slot 1: reg 0x28, 0x000000XX */
53 { 1, 8 }, /* Slot 2: reg 0x28, 0x0000XX00 */
54 };
55
56 /* IO FPGA structure */
57 struct c3725_iofpga_data {
58 vm_obj_t vm_obj;
59 struct vdevice dev;
60 c3725_t *router;
61
62 /* Network IRQ status */
63 m_uint16_t net_irq_status[2];
64
65 /* Interrupt mask */
66 m_uint16_t intr_mask;
67 };
68
69 /* Mainboard EEPROM definition */
70 static const struct nmc93cX6_eeprom_def eeprom_mb_def = {
71 EEPROM_MB_CLK, EEPROM_MB_CS,
72 EEPROM_MB_DIN, EEPROM_MB_DOUT,
73 };
74
75 /* Mainboard EEPROM */
76 static const struct nmc93cX6_group eeprom_mb_group = {
77 EEPROM_TYPE_NMC93C46, 1, 0, "Mainboard EEPROM", 0, { &eeprom_mb_def },
78 };
79
80 /* NM EEPROM definition */
81 static const struct nmc93cX6_eeprom_def eeprom_nm_def = {
82 EEPROM_NM_CLK, EEPROM_NM_CS,
83 EEPROM_NM_DIN, EEPROM_NM_DOUT,
84 };
85
86 /* NM EEPROM */
87 static const struct nmc93cX6_group eeprom_nm_group = {
88 EEPROM_TYPE_NMC93C46, 1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
89 };
90
91 /* 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 /*
132 * dev_c3725_iofpga_access()
133 */
134 static void *
135 dev_c3725_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
136 m_uint32_t offset,u_int op_size,u_int op_type,
137 m_uint64_t *data)
138 {
139 struct c3725_iofpga_data *d = dev->priv_data;
140
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 offset,cpu_get_pc(cpu),op_size);
148 } else {
149 cpu_log(cpu,"IO_FPGA",
150 "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
151 offset,cpu_get_pc(cpu),*data,op_size);
152 }
153 #endif
154
155 switch(offset) {
156 /*
157 * Platform type ?
158 * 0x04 and 0x05 seem to work.
159 */
160 case 0x36:
161 if (op_type == MTS_READ)
162 *data = 0x04 << 5;
163 break;
164
165 /* Mainboard EEPROM */
166 case 0x0e:
167 if (op_type == MTS_WRITE)
168 nmc93cX6_write(&d->router->mb_eeprom_group,(u_int)(*data));
169 else
170 *data = nmc93cX6_read(&d->router->mb_eeprom_group);
171 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 nmc93cX6_write(&d->router->nm_eeprom_group[0],(u_int)(*data));
207 else
208 *data = nmc93cX6_read(&d->router->nm_eeprom_group[0]);
209 break;
210
211 /* NM Slot 2 EEPROM */
212 case 0x46:
213 if (op_type == MTS_WRITE)
214 nmc93cX6_write(&d->router->nm_eeprom_group[1],(u_int)(*data));
215 else
216 *data = nmc93cX6_read(&d->router->nm_eeprom_group[1]);
217 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 *data = d->net_irq_status[0];
271 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 if (op_type == MTS_READ)
282 *data = d->net_irq_status[1];
283 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 offset,cpu_get_pc(cpu),op_size);
337 } else {
338 cpu_log(cpu,"IO_FPGA",
339 "write to unknown addr 0x%x, value=0x%llx, "
340 "pc=0x%llx (size=%u)\n",
341 offset,*data,cpu_get_pc(cpu),op_size);
342 }
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 static void
369 dev_c3725_iofpga_shutdown(vm_instance_t *vm,struct c3725_iofpga_data *d)
370 {
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 struct c3725_iofpga_data *d;
387
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 d->net_irq_status[0] = 0xFFFF;
397 d->net_irq_status[1] = 0xFFFF;
398
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