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 --- |