/* Early cpumask setup - runs on TP0 */ static void brcmstb_smp_setup(void) { __cpu_number_map[0] = 0; __cpu_logical_map[0] = 0; set_cpu_possible(0, 1); set_cpu_present(0, 1); __cpu_number_map[1] = 1; __cpu_logical_map[1] = 1; set_cpu_possible(1, 1); set_cpu_present(1, 1); #if defined(CONFIG_BMIPS4380) /* NBK and weak order flags */ set_c0_brcm_config_0(0x30000); /* * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other TP * MIPS interrupt 2 (HW INT 0) is the TP0 L1 controller output * MIPS interrupt 3 (HW INT 1) is the TP1 L1 controller output */ change_c0_brcm_cmt_intr(0xf8018000, (0x02 << 27) | (0x03 << 15)); #elif defined(CONFIG_BMIPS5000) /* enable raceless SW interrupts */ set_c0_brcm_config(0x03 << 22); /* clear any pending SW interrupts */ write_c0_brcm_action(0x2000 | (0 << 9) | (0 << 8)); write_c0_brcm_action(0x2000 | (0 << 9) | (1 << 8)); write_c0_brcm_action(0x2000 | (1 << 9) | (0 << 8)); write_c0_brcm_action(0x2000 | (1 << 9) | (1 << 8)); #endif }
static void brcmstb_ack_ipi(unsigned int irq) { //unsigned int bit = (irq == BRCM_IRQ_IPI0) ? 0 : 1; unsigned int bit = smp_processor_id(); write_c0_brcm_action(0x2000 | (bit << 8) | (smp_processor_id() << 9)); irq_enable_hazard(); }
static void brcmstb_send_ipi_single(int cpu, unsigned int action) { //unsigned int bit = (action == SMP_RESCHEDULE_YOURSELF) ? 0 : 1; unsigned int bit = cpu; write_c0_brcm_action(0x3000 | (bit << 8) | (cpu << 9)); irq_enable_hazard(); }
/* Tell the hardware to boot TP1 - runs on TP0 */ static void brcmstb_boot_secondary(int cpu, struct task_struct *idle) { brcmstb_smp_boot_sp = __KSTK_TOS(idle); brcmstb_smp_boot_gp = (unsigned long)task_thread_info(idle); mb(); /* * TP1 initial boot sequence: * brcm_reset_nmi_vec @ a000_0000 -> * brcmstb_tp1_entry -> * brcm_upper_tlb_setup (cached function call) -> * start_secondary (cached jump) * * TP1 warm restart sequence: * play_dead WAIT loop -> * brcm_tp1_int_vec @ BRCM_WARM_RESTART_VEC -> * eret to play_dead -> * brcmstb_tp1_reentry -> * start_secondary * * Vector relocation code is in arch/mips/brcmstb/prom.c * Actual boot vectors are in arch/mips/brcmstb/vector.S */ printk(KERN_INFO "SMP: Booting CPU%d...\n", cpu); /* warm restart */ brcmstb_send_ipi_single(1, 0); #if defined(CONFIG_BMIPS4380) set_c0_brcm_cmt_ctrl(0x01); #elif defined(CONFIG_BMIPS5000) write_c0_brcm_action(0x9); #endif }
/* Early cpumask setup - runs on TP0 */ void brcmstb_smp_setup(void) { int i; /* 1:1 mapping between logical and physical CPUs */ for (i = 0; i < NR_CPUS; i++) { cpu_clear(i, cpu_possible_map); __cpu_number_map[i] = i; __cpu_logical_map[i] = i; } /* Enable TP0, TP1 */ cpu_set(0, cpu_possible_map); cpu_set(1, cpu_possible_map); cpu_present_map = cpu_possible_map; #if defined(CONFIG_BMIPS4380) /* NBK and weak order flags */ set_c0_brcm_config_0(0x30000); /* * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other TP * MIPS interrupt 2 (HW INT 0) is the TP0 L1 controller output * MIPS interrupt 3 (HW INT 1) is the TP1 L1 controller output */ change_c0_brcm_cmt_intr(0xf8018000, (0x02 << 27) | (0x03 << 15)); #elif defined(CONFIG_BMIPS5000) /* enable raceless SW interrupts */ set_c0_brcm_config(0x03 << 22); /* clear any pending SW interrupts */ write_c0_brcm_action(0x2000 | (0 << 9) | (0 << 8)); write_c0_brcm_action(0x2000 | (0 << 9) | (1 << 8)); write_c0_brcm_action(0x2000 | (1 << 9) | (0 << 8)); write_c0_brcm_action(0x2000 | (1 << 9) | (1 << 8)); /* send HW interrupt 0 to TP0, HW interrupt 1 to TP1 */ change_c0_brcm_mode(0x1f << 27, 0x02 << 27); #endif }
static void brcmstb_ack_ipi(unsigned int irq) { unsigned int bit = smp_processor_id(); write_c0_brcm_action(0x2000 | (bit << 8) | (smp_processor_id() << 9)); irq_enable_hazard(); }
static void brcmstb_send_ipi_single(int cpu, unsigned int action) { unsigned int bit = cpu; write_c0_brcm_action(0x3000 | (bit << 8) | (cpu << 9)); irq_enable_hazard(); }