/[dynamips]/upstream/dynamips-0.2.6-RC3/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.6-RC3/dev_c3745_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Sat Oct 6 16:06:49 2007 UTC (12 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 9518 byte(s)
dynamips-0.2.6-RC3

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

  ViewVC Help
Powered by ViewVC 1.1.26