diff options
Diffstat (limited to 'arch/mips/sgi-ip27/ip27-smp.c')
| -rw-r--r-- | arch/mips/sgi-ip27/ip27-smp.c | 131 |
1 files changed, 72 insertions, 59 deletions
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index 17f768cba94..f9ae6a8fa7c 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c @@ -33,7 +33,7 @@ static void alloc_cpupda(cpuid_t cpu, int cpunum) nasid_t nasid = COMPACT_TO_NASID_NODEID(node); cputonasid(cpunum) = nasid; - cpu_data[cpunum].p_nodeid = node; + sn_cpu_info[cpunum].p_nodeid = node; cputoslice(cpunum) = get_cpu_slice(cpu); } @@ -76,7 +76,7 @@ static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest) /* Only let it join in if it's marked enabled */ if ((acpu->cpu_info.flags & KLINFO_ENABLE) && (tot_cpus_found != NR_CPUS)) { - cpu_set(cpuid, phys_cpu_present_map); + set_cpu_possible(cpuid, true); alloc_cpupda(cpuid, tot_cpus_found); cpus_found++; tot_cpus_found++; @@ -127,99 +127,112 @@ void cpu_node_probe(void) printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes()); } -static void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, - int base_level) +static __init void intr_clear_all(nasid_t nasid) { - volatile hubreg_t bits; int i; - /* Check pending interrupts */ - if ((bits = HUB_L(pend)) != 0) - for (i = 0; i < N_INTPEND_BITS; i++) - if (bits & (1 << i)) - LOCAL_HUB_CLR_INTR(base_level + i); -} - -static void intr_clear_all(nasid_t nasid) -{ REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0); REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0); REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0); REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0); - intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0), - INT_PEND0_BASELVL); - intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1), - INT_PEND1_BASELVL); + + for (i = 0; i < 128; i++) + REMOTE_HUB_CLR_INTR(nasid, i); } -void __init prom_prepare_cpus(unsigned int max_cpus) +static void ip27_send_ipi_single(int destid, unsigned int action) { - cnodeid_t cnode; + int irq; - for_each_online_node(cnode) - intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); + switch (action) { + case SMP_RESCHEDULE_YOURSELF: + irq = CPU_RESCHED_A_IRQ; + break; + case SMP_CALL_FUNCTION: + irq = CPU_CALL_A_IRQ; + break; + default: + panic("sendintr"); + } - replicate_kernel_text(); + irq += cputoslice(destid); /* - * Assumption to be fixed: we're always booted on logical / physical - * processor 0. While we're always running on logical processor 0 - * this still means this is physical processor zero; it might for - * example be disabled in the firwware. + * Convert the compact hub number to the NASID to get the correct + * part of the address space. Then set the interrupt bit associated + * with the CPU we want to send the interrupt to. */ - alloc_cpupda(0, 0); + REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); } -/* - * Launch a slave into smp_bootstrap(). It doesn't take an argument, and we - * set sp to the kernel stack of the newly created idle process, gp to the proc - * struct so that current_thread_info() will work. - */ -void __init prom_boot_secondary(int cpu, struct task_struct *idle) +static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action) { - unsigned long gp = (unsigned long) idle->thread_info; - unsigned long sp = gp + THREAD_SIZE - 32; + unsigned int i; - LAUNCH_SLAVE(cputonasid(cpu),cputoslice(cpu), - (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), - 0, (void *) sp, (void *) gp); + for_each_cpu(i, mask) + ip27_send_ipi_single(i, action); } -void prom_init_secondary(void) +static void ip27_init_secondary(void) { per_cpu_init(); - local_irq_enable(); } -void __init prom_cpus_done(void) +static void ip27_smp_finish(void) { + extern void hub_rt_clock_event_init(void); + + hub_rt_clock_event_init(); + local_irq_enable(); } -void prom_smp_finish(void) +/* + * Launch a slave into smp_bootstrap(). It doesn't take an argument, and we + * set sp to the kernel stack of the newly created idle process, gp to the proc + * struct so that current_thread_info() will work. + */ +static void ip27_boot_secondary(int cpu, struct task_struct *idle) { + unsigned long gp = (unsigned long)task_thread_info(idle); + unsigned long sp = __KSTK_TOS(idle); + + LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), + (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), + 0, (void *) sp, (void *) gp); } -void core_send_ipi(int destid, unsigned int action) +static void __init ip27_smp_setup(void) { - int irq; + cnodeid_t cnode; - switch (action) { - case SMP_RESCHEDULE_YOURSELF: - irq = CPU_RESCHED_A_IRQ; - break; - case SMP_CALL_FUNCTION: - irq = CPU_CALL_A_IRQ; - break; - default: - panic("sendintr"); + for_each_online_node(cnode) { + if (cnode == 0) + continue; + intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); } - irq += cputoslice(destid); + replicate_kernel_text(); /* - * Convert the compact hub number to the NASID to get the correct - * part of the address space. Then set the interrupt bit associated - * with the CPU we want to send the interrupt to. + * Assumption to be fixed: we're always booted on logical / physical + * processor 0. While we're always running on logical processor 0 + * this still means this is physical processor zero; it might for + * example be disabled in the firmware. */ - REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); + alloc_cpupda(0, 0); } + +static void __init ip27_prepare_cpus(unsigned int max_cpus) +{ + /* We already did everything necessary earlier */ +} + +struct plat_smp_ops ip27_smp_ops = { + .send_ipi_single = ip27_send_ipi_single, + .send_ipi_mask = ip27_send_ipi_mask, + .init_secondary = ip27_init_secondary, + .smp_finish = ip27_smp_finish, + .boot_secondary = ip27_boot_secondary, + .smp_setup = ip27_smp_setup, + .prepare_cpus = ip27_prepare_cpus, +}; |
