/[dynamips]/upstream/dynamips-0.2.7-RC2/dev_c3745_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_c3745_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: 11116 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco 3745 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_c3745.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 Motherboard EEPROM (0x00) */
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 I/O board EEPROM (0x01) */
39 #define EEPROM_IO_DOUT 3
40 #define EEPROM_IO_DIN 2
41 #define EEPROM_IO_CLK 1
42 #define EEPROM_IO_CS 8
43
44 /* Definitions for Midplane EEPROM (0x02) */
45 #define EEPROM_MP_DOUT 3
46 #define EEPROM_MP_DIN 2
47 #define EEPROM_MP_CLK 1
48 #define EEPROM_MP_CS 9
49
50 /* Definitions for Network Modules EEPROM */
51 #define EEPROM_NM_DOUT 7
52 #define EEPROM_NM_DIN 6
53 #define EEPROM_NM_CLK 2
54 #define EEPROM_NM_CS 4
55
56 /* Network IRQ distribution */
57 struct net_irq_distrib {
58 u_int reg;
59 u_int offset;
60 };
61
62 static struct net_irq_distrib net_irq_dist[C3745_MAX_NM_BAYS] = {
63 { 0, 0 }, /* Slot 0: reg 0x20, 0x00XX */
64 { 1, 0 }, /* Slot 1: reg 0x22, 0x000X */
65 { 1, 4 }, /* Slot 2: reg 0x22, 0x00X0 */
66 { 1, 8 }, /* Slot 3: reg 0x22, 0x0X00 */
67 { 1, 12 }, /* Slot 4: reg 0x22, 0xX000 */
68 };
69
70 /* IO FPGA structure */
71 struct c3745_iofpga_data {
72 vm_obj_t vm_obj;
73 struct vdevice dev;
74 c3745_t *router;
75
76 /* Network IRQ status */
77 m_uint16_t net_irq_status[2];
78
79 /* Interrupt mask */
80 m_uint16_t intr_mask,io_mask2;
81
82 /* EEPROM select */
83 u_int eeprom_select;
84 };
85
86 /* Motherboard EEPROM definition */
87 static const struct nmc93cX6_eeprom_def eeprom_mb_def = {
88 EEPROM_MB_CLK, EEPROM_MB_CS,
89 EEPROM_MB_DIN, EEPROM_MB_DOUT,
90 };
91
92 /* I/O board EEPROM definition */
93 static const struct nmc93cX6_eeprom_def eeprom_io_def = {
94 EEPROM_IO_CLK, EEPROM_IO_CS,
95 EEPROM_IO_DIN, EEPROM_IO_DOUT,
96 };
97
98 /* Midplane EEPROM definition */
99 static const struct nmc93cX6_eeprom_def eeprom_mp_def = {
100 EEPROM_MP_CLK, EEPROM_MP_CS,
101 EEPROM_MP_DIN, EEPROM_MP_DOUT,
102 };
103
104 /* System EEPROM group */
105 static const struct nmc93cX6_group eeprom_sys_group = {
106 EEPROM_TYPE_NMC93C46, 3, 0, "System EEPROM", 0,
107 { &eeprom_mb_def, &eeprom_io_def, &eeprom_mp_def },
108 };
109
110 /* NM EEPROM definition */
111 static const struct nmc93cX6_eeprom_def eeprom_nm_def = {
112 EEPROM_NM_CLK, EEPROM_NM_CS,
113 EEPROM_NM_DIN, EEPROM_NM_DOUT,
114 };
115
116 /* NM EEPROM */
117 static const struct nmc93cX6_group eeprom_nm_group = {
118 EEPROM_TYPE_NMC93C46, 1, 0, "NM EEPROM", 0, { &eeprom_nm_def },
119 };
120
121 /* Update network interrupt status */
122 static inline void dev_c3745_iofpga_net_update_irq(struct c3745_iofpga_data *d)
123 {
124 if ((d->net_irq_status[0] != 0xFFFF) || (d->net_irq_status[1] != 0xFFFF)) {
125 vm_set_irq(d->router->vm,C3745_NETIO_IRQ);
126 } else {
127 vm_clear_irq(d->router->vm,C3745_NETIO_IRQ);
128 }
129 }
130
131 /* Trigger a Network IRQ for the specified slot/port */
132 void dev_c3745_iofpga_net_set_irq(struct c3745_iofpga_data *d,
133 u_int slot,u_int port)
134 {
135 struct net_irq_distrib *irq_dist;
136
137 #if DEBUG_NET_IRQ
138 vm_log(d->router->vm,"IO_FPGA","setting NetIRQ for slot %u port %u\n",
139 slot,port);
140 #endif
141 irq_dist = &net_irq_dist[slot];
142 d->net_irq_status[irq_dist->reg] &= ~(1 << (irq_dist->offset + port));
143 dev_c3745_iofpga_net_update_irq(d);
144 }
145
146 /* Clear a Network IRQ for the specified slot/port */
147 void dev_c3745_iofpga_net_clear_irq(struct c3745_iofpga_data *d,
148 u_int slot,u_int port)
149 {
150 struct net_irq_distrib *irq_dist;
151
152 #if DEBUG_NET_IRQ
153 vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
154 slot,port);
155 #endif
156 irq_dist = &net_irq_dist[slot];
157 d->net_irq_status[irq_dist->reg] |= (1 << (irq_dist->offset + port));
158 dev_c3745_iofpga_net_update_irq(d);
159 }
160
161 /*
162 * dev_c3745_iofpga_access()
163 */
164 static void *
165 dev_c3745_iofpga_access(cpu_gen_t *cpu,struct vdevice *dev,
166 m_uint32_t offset,u_int op_size,u_int op_type,
167 m_uint64_t *data)
168 {
169 struct c3745_iofpga_data *d = dev->priv_data;
170 u_int slot;
171
172 if (op_type == MTS_READ)
173 *data = 0x0;
174
175 #if DEBUG_ACCESS
176 if (op_type == MTS_READ) {
177 cpu_log(cpu,"IO_FPGA","reading reg 0x%x at pc=0x%llx (size=%u)\n",
178 offset,cpu_get_pc(cpu),op_size);
179 } else {
180 cpu_log(cpu,"IO_FPGA",
181 "writing reg 0x%x at pc=0x%llx, data=0x%llx (size=%u)\n",
182 offset,cpu_get_pc(cpu),*data,op_size);
183 }
184 #endif
185
186 switch(offset) {
187 /* Unknown */
188 case 0x000000:
189 if (op_type == MTS_READ)
190 *data = 0xFFFF;
191 break;
192
193 /* Unknown */
194 case 0x000004:
195 if (op_type == MTS_READ)
196 *data = 0xFFFF;
197 break;
198
199 /*
200 * CompactFlash.
201 *
202 * Bit 0: Slot0 Compact Flash presence.
203 * Bit 1: System Compact Flash presence.
204 */
205 case 0x000012:
206 if (op_type == MTS_READ) {
207 *data = 0xFFFF;
208
209 /* System Flash ? */
210 if (cpu->vm->pcmcia_disk_size[0])
211 *data &= ~0x02;
212
213 /* Slot0 Flash ? */
214 if (cpu->vm->pcmcia_disk_size[1])
215 *data &= ~0x01;
216 }
217 break;
218
219 /* Suppress the "****TDM FPGA download failed.." message */
220 case 0x000014:
221 if (op_type == MTS_READ)
222 *data = 0x00FF;
223 break;
224
225 /* Power supply status */
226 case 0x00000a:
227 if (op_type == MTS_READ)
228 *data = 0x0000;
229 break;
230
231 /* Fan status */
232 case 0x00000c:
233 if (op_type == MTS_READ)
234 *data = 0x0000;
235 break;
236
237 /* System EEPROMs */
238 case 0x00000e:
239 if (op_type == MTS_WRITE)
240 nmc93cX6_write(&d->router->sys_eeprom_group,(u_int)(*data));
241 else
242 *data = nmc93cX6_read(&d->router->sys_eeprom_group);
243 break;
244
245 /*
246 * Network interrupt status.
247 *
248 * Bit 0: 0 = GT96100 Ethernet ports.
249 * Bit 8: 0 = AIM slot 0.
250 * Bit 9: 0 = AIM slot 1.
251 */
252 case 0x000020:
253 if (op_type == MTS_READ)
254 *data = d->net_irq_status[0];
255 break;
256
257 /*
258 * Network interrupt status.
259 *
260 * Bit 0: 0 = Interrupt for slot 1
261 * Bit 4: 0 = Interrupt for slot 2
262 * Bit 8: 0 = Interrupt for slot 3
263 * Bit 12: 0 = Interrupt for slot 4
264 */
265 case 0x000022:
266 if (op_type == MTS_READ)
267 *data = d->net_irq_status[1];
268 break;
269
270 /*
271 * Per Slot Intr Mask (seen with "sh platform").
272 * IO Mask 1 is the lower 8-bits.
273 */
274 case 0x00002a:
275 if (op_type == MTS_READ)
276 *data = d->intr_mask;
277 else
278 d->intr_mask = *data;
279 break;
280
281 /* IO Mask 2 (seen with "sh platform") */
282 case 0x00002c:
283 if (op_type == MTS_READ)
284 *data = d->io_mask2;
285 else
286 d->io_mask2 = *data;
287 break;
288
289 /* EEPROM in slots 1-4 */
290 case 0x000040:
291 case 0x000042:
292 case 0x000044:
293 case 0x000046:
294 slot = (offset - 0x000040) >> 1;
295
296 if (op_type == MTS_WRITE)
297 nmc93cX6_write(&d->router->nm_eeprom_group[slot],(u_int)(*data));
298 else
299 *data = nmc93cX6_read(&d->router->nm_eeprom_group[slot]);
300 break;
301
302 /* AIM slot 0 EEPROM */
303 case 0x000048:
304 if (op_type == MTS_READ)
305 *data = 0xFFFF;
306 break;
307
308 /* AIM slot 1 EEPROM */
309 case 0x00004A:
310 if (op_type == MTS_READ)
311 *data = 0xFFFF;
312 break;
313
314 /*
315 * NM presence.
316 *
317 * Bit 0: 0 = NM present in slot 2 (0x42)
318 * Bit 4: 0 = NM present in slot 4 (0x46)
319 * Bit 8: 0 = NM present in slot 1 (0x40)
320 * Bit 12: 0 = NM present in slot 3 (0x44)
321 */
322 case 0x00004e:
323 if (op_type == MTS_READ) {
324 *data = 0xFFFF;
325
326 if (c3745_nm_check_eeprom(d->router,1))
327 *data &= ~0x0100;
328
329 if (c3745_nm_check_eeprom(d->router,2))
330 *data &= ~0x0001;
331
332 if (c3745_nm_check_eeprom(d->router,3))
333 *data &= ~0x1000;
334
335 if (c3745_nm_check_eeprom(d->router,4))
336 *data &= ~0x0010;
337 }
338 break;
339
340 /* VWIC/WIC related */
341 case 0x100004:
342 case 0x100006:
343 case 0x100008:
344 if (op_type == MTS_READ)
345 *data = 0xFFFF;
346 break;
347
348 #if DEBUG_UNKNOWN
349 default:
350 if (op_type == MTS_READ) {
351 cpu_log(cpu,"IO_FPGA",
352 "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
353 offset,cpu_get_pc(cpu),op_size);
354 } else {
355 cpu_log(cpu,"IO_FPGA",
356 "write to unknown addr 0x%x, value=0x%llx, "
357 "pc=0x%llx (size=%u)\n",
358 offset,*data,cpu_get_pc(cpu),op_size);
359 }
360 #endif
361 }
362
363 return NULL;
364 }
365
366 /* Initialize EEPROM groups */
367 void c3745_init_eeprom_groups(c3745_t *router)
368 {
369 int i;
370
371 /* Initialize Mainboard EEPROM */
372 router->sys_eeprom_group = eeprom_sys_group;
373
374 for(i=0;i<3;i++) {
375 router->sys_eeprom_group.eeprom[i] = &router->sys_eeprom[i];
376 router->sys_eeprom[i].data = NULL;
377 router->sys_eeprom[i].len = 0;
378 }
379
380 /* EEPROMs for Network Modules */
381 for(i=1;i<=4;i++) {
382 router->nm_eeprom_group[i-1] = eeprom_nm_group;
383 router->nm_eeprom_group[i-1].eeprom[0] = &router->nm_bay[i].eeprom;
384 }
385 }
386
387 /* Shutdown the IO FPGA device */
388 static void
389 dev_c3745_iofpga_shutdown(vm_instance_t *vm,struct c3745_iofpga_data *d)
390 {
391 if (d != NULL) {
392 /* Remove the device */
393 dev_remove(vm,&d->dev);
394
395 /* Free the structure itself */
396 free(d);
397 }
398 }
399
400 /*
401 * dev_c3745_iofpga_init()
402 */
403 int dev_c3745_iofpga_init(c3745_t *router,m_uint64_t paddr,m_uint32_t len)
404 {
405 vm_instance_t *vm = router->vm;
406 struct c3745_iofpga_data *d;
407
408 /* Allocate private data structure */
409 if (!(d = malloc(sizeof(*d)))) {
410 fprintf(stderr,"IO_FPGA: out of memory\n");
411 return(-1);
412 }
413
414 memset(d,0,sizeof(*d));
415 d->router = router;
416 d->net_irq_status[0] = 0xFFFF;
417 d->net_irq_status[1] = 0xFFFF;
418
419 vm_object_init(&d->vm_obj);
420 d->vm_obj.name = "io_fpga";
421 d->vm_obj.data = d;
422 d->vm_obj.shutdown = (vm_shutdown_t)dev_c3745_iofpga_shutdown;
423
424 /* Set device properties */
425 dev_init(&d->dev);
426 d->dev.name = "io_fpga";
427 d->dev.phys_addr = paddr;
428 d->dev.phys_len = len;
429 d->dev.priv_data = d;
430 d->dev.handler = dev_c3745_iofpga_access;
431
432 /* Map this device to the VM */
433 vm_bind_device(router->vm,&d->dev);
434 vm_object_add(vm,&d->vm_obj);
435 return(0);
436 }

  ViewVC Help
Powered by ViewVC 1.1.26