0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/delay.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/smp.h>
0010 #include <linux/kernel_stat.h>
0011 #include <linux/sched/task_stack.h>
0012
0013 #include <asm/mmu_context.h>
0014 #include <asm/io.h>
0015 #include <asm/fw/cfe/cfe_api.h>
0016 #include <asm/sibyte/sb1250.h>
0017 #include <asm/sibyte/sb1250_regs.h>
0018 #include <asm/sibyte/sb1250_int.h>
0019
0020 static void *mailbox_set_regs[] = {
0021 IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
0022 IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
0023 };
0024
0025 static void *mailbox_clear_regs[] = {
0026 IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
0027 IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
0028 };
0029
0030 static void *mailbox_regs[] = {
0031 IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
0032 IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
0033 };
0034
0035
0036
0037
0038 void sb1250_smp_init(void)
0039 {
0040 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
0041 STATUSF_IP1 | STATUSF_IP0;
0042
0043
0044 change_c0_status(ST0_IM, imask);
0045 }
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 static void sb1250_send_ipi_single(int cpu, unsigned int action)
0057 {
0058 __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
0059 }
0060
0061 static inline void sb1250_send_ipi_mask(const struct cpumask *mask,
0062 unsigned int action)
0063 {
0064 unsigned int i;
0065
0066 for_each_cpu(i, mask)
0067 sb1250_send_ipi_single(i, action);
0068 }
0069
0070
0071
0072
0073 static void sb1250_init_secondary(void)
0074 {
0075 extern void sb1250_smp_init(void);
0076
0077 sb1250_smp_init();
0078 }
0079
0080
0081
0082
0083
0084 static void sb1250_smp_finish(void)
0085 {
0086 extern void sb1250_clockevent_init(void);
0087
0088 sb1250_clockevent_init();
0089 local_irq_enable();
0090 }
0091
0092
0093
0094
0095
0096 static int sb1250_boot_secondary(int cpu, struct task_struct *idle)
0097 {
0098 int retval;
0099
0100 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
0101 __KSTK_TOS(idle),
0102 (unsigned long)task_thread_info(idle), 0);
0103 if (retval != 0)
0104 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
0105 return retval;
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115 static void __init sb1250_smp_setup(void)
0116 {
0117 int i, num;
0118
0119 init_cpu_possible(cpumask_of(0));
0120 __cpu_number_map[0] = 0;
0121 __cpu_logical_map[0] = 0;
0122
0123 for (i = 1, num = 0; i < NR_CPUS; i++) {
0124 if (cfe_cpu_stop(i) == 0) {
0125 set_cpu_possible(i, true);
0126 __cpu_number_map[i] = ++num;
0127 __cpu_logical_map[num] = i;
0128 }
0129 }
0130 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
0131 }
0132
0133 static void __init sb1250_prepare_cpus(unsigned int max_cpus)
0134 {
0135 }
0136
0137 const struct plat_smp_ops sb_smp_ops = {
0138 .send_ipi_single = sb1250_send_ipi_single,
0139 .send_ipi_mask = sb1250_send_ipi_mask,
0140 .init_secondary = sb1250_init_secondary,
0141 .smp_finish = sb1250_smp_finish,
0142 .boot_secondary = sb1250_boot_secondary,
0143 .smp_setup = sb1250_smp_setup,
0144 .prepare_cpus = sb1250_prepare_cpus,
0145 };
0146
0147 void sb1250_mailbox_interrupt(void)
0148 {
0149 int cpu = smp_processor_id();
0150 int irq = K_INT_MBOX_0;
0151 unsigned int action;
0152
0153 kstat_incr_irq_this_cpu(irq);
0154
0155 action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
0156
0157
0158 ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
0159
0160 if (action & SMP_RESCHEDULE_YOURSELF)
0161 scheduler_ipi();
0162
0163 if (action & SMP_CALL_FUNCTION) {
0164 irq_enter();
0165 generic_smp_call_function_interrupt();
0166 irq_exit();
0167 }
0168 }