0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/init.h>
0010 #include <linux/sched.h>
0011 #include <linux/sched/task_stack.h>
0012 #include <linux/topology.h>
0013 #include <linux/nodemask.h>
0014
0015 #include <asm/page.h>
0016 #include <asm/processor.h>
0017 #include <asm/ptrace.h>
0018 #include <asm/sn/agent.h>
0019 #include <asm/sn/arch.h>
0020 #include <asm/sn/gda.h>
0021 #include <asm/sn/intr.h>
0022 #include <asm/sn/klconfig.h>
0023 #include <asm/sn/launch.h>
0024 #include <asm/sn/mapped_kernel.h>
0025 #include <asm/sn/types.h>
0026
0027 #include "ip27-common.h"
0028
0029 static int node_scan_cpus(nasid_t nasid, int highest)
0030 {
0031 static int cpus_found;
0032 lboard_t *brd;
0033 klcpu_t *acpu;
0034 cpuid_t cpuid;
0035
0036 brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
0037
0038 do {
0039 acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
0040 while (acpu) {
0041 cpuid = acpu->cpu_info.virtid;
0042
0043 if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
0044 (cpus_found != NR_CPUS)) {
0045 if (cpuid > highest)
0046 highest = cpuid;
0047 set_cpu_possible(cpuid, true);
0048 cputonasid(cpus_found) = nasid;
0049 cputoslice(cpus_found) = acpu->cpu_info.physid;
0050 sn_cpu_info[cpus_found].p_speed =
0051 acpu->cpu_speed;
0052 cpus_found++;
0053 }
0054 acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
0055 KLSTRUCT_CPU);
0056 }
0057 brd = KLCF_NEXT(brd);
0058 if (!brd)
0059 break;
0060
0061 brd = find_lboard(brd, KLTYPE_IP27);
0062 } while (brd);
0063
0064 return highest;
0065 }
0066
0067 void cpu_node_probe(void)
0068 {
0069 int i, highest = 0;
0070 gda_t *gdap = GDA;
0071
0072 nodes_clear(node_online_map);
0073 for (i = 0; i < MAX_NUMNODES; i++) {
0074 nasid_t nasid = gdap->g_nasidtable[i];
0075 if (nasid == INVALID_NASID)
0076 break;
0077 node_set_online(nasid);
0078 highest = node_scan_cpus(nasid, highest);
0079 }
0080
0081 printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
0082 }
0083
0084 static __init void intr_clear_all(nasid_t nasid)
0085 {
0086 int i;
0087
0088 REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
0089 REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
0090 REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
0091 REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
0092
0093 for (i = 0; i < 128; i++)
0094 REMOTE_HUB_CLR_INTR(nasid, i);
0095 }
0096
0097 static void ip27_send_ipi_single(int destid, unsigned int action)
0098 {
0099 int irq;
0100
0101 switch (action) {
0102 case SMP_RESCHEDULE_YOURSELF:
0103 irq = CPU_RESCHED_A_IRQ;
0104 break;
0105 case SMP_CALL_FUNCTION:
0106 irq = CPU_CALL_A_IRQ;
0107 break;
0108 default:
0109 panic("sendintr");
0110 }
0111
0112 irq += cputoslice(destid);
0113
0114
0115
0116
0117
0118 REMOTE_HUB_SEND_INTR(cpu_to_node(destid), irq);
0119 }
0120
0121 static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action)
0122 {
0123 unsigned int i;
0124
0125 for_each_cpu(i, mask)
0126 ip27_send_ipi_single(i, action);
0127 }
0128
0129 static void ip27_init_cpu(void)
0130 {
0131 per_cpu_init();
0132 }
0133
0134 static void ip27_smp_finish(void)
0135 {
0136 hub_rt_clock_event_init();
0137 local_irq_enable();
0138 }
0139
0140
0141
0142
0143
0144
0145 static int ip27_boot_secondary(int cpu, struct task_struct *idle)
0146 {
0147 unsigned long gp = (unsigned long)task_thread_info(idle);
0148 unsigned long sp = __KSTK_TOS(idle);
0149
0150 LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
0151 (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
0152 0, (void *) sp, (void *) gp);
0153 return 0;
0154 }
0155
0156 static void __init ip27_smp_setup(void)
0157 {
0158 nasid_t nasid;
0159
0160 for_each_online_node(nasid) {
0161 if (nasid == 0)
0162 continue;
0163 intr_clear_all(nasid);
0164 }
0165
0166 replicate_kernel_text();
0167
0168
0169
0170
0171 cputonasid(0) = 0;
0172 cputoslice(0) = LOCAL_HUB_L(PI_CPU_NUM);
0173 }
0174
0175 static void __init ip27_prepare_cpus(unsigned int max_cpus)
0176 {
0177
0178 }
0179
0180 const struct plat_smp_ops ip27_smp_ops = {
0181 .send_ipi_single = ip27_send_ipi_single,
0182 .send_ipi_mask = ip27_send_ipi_mask,
0183 .init_secondary = ip27_init_cpu,
0184 .smp_finish = ip27_smp_finish,
0185 .boot_secondary = ip27_boot_secondary,
0186 .smp_setup = ip27_smp_setup,
0187 .prepare_cpus = ip27_prepare_cpus,
0188 .prepare_boot_cpu = ip27_init_cpu,
0189 };