/[dynamips]/upstream/dynamips-0.2.7-RC1/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-RC1/dev_c3745_iofpga.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 9583 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26