--- upstream/dynamips-0.2.7-RC1/dev_c2691.c 2007/10/06 16:23:47 7 +++ upstream/dynamips-0.2.7-RC3/dev_c2691.c 2007/10/06 16:26:06 9 @@ -1,5 +1,5 @@ /* - * Cisco 2691 simulation platform. + * Cisco router simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 2691 routines and definitions (EEPROM,...). @@ -22,6 +22,7 @@ #include "cisco_eeprom.h" #include "dev_rom.h" #include "dev_c2691.h" +#include "dev_c2691_iofpga.h" #include "dev_vtty.h" #include "registry.h" @@ -330,6 +331,26 @@ registry_foreach_type(OBJ_TYPE_VM,c2691_reg_save_config,fd,NULL); } +/* Get slot/port corresponding to specified network IRQ */ +static inline void +c2691_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port) +{ + irq -= C2691_NETIO_IRQ_BASE; + *port = irq & C2691_NETIO_IRQ_PORT_MASK; + *slot = irq >> C2691_NETIO_IRQ_PORT_BITS; +} + +/* Get network IRQ for specified slot/port */ +u_int c2691_net_irq_for_slot_port(u_int slot,u_int port) +{ + u_int irq; + + irq = (slot << C2691_NETIO_IRQ_PORT_BITS) + port; + irq += C2691_NETIO_IRQ_BASE; + + return(irq); +} + /* Set NM EEPROM definition */ int c2691_nm_set_eeprom(c2691_t *router,u_int nm_bay, const struct cisco_eeprom *eeprom) @@ -686,7 +707,7 @@ snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,nm_bay); /* Initialize NM driver */ - if (bay->nm_driver->nm_init(router,bay->dev_name,nm_bay) == 1) { + if (bay->nm_driver->nm_init(router,bay->dev_name,nm_bay) == -1) { vm_error(router->vm,"unable to initialize NM %u.\n",nm_bay); return(-1); } @@ -1009,7 +1030,7 @@ } return(dev_gt96100_init(vm,"gt96100",C2691_GT96K_ADDR,0x200000, - C2691_GT96K_IRQ,C2691_NETIO_IRQ)); + C2691_GT96K_IRQ,c2691_net_irq_for_slot_port(0,0))); } /* Initialize a Cisco 2691 */ @@ -1146,6 +1167,11 @@ if (dev_c2691_iofpga_init(router,C2691_IOFPGA_ADDR,0x40000) == -1) return(-1); + if (!(obj = vm_object_find(router->vm,"io_fpga"))) + return(-1); + + router->iofpga_data = obj->data; + #if 0 /* PCI IO space */ if (!(vm->pci_io_space = pci_io_data_init(vm,C2691_PCI_IO_ADDR))) @@ -1250,6 +1276,47 @@ return(0); } +/* Set an IRQ */ +static void c2691_set_irq(vm_instance_t *vm,u_int irq) +{ + c2691_t *router = VM_C2691(vm); + cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu); + u_int slot,port; + + switch(irq) { + case 0 ... 7: + mips64_set_irq(cpu0,irq); + + if (cpu0->irq_idle_preempt[irq]) + cpu_idle_break_wait(cpu0->gen); + break; + + case C2691_NETIO_IRQ_BASE ... C2691_NETIO_IRQ_END: + c2691_net_irq_get_slot_port(irq,&slot,&port); + dev_c2691_iofpga_net_set_irq(router->iofpga_data,slot,port); + break; + } +} + +/* Clear an IRQ */ +static void c2691_clear_irq(vm_instance_t *vm,u_int irq) +{ + c2691_t *router = VM_C2691(vm); + cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu); + u_int slot,port; + + switch(irq) { + case 0 ... 7: + mips64_clear_irq(cpu0,irq); + break; + + case C2691_NETIO_IRQ_BASE ... C2691_NETIO_IRQ_END: + c2691_net_irq_get_slot_port(irq,&slot,&port); + dev_c2691_iofpga_net_clear_irq(router->iofpga_data,slot,port); + break; + } +} + /* Initialize a Cisco 2691 instance */ int c2691_init_instance(c2691_t *router) { @@ -1268,6 +1335,10 @@ return(-1); } + /* IRQ routing */ + vm->set_irq = c2691_set_irq; + vm->clear_irq = c2691_clear_irq; + /* Load IOS configuration file */ if (vm->ios_config != NULL) { vm_nvram_push_config(vm,vm->ios_config);