root/arch/mips/sibyte/sb1250/smp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sb1250_smp_init
  2. sb1250_send_ipi_single
  3. sb1250_send_ipi_mask
  4. sb1250_init_secondary
  5. sb1250_smp_finish
  6. sb1250_boot_secondary
  7. sb1250_smp_setup
  8. sb1250_prepare_cpus
  9. sb1250_mailbox_interrupt

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
   4  */
   5 
   6 #include <linux/init.h>
   7 #include <linux/delay.h>
   8 #include <linux/interrupt.h>
   9 #include <linux/smp.h>
  10 #include <linux/kernel_stat.h>
  11 #include <linux/sched/task_stack.h>
  12 
  13 #include <asm/mmu_context.h>
  14 #include <asm/io.h>
  15 #include <asm/fw/cfe/cfe_api.h>
  16 #include <asm/sibyte/sb1250.h>
  17 #include <asm/sibyte/sb1250_regs.h>
  18 #include <asm/sibyte/sb1250_int.h>
  19 
  20 static void *mailbox_set_regs[] = {
  21         IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
  22         IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
  23 };
  24 
  25 static void *mailbox_clear_regs[] = {
  26         IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
  27         IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
  28 };
  29 
  30 static void *mailbox_regs[] = {
  31         IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
  32         IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
  33 };
  34 
  35 /*
  36  * SMP init and finish on secondary CPUs
  37  */
  38 void sb1250_smp_init(void)
  39 {
  40         unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
  41                 STATUSF_IP1 | STATUSF_IP0;
  42 
  43         /* Set interrupt mask, but don't enable */
  44         change_c0_status(ST0_IM, imask);
  45 }
  46 
  47 /*
  48  * These are routines for dealing with the sb1250 smp capabilities
  49  * independent of board/firmware
  50  */
  51 
  52 /*
  53  * Simple enough; everything is set up, so just poke the appropriate mailbox
  54  * register, and we should be set
  55  */
  56 static void sb1250_send_ipi_single(int cpu, unsigned int action)
  57 {
  58         __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
  59 }
  60 
  61 static inline void sb1250_send_ipi_mask(const struct cpumask *mask,
  62                                         unsigned int action)
  63 {
  64         unsigned int i;
  65 
  66         for_each_cpu(i, mask)
  67                 sb1250_send_ipi_single(i, action);
  68 }
  69 
  70 /*
  71  * Code to run on secondary just after probing the CPU
  72  */
  73 static void sb1250_init_secondary(void)
  74 {
  75         extern void sb1250_smp_init(void);
  76 
  77         sb1250_smp_init();
  78 }
  79 
  80 /*
  81  * Do any tidying up before marking online and running the idle
  82  * loop
  83  */
  84 static void sb1250_smp_finish(void)
  85 {
  86         extern void sb1250_clockevent_init(void);
  87 
  88         sb1250_clockevent_init();
  89         local_irq_enable();
  90 }
  91 
  92 /*
  93  * Setup the PC, SP, and GP of a secondary processor and start it
  94  * running!
  95  */
  96 static int sb1250_boot_secondary(int cpu, struct task_struct *idle)
  97 {
  98         int retval;
  99 
 100         retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
 101                                __KSTK_TOS(idle),
 102                                (unsigned long)task_thread_info(idle), 0);
 103         if (retval != 0)
 104                 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
 105         return retval;
 106 }
 107 
 108 /*
 109  * Use CFE to find out how many CPUs are available, setting up
 110  * cpu_possible_mask and the logical/physical mappings.
 111  * XXXKW will the boot CPU ever not be physical 0?
 112  *
 113  * Common setup before any secondaries are started
 114  */
 115 static void __init sb1250_smp_setup(void)
 116 {
 117         int i, num;
 118 
 119         init_cpu_possible(cpumask_of(0));
 120         __cpu_number_map[0] = 0;
 121         __cpu_logical_map[0] = 0;
 122 
 123         for (i = 1, num = 0; i < NR_CPUS; i++) {
 124                 if (cfe_cpu_stop(i) == 0) {
 125                         set_cpu_possible(i, true);
 126                         __cpu_number_map[i] = ++num;
 127                         __cpu_logical_map[num] = i;
 128                 }
 129         }
 130         printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
 131 }
 132 
 133 static void __init sb1250_prepare_cpus(unsigned int max_cpus)
 134 {
 135 }
 136 
 137 const struct plat_smp_ops sb_smp_ops = {
 138         .send_ipi_single        = sb1250_send_ipi_single,
 139         .send_ipi_mask          = sb1250_send_ipi_mask,
 140         .init_secondary         = sb1250_init_secondary,
 141         .smp_finish             = sb1250_smp_finish,
 142         .boot_secondary         = sb1250_boot_secondary,
 143         .smp_setup              = sb1250_smp_setup,
 144         .prepare_cpus           = sb1250_prepare_cpus,
 145 };
 146 
 147 void sb1250_mailbox_interrupt(void)
 148 {
 149         int cpu = smp_processor_id();
 150         int irq = K_INT_MBOX_0;
 151         unsigned int action;
 152 
 153         kstat_incr_irq_this_cpu(irq);
 154         /* Load the mailbox register to figure out what we're supposed to do */
 155         action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
 156 
 157         /* Clear the mailbox to clear the interrupt */
 158         ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
 159 
 160         if (action & SMP_RESCHEDULE_YOURSELF)
 161                 scheduler_ipi();
 162 
 163         if (action & SMP_CALL_FUNCTION) {
 164                 irq_enter();
 165                 generic_smp_call_function_interrupt();
 166                 irq_exit();
 167         }
 168 }

/* [<][>][^][v][top][bottom][index][help] */