1 // SPDX-License-Identifier: GPL-2.0
3 * ip30-smp.c: SMP on IP30 architecture.
4 * Based off of the original IP30 SMP code, with inspiration from ip27-smp.c
7 * Copyright (C) 2005-2007 Stanislaw Skowronek <skylark@unaligned.org>
8 * 2006-2007, 2014-2015 Joshua Kinard <kumba@gentoo.org>
9 * 2009 Johannes Dickgreber <tanzy@gmx.de>
12 #include <linux/init.h>
13 #include <linux/sched.h>
14 #include <linux/sched/task_stack.h>
17 #include <asm/sgi/heart.h>
19 #include "ip30-common.h"
21 #define MPCONF_MAGIC 0xbaddeed2
22 #define MPCONF_ADDR 0xa800000000000600L
23 #define MPCONF_SIZE 0x80
24 #define MPCONF(x) (MPCONF_ADDR + (x) * MPCONF_SIZE)
26 /* HEART can theoretically do 4 CPUs, but only 2 are physically possible */
46 static void ip30_smp_send_ipi_single(int cpu, u32 action)
51 case SMP_RESCHEDULE_YOURSELF:
52 irq = HEART_L2_INT_RESCHED_CPU_0;
54 case SMP_CALL_FUNCTION:
55 irq = HEART_L2_INT_CALL_CPU_0;
58 panic("IP30: Unknown action value in %s!\n", __func__);
63 /* Poke the other CPU -- it's got mail! */
64 heart_write(BIT_ULL(irq), &heart_regs->set_isr);
67 static void ip30_smp_send_ipi_mask(const struct cpumask *mask, u32 action)
72 ip30_smp_send_ipi_single(i, action);
75 static void __init ip30_smp_setup(void)
81 init_cpu_possible(cpumask_of(0));
83 /* Scan the MPCONF structure and enumerate available CPUs. */
84 for (i = 0; i < MP_NCPU; i++) {
85 mpc = (struct mpconf *)MPCONF(i);
86 if (mpc->magic == MPCONF_MAGIC) {
87 set_cpu_possible(i, true);
88 __cpu_number_map[i] = ++ncpu;
89 __cpu_logical_map[ncpu] = i;
90 pr_info("IP30: Slot: %d, PrID: %.8x, PhyID: %d, VirtID: %d\n",
91 i, mpc->prid, mpc->physid, mpc->virtid);
94 pr_info("IP30: Detected %d CPU(s) present.\n", ncpu);
97 * Set the coherency algorithm to '5' (cacheable coherent
98 * exclusive on write). This is needed on IP30 SMP, especially
99 * for R14000 CPUs, otherwise, instruction bus errors will
100 * occur upon reaching userland.
102 change_c0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
105 static void __init ip30_smp_prepare_cpus(unsigned int max_cpus)
107 /* nothing to do here */
110 static int __init ip30_smp_boot_secondary(int cpu, struct task_struct *idle)
112 struct mpconf *mpc = (struct mpconf *)MPCONF(cpu);
114 /* Stack pointer (sp). */
115 mpc->stackaddr = (void *)__KSTK_TOS(idle);
117 /* Global pointer (gp). */
118 mpc->lnch_parm = task_thread_info(idle);
120 mb(); /* make sure stack and lparm are written */
123 mpc->launch = smp_bootstrap;
125 /* CPUx now executes smp_bootstrap, then ip30_smp_finish */
129 static void __init ip30_smp_init_cpu(void)
134 static void __init ip30_smp_finish(void)
136 enable_percpu_irq(get_c0_compare_int(), IRQ_TYPE_NONE);
140 struct plat_smp_ops __read_mostly ip30_smp_ops = {
141 .send_ipi_single = ip30_smp_send_ipi_single,
142 .send_ipi_mask = ip30_smp_send_ipi_mask,
143 .smp_setup = ip30_smp_setup,
144 .prepare_cpus = ip30_smp_prepare_cpus,
145 .boot_secondary = ip30_smp_boot_secondary,
146 .init_secondary = ip30_smp_init_cpu,
147 .smp_finish = ip30_smp_finish,
148 .prepare_boot_cpu = ip30_smp_init_cpu,