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
,