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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
2 * Cisco router simulation platform.
3 * Copyright (C) 2005-2006 Christophe Fillot. All rights reserved.
4 *
5 * PA-MC-8TE1 card. Doesn't work at this time.
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <errno.h>
13 #include <pthread.h>
14 #include <assert.h>
15
16 #include "cpu.h"
17 #include "vm.h"
18 #include "dynamips.h"
19 #include "memory.h"
20 #include "device.h"
21 #include "net.h"
22 #include "net_io.h"
23 #include "ptask.h"
24 #include "dev_c7200.h"
25 #include "dev_plx.h"
26
27 /* Debugging flags */
28 #define DEBUG_ACCESS 1
29 #define DEBUG_UNKNOWN 1
30 #define DEBUG_TRANSMIT 1
31 #define DEBUG_RECEIVE 1
32
33 /* SSRAM */
34 #define SSRAM_START 0x10000
35 #define SSRAM_END 0x30000
36
37 /* PA-MC-8TE1 Data */
38 struct pa_mc_data {
39 char *name;
40
41 /* Virtual machine */
42 vm_instance_t *vm;
43
44 /* PCI device information */
45 struct vdevice dev;
46 struct pci_device *pci_dev;
47
48 /* SSRAM device */
49 struct vdevice ssram_dev;
50 char *ssram_name;
51 m_uint8_t ssram_data[0x20000];
52
53 /* PLX9054 */
54 vm_obj_t *plx_obj;
55
56 /* NetIO descriptor */
57 netio_desc_t *nio;
58
59 /* TX ring scanner task id */
60 ptask_id_t tx_tid;
61 };
62
63 /* Log a PA-MC-8TE1 message */
64 #define PA_MC_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
65
66 /*
67 * dev_ssram_access
68 */
69 static void *dev_ssram_access(cpu_gen_t *cpu,struct vdevice *dev,
70 m_uint32_t offset,u_int op_size,u_int op_type,
71 m_uint64_t *data)
72 {
73 struct pa_mc_data *d = dev->priv_data;
74
75 if (op_type == MTS_READ)
76 *data = 0;
77
78 if ((offset >= SSRAM_START) && (offset < SSRAM_END))
79 return(&d->ssram_data[offset-SSRAM_START]);
80
81 #if DEBUG_ACCESS
82 if (op_type == MTS_READ) {
83 cpu_log(cpu,d->name,
84 "read access to offset = 0x%x, pc = 0x%llx (size=%u)\n",
85 offset,cpu_get_pc(cpu),op_size);
86 } else {
87 cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
88 "val = 0x%llx (size=%u)\n",
89 offset,cpu_get_pc(cpu),*data,op_size);
90 }
91 #endif
92
93 switch(offset) {
94 case 0xfff0c:
95 if (op_type == MTS_READ)
96 *data = 0xdeadbeef;
97 break;
98
99 case 0xfff10:
100 if (op_type == MTS_READ)
101 *data = 0xbeeffeed;
102 break;
103
104 case 0x08: /* max_dsx1 */
105 case 0x10: /* no_buf */
106 case 0x18: /* ev */
107 if (op_type == MTS_READ)
108 *data = 0x0ULL;
109 break;
110
111 case 0x00: /* tx packets */
112 if (op_type == MTS_READ)
113 *data = 0x0;
114 break;
115
116 case 0x04: /* rx packets */
117 if (op_type == MTS_READ)
118 *data = 0x0;
119 break;
120
121 case 0x0c: /* rx drops */
122 if (op_type == MTS_READ)
123 *data = 0;
124 break;
125 }
126
127 return NULL;
128 }
129
130 /* Callback when PLX9054 PCI-to-Local register is written */
131 static void plx9054_doorbell_callback(struct plx_data *plx_data,
132 struct pa_mc_data *pa_data,
133 m_uint32_t val)
134 {
135 printf("DOORBELL: 0x%x\n",val);
136
137 /* Trigger interrupt */
138 vm_set_irq(pa_data->vm,2);
139 vm_set_irq(pa_data->vm,3);
140 }
141
142 /*
143 * pa_mc8te1_access()
144 */
145 static void *pa_mc8te1_access(cpu_gen_t *cpu,struct vdevice *dev,
146 m_uint32_t offset,u_int op_size,u_int op_type,
147 m_uint64_t *data)
148 {
149 struct pa_mc_data *d = dev->priv_data;
150
151 if (op_type == MTS_READ)
152 *data = 0;
153
154 #if DEBUG_ACCESS
155 if (op_type == MTS_READ) {
156 cpu_log(cpu,d->name,"read access to offset = 0x%x, pc = 0x%llx\n",
157 offset,cpu_get_pc(cpu));
158 } else {
159 cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
160 "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);
161 }
162 #endif
163
164 switch(offset) {
165
166 #if DEBUG_UNKNOWN
167 default:
168 if (op_type == MTS_READ) {
169 cpu_log(cpu,d->name,
170 "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",
171 offset,cpu_get_pc(cpu),op_size);
172 } else {
173 cpu_log(cpu,d->name,
174 "write to unknown addr 0x%x, value=0x%llx, "
175 "pc=0x%llx (size=%u)\n",
176 offset,*data,cpu_get_pc(cpu),op_size);
177 }
178 #endif
179 }
180
181 return NULL;
182 }
183
184 /*
185 * pci_pos_read()
186 */
187 static m_uint32_t pci_pos_read(cpu_gen_t *cpu,struct pci_device *dev,int reg)
188 {
189 struct pa_mc_data *d = dev->priv_data;
190
191 #if DEBUG_ACCESS
192 PA_MC_LOG(d,"read PCI register 0x%x\n",reg);
193 #endif
194
195 switch(reg) {
196 case PCI_REG_BAR0:
197 return(d->dev.phys_addr);
198 default:
199 return(0);
200 }
201 }
202
203 /*
204 * pci_pos_write()
205 */
206 static void pci_pos_write(cpu_gen_t *cpu,struct pci_device *dev,
207 int reg,m_uint32_t value)
208 {
209 struct pa_mc_data *d = dev->priv_data;
210
211 #if DEBUG_ACCESS
212 PA_MC_LOG(d,"write 0x%x to PCI register 0x%x\n",value,reg);
213 #endif
214
215 switch(reg) {
216 case PCI_REG_BAR0:
217 //vm_map_device(cpu->vm,&d->dev,(m_uint64_t)value);
218 PA_MC_LOG(d,"registers are mapped at 0x%x\n",value);
219 break;
220 }
221 }
222
223 /*
224 * dev_c7200_pa_mc8te1_init()
225 *
226 * Add a PA-MC-8TE1 port adapter into specified slot.
227 */
228 int dev_c7200_pa_mc8te1_init(c7200_t *router,char *name,u_int pa_bay)
229 {
230 struct pa_mc_data *d;
231
232 /* Allocate the private data structure for PA-MC-8TE1 chip */
233 if (!(d = malloc(sizeof(*d)))) {
234 fprintf(stderr,"%s (PA-MC-8TE1): out of memory\n",name);
235 return(-1);
236 }
237
238 memset(d,0,sizeof(*d));
239 d->name = name;
240 d->vm = router->vm;
241
242 /* Set the EEPROM */
243 c7200_pa_set_eeprom(router,pa_bay,cisco_eeprom_find_pa("PA-MC-8TE1"));
244
245 /* Create the PM7380 */
246 d->pci_dev = pci_dev_add(router->pa_bay[pa_bay].pci_map,name,
247 0x11f8, 0x7380,
248 0,0,C7200_NETIO_IRQ,d,
249 NULL,pci_pos_read,pci_pos_write);
250
251 /* Initialize SSRAM device */
252 d->ssram_name = dyn_sprintf("%s_ssram",name);
253 dev_init(&d->ssram_dev);
254 d->ssram_dev.name = d->ssram_name;
255 d->ssram_dev.priv_data = d;
256 d->ssram_dev.handler = dev_ssram_access;
257
258 /* Create the PLX9054 */
259 d->plx_obj = dev_plx9054_init(d->vm,d->name,
260 router->pa_bay[pa_bay].pci_map,1,
261 &d->ssram_dev,NULL);
262
263 /* Set callback function for PLX9054 PCI-To-Local doorbell */
264 dev_plx_set_pci2loc_doorbell_cbk(d->plx_obj->data,
265 (dev_plx_doorbell_cbk)
266 plx9054_doorbell_callback,
267 d);
268
269 /* Store device info into the router structure */
270 return(c7200_pa_set_drvinfo(router,pa_bay,d));
271 }
272
273 /* Remove a PA-POS-OC3 from the specified slot */
274 int dev_c7200_pa_mc8te1_shutdown(c7200_t *router,u_int pa_bay)
275 {
276 struct c7200_pa_bay *bay;
277 struct pa_mc_data *d;
278
279 if (!(bay = c7200_pa_get_info(router,pa_bay)))
280 return(-1);
281
282 d = bay->drv_info;
283
284 /* Remove the PA EEPROM */
285 c7200_pa_unset_eeprom(router,pa_bay);
286
287 /* Remove the PCI device */
288 pci_dev_remove(d->pci_dev);
289
290 /* Remove the PLX9054 chip */
291 vm_object_remove(d->vm,d->plx_obj);
292
293 /* Remove the device from the CPU address space */
294 //vm_unbind_device(router->vm,&d->dev);
295 vm_unbind_device(router->vm,&d->ssram_dev);
296
297 cpu_group_rebuild_mts(router->vm->cpu_group);
298
299 /* Free the device structure itself */
300 free(d);
301 return(0);
302 }
303
304 /* Bind a Network IO descriptor to a specific port */
305 int dev_c7200_pa_mc8te1_set_nio(c7200_t *router,u_int pa_bay,u_int port_id,
306 netio_desc_t *nio)
307 {
308 struct pa_mc_data *d;
309
310 if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))
311 return(-1);
312
313 if (d->nio != NULL)
314 return(-1);
315
316 d->nio = nio;
317 //d->tx_tid = ptask_add((ptask_callback)dev_pos_oc3_handle_txring,d,NULL);
318 //netio_rxl_add(nio,(netio_rx_handler_t)dev_pos_oc3_handle_rxring,d,NULL);
319 return(0);
320 }
321
322 /* Bind a Network IO descriptor to a specific port */
323 int dev_c7200_pa_mc8te1_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id)
324 {
325 struct pa_mc_data *d;
326
327 if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))
328 return(-1);
329
330 if (d->nio) {
331 ptask_remove(d->tx_tid);
332 netio_rxl_remove(d->nio);
333 d->nio = NULL;
334 }
335 return(0);
336 }
337
338 /* PA-MC-8TE1 driver */
339 struct c7200_pa_driver dev_c7200_pa_mc8te1_driver = {
340 "PA-MC-8TE1", 0,
341 dev_c7200_pa_mc8te1_init,
342 dev_c7200_pa_mc8te1_shutdown,
343 dev_c7200_pa_mc8te1_set_nio,
344 dev_c7200_pa_mc8te1_unset_nio,
345 NULL,
346 };

  ViewVC Help
Powered by ViewVC 1.1.26