--- upstream/dynamips-0.2.7-RC1/dev_c3745.c 2007/10/06 16:23:47 7 +++ upstream/dynamips-0.2.7-RC2/dev_c3745.c 2007/10/06 16:24:54 8 @@ -22,6 +22,7 @@ #include "cisco_eeprom.h" #include "dev_rom.h" #include "dev_c3745.h" +#include "dev_c3745_iofpga.h" #include "dev_vtty.h" #include "registry.h" @@ -368,6 +369,26 @@ registry_foreach_type(OBJ_TYPE_VM,c3745_reg_save_config,fd,NULL); } +/* Get slot/port corresponding to specified network IRQ */ +static inline void +c3745_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port) +{ + irq -= C3745_NETIO_IRQ_BASE; + *port = irq & C3745_NETIO_IRQ_PORT_MASK; + *slot = irq >> C3745_NETIO_IRQ_PORT_BITS; +} + +/* Get network IRQ for specified slot/port */ +u_int c3745_net_irq_for_slot_port(u_int slot,u_int port) +{ + u_int irq; + + irq = (slot << C3745_NETIO_IRQ_PORT_BITS) + port; + irq += C3745_NETIO_IRQ_BASE; + + return(irq); +} + /* Set NM EEPROM definition */ int c3745_nm_set_eeprom(c3745_t *router,u_int nm_bay, const struct cisco_eeprom *eeprom) @@ -724,7 +745,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); } @@ -1049,7 +1070,7 @@ } return(dev_gt96100_init(vm,"gt96100",C3745_GT96K_ADDR,0x200000, - C3745_GT96K_IRQ,C3745_NETIO_IRQ)); + C3745_GT96K_IRQ,c3745_net_irq_for_slot_port(0,0))); } /* Initialize a Cisco 3745 */ @@ -1200,6 +1221,11 @@ if (dev_c3745_iofpga_init(router,C3745_IOFPGA_ADDR,0x200000) == -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,C3745_PCI_IO_ADDR))) @@ -1304,6 +1330,47 @@ return(0); } +/* Set an IRQ */ +static void c3745_set_irq(vm_instance_t *vm,u_int irq) +{ + c3745_t *router = VM_C3745(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 C3745_NETIO_IRQ_BASE ... C3745_NETIO_IRQ_END: + c3745_net_irq_get_slot_port(irq,&slot,&port); + dev_c3745_iofpga_net_set_irq(router->iofpga_data,slot,port); + break; + } +} + +/* Clear an IRQ */ +static void c3745_clear_irq(vm_instance_t *vm,u_int irq) +{ + c3745_t *router = VM_C3745(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 C3745_NETIO_IRQ_BASE ... C3745_NETIO_IRQ_END: + c3745_net_irq_get_slot_port(irq,&slot,&port); + dev_c3745_iofpga_net_clear_irq(router->iofpga_data,slot,port); + break; + } +} + /* Initialize a Cisco 3745 instance */ int c3745_init_instance(c3745_t *router) { @@ -1322,6 +1389,10 @@ return(-1); } + /* IRQ routing */ + vm->set_irq = c3745_set_irq; + vm->clear_irq = c3745_clear_irq; + /* Load IOS configuration file */ if (vm->ios_config != NULL) { vm_nvram_push_config(vm,vm->ios_config);