smp.c (09206b600c76f20984e80d99f3b5343c79332a97) smp.c (9b256714979fad61ae11d90b53cf67dd5e6484eb)
1/*
2 * SMP support for PowerNV machines.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version

--- 141 unchanged lines hidden (view full) ---

150 generic_set_cpu_dead(cpu);
151 smp_wmb();
152
153 wmask = SRR1_WAKEMASK;
154 if (cpu_has_feature(CPU_FTR_ARCH_207S))
155 wmask = SRR1_WAKEMASK_P8;
156
157 idle_states = pnv_get_supported_cpuidle_states();
1/*
2 * SMP support for PowerNV machines.
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version

--- 141 unchanged lines hidden (view full) ---

150 generic_set_cpu_dead(cpu);
151 smp_wmb();
152
153 wmask = SRR1_WAKEMASK;
154 if (cpu_has_feature(CPU_FTR_ARCH_207S))
155 wmask = SRR1_WAKEMASK_P8;
156
157 idle_states = pnv_get_supported_cpuidle_states();
158
158 /* We don't want to take decrementer interrupts while we are offline,
159 /* We don't want to take decrementer interrupts while we are offline,
159 * so clear LPCR:PECE1. We keep PECE2 enabled.
160 * so clear LPCR:PECE1. We keep PECE2 (and LPCR_PECE_HVEE on P9)
161 * enabled as to let IPIs in.
160 */
161 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
162
163 /*
164 * Hard-disable interrupts, and then clear irq_happened flags
165 * that we can safely ignore while off-line, since they
166 * are for things for which we do no processing when off-line
167 * (or in the case of HMI, all the processing we need to do

--- 9 unchanged lines hidden (view full) ---

177 * mode, which are handled explicitly below, and those
178 * for coming online, which are handled via
179 * generic_check_cpu_restart() calls.
180 */
181 kvmppc_set_host_ipi(cpu, 0);
182
183 ppc64_runlatch_off();
184
162 */
163 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
164
165 /*
166 * Hard-disable interrupts, and then clear irq_happened flags
167 * that we can safely ignore while off-line, since they
168 * are for things for which we do no processing when off-line
169 * (or in the case of HMI, all the processing we need to do

--- 9 unchanged lines hidden (view full) ---

179 * mode, which are handled explicitly below, and those
180 * for coming online, which are handled via
181 * generic_check_cpu_restart() calls.
182 */
183 kvmppc_set_host_ipi(cpu, 0);
184
185 ppc64_runlatch_off();
186
185 if (cpu_has_feature(CPU_FTR_ARCH_300)) {
186 srr1 = power9_idle_stop(pnv_deepest_stop_psscr_val,
187 pnv_deepest_stop_psscr_mask);
188 } else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
187 if (cpu_has_feature(CPU_FTR_ARCH_300))
188 srr1 = power9_idle_stop(pnv_deepest_stop_state);
189 else if (idle_states & OPAL_PM_WINKLE_ENABLED)
189 srr1 = power7_winkle();
190 srr1 = power7_winkle();
190 } else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
191 (idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
191 else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
192 (idle_states & OPAL_PM_SLEEP_ENABLED_ER1))
192 srr1 = power7_sleep();
193 srr1 = power7_sleep();
193 } else {
194 else
194 srr1 = power7_nap(1);
195 srr1 = power7_nap(1);
195 }
196
197 ppc64_runlatch_on();
198
199 /*
200 * If the SRR1 value indicates that we woke up due to
201 * an external interrupt, then clear the interrupt.
202 * We clear the interrupt before checking for the
203 * reason, so as to avoid a race where we wake up for
204 * some other reason, find nothing and clear the interrupt
205 * just as some other cpu is sending us an interrupt.
206 * If we returned from power7_nap as a result of
207 * having finished executing in a KVM guest, then srr1
208 * contains 0.
209 */
210 if (((srr1 & wmask) == SRR1_WAKEEE) ||
196
197 ppc64_runlatch_on();
198
199 /*
200 * If the SRR1 value indicates that we woke up due to
201 * an external interrupt, then clear the interrupt.
202 * We clear the interrupt before checking for the
203 * reason, so as to avoid a race where we wake up for
204 * some other reason, find nothing and clear the interrupt
205 * just as some other cpu is sending us an interrupt.
206 * If we returned from power7_nap as a result of
207 * having finished executing in a KVM guest, then srr1
208 * contains 0.
209 */
210 if (((srr1 & wmask) == SRR1_WAKEEE) ||
211 ((srr1 & wmask) == SRR1_WAKEHVI) ||
211 (local_paca->irq_happened & PACA_IRQ_EE)) {
212 (local_paca->irq_happened & PACA_IRQ_EE)) {
212 icp_native_flush_interrupt();
213 if (cpu_has_feature(CPU_FTR_ARCH_300))
214 icp_opal_flush_interrupt();
215 else
216 icp_native_flush_interrupt();
213 } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
214 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
215 asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
216 }
217 local_paca->irq_happened &= ~(PACA_IRQ_EE | PACA_IRQ_DBELL);
218 smp_mb();
219
220 if (cpu_core_split_required())
221 continue;
222
223 if (srr1 && !generic_check_cpu_restart(cpu))
224 DBG("CPU%d Unexpected exit while offline !\n", cpu);
225 }
217 } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
218 unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
219 asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
220 }
221 local_paca->irq_happened &= ~(PACA_IRQ_EE | PACA_IRQ_DBELL);
222 smp_mb();
223
224 if (cpu_core_split_required())
225 continue;
226
227 if (srr1 && !generic_check_cpu_restart(cpu))
228 DBG("CPU%d Unexpected exit while offline !\n", cpu);
229 }
230
231 /* Re-enable decrementer interrupts */
226 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
227 DBG("CPU%d coming online...\n", cpu);
228}
229
230#endif /* CONFIG_HOTPLUG_CPU */
231
232static int pnv_cpu_bootable(unsigned int nr)
233{

--- 34 unchanged lines hidden ---
232 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
233 DBG("CPU%d coming online...\n", cpu);
234}
235
236#endif /* CONFIG_HOTPLUG_CPU */
237
238static int pnv_cpu_bootable(unsigned int nr)
239{

--- 34 unchanged lines hidden ---