diff options
Diffstat (limited to 'arch/mips/netlogic/common/smp.c')
-rw-r--r-- | arch/mips/netlogic/common/smp.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index 4fe8992b291c..e40b467f6184 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c | |||
@@ -59,12 +59,17 @@ | |||
59 | 59 | ||
60 | void nlm_send_ipi_single(int logical_cpu, unsigned int action) | 60 | void nlm_send_ipi_single(int logical_cpu, unsigned int action) |
61 | { | 61 | { |
62 | int cpu = cpu_logical_map(logical_cpu); | 62 | int cpu, node; |
63 | uint64_t picbase; | ||
64 | |||
65 | cpu = cpu_logical_map(logical_cpu); | ||
66 | node = cpu / NLM_CPUS_PER_NODE; | ||
67 | picbase = nlm_get_node(node)->picbase; | ||
63 | 68 | ||
64 | if (action & SMP_CALL_FUNCTION) | 69 | if (action & SMP_CALL_FUNCTION) |
65 | nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0); | 70 | nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0); |
66 | if (action & SMP_RESCHEDULE_YOURSELF) | 71 | if (action & SMP_RESCHEDULE_YOURSELF) |
67 | nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); | 72 | nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); |
68 | } | 73 | } |
69 | 74 | ||
70 | void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) | 75 | void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) |
@@ -96,11 +101,12 @@ void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) | |||
96 | void nlm_early_init_secondary(int cpu) | 101 | void nlm_early_init_secondary(int cpu) |
97 | { | 102 | { |
98 | change_c0_config(CONF_CM_CMASK, 0x3); | 103 | change_c0_config(CONF_CM_CMASK, 0x3); |
99 | write_c0_ebase((uint32_t)nlm_common_ebase); | ||
100 | #ifdef CONFIG_CPU_XLP | 104 | #ifdef CONFIG_CPU_XLP |
101 | if (cpu % 4 == 0) | 105 | /* mmu init, once per core */ |
106 | if (cpu % NLM_THREADS_PER_CORE == 0) | ||
102 | xlp_mmu_init(); | 107 | xlp_mmu_init(); |
103 | #endif | 108 | #endif |
109 | write_c0_ebase(nlm_current_node()->ebase); | ||
104 | } | 110 | } |
105 | 111 | ||
106 | /* | 112 | /* |
@@ -108,7 +114,7 @@ void nlm_early_init_secondary(int cpu) | |||
108 | */ | 114 | */ |
109 | static void __cpuinit nlm_init_secondary(void) | 115 | static void __cpuinit nlm_init_secondary(void) |
110 | { | 116 | { |
111 | current_cpu_data.core = hard_smp_processor_id() / 4; | 117 | current_cpu_data.core = hard_smp_processor_id() / NLM_THREADS_PER_CORE; |
112 | nlm_smp_irq_init(); | 118 | nlm_smp_irq_init(); |
113 | } | 119 | } |
114 | 120 | ||
@@ -142,22 +148,22 @@ cpumask_t phys_cpu_present_map; | |||
142 | 148 | ||
143 | void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) | 149 | void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) |
144 | { | 150 | { |
145 | unsigned long gp = (unsigned long)task_thread_info(idle); | 151 | int cpu, node; |
146 | unsigned long sp = (unsigned long)__KSTK_TOS(idle); | ||
147 | int cpu = cpu_logical_map(logical_cpu); | ||
148 | 152 | ||
149 | nlm_next_sp = sp; | 153 | cpu = cpu_logical_map(logical_cpu); |
150 | nlm_next_gp = gp; | 154 | node = cpu / NLM_CPUS_PER_NODE; |
155 | nlm_next_sp = (unsigned long)__KSTK_TOS(idle); | ||
156 | nlm_next_gp = (unsigned long)task_thread_info(idle); | ||
151 | 157 | ||
152 | /* barrier */ | 158 | /* barrier for sp/gp store above */ |
153 | __sync(); | 159 | __sync(); |
154 | nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1); | 160 | nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1); /* NMI */ |
155 | } | 161 | } |
156 | 162 | ||
157 | void __init nlm_smp_setup(void) | 163 | void __init nlm_smp_setup(void) |
158 | { | 164 | { |
159 | unsigned int boot_cpu; | 165 | unsigned int boot_cpu; |
160 | int num_cpus, i; | 166 | int num_cpus, i, ncore; |
161 | 167 | ||
162 | boot_cpu = hard_smp_processor_id(); | 168 | boot_cpu = hard_smp_processor_id(); |
163 | cpumask_clear(&phys_cpu_present_map); | 169 | cpumask_clear(&phys_cpu_present_map); |
@@ -182,11 +188,16 @@ void __init nlm_smp_setup(void) | |||
182 | } | 188 | } |
183 | } | 189 | } |
184 | 190 | ||
191 | /* check with the cores we have worken up */ | ||
192 | for (ncore = 0, i = 0; i < NLM_NR_NODES; i++) | ||
193 | ncore += hweight32(nlm_get_node(i)->coremask); | ||
194 | |||
185 | pr_info("Phys CPU present map: %lx, possible map %lx\n", | 195 | pr_info("Phys CPU present map: %lx, possible map %lx\n", |
186 | (unsigned long)cpumask_bits(&phys_cpu_present_map)[0], | 196 | (unsigned long)cpumask_bits(&phys_cpu_present_map)[0], |
187 | (unsigned long)cpumask_bits(cpu_possible_mask)[0]); | 197 | (unsigned long)cpumask_bits(cpu_possible_mask)[0]); |
188 | 198 | ||
189 | pr_info("Detected %i Slave CPU(s)\n", num_cpus); | 199 | pr_info("Detected (%dc%dt) %d Slave CPU(s)\n", ncore, |
200 | nlm_threads_per_core, num_cpus); | ||
190 | nlm_set_nmi_handler(nlm_boot_secondary_cpus); | 201 | nlm_set_nmi_handler(nlm_boot_secondary_cpus); |
191 | } | 202 | } |
192 | 203 | ||
@@ -196,7 +207,7 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask) | |||
196 | int threadmode, i, j; | 207 | int threadmode, i, j; |
197 | 208 | ||
198 | core0_thr_mask = 0; | 209 | core0_thr_mask = 0; |
199 | for (i = 0; i < 4; i++) | 210 | for (i = 0; i < NLM_THREADS_PER_CORE; i++) |
200 | if (cpumask_test_cpu(i, wakeup_mask)) | 211 | if (cpumask_test_cpu(i, wakeup_mask)) |
201 | core0_thr_mask |= (1 << i); | 212 | core0_thr_mask |= (1 << i); |
202 | switch (core0_thr_mask) { | 213 | switch (core0_thr_mask) { |
@@ -217,9 +228,9 @@ static int nlm_parse_cpumask(cpumask_t *wakeup_mask) | |||
217 | } | 228 | } |
218 | 229 | ||
219 | /* Verify other cores CPU masks */ | 230 | /* Verify other cores CPU masks */ |
220 | for (i = 0; i < NR_CPUS; i += 4) { | 231 | for (i = 0; i < NR_CPUS; i += NLM_THREADS_PER_CORE) { |
221 | core_thr_mask = 0; | 232 | core_thr_mask = 0; |
222 | for (j = 0; j < 4; j++) | 233 | for (j = 0; j < NLM_THREADS_PER_CORE; j++) |
223 | if (cpumask_test_cpu(i + j, wakeup_mask)) | 234 | if (cpumask_test_cpu(i + j, wakeup_mask)) |
224 | core_thr_mask |= (1 << j); | 235 | core_thr_mask |= (1 << j); |
225 | if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask) | 236 | if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask) |