1 |
/* |
/* |
2 |
* Cisco C7200 (Predator) Simulation Platform. |
* Cisco router simulation platform. |
3 |
* Copyright (C) 2005-2006 Christophe Fillot. All rights reserved. |
* Copyright (C) 2005-2006 Christophe Fillot. All rights reserved. |
4 |
* |
* |
5 |
* PA-MC-8TE1 card. Doesn't work at this time. |
* PA-MC-8TE1 card. Doesn't work at this time. |
13 |
#include <pthread.h> |
#include <pthread.h> |
14 |
#include <assert.h> |
#include <assert.h> |
15 |
|
|
16 |
#include "mips64.h" |
#include "cpu.h" |
17 |
|
#include "vm.h" |
18 |
#include "dynamips.h" |
#include "dynamips.h" |
19 |
#include "memory.h" |
#include "memory.h" |
20 |
#include "device.h" |
#include "device.h" |
37 |
/* PA-MC-8TE1 Data */ |
/* PA-MC-8TE1 Data */ |
38 |
struct pa_mc_data { |
struct pa_mc_data { |
39 |
char *name; |
char *name; |
40 |
|
u_int irq; |
41 |
|
|
42 |
/* Virtual machine */ |
/* Virtual machine */ |
43 |
vm_instance_t *vm; |
vm_instance_t *vm; |
52 |
m_uint8_t ssram_data[0x20000]; |
m_uint8_t ssram_data[0x20000]; |
53 |
|
|
54 |
/* PLX9054 */ |
/* PLX9054 */ |
55 |
|
char *plx_name; |
56 |
vm_obj_t *plx_obj; |
vm_obj_t *plx_obj; |
57 |
|
|
58 |
/* NetIO descriptor */ |
/* NetIO descriptor */ |
68 |
/* |
/* |
69 |
* dev_ssram_access |
* dev_ssram_access |
70 |
*/ |
*/ |
71 |
static void *dev_ssram_access(cpu_mips_t *cpu,struct vdevice *dev, |
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, |
m_uint32_t offset,u_int op_size,u_int op_type, |
73 |
m_uint64_t *data) |
m_uint64_t *data) |
74 |
{ |
{ |
84 |
if (op_type == MTS_READ) { |
if (op_type == MTS_READ) { |
85 |
cpu_log(cpu,d->name, |
cpu_log(cpu,d->name, |
86 |
"read access to offset = 0x%x, pc = 0x%llx (size=%u)\n", |
"read access to offset = 0x%x, pc = 0x%llx (size=%u)\n", |
87 |
offset,cpu->pc,op_size); |
offset,cpu_get_pc(cpu),op_size); |
88 |
} else { |
} else { |
89 |
cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, " |
cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, " |
90 |
"val = 0x%llx (size=%u)\n",offset,cpu->pc,*data,op_size); |
"val = 0x%llx (size=%u)\n", |
91 |
|
offset,cpu_get_pc(cpu),*data,op_size); |
92 |
} |
} |
93 |
#endif |
#endif |
94 |
|
|
137 |
printf("DOORBELL: 0x%x\n",val); |
printf("DOORBELL: 0x%x\n",val); |
138 |
|
|
139 |
/* Trigger interrupt */ |
/* Trigger interrupt */ |
140 |
vm_set_irq(pa_data->vm,2); |
//vm_set_irq(pa_data->vm,pa_data->irq); |
141 |
vm_set_irq(pa_data->vm,3); |
vm_set_irq(pa_data->vm,3); |
142 |
} |
} |
143 |
|
|
144 |
/* |
/* |
145 |
* pa_mc8te1_access() |
* pa_mc8te1_access() |
146 |
*/ |
*/ |
147 |
static void *pa_mc8te1_access(cpu_mips_t *cpu,struct vdevice *dev, |
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, |
m_uint32_t offset,u_int op_size,u_int op_type, |
149 |
m_uint64_t *data) |
m_uint64_t *data) |
150 |
{ |
{ |
156 |
#if DEBUG_ACCESS |
#if DEBUG_ACCESS |
157 |
if (op_type == MTS_READ) { |
if (op_type == MTS_READ) { |
158 |
cpu_log(cpu,d->name,"read access to offset = 0x%x, pc = 0x%llx\n", |
cpu_log(cpu,d->name,"read access to offset = 0x%x, pc = 0x%llx\n", |
159 |
offset,cpu->pc); |
offset,cpu_get_pc(cpu)); |
160 |
} else { |
} else { |
161 |
cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, " |
cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, " |
162 |
"val = 0x%llx\n",offset,cpu->pc,*data); |
"val = 0x%llx\n",offset,cpu_get_pc(cpu),*data); |
163 |
} |
} |
164 |
#endif |
#endif |
165 |
|
|
170 |
if (op_type == MTS_READ) { |
if (op_type == MTS_READ) { |
171 |
cpu_log(cpu,d->name, |
cpu_log(cpu,d->name, |
172 |
"read from unknown addr 0x%x, pc=0x%llx (size=%u)\n", |
"read from unknown addr 0x%x, pc=0x%llx (size=%u)\n", |
173 |
offset,cpu->pc,op_size); |
offset,cpu_get_pc(cpu),op_size); |
174 |
} else { |
} else { |
175 |
cpu_log(cpu,d->name, |
cpu_log(cpu,d->name, |
176 |
"write to unknown addr 0x%x, value=0x%llx, " |
"write to unknown addr 0x%x, value=0x%llx, " |
177 |
"pc=0x%llx (size=%u)\n",offset,*data,cpu->pc,op_size); |
"pc=0x%llx (size=%u)\n", |
178 |
|
offset,*data,cpu_get_pc(cpu),op_size); |
179 |
} |
} |
180 |
#endif |
#endif |
181 |
} |
} |
186 |
/* |
/* |
187 |
* pci_pos_read() |
* pci_pos_read() |
188 |
*/ |
*/ |
189 |
static m_uint32_t pci_pos_read(cpu_mips_t *cpu,struct pci_device *dev,int reg) |
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; |
struct pa_mc_data *d = dev->priv_data; |
192 |
|
|
205 |
/* |
/* |
206 |
* pci_pos_write() |
* pci_pos_write() |
207 |
*/ |
*/ |
208 |
static void pci_pos_write(cpu_mips_t *cpu,struct pci_device *dev, |
static void pci_pos_write(cpu_gen_t *cpu,struct pci_device *dev, |
209 |
int reg,m_uint32_t value) |
int reg,m_uint32_t value) |
210 |
{ |
{ |
211 |
struct pa_mc_data *d = dev->priv_data; |
struct pa_mc_data *d = dev->priv_data; |
227 |
* |
* |
228 |
* Add a PA-MC-8TE1 port adapter into specified slot. |
* 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) |
int dev_c7200_pa_mc8te1_init(vm_instance_t *vm,struct cisco_card *card) |
231 |
{ |
{ |
232 |
struct pa_mc_data *d; |
struct pa_mc_data *d; |
233 |
|
u_int slot = card->slot_id; |
234 |
|
|
235 |
/* Allocate the private data structure for PA-MC-8TE1 chip */ |
/* Allocate the private data structure for PA-MC-8TE1 chip */ |
236 |
if (!(d = malloc(sizeof(*d)))) { |
if (!(d = malloc(sizeof(*d)))) { |
237 |
fprintf(stderr,"%s (PA-MC-8TE1): out of memory\n",name); |
vm_error(vm,"%s: out of memory\n",card->dev_name); |
238 |
return(-1); |
return(-1); |
239 |
} |
} |
240 |
|
|
241 |
memset(d,0,sizeof(*d)); |
memset(d,0,sizeof(*d)); |
242 |
d->name = name; |
d->name = card->dev_name; |
243 |
d->vm = router->vm; |
d->vm = vm; |
244 |
|
d->irq = c7200_net_irq_for_slot_port(slot,0); |
245 |
|
|
246 |
|
/* Set the PCI bus */ |
247 |
|
card->pci_bus = vm->slots_pci_bus[slot]; |
248 |
|
|
249 |
/* Set the EEPROM */ |
/* Set the EEPROM */ |
250 |
c7200_pa_set_eeprom(router,pa_bay,cisco_eeprom_find_pa("PA-MC-8TE1")); |
cisco_card_set_eeprom(vm,card,cisco_eeprom_find_pa("PA-MC-8TE1")); |
251 |
|
c7200_set_slot_eeprom(VM_C7200(vm),slot,&card->eeprom); |
252 |
|
|
253 |
/* Create the PM7380 */ |
/* Create the PM7380 */ |
254 |
d->pci_dev = pci_dev_add(router->pa_bay[pa_bay].pci_map,name, |
d->pci_dev = pci_dev_add(card->pci_bus,card->dev_name, |
255 |
0x11f8, 0x7380, |
0x11f8, 0x7380, |
256 |
0,0,C7200_NETIO_IRQ,d, |
0,0,d->irq,d, |
257 |
NULL,pci_pos_read,pci_pos_write); |
NULL,pci_pos_read,pci_pos_write); |
258 |
|
|
259 |
/* Initialize SSRAM device */ |
/* Initialize SSRAM device */ |
260 |
d->ssram_name = dyn_sprintf("%s_ssram",name); |
d->ssram_name = dyn_sprintf("%s_ssram",card->dev_name); |
261 |
dev_init(&d->ssram_dev); |
dev_init(&d->ssram_dev); |
262 |
d->ssram_dev.name = d->ssram_name; |
d->ssram_dev.name = d->ssram_name; |
263 |
d->ssram_dev.priv_data = d; |
d->ssram_dev.priv_data = d; |
264 |
d->ssram_dev.handler = dev_ssram_access; |
d->ssram_dev.handler = dev_ssram_access; |
265 |
|
|
266 |
/* Create the PLX9054 */ |
/* Create the PLX9054 */ |
267 |
d->plx_obj = dev_plx9054_init(d->vm,d->name, |
d->plx_name = dyn_sprintf("%s_plx",card->dev_name); |
268 |
router->pa_bay[pa_bay].pci_map,1, |
d->plx_obj = dev_plx9054_init(vm,d->plx_name, |
269 |
|
card->pci_bus,1, |
270 |
&d->ssram_dev,NULL); |
&d->ssram_dev,NULL); |
271 |
|
|
272 |
/* Set callback function for PLX9054 PCI-To-Local doorbell */ |
/* Set callback function for PLX9054 PCI-To-Local doorbell */ |
276 |
d); |
d); |
277 |
|
|
278 |
/* Store device info into the router structure */ |
/* Store device info into the router structure */ |
279 |
return(c7200_pa_set_drvinfo(router,pa_bay,d)); |
card->drv_info = d; |
280 |
|
return(0); |
281 |
} |
} |
282 |
|
|
283 |
/* Remove a PA-POS-OC3 from the specified slot */ |
/* Remove a PA-POS-OC3 from the specified slot */ |
284 |
int dev_c7200_pa_mc8te1_shutdown(c7200_t *router,u_int pa_bay) |
int dev_c7200_pa_mc8te1_shutdown(vm_instance_t *vm,struct cisco_card *card) |
285 |
{ |
{ |
286 |
struct c7200_pa_bay *bay; |
struct pa_mc_data *d = card->drv_info; |
|
struct pa_mc_data *d; |
|
|
|
|
|
if (!(bay = c7200_pa_get_info(router,pa_bay))) |
|
|
return(-1); |
|
|
|
|
|
d = bay->drv_info; |
|
287 |
|
|
288 |
/* Remove the PA EEPROM */ |
/* Remove the PA EEPROM */ |
289 |
c7200_pa_unset_eeprom(router,pa_bay); |
cisco_card_unset_eeprom(card); |
290 |
|
c7200_set_slot_eeprom(VM_C7200(vm),card->slot_id,NULL); |
291 |
|
|
292 |
/* Remove the PCI device */ |
/* Remove the PCI device */ |
293 |
pci_dev_remove(d->pci_dev); |
pci_dev_remove(d->pci_dev); |
294 |
|
|
295 |
/* Remove the PLX9054 chip */ |
/* Remove the PLX9054 chip */ |
296 |
vm_object_remove(d->vm,d->plx_obj); |
vm_object_remove(vm,d->plx_obj); |
297 |
|
|
298 |
/* Remove the device from the CPU address space */ |
/* Remove the device from the CPU address space */ |
299 |
//vm_unbind_device(router->vm,&d->dev); |
//vm_unbind_device(vm,&d->dev); |
300 |
vm_unbind_device(router->vm,&d->ssram_dev); |
vm_unbind_device(vm,&d->ssram_dev); |
301 |
|
|
302 |
cpu_group_rebuild_mts(router->vm->cpu_group); |
cpu_group_rebuild_mts(vm->cpu_group); |
303 |
|
|
304 |
/* Free the device structure itself */ |
/* Free the device structure itself */ |
305 |
free(d); |
free(d); |
307 |
} |
} |
308 |
|
|
309 |
/* Bind a Network IO descriptor to a specific port */ |
/* Bind a Network IO descriptor to a specific port */ |
310 |
int dev_c7200_pa_mc8te1_set_nio(c7200_t *router,u_int pa_bay,u_int port_id, |
int dev_c7200_pa_mc8te1_set_nio(vm_instance_t *vm,struct cisco_card *card, |
311 |
netio_desc_t *nio) |
u_int port_id,netio_desc_t *nio) |
312 |
{ |
{ |
313 |
struct pa_mc_data *d; |
struct pa_mc_data *d = card->drv_info; |
314 |
|
|
315 |
if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay))) |
if (!d || (port_id > 0)) |
316 |
return(-1); |
return(-1); |
317 |
|
|
318 |
if (d->nio != NULL) |
if (d->nio != NULL) |
325 |
} |
} |
326 |
|
|
327 |
/* Bind a Network IO descriptor to a specific port */ |
/* Bind a Network IO descriptor to a specific port */ |
328 |
int dev_c7200_pa_mc8te1_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id) |
int dev_c7200_pa_mc8te1_unset_nio(vm_instance_t *vm,struct cisco_card *card, |
329 |
|
u_int port_id) |
330 |
{ |
{ |
331 |
struct pa_mc_data *d; |
struct pa_mc_data *d = card->drv_info; |
332 |
|
|
333 |
if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay))) |
if (!d || (port_id > 0)) |
334 |
return(-1); |
return(-1); |
335 |
|
|
336 |
if (d->nio) { |
if (d->nio) { |
342 |
} |
} |
343 |
|
|
344 |
/* PA-MC-8TE1 driver */ |
/* PA-MC-8TE1 driver */ |
345 |
struct c7200_pa_driver dev_c7200_pa_mc8te1_driver = { |
struct cisco_card_driver dev_c7200_pa_mc8te1_driver = { |
346 |
"PA-MC-8TE1", 0, |
"PA-MC-8TE1", 0, 0, |
347 |
dev_c7200_pa_mc8te1_init, |
dev_c7200_pa_mc8te1_init, |
348 |
dev_c7200_pa_mc8te1_shutdown, |
dev_c7200_pa_mc8te1_shutdown, |
349 |
|
NULL, |
350 |
dev_c7200_pa_mc8te1_set_nio, |
dev_c7200_pa_mc8te1_set_nio, |
351 |
dev_c7200_pa_mc8te1_unset_nio, |
dev_c7200_pa_mc8te1_unset_nio, |
352 |
NULL, |
NULL, |