The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/malta/malta_mp.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Portions of this software were developed by SRI International and the
    6  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
    7  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
    8  *
    9  * Portions of this software were developed by the University of Cambridge
   10  * Computer Laboratory as part of the CTSRD Project, with support from the
   11  * UK Higher Education Innovation Fund (HEIF).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  * $FreeBSD$
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD$");
   39 
   40 #include <sys/param.h>
   41 #include <sys/conf.h>
   42 #include <sys/kernel.h>
   43 #include <sys/smp.h>
   44 #include <sys/systm.h>
   45 
   46 #include <machine/cpufunc.h>
   47 #include <machine/hwfunc.h>
   48 #include <machine/md_var.h>
   49 #include <machine/smp.h>
   50 
   51 #define VPECONF0_VPA    (1 << 0)
   52 #define MVPCONTROL_VPC  (1 << 1)
   53 #define MVPCONF0_PVPE_SHIFT     10
   54 #define MVPCONF0_PVPE_MASK      (0xf << MVPCONF0_PVPE_SHIFT)
   55 #define TCSTATUS_A      (1 << 13)
   56 
   57 unsigned malta_ap_boot = ~0;
   58 
   59 #define C_SW0           (1 << 8)
   60 #define C_SW1           (1 << 9)
   61 #define C_IRQ0          (1 << 10)
   62 #define C_IRQ1          (1 << 11)
   63 #define C_IRQ2          (1 << 12)
   64 #define C_IRQ3          (1 << 13)
   65 #define C_IRQ4          (1 << 14)
   66 #define C_IRQ5          (1 << 15)
   67 
   68 static inline void
   69 evpe(void)
   70 {
   71         __asm __volatile(
   72         "       .set push                       \n"
   73         "       .set noreorder                  \n"
   74         "       .set noat                       \n"
   75         "       .set mips32r2                   \n"
   76         "       .word   0x41600021      # evpe  \n"
   77         "       ehb                             \n"
   78         "       .set pop                        \n");
   79 }
   80 
   81 static inline void
   82 ehb(void)
   83 {
   84         __asm __volatile(
   85         "       .set mips32r2   \n"
   86         "       ehb             \n"
   87         "       .set mips0      \n");
   88 }
   89 
   90 #define mttc0(rd, sel, val)                                             \
   91 ({                                                                      \
   92         __asm __volatile(                                               \
   93         "       .set push                                       \n"     \
   94         "       .set mips32r2                                   \n"     \
   95         "       .set noat                                       \n"     \
   96         "       move    $1, %0                                  \n"     \
   97         "       .word 0x41810000 | (" #rd " << 11) | " #sel "   \n"     \
   98         "       .set pop                                        \n"     \
   99         :: "r" (val));                                                  \
  100 })
  101 
  102 #define mftc0(rt, sel)                                                  \
  103 ({                                                                      \
  104         unsigned long __res;                                            \
  105         __asm __volatile(                                               \
  106         "       .set push                                       \n"     \
  107         "       .set mips32r2                                   \n"     \
  108         "       .set noat                                       \n"     \
  109         "       .word 0x41000800 | (" #rt " << 16) | " #sel "   \n"     \
  110         "       move    %0, $1                                  \n"     \
  111         "       .set pop                                        \n"     \
  112         : "=r" (__res));                                                \
  113          __res;                                                         \
  114 })
  115 
  116 #define write_c0_register32(reg, sel, val)                              \
  117 ({                                                                      \
  118         __asm __volatile(                                               \
  119         "       .set push                                       \n"     \
  120         "       .set mips32                                     \n"     \
  121         "       mtc0    %0, $%1, %2                             \n"     \
  122         "       .set pop                                        \n"     \
  123         :: "r" (val), "i" (reg), "i" (sel));                            \
  124 })
  125 
  126 #define read_c0_register32(reg, sel)                                    \
  127 ({                                                                      \
  128         uint32_t __retval;                                              \
  129         __asm __volatile(                                               \
  130         "       .set push                                       \n"     \
  131         "       .set mips32                                     \n"     \
  132         "       mfc0    %0, $%1, %2                             \n"     \
  133         "       .set pop                                        \n"     \
  134         : "=r" (__retval) : "i" (reg), "i" (sel));                      \
  135         __retval;                                                       \
  136 })
  137 
  138 static void
  139 set_thread_context(int cpuid)
  140 {
  141         uint32_t reg;
  142 
  143         reg = read_c0_register32(1, 1);
  144         reg &= ~(0xff);
  145         reg |= cpuid;
  146         write_c0_register32(1, 1, reg);
  147 
  148         ehb();
  149 }
  150 
  151 void
  152 platform_ipi_send(int cpuid)
  153 {
  154         uint32_t reg;
  155 
  156         set_thread_context(cpuid);
  157 
  158         /* Set cause */
  159         reg = mftc0(13, 0);
  160         reg |= (C_SW1);
  161         mttc0(13, 0, reg);
  162 }
  163 
  164 void
  165 platform_ipi_clear(void)
  166 {
  167         uint32_t reg;
  168 
  169         reg = mips_rd_cause();
  170         reg &= ~(C_SW1);
  171         mips_wr_cause(reg);
  172 }
  173 
  174 int
  175 platform_ipi_hardintr_num(void)
  176 {
  177 
  178         return (-1);
  179 }
  180 
  181 int
  182 platform_ipi_softintr_num(void)
  183 {
  184 
  185         return (1);
  186 }
  187 
  188 void
  189 platform_init_ap(int cpuid)
  190 {
  191         uint32_t clock_int_mask;
  192         uint32_t ipi_intr_mask;
  193 
  194         /*
  195          * Clear any pending IPIs.
  196          */
  197         platform_ipi_clear();
  198 
  199         /*
  200          * Unmask the clock and ipi interrupts.
  201          */
  202         ipi_intr_mask = soft_int_mask(platform_ipi_softintr_num());
  203         clock_int_mask = hard_int_mask(5);
  204         set_intr_mask(ipi_intr_mask | clock_int_mask);
  205 
  206         mips_wbflush();
  207 }
  208 
  209 void
  210 platform_cpu_mask(cpuset_t *mask)
  211 {
  212         uint32_t i, ncpus, reg;
  213 
  214         reg = mftc0(0, 2);
  215         ncpus = ((reg & MVPCONF0_PVPE_MASK) >> MVPCONF0_PVPE_SHIFT) + 1;
  216 
  217         CPU_ZERO(mask);
  218         for (i = 0; i < ncpus; i++)
  219                 CPU_SET(i, mask);
  220 }
  221 
  222 struct cpu_group *
  223 platform_smp_topo(void)
  224 {
  225 
  226         return (smp_topo_none());
  227 }
  228 
  229 int
  230 platform_start_ap(int cpuid)
  231 {
  232         uint32_t reg;
  233         int timeout;
  234 
  235         /* Enter into configuration */
  236         reg = read_c0_register32(0, 1);
  237         reg |= (MVPCONTROL_VPC);
  238         write_c0_register32(0, 1, reg);
  239 
  240         set_thread_context(cpuid);
  241 
  242         /*
  243          * Hint: how to set entry point.
  244          * reg = 0x80000000;
  245          * mttc0(2, 3, reg);
  246          */
  247 
  248         /* Enable thread */
  249         reg = mftc0(2, 1);
  250         reg |= (TCSTATUS_A);
  251         mttc0(2, 1, reg);
  252 
  253         /* Unhalt CPU core */
  254         mttc0(2, 4, 0);
  255 
  256         /* Activate VPE */
  257         reg = mftc0(1, 2);
  258         reg |= (VPECONF0_VPA);
  259         mttc0(1, 2, reg);
  260 
  261         /* Out of configuration */
  262         reg = read_c0_register32(0, 1);
  263         reg &= ~(MVPCONTROL_VPC);
  264         write_c0_register32(0, 1, reg);
  265 
  266         evpe();
  267 
  268         if (atomic_cmpset_32(&malta_ap_boot, ~0, cpuid) == 0)
  269                 return (-1);
  270 
  271         printf("Waiting for cpu%d to start\n", cpuid);
  272 
  273         timeout = 100;
  274         do {
  275                 DELAY(1000);
  276                 if (atomic_cmpset_32(&malta_ap_boot, 0, ~0) != 0) {
  277                         printf("CPU %d started\n", cpuid);
  278                         return (0);
  279                 }
  280         } while (timeout--);
  281 
  282         printf("CPU %d failed to start\n", cpuid);
  283 
  284         return (0);
  285 }

Cache object: 79e9116fcfe788e1f0d095bef37f5ade


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.