perf stat aggregation: Start using cpu_aggr_id in map
[linux-2.6-microblaze.git] / arch / mips / sgi-ip30 / ip30-smp.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * ip30-smp.c: SMP on IP30 architecture.
4  * Based off of the original IP30 SMP code, with inspiration from ip27-smp.c
5  * and smp-bmips.c.
6  *
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>
10  */
11
12 #include <linux/init.h>
13 #include <linux/sched.h>
14 #include <linux/sched/task_stack.h>
15
16 #include <asm/time.h>
17 #include <asm/sgi/heart.h>
18
19 #include "ip30-common.h"
20
21 #define MPCONF_MAGIC    0xbaddeed2
22 #define MPCONF_ADDR     0xa800000000000600L
23 #define MPCONF_SIZE     0x80
24 #define MPCONF(x)       (MPCONF_ADDR + (x) * MPCONF_SIZE)
25
26 /* HEART can theoretically do 4 CPUs, but only 2 are physically possible */
27 #define MP_NCPU         2
28
29 struct mpconf {
30         u32 magic;
31         u32 prid;
32         u32 physid;
33         u32 virtid;
34         u32 scachesz;
35         u16 fanloads;
36         u16 res;
37         void *launch;
38         void *rendezvous;
39         u64 res2[3];
40         void *stackaddr;
41         void *lnch_parm;
42         void *rndv_parm;
43         u32 idleflag;
44 };
45
46 static void ip30_smp_send_ipi_single(int cpu, u32 action)
47 {
48         int irq;
49
50         switch (action) {
51         case SMP_RESCHEDULE_YOURSELF:
52                 irq = HEART_L2_INT_RESCHED_CPU_0;
53                 break;
54         case SMP_CALL_FUNCTION:
55                 irq = HEART_L2_INT_CALL_CPU_0;
56                 break;
57         default:
58                 panic("IP30: Unknown action value in %s!\n", __func__);
59         }
60
61         irq += cpu;
62
63         /* Poke the other CPU -- it's got mail! */
64         heart_write(BIT_ULL(irq), &heart_regs->set_isr);
65 }
66
67 static void ip30_smp_send_ipi_mask(const struct cpumask *mask, u32 action)
68 {
69         u32 i;
70
71         for_each_cpu(i, mask)
72                 ip30_smp_send_ipi_single(i, action);
73 }
74
75 static void __init ip30_smp_setup(void)
76 {
77         int i;
78         int ncpu = 0;
79         struct mpconf *mpc;
80
81         init_cpu_possible(cpumask_of(0));
82
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);
92                 }
93         }
94         pr_info("IP30: Detected %d CPU(s) present.\n", ncpu);
95
96         /*
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.
101          */
102         change_c0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
103 }
104
105 static void __init ip30_smp_prepare_cpus(unsigned int max_cpus)
106 {
107         /* nothing to do here */
108 }
109
110 static int __init ip30_smp_boot_secondary(int cpu, struct task_struct *idle)
111 {
112         struct mpconf *mpc = (struct mpconf *)MPCONF(cpu);
113
114         /* Stack pointer (sp). */
115         mpc->stackaddr = (void *)__KSTK_TOS(idle);
116
117         /* Global pointer (gp). */
118         mpc->lnch_parm = task_thread_info(idle);
119
120         mb(); /* make sure stack and lparm are written */
121
122         /* Boot CPUx. */
123         mpc->launch = smp_bootstrap;
124
125         /* CPUx now executes smp_bootstrap, then ip30_smp_finish */
126         return 0;
127 }
128
129 static void __init ip30_smp_init_cpu(void)
130 {
131         ip30_per_cpu_init();
132 }
133
134 static void __init ip30_smp_finish(void)
135 {
136         enable_percpu_irq(get_c0_compare_int(), IRQ_TYPE_NONE);
137         local_irq_enable();
138 }
139
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,
149 };