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

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

DEFINITIONS

This source file includes following definitions.
  1. bcm1480_smp_init
  2. bcm1480_send_ipi_single
  3. bcm1480_send_ipi_mask
  4. bcm1480_init_secondary
  5. bcm1480_smp_finish
  6. bcm1480_boot_secondary
  7. bcm1480_smp_setup
  8. bcm1480_prepare_cpus
  9. bcm1480_mailbox_interrupt

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

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