24 |
#include "cisco_eeprom.h" |
#include "cisco_eeprom.h" |
25 |
#include "dev_rom.h" |
#include "dev_rom.h" |
26 |
#include "dev_c7200.h" |
#include "dev_c7200.h" |
27 |
|
#include "dev_c7200_mpfpga.h" |
28 |
#include "dev_vtty.h" |
#include "dev_vtty.h" |
29 |
#include "registry.h" |
#include "registry.h" |
30 |
#include "net.h" |
#include "net.h" |
534 |
registry_foreach_type(OBJ_TYPE_VM,c7200_reg_save_config,fd,NULL); |
registry_foreach_type(OBJ_TYPE_VM,c7200_reg_save_config,fd,NULL); |
535 |
} |
} |
536 |
|
|
537 |
|
/* Get slot/port corresponding to specified network IRQ */ |
538 |
|
static inline void |
539 |
|
c7200_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port) |
540 |
|
{ |
541 |
|
irq -= C7200_NETIO_IRQ_BASE; |
542 |
|
*port = irq & C7200_NETIO_IRQ_PORT_MASK; |
543 |
|
*slot = irq >> C7200_NETIO_IRQ_PORT_BITS; |
544 |
|
} |
545 |
|
|
546 |
|
/* Get network IRQ for specified slot/port */ |
547 |
|
u_int c7200_net_irq_for_slot_port(u_int slot,u_int port) |
548 |
|
{ |
549 |
|
u_int irq; |
550 |
|
|
551 |
|
irq = (slot << C7200_NETIO_IRQ_PORT_BITS) + port; |
552 |
|
irq += C7200_NETIO_IRQ_BASE; |
553 |
|
|
554 |
|
return(irq); |
555 |
|
} |
556 |
|
|
557 |
/* Set NPE eeprom definition */ |
/* Set NPE eeprom definition */ |
558 |
static int c7200_npe_set_eeprom(c7200_t *router) |
static int c7200_npe_set_eeprom(c7200_t *router) |
559 |
{ |
{ |
948 |
snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,pa_bay); |
snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,pa_bay); |
949 |
|
|
950 |
/* Initialize PA driver */ |
/* Initialize PA driver */ |
951 |
if (bay->pa_driver->pa_init(router,bay->dev_name,pa_bay) == 1) { |
if (bay->pa_driver->pa_init(router,bay->dev_name,pa_bay) == -1) { |
952 |
vm_error(router->vm,"unable to initialize PA %u.\n",pa_bay); |
vm_error(router->vm,"unable to initialize PA %u.\n",pa_bay); |
953 |
return(-1); |
return(-1); |
954 |
} |
} |
2030 |
struct vm_instance *vm = router->vm; |
struct vm_instance *vm = router->vm; |
2031 |
cpu_mips_t *cpu0; |
cpu_mips_t *cpu0; |
2032 |
cpu_gen_t *gen0; |
cpu_gen_t *gen0; |
2033 |
|
vm_obj_t *obj; |
2034 |
|
|
2035 |
/* Copy config register setup into "active" config register */ |
/* Copy config register setup into "active" config register */ |
2036 |
vm->conf_reg = vm->conf_reg_setup; |
vm->conf_reg = vm->conf_reg_setup; |
2114 |
} |
} |
2115 |
|
|
2116 |
/* Byte swapping */ |
/* Byte swapping */ |
2117 |
dev_bswap_init(vm,"mem_bswap",C7200_BSWAP_ADDR,512*1048576,0x00000000ULL); |
dev_bswap_init(vm,"mem_bswap",C7200_BSWAP_ADDR,1024*1048576,0x00000000ULL); |
2118 |
|
|
2119 |
/* PCI IO space */ |
/* PCI IO space */ |
2120 |
if (!(vm->pci_io_space = pci_io_data_init(vm,C7200_PCI_IO_ADDR))) |
if (!(vm->pci_io_space = pci_io_data_init(vm,C7200_PCI_IO_ADDR))) |
2136 |
/* Midplane FPGA */ |
/* Midplane FPGA */ |
2137 |
dev_c7200_mpfpga_init(router,C7200_MPFPGA_ADDR,0x1000); |
dev_c7200_mpfpga_init(router,C7200_MPFPGA_ADDR,0x1000); |
2138 |
|
|
2139 |
|
if (!(obj = vm_object_find(router->vm,"mp_fpga"))) |
2140 |
|
return(-1); |
2141 |
|
|
2142 |
|
router->mpfpga_data = obj->data; |
2143 |
|
|
2144 |
/* IO FPGA */ |
/* IO FPGA */ |
2145 |
if (dev_c7200_iofpga_init(router,C7200_IOFPGA_ADDR,0x1000) == -1) |
if (dev_c7200_iofpga_init(router,C7200_IOFPGA_ADDR,0x1000) == -1) |
2146 |
return(-1); |
return(-1); |
2154 |
static int c7200p_init_platform(c7200_t *router) |
static int c7200p_init_platform(c7200_t *router) |
2155 |
{ |
{ |
2156 |
struct vm_instance *vm = router->vm; |
struct vm_instance *vm = router->vm; |
|
vm_obj_t *obj; |
|
2157 |
cpu_ppc_t *cpu0; |
cpu_ppc_t *cpu0; |
2158 |
cpu_gen_t *gen0; |
cpu_gen_t *gen0; |
2159 |
|
vm_obj_t *obj; |
2160 |
|
|
2161 |
/* Copy config register setup into "active" config register */ |
/* Copy config register setup into "active" config register */ |
2162 |
vm->conf_reg = vm->conf_reg_setup; |
vm->conf_reg = vm->conf_reg_setup; |
2189 |
vm->boot_cpu = gen0; |
vm->boot_cpu = gen0; |
2190 |
|
|
2191 |
/* Mark the Network IO interrupt as high priority */ |
/* Mark the Network IO interrupt as high priority */ |
2192 |
cpu0->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE; |
vm->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE; |
2193 |
|
|
2194 |
/* Copy some parameters from VM to CPU0 (idle PC, ...) */ |
/* Copy some parameters from VM to CPU0 (idle PC, ...) */ |
2195 |
cpu0->idle_pc = vm->idle_pc; |
cpu0->idle_pc = vm->idle_pc; |
2260 |
if (dev_c7200_mpfpga_init(router,C7200_G2_MPFPGA_ADDR,0x10000) == -1) |
if (dev_c7200_mpfpga_init(router,C7200_G2_MPFPGA_ADDR,0x10000) == -1) |
2261 |
return(-1); |
return(-1); |
2262 |
|
|
2263 |
|
if (!(obj = vm_object_find(router->vm,"mp_fpga"))) |
2264 |
|
return(-1); |
2265 |
|
|
2266 |
|
router->mpfpga_data = obj->data; |
2267 |
|
|
2268 |
/* If we have nothing in slot 0, the console is handled by the MV64460 */ |
/* If we have nothing in slot 0, the console is handled by the MV64460 */ |
2269 |
if (!c7200_pa_check_eeprom(router,0)) { |
if (!c7200_pa_check_eeprom(router,0)) { |
2270 |
vm_log(vm,"CONSOLE","console managed by NPE-G2 board\n"); |
vm_log(vm,"CONSOLE","console managed by NPE-G2 board\n"); |
2377 |
return(0); |
return(0); |
2378 |
} |
} |
2379 |
|
|
2380 |
|
/* Set an IRQ */ |
2381 |
|
static void c7200m_set_irq(vm_instance_t *vm,u_int irq) |
2382 |
|
{ |
2383 |
|
c7200_t *router = VM_C7200(vm); |
2384 |
|
cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu); |
2385 |
|
u_int slot,port; |
2386 |
|
|
2387 |
|
switch(irq) { |
2388 |
|
case 0 ... 7: |
2389 |
|
mips64_set_irq(cpu0,irq); |
2390 |
|
|
2391 |
|
if (cpu0->irq_idle_preempt[irq]) |
2392 |
|
cpu_idle_break_wait(cpu0->gen); |
2393 |
|
break; |
2394 |
|
|
2395 |
|
case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END: |
2396 |
|
c7200_net_irq_get_slot_port(irq,&slot,&port); |
2397 |
|
dev_c7200_mpfpga_net_set_irq(router->mpfpga_data,slot,port); |
2398 |
|
break; |
2399 |
|
} |
2400 |
|
} |
2401 |
|
|
2402 |
|
/* Clear an IRQ */ |
2403 |
|
static void c7200m_clear_irq(vm_instance_t *vm,u_int irq) |
2404 |
|
{ |
2405 |
|
c7200_t *router = VM_C7200(vm); |
2406 |
|
cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu); |
2407 |
|
u_int slot,port; |
2408 |
|
|
2409 |
|
switch(irq) { |
2410 |
|
case 0 ... 7: |
2411 |
|
mips64_clear_irq(cpu0,irq); |
2412 |
|
break; |
2413 |
|
|
2414 |
|
case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END: |
2415 |
|
c7200_net_irq_get_slot_port(irq,&slot,&port); |
2416 |
|
dev_c7200_mpfpga_net_clear_irq(router->mpfpga_data,slot,port); |
2417 |
|
break; |
2418 |
|
} |
2419 |
|
} |
2420 |
|
|
2421 |
/* Initialize a Cisco 7200 instance (MIPS) */ |
/* Initialize a Cisco 7200 instance (MIPS) */ |
2422 |
static int c7200m_init_instance(c7200_t *router) |
static int c7200m_init_instance(c7200_t *router) |
2423 |
{ |
{ |
2431 |
return(-1); |
return(-1); |
2432 |
} |
} |
2433 |
|
|
2434 |
|
/* IRQ routing */ |
2435 |
|
vm->set_irq = c7200m_set_irq; |
2436 |
|
vm->clear_irq = c7200m_clear_irq; |
2437 |
|
|
2438 |
/* Load IOS configuration file */ |
/* Load IOS configuration file */ |
2439 |
if (vm->ios_config != NULL) { |
if (vm->ios_config != NULL) { |
2440 |
vm_nvram_push_config(vm,vm->ios_config); |
vm_nvram_push_config(vm,vm->ios_config); |
2467 |
{ |
{ |
2468 |
c7200_t *router = VM_C7200(vm); |
c7200_t *router = VM_C7200(vm); |
2469 |
cpu_ppc_t *cpu0 = CPU_PPC32(vm->boot_cpu); |
cpu_ppc_t *cpu0 = CPU_PPC32(vm->boot_cpu); |
2470 |
|
u_int slot,port; |
2471 |
|
|
2472 |
switch(irq) { |
switch(irq) { |
2473 |
case C7200_VTIMER_IRQ: |
case C7200_VTIMER_IRQ: |
2474 |
ppc32_trigger_timer_irq(cpu0); |
ppc32_trigger_timer_irq(cpu0); |
2485 |
case C7200_OIR_IRQ: |
case C7200_OIR_IRQ: |
2486 |
dev_mv64460_set_gpp_intr(router->mv64460_sysctr,0); |
dev_mv64460_set_gpp_intr(router->mv64460_sysctr,0); |
2487 |
break; |
break; |
2488 |
|
case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END: |
2489 |
|
c7200_net_irq_get_slot_port(irq,&slot,&port); |
2490 |
|
dev_c7200_mpfpga_net_set_irq(router->mpfpga_data,slot,port); |
2491 |
|
break; |
2492 |
} |
} |
2493 |
|
|
2494 |
if (cpu0->irq_idle_preempt[irq]) |
if (vm->irq_idle_preempt[irq]) |
2495 |
cpu_idle_break_wait(cpu0->gen); |
cpu_idle_break_wait(cpu0->gen); |
2496 |
} |
} |
2497 |
|
|
2499 |
static void c7200p_clear_irq(vm_instance_t *vm,u_int irq) |
static void c7200p_clear_irq(vm_instance_t *vm,u_int irq) |
2500 |
{ |
{ |
2501 |
c7200_t *router = VM_C7200(vm); |
c7200_t *router = VM_C7200(vm); |
2502 |
|
u_int slot,port; |
2503 |
|
|
2504 |
switch(irq) { |
switch(irq) { |
2505 |
case C7200_DUART_IRQ: |
case C7200_DUART_IRQ: |
2514 |
case C7200_OIR_IRQ: |
case C7200_OIR_IRQ: |
2515 |
dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,0); |
dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,0); |
2516 |
break; |
break; |
2517 |
|
case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END: |
2518 |
|
c7200_net_irq_get_slot_port(irq,&slot,&port); |
2519 |
|
dev_c7200_mpfpga_net_clear_irq(router->mpfpga_data,slot,port); |
2520 |
|
break; |
2521 |
} |
} |
2522 |
} |
} |
2523 |
|
|
2535 |
return(-1); |
return(-1); |
2536 |
} |
} |
2537 |
|
|
2538 |
|
/* IRQ routing */ |
2539 |
|
vm->set_irq = c7200p_set_irq; |
2540 |
|
vm->clear_irq = c7200p_clear_irq; |
2541 |
|
|
2542 |
/* Load ROM (ELF image or embedded) */ |
/* Load ROM (ELF image or embedded) */ |
2543 |
cpu0 = CPU_PPC32(vm->boot_cpu); |
cpu0 = CPU_PPC32(vm->boot_cpu); |
2544 |
rom_entry_point = (m_uint32_t)PPC32_ROM_START; |
rom_entry_point = (m_uint32_t)PPC32_ROM_START; |
2580 |
cpu0->bat[PPC32_DBAT_IDX][3].reg[0] = 0xF0001FFE; |
cpu0->bat[PPC32_DBAT_IDX][3].reg[0] = 0xF0001FFE; |
2581 |
cpu0->bat[PPC32_DBAT_IDX][3].reg[1] = 0xF0000003; |
cpu0->bat[PPC32_DBAT_IDX][3].reg[1] = 0xF0000003; |
2582 |
|
|
|
/* IRQ routing */ |
|
|
vm->set_irq = c7200p_set_irq; |
|
|
vm->clear_irq = c7200p_clear_irq; |
|
2583 |
|
|
2584 |
return(c7200p_boot_ios(router)); |
return(c7200p_boot_ios(router)); |
2585 |
} |
} |