From patchwork Fri Nov 20 09:14:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenhui zhao X-Patchwork-Id: 546856 X-Patchwork-Delegate: scottwood@freescale.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A4BD0140D5F for ; Fri, 20 Nov 2015 20:32:51 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 843401A1AA2 for ; Fri, 20 Nov 2015 20:32:51 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1bon0145.outbound.protection.outlook.com [157.56.111.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 7CAC51A023F for ; Fri, 20 Nov 2015 20:28:16 +1100 (AEDT) Received: from BN3PR0301CA0063.namprd03.prod.outlook.com (10.160.152.159) by CY1PR03MB1486.namprd03.prod.outlook.com (10.163.17.16) with Microsoft SMTP Server (TLS) id 15.1.331.20; Fri, 20 Nov 2015 09:13:44 +0000 Received: from BY2FFO11FD035.protection.gbl (2a01:111:f400:7c0c::173) by BN3PR0301CA0063.outlook.office365.com (2a01:111:e400:401e::31) with Microsoft SMTP Server (TLS) id 15.1.331.20 via Frontend Transport; Fri, 20 Nov 2015 09:13:44 +0000 Authentication-Results: spf=permerror (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; Received-SPF: PermError (protection.outlook.com: domain of freescale.com used an invalid SPF mechanism) Received: from az84smr01.freescale.net (192.88.158.2) by BY2FFO11FD035.mail.protection.outlook.com (10.1.14.220) with Microsoft SMTP Server (TLS) id 15.1.331.11 via Frontend Transport; Fri, 20 Nov 2015 09:13:43 +0000 Received: from localhost.localdomain ([10.193.20.174]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id tAK9DUPe015178; Fri, 20 Nov 2015 02:13:41 -0700 From: Chenhui Zhao To: Subject: [PATCH v3 6/6] powerpc/mpc85xx: Add CPU hotplug support for E6500 Date: Fri, 20 Nov 2015 17:14:02 +0800 Message-ID: <1448010842-22345-6-git-send-email-chenhui.zhao@freescale.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1448010842-22345-1-git-send-email-chenhui.zhao@freescale.com> References: <1448010842-22345-1-git-send-email-chenhui.zhao@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD035; 1:clpoUTPmqLMXrWznAmCwHjNnWLOUWl1JRizrIOygbQyAtxmJLVEabkhf+fZjYl3lRUrA5cN8PxlN/fhX7ds5sseUHwEr+XAk3NkT7Jw0371Aegj5mA0fMy/CnohIagykhPp/meCYSw9UkRxC6sARSJlVPx9k5mJPzXnusIMnIUY/IFDqOd3acayFKbCRdnooI3Qb+ObmJjgxrVvDgteca3yjsmq7vX6njWJTsyX0BoG1CIogE0SEIXWCg3ZxgNqSkMaN1bZQdL5US0EsWoKJ4HRTbHGO7nohymvCM6J6pM38d7QysS3voJYNPqbbl+RbMBIjwBQHm2cR//W7cToZIGHFn9SndaeAq/jlqM27OqaeIcCGDDs7KseJ71OQ9HJC7lHpQr6PckMCC7OeLy22SPVczUSQu8c/+ekXuyGiXu8= X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(2980300002)(448002)(199003)(189002)(92566002)(11100500001)(2351001)(50466002)(48376002)(50986999)(69596002)(19580405001)(6806005)(5008740100001)(5001920100001)(104016004)(19580395003)(107886002)(5001960100002)(110136002)(36756003)(229853001)(81156007)(4001430100002)(97736004)(5007970100001)(450100001)(189998001)(586003)(33646002)(50226001)(5003940100001)(76176999)(86362001)(2950100001)(77096005)(49486002)(575784001)(47776003)(87936001)(106466001)(85326001); DIR:OUT; SFP:1102; SCL:1; SRVR:CY1PR03MB1486; H:az84smr01.freescale.net; FPR:; SPF:PermError; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; CY1PR03MB1486; 2:Er70dNHgN7Ppb/Emwe3Es7tzT/od/buxaCeFD8J/TFonz2dG6Cr5wK7MYI+g6LzkSQm0+uyuNrxCDHVza97ZMUOQYzGF5KfWaX2jhlZtBJ5hom/lX8tfGQCv4wEEORMxKeBQ9dl2Ang5218yRi4+zg==; 3:lNT5pLixfTou8MYNHboR+QxysBBsJi7ca/GIQOyjPgYj2peR23cz0NeBHHjbCvOcTb8MgsB7KtZOeVWPaN4H3L1PwytPBhl21xOAhrFIa/PAafIUZIexZVUHN0v0hYhjEmO8Vb+Vrk6HwmE6P91JdATe5kyNVBlvHxet3O7c69uBDZGZVvW4U8DUxvzBLPXZ5wQ+89U7OyUBamzPBuOj41XaMlhC3ihFOlNtPiWyTTo=; 25:UPJM7Smky9wseDJnjq9go/sb2HGIY5f42AN1ecCgt08GTiAAfGg26EOTCvuGCUlY9oOIZObAem+j3DGUjcUkO1/w8/KzAjDXmbwKZEqRNXTVkZUq5zw8mHd2yWwhzlw+oytBjiaSGRY527bpJU/FYghcarYptQIDfqCfOURnAZD1/jclPzBbu4Pdhy8oIK/rZvRGSB3thuv15SAyVJRLW6H3nx4XrcCOUqyb8Akd/rF3JUGnunyBeP3U+71ecY+3G1M8N3ephvfxconIvC5ESA== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR03MB1486; X-Microsoft-Exchange-Diagnostics: 1; CY1PR03MB1486; 20:qy0g4I5NNt00GsAoIzrJOgPjLlEFTly25yQJ8LQoqQCNgtyB6o9CwJCeCsix9ubrJ2QvX8iHb5MW7ojVKEGH0YZ3h5vOGsceTPlLpS7bE0Kt0GnBjjGhW84nvNRvlPV+KrN5/mnX662JiniE/CofBvh8spPcFsq2OvzKTG/8vUX61l432cC1GiprlJAWKwAe6t/v8E2v6LcWEox27z4KQ7xd2l1JDclpSZMu//oMn0BtY4/j6I3k71kTa+kHrXz4MM4yYThmdw2VqKGqhehz+XGRnUg/h5gYxT3CqKlSkiRtAsmokhTxGYTq4wo2ddcyg3Su1G4S97F3xdr/tlDfMduIx5d5usQoSUTnZXQz1Kg=; 4:tIXye1uv7eWIfoB5bc/s9w0y662ABpJnzCHv8dn5JTn+Xg4HVLVeSFLEGqZb5c7+KH5YzWVrF2YI9U7Mjf8AejaD6Djt58UWE4q5kxuV3Rw0DQsYanolFOUxP46CbB33mcA17FGNyv5+EVlLY3xmdp2rrEmxkh1rE5hfNcGelox8kNqmDJZXd3onMXX3p4hz/X0XkgPAZIGqpi8BabhJTuCZ9dPIo7z5jghCEcbXII87a1hdMAfitnwmOB4p9t9cAOkp+hmXgfw+frfzw4hkZTUhrs/BulPCDZ9OHeLbYgyAgptgK5qLK9/2wzsFhVz0JtgKqgxHipEJUQDq1fFHsp1Ee9zhNrkPCgHdlm0F4yft5/KPGPQft9GZc7zpau23j/j/9uKq3aDA1zePt+zhfnArGmSlu5GCG49tYt02rYdaoolktXjV9+Wk250dfdV7 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(101931422205132); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(520078)(5005006)(8121501046)(10201501046)(3002001); SRVR:CY1PR03MB1486; BCL:0; PCL:0; RULEID:; SRVR:CY1PR03MB1486; X-Forefront-PRVS: 07665BE9D1 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY1PR03MB1486; 23:LSGgBEFMtWZ9gIEHlgu0VXLY6wnIWcGRtiJ9+8Gbg?= =?us-ascii?Q?ZcNGjR/tBrJmEhRjVq9UiJlGWDw6/NkxOvg6VzOubj/rY5xaU8KEV9Z7GSis?= =?us-ascii?Q?aRkSVxHGplusZV4soiI1RafuRlYGiaZi8XzYVBZxrxDLvmoJao83i9tdZjrz?= =?us-ascii?Q?Y/s0Z+JosG0YFEE0db3+/rr9AkujdXDwZYE6Q6hzyR7i7e0OahIXvbQE+BR6?= =?us-ascii?Q?XylP6FCODLZ7h4F4Ihd8WFMspewqVqzhQGtMecS9YYZPQZMGCq+DGllQeVbb?= =?us-ascii?Q?dgs4+HrPtV2p3QNLqaQsVz2mIfr5sZBdue7pw/4mkYH8juUNo6GDxrJGYIWk?= =?us-ascii?Q?QO9JS+XuFzIN1QIfq/MecfWWKysTEAD5Hmwx8KgZbgmMtzORU9Q9YKXH5hCM?= =?us-ascii?Q?Jhurh+Rrp8PHdePoz5zqhdudit+tHo4oHXe1NJw3rEJ5fUS97+B+dVzM/zqe?= =?us-ascii?Q?vhCFSU7p1BGVZkyRFNg6wksNQx2okLJJrOGFDXfLBfxHP9q+4TfB8GTA/NeT?= =?us-ascii?Q?1l65abz1SBmLYW7ACdrVEQN/yRb4HbeWBbJXzVXqEUIfY9/u0iUz0Fldjo2w?= =?us-ascii?Q?NO6GF2p2k6BQVo/dcvCO3hfG4nPX5HhGbmpf/l7ap9fG9ovte3E0/8sny8un?= =?us-ascii?Q?St+2S+aSBcWhQg3PX+IB0LIPCZK2YiQPxk0CDKrYMSk7FNIC0vyeE8zLgzKf?= =?us-ascii?Q?14hxpG1Mz1xli2Rhs/dB/bIBbOkgNSz4C5Lgmf5hSd6RlsFJcNG7+YcNOGlJ?= =?us-ascii?Q?5LJPreADS9sW6JNrI8fTMSN+Bi05yEyPldTcoNSNo/n58qAl4t3d8UYOYpNf?= =?us-ascii?Q?NcLiuQe06G52HemzQyT+5zsYXzjmToNfJQM+cR3Sf1vtrH19pG+CS+y5aYbF?= =?us-ascii?Q?9estHjAKkwfKvs984NWQELokp+AW+2jZEismcbB0yRIZ6kPZmV/y0l2ISqN8?= =?us-ascii?Q?zGJeEzIRcHPqby/Szjqe/Wjm4b0wD/5yEVyNCnHfObRX4nYjFqX3YtS46OKS?= =?us-ascii?Q?sAUr1z0mGfww0+kp/ObXseYvd38F4C6QcCOhippTnXgwnblr7hLc3VtbvdRg?= =?us-ascii?Q?v+7Jawl9hvINsRSuhszK7fFJP8RTdGo9dWOhpqs0GqO46zTKQZrEqGoyHI1i?= =?us-ascii?Q?MMdFrDW51SVJf85gGx+/30VOcSjpBvPXDyaS2oiwe1jMp6On5CBcA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY1PR03MB1486; 5:YyMlemUaAsCnnuKFEvJOW0PUmtmdkbbUcg7REubG50w3cGSvjJyxGPz781JpR9GaeTu8GH21o62C8M0snylbgBc97brsE95MW38CxHWJRKwT2PqaC46RhoZNygSe0c4pnr1utJ1P3PvVn6+n8dmDEw==; 24:3IB2imFoXnZcyJ/6BSYscEAPrNbsOK9JrkDfNj1XJ8jFc4z+fvfzrhmtURPaNEw6RHnwv7nnJHkI5y8ZnnSpbbo+PKaWVV45jvTJ1iNXlJw= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Nov 2015 09:13:43.0004 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR03MB1486 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: scottwood@freescale.com Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Support Freescale E6500 core-based platforms, like t4240. Support disabling/enabling individual CPU thread dynamically. Signed-off-by: Chenhui Zhao --- changes for v3 * rebase patches on the latest code * add const for info in wake_hw_thread() * use r8 instead of r13 in the assemble code * added some comments in code * checked SPRN_BUCSR to see whether the current thread has been initialized * changed the flow in smp_85xx_kick_cpu() * changed that the code to start thread in generic_secondary_smp_init does not depend on which thread it is running major changes for v2: * start Thread1 by Thread0 when we want to boot Thread1 only replacing the method of changing cpu physical id arch/powerpc/include/asm/cputhreads.h | 6 +++ arch/powerpc/include/asm/smp.h | 1 + arch/powerpc/kernel/head_64.S | 78 +++++++++++++++++++++++++++++++++++ arch/powerpc/platforms/85xx/smp.c | 70 +++++++++++++++++-------------- 4 files changed, 124 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index e5a769d..9ec41e5 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -1,6 +1,7 @@ #ifndef _ASM_POWERPC_CPUTHREADS_H #define _ASM_POWERPC_CPUTHREADS_H +#ifndef __ASSEMBLY__ #include /* @@ -102,7 +103,12 @@ static inline u32 get_tensr(void) return 1; } +void book3e_start_thread(int thread, unsigned long addr); void book3e_stop_thread(int thread); +#endif /* __ASSEMBLY__ */ + +#define INVALID_THREAD_HWID 0x0fff + #endif /* _ASM_POWERPC_CPUTHREADS_H */ diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index bdb8111..174271e 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -200,6 +200,7 @@ extern void generic_secondary_thread_init(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; +extern unsigned int booting_thread_hwid; extern void __early_start(void); #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 6036253..2916283 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -40,6 +40,7 @@ #include #include #include +#include /* The physical memory is laid out such that the secondary processor * spin code sits at 0x0000...0x00ff. On server, the vectors follow @@ -182,6 +183,45 @@ exception_marker: #ifdef CONFIG_PPC_BOOK3E /* + * The booting_thread_hwid holds the thread id we want to boot in cpu + * hotplug case. It is set by cpu hotplug code, and is invalid by default. + * The thread id is the same as the initial value of SPRN_PIR[THREAD_ID] + * bit field. + */ + .globl booting_thread_hwid +booting_thread_hwid: + .long INVALID_THREAD_HWID + .align 3 +/* + * start a thread in the same core + * input parameters: + * r3 = the thread physical id + * r4 = the entry point where thread starts + */ +_GLOBAL(book3e_start_thread) + LOAD_REG_IMMEDIATE(r5, MSR_KERNEL) + cmpi 0, r3, 0 + beq 10f + cmpi 0, r3, 1 + beq 11f + /* If the thread id is invalid, just exit. */ + b 13f +10: + mttmr TMRN_IMSR0, r5 + mttmr TMRN_INIA0, r4 + b 12f +11: + mttmr TMRN_IMSR1, r5 + mttmr TMRN_INIA1, r4 +12: + isync + li r6, 1 + sld r6, r6, r3 + mtspr SPRN_TENS, r6 +13: + blr + +/* * stop a thread in the same core * input parameter: * r3 = the thread physical id @@ -280,6 +320,44 @@ _GLOBAL(generic_secondary_smp_init) mr r3,r24 mr r4,r25 bl book3e_secondary_core_init + +/* + * After common core init has finished, check if the current thread is the + * one we wanted to boot. If not, start the specified thread and stop the + * current thread. + */ + LOAD_REG_ADDR(r4, booting_thread_hwid) + lwz r3, 0(r4) + li r5, INVALID_THREAD_HWID + cmpw r3, r5 + beq 20f + + /* + * The value of booting_thread_hwid has been stored in r3, + * so make it invalid. + */ + stw r5, 0(r4) + + /* + * Get the current thread id and check if it is the one we wanted. + * If not, start the one specified in booting_thread_hwid and stop + * the current thread. + */ + mfspr r8, SPRN_TIR + cmpw r3, r8 + beq 20f + + /* start the specified thread */ + LOAD_REG_ADDR(r5, fsl_secondary_thread_init) + ld r4, 0(r5) + bl book3e_start_thread + + /* stop the current thread */ + mr r3, r8 + bl book3e_stop_thread +10: + b 10b +20: #endif generic_secondary_common_init: diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 0f56dd5..cc22737 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -182,24 +182,11 @@ static inline u32 read_spin_table_addr_l(void *spin_table) static void wake_hw_thread(void *info) { void fsl_secondary_thread_init(void); - unsigned long imsr, inia; - int nr = *(const int *)info; + unsigned long inia; + int cpu = *(const int *)info; - imsr = MSR_KERNEL; inia = *(unsigned long *)fsl_secondary_thread_init; - - if (cpu_thread_in_core(nr) == 0) { - /* For when we boot on a secondary thread with kdump */ - mttmr(TMRN_IMSR0, imsr); - mttmr(TMRN_INIA0, inia); - mtspr(SPRN_TENS, TEN_THREAD(0)); - } else { - mttmr(TMRN_IMSR1, imsr); - mttmr(TMRN_INIA1, inia); - mtspr(SPRN_TENS, TEN_THREAD(1)); - } - - smp_generic_kick_cpu(nr); + book3e_start_thread(cpu_thread_in_core(cpu), inia); } #endif @@ -294,33 +281,54 @@ static int smp_85xx_kick_cpu(int nr) pr_debug("kick CPU #%d\n", nr); #ifdef CONFIG_PPC64 - /* Threads don't use the spin table */ - if (cpu_thread_in_core(nr) != 0) { - int primary = cpu_first_thread_sibling(nr); - + if (threads_per_core == 2) { if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) return -ENOENT; - if (cpu_thread_in_core(nr) != 1) { - pr_err("%s: cpu %d: invalid hw thread %d\n", - __func__, nr, cpu_thread_in_core(nr)); - return -ENOENT; - } + booting_thread_hwid = cpu_thread_in_core(nr); + primary = cpu_first_thread_sibling(nr); - if (!cpu_online(primary)) { - pr_err("%s: cpu %d: primary %d not online\n", - __func__, nr, primary); - return -ENOENT; + if (qoriq_pm_ops) + qoriq_pm_ops->cpu_up_prepare(nr); + + /* + * If either thread in the core is online, use it to start + * the other. + */ + if (cpu_online(primary)) { + smp_call_function_single(primary, + wake_hw_thread, &nr, 1); + goto done; + } else if (cpu_online(primary + 1)) { + smp_call_function_single(primary + 1, + wake_hw_thread, &nr, 1); + goto done; } - smp_call_function_single(primary, wake_hw_thread, &nr, 0); - return 0; + /* + * If getting here, it means both threads in the core are + * offline. So start the primary thread, then it will start + * the thread specified in booting_thread_hwid, the one + * corresponding to nr. + */ + + } else if (threads_per_core == 1) { + /* + * If one core has only one thread, set booting_thread_hwid to + * an invalid value. + */ + booting_thread_hwid = INVALID_THREAD_HWID; + + } else if (threads_per_core > 2) { + pr_err("Do not support more than 2 threads per CPU."); + return -EINVAL; } ret = smp_85xx_start_cpu(primary); if (ret) return ret; +done: paca[nr].cpu_start = 1; generic_set_cpu_up(nr);