--- upstream/dynamips-0.2.6-RC5/dev_c3725.c 2007/10/06 16:09:07 6 +++ upstream/dynamips-0.2.7/dev_c3725.c 2007/10/06 16:29:14 10 @@ -1,5 +1,5 @@ /* - * Cisco 3725 simulation platform. + * Cisco router simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 3725 routines and definitions (EEPROM,...). @@ -12,14 +12,17 @@ #include #include -#include "mips64.h" +#include "cpu.h" +#include "vm.h" #include "dynamips.h" #include "memory.h" #include "device.h" #include "pci_io.h" #include "dev_gt.h" #include "cisco_eeprom.h" +#include "dev_rom.h" #include "dev_c3725.h" +#include "dev_c3725_iofpga.h" #include "dev_vtty.h" #include "registry.h" @@ -328,6 +331,26 @@ registry_foreach_type(OBJ_TYPE_VM,c3725_reg_save_config,fd,NULL); } +/* Get slot/port corresponding to specified network IRQ */ +static inline void +c3725_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port) +{ + irq -= C3725_NETIO_IRQ_BASE; + *port = irq & C3725_NETIO_IRQ_PORT_MASK; + *slot = irq >> C3725_NETIO_IRQ_PORT_BITS; +} + +/* Get network IRQ for specified slot/port */ +u_int c3725_net_irq_for_slot_port(u_int slot,u_int port) +{ + u_int irq; + + irq = (slot << C3725_NETIO_IRQ_PORT_BITS) + port; + irq += C3725_NETIO_IRQ_BASE; + + return(irq); +} + /* Get PCI device for the specified NM bay */ int c3725_nm_get_pci_device(u_int nm_bay) { @@ -697,7 +720,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); } @@ -1020,7 +1043,7 @@ } return(dev_gt96100_init(vm,"gt96100",C3725_GT96K_ADDR,0x200000, - C3725_GT96K_IRQ,C3725_NETIO_IRQ)); + C3725_GT96K_IRQ,c3725_net_irq_for_slot_port(0,0))); } /* Initialize a Cisco 3725 */ @@ -1029,7 +1052,7 @@ vm_instance_t *vm = router->vm; /* Set the processor type: R7000 */ - mips64_set_prid(vm->boot_cpu,MIPS_PRID_R7000); + mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R7000); /* Initialize the Galileo GT-96100 PCI controller */ if (c3725_init_gt96100(router) == -1) @@ -1105,11 +1128,10 @@ /* Initialize the C3725 Platform */ int c3725_init_platform(c3725_t *router) { - extern m_uint8_t microcode[]; - extern ssize_t microcode_len; vm_instance_t *vm = router->vm; struct c3725_nm_bay *nm_bay; cpu_mips_t *cpu; + cpu_gen_t *gen; vm_obj_t *obj; int i; @@ -1123,14 +1145,20 @@ vm->cpu_group = cpu_group_create("System CPU"); /* Initialize the virtual MIPS processor */ - if (!(cpu = cpu_create(vm,0))) { + if (!(gen = cpu_create(vm,CPU_TYPE_MIPS64,0))) { vm_error(vm,"unable to create CPU!\n"); return(-1); } + cpu = CPU_MIPS64(gen); + /* Add this CPU to the system CPU group */ - cpu_group_add(vm->cpu_group,cpu); - vm->boot_cpu = cpu; + cpu_group_add(vm->cpu_group,gen); + vm->boot_cpu = gen; + + /* Initialize the IRQ routing vectors */ + vm->set_irq = mips64_vm_set_irq; + vm->clear_irq = mips64_vm_clear_irq; /* Mark the Network IO interrupt as high priority */ cpu->irq_idle_preempt[C3725_NETIO_IRQ] = TRUE; @@ -1147,12 +1175,17 @@ dev_remote_control_init(vm,0x16000000,0x1000); /* Specific Storage Area (SSA) */ - dev_ram_init(vm,"ssa",TRUE,FALSE,NULL,0x16001000ULL,0x7000); + dev_ram_init(vm,"ssa",TRUE,FALSE,NULL,FALSE,0x16001000ULL,0x7000); /* IO FPGA */ if (dev_c3725_iofpga_init(router,C3725_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,C3725_PCI_IO_ADDR))) @@ -1170,7 +1203,7 @@ if (!(obj = dev_flash_init(vm,"rom",C3725_ROM_ADDR,vm->rom_size*1048576))) return(-1); - dev_flash_copy_data(obj,0,microcode,microcode_len); + dev_flash_copy_data(obj,0,mips64_microcode,mips64_microcode_len); c3725_nvram_check_empty_config(vm); /* Initialize the NS16552 DUART */ @@ -1211,6 +1244,7 @@ int c3725_boot_ios(c3725_t *router) { vm_instance_t *vm = router->vm; + cpu_mips_t *cpu; if (!vm->boot_cpu) return(-1); @@ -1225,10 +1259,11 @@ } /* Reset the boot CPU */ - mips64_reset(vm->boot_cpu); + cpu = CPU_MIPS64(vm->boot_cpu); + mips64_reset(cpu); /* Load IOS image */ - if (mips64_load_elf_image(vm->boot_cpu,vm->ios_image, + if (mips64_load_elf_image(cpu,vm->ios_image, (vm->ghost_status == VM_GHOST_RAM_USE), &vm->ios_entry_point) < 0) { @@ -1239,11 +1274,11 @@ /* Launch the simulation */ printf("\nC3725 '%s': starting simulation (CPU0 PC=0x%llx), " "JIT %sabled.\n", - vm->name,vm->boot_cpu->pc,vm->jit_use ? "en":"dis"); + vm->name,cpu->pc,vm->jit_use ? "en":"dis"); vm_log(vm,"C3725_BOOT", "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n", - vm->boot_cpu->pc,vm->boot_cpu->idle_pc,vm->jit_use ? "on":"off"); + cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off"); /* Start main CPU */ if (vm->ghost_status != VM_GHOST_RAM_GENERATE) { @@ -1255,6 +1290,47 @@ return(0); } +/* Set an IRQ */ +static void c3725_set_irq(vm_instance_t *vm,u_int irq) +{ + c3725_t *router = VM_C3725(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 C3725_NETIO_IRQ_BASE ... C3725_NETIO_IRQ_END: + c3725_net_irq_get_slot_port(irq,&slot,&port); + dev_c3725_iofpga_net_set_irq(router->iofpga_data,slot,port); + break; + } +} + +/* Clear an IRQ */ +static void c3725_clear_irq(vm_instance_t *vm,u_int irq) +{ + c3725_t *router = VM_C3725(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 C3725_NETIO_IRQ_BASE ... C3725_NETIO_IRQ_END: + c3725_net_irq_get_slot_port(irq,&slot,&port); + dev_c3725_iofpga_net_clear_irq(router->iofpga_data,slot,port); + break; + } +} + /* Initialize a Cisco 3725 instance */ int c3725_init_instance(c3725_t *router) { @@ -1273,6 +1349,10 @@ return(-1); } + /* IRQ routing */ + vm->set_irq = c3725_set_irq; + vm->clear_irq = c3725_clear_irq; + /* Load IOS configuration file */ if (vm->ios_config != NULL) { vm_nvram_push_config(vm,vm->ios_config); @@ -1280,7 +1360,7 @@ } /* Load ROM (ELF image or embedded) */ - cpu0 = vm->boot_cpu; + cpu0 = CPU_MIPS64(vm->boot_cpu); rom_entry_point = (m_uint32_t)MIPS_ROM_PC; if ((vm->rom_filename != NULL) &&