···14411441 select SMP14421442 select SYS_SUPPORTS_SCHED_SMT if SMP14431443 select SYS_SUPPORTS_SMP14441444+ select SMP_UP14441445 help14451446 This is a kernel model which is also known a VSMP or lately14461447 has been marketesed into SMVP.···14581457 select NR_CPUS_DEFAULT_814591458 select SMP14601459 select SYS_SUPPORTS_SMP14601460+ select SMP_UP14611461 help14621462 This is a kernel model which is known a SMTC or lately has been14631463 marketesed into SMVP.···17361734 available at <http://www.tldp.org/docs.html#howto>.1737173517381736 If you don't know what to do here, say N.17371737+17381738+config SMP_UP17391739+ bool1739174017401741config SYS_SUPPORTS_SMP17411742 bool
···215215 write_tc_c0_tchalt(TCHALT_H);216216}217217218218+static void vsmp_send_ipi_single(int cpu, unsigned int action)219219+{220220+ int i;221221+ unsigned long flags;222222+ int vpflags;223223+224224+ local_irq_save(flags);225225+226226+ vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */227227+228228+ switch (action) {229229+ case SMP_CALL_FUNCTION:230230+ i = C_SW1;231231+ break;232232+233233+ case SMP_RESCHEDULE_YOURSELF:234234+ default:235235+ i = C_SW0;236236+ break;237237+ }238238+239239+ /* 1:1 mapping of vpe and tc... */240240+ settc(cpu);241241+ write_vpe_c0_cause(read_vpe_c0_cause() | i);242242+ evpe(vpflags);243243+244244+ local_irq_restore(flags);245245+}246246+247247+static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)248248+{249249+ unsigned int i;250250+251251+ for_each_cpu_mask(i, mask)252252+ vsmp_send_ipi_single(i, action);253253+}254254+255255+static void __cpuinit vsmp_init_secondary(void)256256+{257257+ /* Enable per-cpu interrupts */258258+259259+ /* This is Malta specific: IPI,performance and timer inetrrupts */260260+ write_c0_status((read_c0_status() & ~ST0_IM ) |261261+ (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));262262+}263263+264264+static void __cpuinit vsmp_smp_finish(void)265265+{266266+ write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));267267+268268+#ifdef CONFIG_MIPS_MT_FPAFF269269+ /* If we have an FPU, enroll ourselves in the FPU-full mask */270270+ if (cpu_has_fpu)271271+ cpu_set(smp_processor_id(), mt_fpu_cpumask);272272+#endif /* CONFIG_MIPS_MT_FPAFF */273273+274274+ local_irq_enable();275275+}276276+277277+static void vsmp_cpus_done(void)278278+{279279+}280280+281281+/*282282+ * Setup the PC, SP, and GP of a secondary processor and start it283283+ * running!284284+ * smp_bootstrap is the place to resume from285285+ * __KSTK_TOS(idle) is apparently the stack pointer286286+ * (unsigned long)idle->thread_info the gp287287+ * assumes a 1:1 mapping of TC => VPE288288+ */289289+static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)290290+{291291+ struct thread_info *gp = task_thread_info(idle);292292+ dvpe();293293+ set_c0_mvpcontrol(MVPCONTROL_VPC);294294+295295+ settc(cpu);296296+297297+ /* restart */298298+ write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);299299+300300+ /* enable the tc this vpe/cpu will be running */301301+ write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);302302+303303+ write_tc_c0_tchalt(0);304304+305305+ /* enable the VPE */306306+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);307307+308308+ /* stack pointer */309309+ write_tc_gpr_sp( __KSTK_TOS(idle));310310+311311+ /* global pointer */312312+ write_tc_gpr_gp((unsigned long)gp);313313+314314+ flush_icache_range((unsigned long)gp,315315+ (unsigned long)(gp + sizeof(struct thread_info)));316316+317317+ /* finally out of configuration and into chaos */318318+ clear_c0_mvpcontrol(MVPCONTROL_VPC);319319+320320+ evpe(EVPE_ENABLE);321321+}322322+218323/*219324 * Common setup before any secondaries are started220325 * Make sure all CPU's are in a sensible state before we boot any of the221326 * secondarys222327 */223223-void __init plat_smp_setup(void)328328+static void __init vsmp_smp_setup(void)224329{225330 unsigned int mvpconf0, ntc, tc, ncpu = 0;226331 unsigned int nvpe;···368263 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);369264}370265371371-void __init plat_prepare_cpus(unsigned int max_cpus)266266+static void __init vsmp_prepare_cpus(unsigned int max_cpus)372267{373268 mips_mt_set_cpuoptions();374269···388283 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);389284}390285391391-/*392392- * Setup the PC, SP, and GP of a secondary processor and start it393393- * running!394394- * smp_bootstrap is the place to resume from395395- * __KSTK_TOS(idle) is apparently the stack pointer396396- * (unsigned long)idle->thread_info the gp397397- * assumes a 1:1 mapping of TC => VPE398398- */399399-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)400400-{401401- struct thread_info *gp = task_thread_info(idle);402402- dvpe();403403- set_c0_mvpcontrol(MVPCONTROL_VPC);404404-405405- settc(cpu);406406-407407- /* restart */408408- write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);409409-410410- /* enable the tc this vpe/cpu will be running */411411- write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);412412-413413- write_tc_c0_tchalt(0);414414-415415- /* enable the VPE */416416- write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);417417-418418- /* stack pointer */419419- write_tc_gpr_sp( __KSTK_TOS(idle));420420-421421- /* global pointer */422422- write_tc_gpr_gp((unsigned long)gp);423423-424424- flush_icache_range((unsigned long)gp,425425- (unsigned long)(gp + sizeof(struct thread_info)));426426-427427- /* finally out of configuration and into chaos */428428- clear_c0_mvpcontrol(MVPCONTROL_VPC);429429-430430- evpe(EVPE_ENABLE);431431-}432432-433433-void __cpuinit prom_init_secondary(void)434434-{435435- /* Enable per-cpu interrupts */436436-437437- /* This is Malta specific: IPI,performance and timer inetrrupts */438438- write_c0_status((read_c0_status() & ~ST0_IM ) |439439- (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));440440-}441441-442442-void __cpuinit prom_smp_finish(void)443443-{444444- write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));445445-446446-#ifdef CONFIG_MIPS_MT_FPAFF447447- /* If we have an FPU, enroll ourselves in the FPU-full mask */448448- if (cpu_has_fpu)449449- cpu_set(smp_processor_id(), mt_fpu_cpumask);450450-#endif /* CONFIG_MIPS_MT_FPAFF */451451-452452- local_irq_enable();453453-}454454-455455-void prom_cpus_done(void)456456-{457457-}458458-459459-void core_send_ipi(int cpu, unsigned int action)460460-{461461- int i;462462- unsigned long flags;463463- int vpflags;464464-465465- local_irq_save(flags);466466-467467- vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */468468-469469- switch (action) {470470- case SMP_CALL_FUNCTION:471471- i = C_SW1;472472- break;473473-474474- case SMP_RESCHEDULE_YOURSELF:475475- default:476476- i = C_SW0;477477- break;478478- }479479-480480- /* 1:1 mapping of vpe and tc... */481481- settc(cpu);482482- write_vpe_c0_cause(read_vpe_c0_cause() | i);483483- evpe(vpflags);484484-485485- local_irq_restore(flags);486486-}286286+struct plat_smp_ops vsmp_smp_ops = {287287+ .send_ipi_single = vsmp_send_ipi_single,288288+ .send_ipi_mask = vsmp_send_ipi_mask,289289+ .init_secondary = vsmp_init_secondary,290290+ .smp_finish = vsmp_smp_finish,291291+ .cpus_done = vsmp_cpus_done,292292+ .boot_secondary = vsmp_boot_secondary,293293+ .smp_setup = vsmp_smp_setup,294294+ .prepare_cpus = vsmp_prepare_cpus,295295+};
+16-7
arch/mips/kernel/smp.c
···3737#include <asm/processor.h>3838#include <asm/system.h>3939#include <asm/mmu_context.h>4040-#include <asm/smp.h>4140#include <asm/time.h>42414342#ifdef CONFIG_MIPS_MT_SMTC···8384 cpu_set(cpu, cpu_sibling_map[cpu]);8485}85868787+struct plat_smp_ops *mp_ops;8888+8989+__cpuinit void register_smp_ops(struct plat_smp_ops *ops)9090+{9191+ if (ops)9292+ printk(KERN_WARNING "Overriding previous set SMP ops\n");9393+9494+ mp_ops = ops;9595+}9696+8697/*8798 * First C code run on the secondary CPUs after being started up by8899 * the master.···109100 cpu_report();110101 per_cpu_trap_init();111102 mips_clockevent_init();112112- prom_init_secondary();103103+ mp_ops->init_secondary();113104114105 /*115106 * XXX parity protection should be folded in here when it's converted···121112 cpu = smp_processor_id();122113 cpu_data[cpu].udelay_val = loops_per_jiffy;123114124124- prom_smp_finish();115115+ mp_ops->smp_finish();125116 set_cpu_sibling_map(cpu);126117127118 cpu_set(cpu, cpu_callin_map);···193184 smp_mb();194185195186 /* Send a message to all other CPUs and wait for them to respond */196196- core_send_ipi_mask(mask, SMP_CALL_FUNCTION);187187+ mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);197188198189 /* Wait for response */199190 /* FIXME: lock-up detection, backtrace on lock-up */···287278288279void __init smp_cpus_done(unsigned int max_cpus)289280{290290- prom_cpus_done();281281+ mp_ops->cpus_done();291282}292283293284/* called from main before smp_init() */···295286{296287 init_new_context(current, &init_mm);297288 current_thread_info()->cpu = 0;298298- plat_prepare_cpus(max_cpus);289289+ mp_ops->prepare_cpus(max_cpus);299290 set_cpu_sibling_map(0);300291#ifndef CONFIG_HOTPLUG_CPU301292 cpu_present_map = cpu_possible_map;···334325 if (IS_ERR(idle))335326 panic(KERN_ERR "Fork failed for CPU %d", cpu);336327337337- prom_boot_secondary(cpu, idle);328328+ mp_ops->boot_secondary(cpu, idle);338329339330 /*340331 * Trust is futile. We should really have timeouts ...
···1616 *1717 */1818/*1919- * Simulator Platform-specific hooks for SMP operation1919+ * Simulator Platform-specific hooks for SMTC operation2020 */2121#include <linux/kernel.h>2222#include <linux/sched.h>···2929#include <asm/processor.h>3030#include <asm/system.h>3131#include <asm/mmu_context.h>3232-#ifdef CONFIG_MIPS_MT_SMTC3332#include <asm/smtc_ipi.h>3434-#endif /* CONFIG_MIPS_MT_SMTC */35333634/* VPE/SMP Prototype implements platform interfaces directly */3737-#if !defined(CONFIG_MIPS_MT_SMP)38353936/*4037 * Cause the specified action to be performed on a targeted "CPU"4138 */42394343-void core_send_ipi(int cpu, unsigned int action)4040+static void ssmtc_send_ipi_single(int cpu, unsigned int action)4441{4545-#ifdef CONFIG_MIPS_MT_SMTC4642 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);4747-#endif /* CONFIG_MIPS_MT_SMTC */4848-/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */4949-4343+ /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */5044}51455252-/*5353- * Platform "CPU" startup hook5454- */5555-5656-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)4646+static inline void ssmtc_send_ipi_mask(cpumask_t mask, unsigned int action)5747{5858-#ifdef CONFIG_MIPS_MT_SMTC5959- smtc_boot_secondary(cpu, idle);6060-#endif /* CONFIG_MIPS_MT_SMTC */4848+ unsigned int i;4949+5050+ for_each_cpu_mask(i, mask)5151+ ssmtc_send_ipi_single(i, action);6152}62536354/*6455 * Post-config but pre-boot cleanup entry point6556 */6666-6767-void __cpuinit prom_init_secondary(void)5757+static void __cpuinit ssmtc_init_secondary(void)6858{6969-#ifdef CONFIG_MIPS_MT_SMTC7059 void smtc_init_secondary(void);71607261 smtc_init_secondary();7373-#endif /* CONFIG_MIPS_MT_SMTC */7462}75637676-void plat_smp_setup(void)6464+/*6565+ * SMP initialization finalization entry point6666+ */6767+static void __cpuinit ssmtc_smp_finish(void)7768{7878-#ifdef CONFIG_MIPS_MT_SMTC6969+ smtc_smp_finish();7070+}7171+7272+/*7373+ * Hook for after all CPUs are online7474+ */7575+static void ssmtc_cpus_done(void)7676+{7777+}7878+7979+/*8080+ * Platform "CPU" startup hook8181+ */8282+static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle)8383+{8484+ smtc_boot_secondary(cpu, idle);8585+}8686+8787+static void __init ssmtc_smp_setup(void)8888+{7989 if (read_c0_config3() & (1 << 2))8090 mipsmt_build_cpu_map(0);8181-#endif /* CONFIG_MIPS_MT_SMTC */8291}83928493/*8594 * Platform SMP pre-initialization8695 */8787-8888-void plat_prepare_cpus(unsigned int max_cpus)9696+static void ssmtc_prepare_cpus(unsigned int max_cpus)8997{9090-#ifdef CONFIG_MIPS_MT_SMTC9198 /*9299 * As noted above, we can assume a single CPU for now93100 * but it may be multithreaded.···10396 if (read_c0_config3() & (1 << 2)) {10497 mipsmt_prepare_cpus();10598 }106106-#endif /* CONFIG_MIPS_MT_SMTC */10799}108100109109-/*110110- * SMP initialization finalization entry point111111- */112112-113113-void __cpuinit prom_smp_finish(void)114114-{115115-#ifdef CONFIG_MIPS_MT_SMTC116116- smtc_smp_finish();117117-#endif /* CONFIG_MIPS_MT_SMTC */118118-}119119-120120-/*121121- * Hook for after all CPUs are online122122- */123123-124124-void prom_cpus_done(void)125125-{126126-#ifdef CONFIG_MIPS_MT_SMTC127127-128128-#endif /* CONFIG_MIPS_MT_SMTC */129129-}130130-#endif /* CONFIG_MIPS32R2_MT_SMP */101101+struct plat_smp_ops ssmtc_smp_ops = {102102+ .send_ipi_single = ssmtc_send_ipi_single,103103+ .send_ipi_mask = ssmtc_send_ipi_mask,104104+ .init_secondary = ssmtc_init_secondary,105105+ .smp_finish = ssmtc_smp_finish,106106+ .cpus_done = ssmtc_cpus_done,107107+ .boot_secondary = ssmtc_boot_secondary,108108+ .smp_setup = ssmtc_smp_setup,109109+ .prepare_cpus = ssmtc_prepare_cpus,110110+};
+5
arch/mips/pmc-sierra/yosemite/prom.c
···1919#include <asm/pgtable.h>2020#include <asm/processor.h>2121#include <asm/reboot.h>2222+#include <asm/smp-ops.h>2223#include <asm/system.h>2324#include <asm/bootinfo.h>2425#include <asm/pmon.h>···7978 __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");8079}81808181+extern struct plat_smp_ops yos_smp_ops;8282+8283/*8384 * Init routine which accepts the variables from PMON8485 */···130127 }131128132129 prom_grab_secondary();130130+131131+ register_smp_ops(&yos_smp_ops);133132}134133135134void __init prom_free_prom_memory(void)
+84-65
arch/mips/pmc-sierra/yosemite/smp.c
···4242 launchstack + LAUNCHSTACK_SIZE, 0);4343}44444545-/*4646- * Detect available CPUs, populate phys_cpu_present_map before smp_init4747- *4848- * We don't want to start the secondary CPU yet nor do we have a nice probing4949- * feature in PMON so we just assume presence of the secondary core.5050- */5151-void __init plat_smp_setup(void)5252-{5353- int i;5454-5555- cpus_clear(phys_cpu_present_map);5656-5757- for (i = 0; i < 2; i++) {5858- cpu_set(i, phys_cpu_present_map);5959- __cpu_number_map[i] = i;6060- __cpu_logical_map[i] = i;6161- }6262-}6363-6464-void __init plat_prepare_cpus(unsigned int max_cpus)6565-{6666- /*6767- * Be paranoid. Enable the IPI only if we're really about to go SMP.6868- */6969- if (cpus_weight(cpu_possible_map))7070- set_c0_status(STATUSF_IP5);7171-}7272-7373-/*7474- * Firmware CPU startup hook7575- * Complicated by PMON's weird interface which tries to minimic the UNIX fork.7676- * It launches the next * available CPU and copies some information on the7777- * stack so the first thing we do is throw away that stuff and load useful7878- * values into the registers ...7979- */8080-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)8181-{8282- unsigned long gp = (unsigned long) task_thread_info(idle);8383- unsigned long sp = __KSTK_TOS(idle);8484-8585- secondary_sp = sp;8686- secondary_gp = gp;8787-8888- spin_unlock(&launch_lock);8989-}9090-9191-/* Hook for after all CPUs are online */9292-void prom_cpus_done(void)9393-{9494-}9595-9696-/*9797- * After we've done initial boot, this function is called to allow the9898- * board code to clean up state, if needed9999- */100100-void __cpuinit prom_init_secondary(void)101101-{102102- set_c0_status(ST0_CO | ST0_IE | ST0_IM);103103-}104104-105105-void __cpuinit prom_smp_finish(void)106106-{107107-}108108-10945void titan_mailbox_irq(void)11046{11147 int cpu = smp_processor_id();···69133/*70134 * Send inter-processor interrupt71135 */7272-void core_send_ipi(int cpu, unsigned int action)136136+static void yos_send_ipi_single(int cpu, unsigned int action)73137{74138 /*75139 * Generate an INTMSG so that it can be sent over to the···95159 break;96160 }97161}162162+163163+static void yos_send_ipi_mask(cpumask_t mask, unsigned int action)164164+{165165+ unsigned int i;166166+167167+ for_each_cpu_mask(i, mask)168168+ yos_send_ipi_single(i, action);169169+}170170+171171+/*172172+ * After we've done initial boot, this function is called to allow the173173+ * board code to clean up state, if needed174174+ */175175+static void __cpuinit yos_init_secondary(void)176176+{177177+ set_c0_status(ST0_CO | ST0_IE | ST0_IM);178178+}179179+180180+static void __cpuinit yos_smp_finish(void)181181+{182182+}183183+184184+/* Hook for after all CPUs are online */185185+static void yos_cpus_done(void)186186+{187187+}188188+189189+/*190190+ * Firmware CPU startup hook191191+ * Complicated by PMON's weird interface which tries to minimic the UNIX fork.192192+ * It launches the next * available CPU and copies some information on the193193+ * stack so the first thing we do is throw away that stuff and load useful194194+ * values into the registers ...195195+ */196196+static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle)197197+{198198+ unsigned long gp = (unsigned long) task_thread_info(idle);199199+ unsigned long sp = __KSTK_TOS(idle);200200+201201+ secondary_sp = sp;202202+ secondary_gp = gp;203203+204204+ spin_unlock(&launch_lock);205205+}206206+207207+/*208208+ * Detect available CPUs, populate phys_cpu_present_map before smp_init209209+ *210210+ * We don't want to start the secondary CPU yet nor do we have a nice probing211211+ * feature in PMON so we just assume presence of the secondary core.212212+ */213213+static void __init yos_smp_setup(void)214214+{215215+ int i;216216+217217+ cpus_clear(phys_cpu_present_map);218218+219219+ for (i = 0; i < 2; i++) {220220+ cpu_set(i, phys_cpu_present_map);221221+ __cpu_number_map[i] = i;222222+ __cpu_logical_map[i] = i;223223+ }224224+}225225+226226+static void __init yos_prepare_cpus(unsigned int max_cpus)227227+{228228+ /*229229+ * Be paranoid. Enable the IPI only if we're really about to go SMP.230230+ */231231+ if (cpus_weight(cpu_possible_map))232232+ set_c0_status(STATUSF_IP5);233233+}234234+235235+struct plat_smp_ops yos_smp_ops = {236236+ .send_ipi_single = yos_send_ipi_single,237237+ .send_ipi_mask = yos_send_ipi_mask,238238+ .init_secondary = yos_init_secondary,239239+ .smp_finish = yos_smp_finish,240240+ .cpus_done = yos_cpus_done,241241+ .boot_secondary = yos_boot_secondary,242242+ .smp_setup = yos_smp_setup,243243+ .prepare_cpus = yos_prepare_cpus,244244+};
+26-14
arch/mips/qemu/q-smp.c
···33 * License. See the file "COPYING" in the main directory of this archive44 * for more details.55 *66- * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)66+ * Copyright (C) 2006, 07 by Ralf Baechle (ralf@linux-mips.org)77 *88 * Symmetric Uniprocessor (TM) Support99 */···1313/*1414 * Send inter-processor interrupt1515 */1616-void core_send_ipi(int cpu, unsigned int action)1616+void up_send_ipi_single(int cpu, unsigned int action)1717{1818- panic(KERN_ERR "%s called", __FUNCTION__);1818+ panic(KERN_ERR "%s called", __func__);1919+}2020+2121+static inline void up_send_ipi_mask(cpumask_t mask, unsigned int action)2222+{2323+ panic(KERN_ERR "%s called", __func__);1924}20252126/*2227 * After we've done initial boot, this function is called to allow the2328 * board code to clean up state, if needed2429 */2525-void __cpuinit prom_init_secondary(void)3030+void __cpuinit up_init_secondary(void)2631{2732}28332929-void __cpuinit prom_smp_finish(void)3434+void __cpuinit up_smp_finish(void)3035{3136}32373338/* Hook for after all CPUs are online */3434-void prom_cpus_done(void)3939+void up_cpus_done(void)3540{3636-}3737-3838-void __init prom_prepare_cpus(unsigned int max_cpus)3939-{4040- cpus_clear(phys_cpu_present_map);4141}42424343/*4444 * Firmware CPU startup hook4545 */4646-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)4646+void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)4747{4848}49495050-void __init plat_smp_setup(void)5050+void __init up_smp_setup(void)5151{5252}5353-void __init plat_prepare_cpus(unsigned int max_cpus)5353+5454+void __init up_prepare_cpus(unsigned int max_cpus)5455{5556}5757+5858+struct plat_smp_ops up_smp_ops = {5959+ .send_ipi_single = up_send_ipi_single,6060+ .send_ipi_mask = up_send_ipi_mask,6161+ .init_secondary = up_init_secondary,6262+ .smp_finish = up_smp_finish,6363+ .cpus_done = up_cpus_done,6464+ .boot_secondary = up_boot_secondary,6565+ .smp_setup = up_smp_setup,6666+ .prepare_cpus = up_prepare_cpus,6767+};
···140140 REMOTE_HUB_CLR_INTR(nasid, i);141141}142142143143-void __init plat_smp_setup(void)144144-{145145- cnodeid_t cnode;146146-147147- for_each_online_node(cnode) {148148- if (cnode == 0)149149- continue;150150- intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));151151- }152152-153153- replicate_kernel_text();154154-155155- /*156156- * Assumption to be fixed: we're always booted on logical / physical157157- * processor 0. While we're always running on logical processor 0158158- * this still means this is physical processor zero; it might for159159- * example be disabled in the firwware.160160- */161161- alloc_cpupda(0, 0);162162-}163163-164164-void __init plat_prepare_cpus(unsigned int max_cpus)165165-{166166- /* We already did everything necessary earlier */167167-}168168-169169-/*170170- * Launch a slave into smp_bootstrap(). It doesn't take an argument, and we171171- * set sp to the kernel stack of the newly created idle process, gp to the proc172172- * struct so that current_thread_info() will work.173173- */174174-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)175175-{176176- unsigned long gp = (unsigned long)task_thread_info(idle);177177- unsigned long sp = __KSTK_TOS(idle);178178-179179- LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),180180- (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),181181- 0, (void *) sp, (void *) gp);182182-}183183-184184-void __cpuinit prom_init_secondary(void)185185-{186186- per_cpu_init();187187- local_irq_enable();188188-}189189-190190-void __init prom_cpus_done(void)191191-{192192-}193193-194194-void __cpuinit prom_smp_finish(void)195195-{196196-}197197-198198-void core_send_ipi(int destid, unsigned int action)143143+static void ip27_send_ipi_single(int destid, unsigned int action)199144{200145 int irq;201146···164219 */165220 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);166221}222222+223223+static void ip27_send_ipi_mask(cpumask_t mask, unsigned int action)224224+{225225+ unsigned int i;226226+227227+ for_each_cpu_mask(i, mask)228228+ ip27_send_ipi_single(i, action);229229+}230230+231231+static void __cpuinit ip27_init_secondary(void)232232+{233233+ per_cpu_init();234234+ local_irq_enable();235235+}236236+237237+static void __cpuinit ip27_smp_finish(void)238238+{239239+}240240+241241+static void __init ip27_cpus_done(void)242242+{243243+}244244+245245+/*246246+ * Launch a slave into smp_bootstrap(). It doesn't take an argument, and we247247+ * set sp to the kernel stack of the newly created idle process, gp to the proc248248+ * struct so that current_thread_info() will work.249249+ */250250+static void __cpuinit ip27_boot_secondary(int cpu, struct task_struct *idle)251251+{252252+ unsigned long gp = (unsigned long)task_thread_info(idle);253253+ unsigned long sp = __KSTK_TOS(idle);254254+255255+ LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),256256+ (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),257257+ 0, (void *) sp, (void *) gp);258258+}259259+260260+static void __init ip27_smp_setup(void)261261+{262262+ cnodeid_t cnode;263263+264264+ for_each_online_node(cnode) {265265+ if (cnode == 0)266266+ continue;267267+ intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));268268+ }269269+270270+ replicate_kernel_text();271271+272272+ /*273273+ * Assumption to be fixed: we're always booted on logical / physical274274+ * processor 0. While we're always running on logical processor 0275275+ * this still means this is physical processor zero; it might for276276+ * example be disabled in the firwware.277277+ */278278+ alloc_cpupda(0, 0);279279+}280280+281281+static void __init ip27_prepare_cpus(unsigned int max_cpus)282282+{283283+ /* We already did everything necessary earlier */284284+}285285+286286+struct plat_smp_ops ip27_smp_ops = {287287+ .send_ipi_single = ip27_send_ipi_single,288288+ .send_ipi_mask = ip27_send_ipi_mask,289289+ .init_secondary = ip27_init_secondary,290290+ .smp_finish = ip27_smp_finish,291291+ .cpus_done = ip27_cpus_done,292292+ .boot_secondary = ip27_boot_secondary,293293+ .smp_setup = ip27_smp_setup,294294+ .prepare_cpus = ip27_prepare_cpus,295295+};
+96-9
arch/mips/sibyte/bcm1480/smp.c
···23232424#include <asm/mmu_context.h>2525#include <asm/io.h>2626+#include <asm/fw/cfe/cfe_api.h>2627#include <asm/sibyte/sb1250.h>2728#include <asm/sibyte/bcm1480_regs.h>2829#include <asm/sibyte/bcm1480_int.h>···6867 change_c0_status(ST0_IM, imask);6968}70697171-void __cpuinit bcm1480_smp_finish(void)7272-{7373- extern void sb1480_clockevent_init(void);7474-7575- sb1480_clockevent_init();7676- local_irq_enable();7777-}7878-7970/*8071 * These are routines for dealing with the sb1250 smp capabilities8172 * independent of board/firmware···7784 * Simple enough; everything is set up, so just poke the appropriate mailbox7885 * register, and we should be set7986 */8080-void core_send_ipi(int cpu, unsigned int action)8787+static void bcm1480_send_ipi_single(int cpu, unsigned int action)8188{8289 __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);8390}9191+9292+static void bcm1480_send_ipi_mask(cpumask_t mask, unsigned int action)9393+{9494+ unsigned int i;9595+9696+ for_each_cpu_mask(i, mask)9797+ bcm1480_send_ipi_single(i, action);9898+}9999+100100+/*101101+ * Code to run on secondary just after probing the CPU102102+ */103103+static void __cpuinit bcm1480_init_secondary(void)104104+{105105+ extern void bcm1480_smp_init(void);106106+107107+ bcm1480_smp_init();108108+}109109+110110+/*111111+ * Do any tidying up before marking online and running the idle112112+ * loop113113+ */114114+static void __cpuinit bcm1480_smp_finish(void)115115+{116116+ extern void sb1480_clockevent_init(void);117117+118118+ sb1480_clockevent_init();119119+ local_irq_enable();120120+ bcm1480_smp_finish();121121+}122122+123123+/*124124+ * Final cleanup after all secondaries booted125125+ */126126+static void bcm1480_cpus_done(void)127127+{128128+}129129+130130+/*131131+ * Setup the PC, SP, and GP of a secondary processor and start it132132+ * running!133133+ */134134+static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle)135135+{136136+ int retval;137137+138138+ retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,139139+ __KSTK_TOS(idle),140140+ (unsigned long)task_thread_info(idle), 0);141141+ if (retval != 0)142142+ printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);143143+}144144+145145+/*146146+ * Use CFE to find out how many CPUs are available, setting up147147+ * phys_cpu_present_map and the logical/physical mappings.148148+ * XXXKW will the boot CPU ever not be physical 0?149149+ *150150+ * Common setup before any secondaries are started151151+ */152152+static void __init bcm1480_smp_setup(void)153153+{154154+ int i, num;155155+156156+ cpus_clear(phys_cpu_present_map);157157+ cpu_set(0, phys_cpu_present_map);158158+ __cpu_number_map[0] = 0;159159+ __cpu_logical_map[0] = 0;160160+161161+ for (i = 1, num = 0; i < NR_CPUS; i++) {162162+ if (cfe_cpu_stop(i) == 0) {163163+ cpu_set(i, phys_cpu_present_map);164164+ __cpu_number_map[i] = ++num;165165+ __cpu_logical_map[num] = i;166166+ }167167+ }168168+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);169169+}170170+171171+static void __init bcm1480_prepare_cpus(unsigned int max_cpus)172172+{173173+}174174+175175+struct plat_smp_ops bcm1480_smp_ops = {176176+ .send_ipi_single = bcm1480_send_ipi_single,177177+ .send_ipi_mask = bcm1480_send_ipi_mask,178178+ .init_secondary = bcm1480_init_secondary,179179+ .smp_finish = bcm1480_smp_finish,180180+ .cpus_done = bcm1480_cpus_done,181181+ .boot_secondary = bcm1480_boot_secondary,182182+ .smp_setup = bcm1480_smp_setup,183183+ .prepare_cpus = bcm1480_prepare_cpus,184184+};8418585186void bcm1480_mailbox_interrupt(void)86187{
···2828#include <asm/bootinfo.h>2929#include <asm/reboot.h>3030#include <asm/sibyte/board.h>3131+#include <asm/smp-ops.h>31323233#include <asm/fw/cfe/cfe_api.h>3334#include <asm/fw/cfe/cfe_error.h>···233232234233#endif235234235235+extern struct plat_smp_ops sb_smp_ops;236236+extern struct plat_smp_ops bcm1480_smp_ops;237237+236238/*237239 * prom_init is called just after the cpu type is determined, from setup_arch()238240 */···344340 arcs_cmdline[CL_SIZE-1] = 0;345341346342 prom_meminit();343343+344344+#if defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)345345+ register_smp_ops(&sb_smp_ops);346346+#endif347347+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)348348+ register_smp_ops(&bcm1480_smp_ops);349349+#endif347350}348351349352void __init prom_free_prom_memory(void)
-110
arch/mips/sibyte/cfe/smp.c
···11-/*22- * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation33- *44- * This program is free software; you can redistribute it and/or55- * modify it under the terms of the GNU General Public License66- * as published by the Free Software Foundation; either version 277- * of the License, or (at your option) any later version.88- *99- * This program is distributed in the hope that it will be useful,1010- * but WITHOUT ANY WARRANTY; without even the implied warranty of1111- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1212- * GNU General Public License for more details.1313- *1414- * You should have received a copy of the GNU General Public License1515- * along with this program; if not, write to the Free Software1616- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.1717- */1818-1919-#include <linux/init.h>2020-#include <linux/sched.h>2121-#include <linux/smp.h>2222-#include <asm/processor.h>2323-2424-#include <asm/fw/cfe/cfe_api.h>2525-#include <asm/fw/cfe/cfe_error.h>2626-2727-/*2828- * Use CFE to find out how many CPUs are available, setting up2929- * phys_cpu_present_map and the logical/physical mappings.3030- * XXXKW will the boot CPU ever not be physical 0?3131- *3232- * Common setup before any secondaries are started3333- */3434-void __init plat_smp_setup(void)3535-{3636- int i, num;3737-3838- cpus_clear(phys_cpu_present_map);3939- cpu_set(0, phys_cpu_present_map);4040- __cpu_number_map[0] = 0;4141- __cpu_logical_map[0] = 0;4242-4343- for (i = 1, num = 0; i < NR_CPUS; i++) {4444- if (cfe_cpu_stop(i) == 0) {4545- cpu_set(i, phys_cpu_present_map);4646- __cpu_number_map[i] = ++num;4747- __cpu_logical_map[num] = i;4848- }4949- }5050- printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);5151-}5252-5353-void __init plat_prepare_cpus(unsigned int max_cpus)5454-{5555-}5656-5757-/*5858- * Setup the PC, SP, and GP of a secondary processor and start it5959- * running!6060- */6161-void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)6262-{6363- int retval;6464-6565- retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,6666- __KSTK_TOS(idle),6767- (unsigned long)task_thread_info(idle), 0);6868- if (retval != 0)6969- printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);7070-}7171-7272-/*7373- * Code to run on secondary just after probing the CPU7474- */7575-void __cpuinit prom_init_secondary(void)7676-{7777-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)7878- extern void bcm1480_smp_init(void);7979- bcm1480_smp_init();8080-#elif defined(CONFIG_SIBYTE_SB1250)8181- extern void sb1250_smp_init(void);8282- sb1250_smp_init();8383-#else8484-#error invalid SMP configuration8585-#endif8686-}8787-8888-/*8989- * Do any tidying up before marking online and running the idle9090- * loop9191- */9292-void __cpuinit prom_smp_finish(void)9393-{9494-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)9595- extern void bcm1480_smp_finish(void);9696- bcm1480_smp_finish();9797-#elif defined(CONFIG_SIBYTE_SB1250)9898- extern void sb1250_smp_finish(void);9999- sb1250_smp_finish();100100-#else101101-#error invalid SMP configuration102102-#endif103103-}104104-105105-/*106106- * Final cleanup after all secondaries booted107107- */108108-void prom_cpus_done(void)109109-{110110-}
+95-9
arch/mips/sibyte/sb1250/smp.c
···24242525#include <asm/mmu_context.h>2626#include <asm/io.h>2727+#include <asm/fw/cfe/cfe_api.h>2728#include <asm/sibyte/sb1250.h>2829#include <asm/sibyte/sb1250_regs.h>2930#include <asm/sibyte/sb1250_int.h>···5655 change_c0_status(ST0_IM, imask);5756}58575959-void __cpuinit sb1250_smp_finish(void)6060-{6161- extern void sb1250_clockevent_init(void);6262-6363- sb1250_clockevent_init();6464- local_irq_enable();6565-}6666-6758/*6859 * These are routines for dealing with the sb1250 smp capabilities6960 * independent of board/firmware···6572 * Simple enough; everything is set up, so just poke the appropriate mailbox6673 * register, and we should be set6774 */6868-void core_send_ipi(int cpu, unsigned int action)7575+static void sb1250_send_ipi_single(int cpu, unsigned int action)6976{7077 __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);7178}7979+8080+static inline void sb1250_send_ipi_mask(cpumask_t mask, unsigned int action)8181+{8282+ unsigned int i;8383+8484+ for_each_cpu_mask(i, mask)8585+ sb1250_send_ipi_single(i, action);8686+}8787+8888+/*8989+ * Code to run on secondary just after probing the CPU9090+ */9191+static void __cpuinit sb1250_init_secondary(void)9292+{9393+ extern void sb1250_smp_init(void);9494+9595+ sb1250_smp_init();9696+}9797+9898+/*9999+ * Do any tidying up before marking online and running the idle100100+ * loop101101+ */102102+static void __cpuinit sb1250_smp_finish(void)103103+{104104+ extern void sb1250_clockevent_init(void);105105+106106+ sb1250_clockevent_init();107107+ local_irq_enable();108108+}109109+110110+/*111111+ * Final cleanup after all secondaries booted112112+ */113113+static void sb1250_cpus_done(void)114114+{115115+}116116+117117+/*118118+ * Setup the PC, SP, and GP of a secondary processor and start it119119+ * running!120120+ */121121+static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle)122122+{123123+ int retval;124124+125125+ retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,126126+ __KSTK_TOS(idle),127127+ (unsigned long)task_thread_info(idle), 0);128128+ if (retval != 0)129129+ printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);130130+}131131+132132+/*133133+ * Use CFE to find out how many CPUs are available, setting up134134+ * phys_cpu_present_map and the logical/physical mappings.135135+ * XXXKW will the boot CPU ever not be physical 0?136136+ *137137+ * Common setup before any secondaries are started138138+ */139139+static void __init sb1250_smp_setup(void)140140+{141141+ int i, num;142142+143143+ cpus_clear(phys_cpu_present_map);144144+ cpu_set(0, phys_cpu_present_map);145145+ __cpu_number_map[0] = 0;146146+ __cpu_logical_map[0] = 0;147147+148148+ for (i = 1, num = 0; i < NR_CPUS; i++) {149149+ if (cfe_cpu_stop(i) == 0) {150150+ cpu_set(i, phys_cpu_present_map);151151+ __cpu_number_map[i] = ++num;152152+ __cpu_logical_map[num] = i;153153+ }154154+ }155155+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);156156+}157157+158158+static void __init sb1250_prepare_cpus(unsigned int max_cpus)159159+{160160+}161161+162162+struct plat_smp_ops sb_smp_ops = {163163+ .send_ipi_single = sb1250_send_ipi_single,164164+ .send_ipi_mask = sb1250_send_ipi_mask,165165+ .init_secondary = sb1250_init_secondary,166166+ .smp_finish = sb1250_smp_finish,167167+ .cpus_done = sb1250_cpus_done,168168+ .boot_secondary = sb1250_boot_secondary,169169+ .smp_setup = sb1250_smp_setup,170170+ .prepare_cpus = sb1250_prepare_cpus,171171+};7217273173void sb1250_mailbox_interrupt(void)74174{
-2
include/asm-mips/sibyte/sb1250.h
···4848extern void sb1250_time_init(void);4949extern void sb1250_mask_irq(int cpu, int irq);5050extern void sb1250_unmask_irq(int cpu, int irq);5151-extern void sb1250_smp_finish(void);52515352extern void bcm1480_time_init(void);5453extern void bcm1480_mask_irq(int cpu, int irq);5554extern void bcm1480_unmask_irq(int cpu, int irq);5656-extern void bcm1480_smp_finish(void);57555856#define AT_spin \5957 __asm__ __volatile__ ( \
+56
include/asm-mips/smp-ops.h
···11+/*22+ * This file is subject to the terms and conditions of the GNU General33+ * Public License. See the file "COPYING" in the main directory of this44+ * archive for more details.55+ *66+ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)77+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.88+ * Copyright (C) 2000, 2001, 2002 Ralf Baechle99+ * Copyright (C) 2000, 2001 Broadcom Corporation1010+ */1111+#ifndef __ASM_SMP_OPS_H1212+#define __ASM_SMP_OPS_H1313+1414+#ifdef CONFIG_SMP1515+1616+#include <linux/cpumask.h>1717+1818+struct plat_smp_ops {1919+ void (*send_ipi_single)(int cpu, unsigned int action);2020+ void (*send_ipi_mask)(cpumask_t mask, unsigned int action);2121+ void (*init_secondary)(void);2222+ void (*smp_finish)(void);2323+ void (*cpus_done)(void);2424+ void (*boot_secondary)(int cpu, struct task_struct *idle);2525+ void (*smp_setup)(void);2626+ void (*prepare_cpus)(unsigned int max_cpus);2727+};2828+2929+extern void register_smp_ops(struct plat_smp_ops *ops);3030+3131+static inline void plat_smp_setup(void)3232+{3333+ extern struct plat_smp_ops *mp_ops; /* private */3434+3535+ mp_ops->smp_setup();3636+}3737+3838+#else /* !CONFIG_SMP */3939+4040+struct plat_smp_ops;4141+4242+static inline void plat_smp_setup(void)4343+{4444+ /* UP, nothing to do ... */4545+}4646+4747+static inline void register_smp_ops(struct plat_smp_ops *ops)4848+{4949+}5050+5151+#endif /* !CONFIG_SMP */5252+5353+extern struct plat_smp_ops up_smp_ops;5454+extern struct plat_smp_ops vsmp_smp_ops;5555+5656+#endif /* __ASM_SMP_OPS_H */
+5-56
include/asm-mips/smp.h
···1111#ifndef __ASM_SMP_H1212#define __ASM_SMP_H13131414-1515-#ifdef CONFIG_SMP1616-1714#include <linux/bitops.h>1815#include <linux/linkage.h>1916#include <linux/threads.h>2017#include <linux/cpumask.h>1818+2119#include <asm/atomic.h>2020+#include <asm/smp-ops.h>22212322extern int smp_num_siblings;2423extern cpumask_t cpu_sibling_map[];···5152extern cpumask_t phys_cpu_present_map;5253#define cpu_possible_map phys_cpu_present_map53545454-/*5555- * These are defined by the board-specific code.5656- */5757-5858-/*5959- * Cause the function described by call_data to be executed on the passed6060- * cpu. When the function has finished, increment the finished field of6161- * call_data.6262- */6363-extern void core_send_ipi(int cpu, unsigned int action);6464-6565-static inline void core_send_ipi_mask(cpumask_t mask, unsigned int action)6666-{6767- unsigned int i;6868-6969- for_each_cpu_mask(i, mask)7070- core_send_ipi(i, action);7171-}7272-7373-7474-/*7575- * Firmware CPU startup hook7676- */7777-extern void prom_boot_secondary(int cpu, struct task_struct *idle);7878-7979-/*8080- * After we've done initial boot, this function is called to allow the8181- * board code to clean up state, if needed8282- */8383-extern void prom_init_secondary(void);8484-8585-/*8686- * Populate cpu_possible_map before smp_init, called from setup_arch.8787- */8888-extern void plat_smp_setup(void);8989-9090-/*9191- * Called in smp_prepare_cpus.9292- */9393-extern void plat_prepare_cpus(unsigned int max_cpus);9494-9595-/*9696- * Last chance for the board code to finish SMP initialization before9797- * the CPU is "online".9898- */9999-extern void prom_smp_finish(void);100100-101101-/* Hook for after all CPUs are online */102102-extern void prom_cpus_done(void);103103-10455extern void asmlinkage smp_bootstrap(void);1055610657/*···60111 */61112static inline void smp_send_reschedule(int cpu)62113{6363- core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);114114+ extern struct plat_smp_ops *mp_ops; /* private */115115+116116+ mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF);64117}6511866119extern asmlinkage void smp_call_function_interrupt(void);6767-6868-#endif /* CONFIG_SMP */6912070121#endif /* __ASM_SMP_H */