15c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* 25c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights 35c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * reserved. 45c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 55c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * This software is available to you under a choice of one of two 65c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * licenses. You may choose to be licensed under the terms of the GNU 75c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * General Public License (GPL) Version 2, available from the file 85c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * COPYING in the main directory of this source tree, or the NetLogic 95c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * license below: 105c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 115c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Redistribution and use in source and binary forms, with or without 125c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * modification, are permitted provided that the following conditions 135c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * are met: 145c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 155c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 1. Redistributions of source code must retain the above copyright 165c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * notice, this list of conditions and the following disclaimer. 175c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 2. Redistributions in binary form must reproduce the above copyright 185c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * notice, this list of conditions and the following disclaimer in 195c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * the documentation and/or other materials provided with the 205c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * distribution. 215c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * 225c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR 235c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 245c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 255c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE 265c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 275c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 285c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 295c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 305c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 315c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 325c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 335c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C */ 345c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 355c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/kernel.h> 365c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/delay.h> 375c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/init.h> 385c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/smp.h> 395c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <linux/irq.h> 405c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 415c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/mmu_context.h> 425c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 435c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/interrupt.h> 445c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/mips-extns.h> 450c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C#include <asm/netlogic/haldefs.h> 460c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C#include <asm/netlogic/common.h> 475c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 4865040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#if defined(CONFIG_CPU_XLP) 4965040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#include <asm/netlogic/xlp-hal/iomap.h> 5066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C#include <asm/netlogic/xlp-hal/xlp.h> 5165040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#include <asm/netlogic/xlp-hal/pic.h> 5265040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#elif defined(CONFIG_CPU_XLR) 535c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/xlr/iomap.h> 545c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C#include <asm/netlogic/xlr/pic.h> 5566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C#include <asm/netlogic/xlr/xlr.h> 5665040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#else 5765040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#error "Unknown CPU" 5865040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#endif 595c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 600c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran Cvoid nlm_send_ipi_single(int logical_cpu, unsigned int action) 615c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 6277ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C int cpu, node; 6377ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C uint64_t picbase; 6477ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C 6577ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C cpu = cpu_logical_map(logical_cpu); 6698d4884ca55883e8b16180bd969a8bccaa885c80Jayachandran C node = nlm_cpuid_to_node(cpu); 6777ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C picbase = nlm_get_node(node)->picbase; 685c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 695c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C if (action & SMP_CALL_FUNCTION) 7077ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0); 710c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C if (action & SMP_RESCHEDULE_YOURSELF) 7277ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); 735c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 745c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 755c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) 765c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 775c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C int cpu; 785c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 795c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C for_each_cpu(cpu, mask) { 800c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C nlm_send_ipi_single(cpu, action); 815c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 825c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 835c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 845c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* IRQ_IPI_SMP_FUNCTION Handler */ 855c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) 865c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 87220d9122e8c5a467fdeefc1857e077f29a623bfdJayachandran C clear_c0_eimr(irq); 88220d9122e8c5a467fdeefc1857e077f29a623bfdJayachandran C ack_c0_eirr(irq); 8965040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C smp_call_function_interrupt(); 90220d9122e8c5a467fdeefc1857e077f29a623bfdJayachandran C set_c0_eimr(irq); 915c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 925c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 935c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* IRQ_IPI_SMP_RESCHEDULE handler */ 945c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) 955c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 96220d9122e8c5a467fdeefc1857e077f29a623bfdJayachandran C clear_c0_eimr(irq); 97220d9122e8c5a467fdeefc1857e077f29a623bfdJayachandran C ack_c0_eirr(irq); 9865040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C scheduler_ipi(); 99220d9122e8c5a467fdeefc1857e077f29a623bfdJayachandran C set_c0_eimr(irq); 1005c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1015c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1025c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* 1035c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Called before going into mips code, early cpu init 1045c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C */ 1050c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran Cvoid nlm_early_init_secondary(int cpu) 1065c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 10765040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C change_c0_config(CONF_CM_CMASK, 0x3); 10865040e224e5b214a93fa0c790add5d69b054ecaeJayachandran C#ifdef CONFIG_CPU_XLP 1095b6ff35d33cb0310c36f9081b9e39cd016715e9cJayachandran C xlp_mmu_init(); 1100c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C#endif 11177ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C write_c0_ebase(nlm_current_node()->ebase); 1125c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1135c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1145c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* 1155c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Code to run on secondary just after probing the CPU 1165c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C */ 117078a55fc824c1633b3a507e4ad48b4637c1dfc18Paul Gortmakerstatic void nlm_init_secondary(void) 1185c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 11938541742da05f65d77e514a70bae9b84251c4bc4Jayachandran C int hwtid; 12038541742da05f65d77e514a70bae9b84251c4bc4Jayachandran C 12138541742da05f65d77e514a70bae9b84251c4bc4Jayachandran C hwtid = hard_smp_processor_id(); 12238541742da05f65d77e514a70bae9b84251c4bc4Jayachandran C current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; 123ed21cfe207276e2d2883173399dd0380db372e18Ganesan Ramalingam nlm_percpu_init(hwtid); 12438541742da05f65d77e514a70bae9b84251c4bc4Jayachandran C nlm_smp_irq_init(hwtid); 1255c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1265c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 127b3ea581834c1e36cc76589e63dedcd99fd6abf51Hillf Dantonvoid nlm_prepare_cpus(unsigned int max_cpus) 128b3ea581834c1e36cc76589e63dedcd99fd6abf51Hillf Danton{ 129b3ea581834c1e36cc76589e63dedcd99fd6abf51Hillf Danton /* declare we are SMT capable */ 130b3ea581834c1e36cc76589e63dedcd99fd6abf51Hillf Danton smp_num_siblings = nlm_threads_per_core; 131b3ea581834c1e36cc76589e63dedcd99fd6abf51Hillf Danton} 132b3ea581834c1e36cc76589e63dedcd99fd6abf51Hillf Danton 1335c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid nlm_smp_finish(void) 1345c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 13539263eeb44308a5d6ea6117376721a6091d2b622Jayachandran C local_irq_enable(); 1365c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1375c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1385c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C/* 1395c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * Boot all other cpus in the system, initialize them, and bring them into 1405c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C * the boot function 1415c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C */ 1425c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cunsigned long nlm_next_gp; 1435c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cunsigned long nlm_next_sp; 14462b734d289989dd15ab7a52227879ce95db9a934Jayachandran Cstatic cpumask_t phys_cpu_present_mask; 1455c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1465c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid nlm_boot_secondary(int logical_cpu, struct task_struct *idle) 1475c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 14877ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C int cpu, node; 1495c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 15077ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C cpu = cpu_logical_map(logical_cpu); 15198d4884ca55883e8b16180bd969a8bccaa885c80Jayachandran C node = nlm_cpuid_to_node(logical_cpu); 15277ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_next_sp = (unsigned long)__KSTK_TOS(idle); 15377ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_next_gp = (unsigned long)task_thread_info(idle); 1545c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 15577ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C /* barrier for sp/gp store above */ 1565c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C __sync(); 15777ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1); /* NMI */ 1585c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 1595c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1605c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cvoid __init nlm_smp_setup(void) 1615c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C{ 1625c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C unsigned int boot_cpu; 16398d4884ca55883e8b16180bd969a8bccaa885c80Jayachandran C int num_cpus, i, ncore, node; 164919f9abb3723f088290c62648b12fbfc7600d923Jayachandran C volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY); 16562b734d289989dd15ab7a52227879ce95db9a934Jayachandran C char buf[64]; 1665c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1675c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C boot_cpu = hard_smp_processor_id(); 16862b734d289989dd15ab7a52227879ce95db9a934Jayachandran C cpumask_clear(&phys_cpu_present_mask); 1695c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 17062b734d289989dd15ab7a52227879ce95db9a934Jayachandran C cpumask_set_cpu(boot_cpu, &phys_cpu_present_mask); 1715c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C __cpu_number_map[boot_cpu] = 0; 1725c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C __cpu_logical_map[0] = boot_cpu; 1730b5f9c005def154f9c21f9be0223b65b50d54368Rusty Russell set_cpu_possible(0, true); 1745c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 1755c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C num_cpus = 1; 1765c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C for (i = 0; i < NR_CPUS; i++) { 177b2788965baed868ce48ebd6d67f00acf617c9ee6Hillf Danton /* 178919f9abb3723f088290c62648b12fbfc7600d923Jayachandran C * cpu_ready array is not set for the boot_cpu, 1790c9654072a6e15aa3da9b314f0c5c01e90938268Jayachandran C * it is only set for ASPs (see smpboot.S) 180b2788965baed868ce48ebd6d67f00acf617c9ee6Hillf Danton */ 181919f9abb3723f088290c62648b12fbfc7600d923Jayachandran C if (cpu_ready[i]) { 18262b734d289989dd15ab7a52227879ce95db9a934Jayachandran C cpumask_set_cpu(i, &phys_cpu_present_mask); 1835c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C __cpu_number_map[i] = num_cpus; 1845c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C __cpu_logical_map[num_cpus] = i; 1850b5f9c005def154f9c21f9be0223b65b50d54368Rusty Russell set_cpu_possible(num_cpus, true); 18698d4884ca55883e8b16180bd969a8bccaa885c80Jayachandran C node = nlm_cpuid_to_node(i); 18798d4884ca55883e8b16180bd969a8bccaa885c80Jayachandran C cpumask_set_cpu(num_cpus, &nlm_get_node(node)->cpumask); 1885c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C ++num_cpus; 1895c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 1905c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C } 1915c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 19262b734d289989dd15ab7a52227879ce95db9a934Jayachandran C cpumask_scnprintf(buf, ARRAY_SIZE(buf), &phys_cpu_present_mask); 19362b734d289989dd15ab7a52227879ce95db9a934Jayachandran C pr_info("Physical CPU mask: %s\n", buf); 19462b734d289989dd15ab7a52227879ce95db9a934Jayachandran C cpumask_scnprintf(buf, ARRAY_SIZE(buf), cpu_possible_mask); 19562b734d289989dd15ab7a52227879ce95db9a934Jayachandran C pr_info("Possible CPU mask: %s\n", buf); 19662b734d289989dd15ab7a52227879ce95db9a934Jayachandran C 1972e240ddd09d41645e928a19a3ff3290a0f546834Jayachandran C /* check with the cores we have woken up */ 19877ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C for (ncore = 0, i = 0; i < NLM_NR_NODES; i++) 19977ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C ncore += hweight32(nlm_get_node(i)->coremask); 20077ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C 20177ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C pr_info("Detected (%dc%dt) %d Slave CPU(s)\n", ncore, 20277ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C nlm_threads_per_core, num_cpus); 20362b734d289989dd15ab7a52227879ce95db9a934Jayachandran C 20462b734d289989dd15ab7a52227879ce95db9a934Jayachandran C /* switch NMI handler to boot CPUs */ 20566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C nlm_set_nmi_handler(nlm_boot_secondary_cpus); 2065c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C} 2075c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C 2082a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran Cstatic int nlm_parse_cpumask(cpumask_t *wakeup_mask) 20966d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C{ 21066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C uint32_t core0_thr_mask, core_thr_mask; 2112a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C int threadmode, i, j; 2122e240ddd09d41645e928a19a3ff3290a0f546834Jayachandran C char buf[64]; 21366d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 2142a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C core0_thr_mask = 0; 21577ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C for (i = 0; i < NLM_THREADS_PER_CORE; i++) 2162a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C if (cpumask_test_cpu(i, wakeup_mask)) 2172a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C core0_thr_mask |= (1 << i); 21866d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C switch (core0_thr_mask) { 21966d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C case 1: 22066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C nlm_threads_per_core = 1; 22166d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C threadmode = 0; 22266d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C break; 22366d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C case 3: 22466d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C nlm_threads_per_core = 2; 22566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C threadmode = 2; 22666d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C break; 22766d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C case 0xf: 22866d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C nlm_threads_per_core = 4; 22966d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C threadmode = 3; 23066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C break; 23166d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C default: 23266d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C goto unsupp; 23366d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C } 23466d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 23566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C /* Verify other cores CPU masks */ 23677ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C for (i = 0; i < NR_CPUS; i += NLM_THREADS_PER_CORE) { 2372a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C core_thr_mask = 0; 23877ae798f5b736dfdc692b86b393d9699052ac77aJayachandran C for (j = 0; j < NLM_THREADS_PER_CORE; j++) 2392a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C if (cpumask_test_cpu(i + j, wakeup_mask)) 2402a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C core_thr_mask |= (1 << j); 2412a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask) 24266d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C goto unsupp; 24366d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C } 24466d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C return threadmode; 24566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 24666d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran Cunsupp: 2472e240ddd09d41645e928a19a3ff3290a0f546834Jayachandran C cpumask_scnprintf(buf, ARRAY_SIZE(buf), wakeup_mask); 2482e240ddd09d41645e928a19a3ff3290a0f546834Jayachandran C panic("Unsupported CPU mask %s", buf); 24966d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C return 0; 25066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C} 25166d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 252078a55fc824c1633b3a507e4ad48b4637c1dfc18Paul Gortmakerint nlm_wakeup_secondary_cpus(void) 25366d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C{ 25453c832197f3adc5a360336f75fe34a95fe2d796bJayachandran C u32 *reset_data; 25566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C int threadmode; 25666d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 25766d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C /* verify the mask and setup core config variables */ 2582a37b1ae443f20470a789b12a45cbc249c9e50a6Jayachandran C threadmode = nlm_parse_cpumask(&nlm_cpumask); 25966d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 26066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C /* Setup CPU init parameters */ 26153c832197f3adc5a360336f75fe34a95fe2d796bJayachandran C reset_data = nlm_get_boot_data(BOOT_THREAD_MODE); 26253c832197f3adc5a360336f75fe34a95fe2d796bJayachandran C *reset_data = threadmode; 26366d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 26466d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C#ifdef CONFIG_CPU_XLP 26566d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C xlp_wakeup_secondary_cpus(); 26666d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C#else 26766d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C xlr_wakeup_secondary_cpus(); 26866d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C#endif 26966d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C return 0; 27066d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C} 27166d29985fab8207b1b2c03ac34a2c294c5b47a30Jayachandran C 2725c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran Cstruct plat_smp_ops nlm_smp_ops = { 2735c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .send_ipi_single = nlm_send_ipi_single, 2745c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .send_ipi_mask = nlm_send_ipi_mask, 2755c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .init_secondary = nlm_init_secondary, 2765c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .smp_finish = nlm_smp_finish, 2775c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .boot_secondary = nlm_boot_secondary, 2785c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .smp_setup = nlm_smp_setup, 2795c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C .prepare_cpus = nlm_prepare_cpus, 2805c642506740ecbf20fb7a9e482287e4e5c639e5cJayachandran C}; 281