/[dynamips]/upstream/dynamips-0.2.7-RC2/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-RC2/dev_pa_mc8te1.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: 8754 byte(s)
dynamips-0.2.7-RC2

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

  ViewVC Help
Powered by ViewVC 1.1.26