Author: br
Date: Fri Sep  9 14:50:44 2016
New Revision: 305664
URL: https://svnweb.freebsd.org/changeset/base/305664

Log:
  Add support for SMP on MIPS Malta platform.
  Tested in QEMU on Malta32, Malta64.
  
  Sponsored by: DARPA, AFRL
  Sponsored by: HEIF5

Added:
  head/sys/mips/malta/asm_malta.S   (contents, props changed)
  head/sys/mips/malta/malta_mp.c   (contents, props changed)
Modified:
  head/sys/conf/options.mips
  head/sys/mips/malta/files.malta
  head/sys/mips/malta/std.malta
  head/sys/mips/mips/locore.S

Modified: head/sys/conf/options.mips
==============================================================================
--- head/sys/conf/options.mips  Fri Sep  9 14:09:50 2016        (r305663)
+++ head/sys/conf/options.mips  Fri Sep  9 14:50:44 2016        (r305664)
@@ -45,6 +45,7 @@ CPU_CNMIPS    opt_global.h
 CPU_RMI                opt_global.h
 CPU_NLM                opt_global.h
 CPU_BERI       opt_global.h
+CPU_MALTA      opt_global.h
 
 # which MACHINE_ARCH architecture
 MIPS

Added: head/sys/mips/malta/asm_malta.S
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/malta/asm_malta.S     Fri Sep  9 14:50:44 2016        
(r305664)
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2016 Ruslan Bukin <[email protected]>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asm.h>
+
+#define        VPECONF0_MVP    (1 << 1)
+
+       .set noreorder
+
+#ifdef SMP
+/*
+ * This function must be implemented in assembly because it is called early
+ * in AP boot without a valid stack.
+ */
+LEAF(platform_processor_id)
+       .set push
+       .set mips32r2
+       mfc0    v0, $15, 1
+       jr      ra
+       andi    v0, 0x1f
+       .set pop
+END(platform_processor_id)
+
+LEAF(enable_mvp)
+       .set push
+       .set mips32r2
+       .set noat
+       li      t2, (VPECONF0_MVP)
+       move    $1, t2
+       jr      ra
+       .word   0x41810000 | (1 << 11) | 2      # mttc0 t2, $1, 2
+       .set pop
+END(enable_mvp)
+
+/*
+ * Called on APs to wait until they are told to launch.
+ */
+LEAF(malta_ap_wait)
+       jal     platform_processor_id
+       nop
+
+1:
+       ll      t0, malta_ap_boot
+       bne     v0, t0, 1b
+       nop
+
+       move    t0, zero
+       sc      t0, malta_ap_boot
+
+       beqz    t0, 1b
+       nop
+
+       j       mpentry
+       nop
+END(malta_ap_wait)
+#endif

Modified: head/sys/mips/malta/files.malta
==============================================================================
--- head/sys/mips/malta/files.malta     Fri Sep  9 14:09:50 2016        
(r305663)
+++ head/sys/mips/malta/files.malta     Fri Sep  9 14:50:44 2016        
(r305664)
@@ -10,3 +10,7 @@ mips/malta/malta_machdep.c            standard
 mips/malta/yamon.c                     standard
 mips/mips/intr_machdep.c               standard
 mips/mips/tick.c                       standard
+
+# SMP
+mips/malta/asm_malta.S                 optional smp
+mips/malta/malta_mp.c                  optional smp

Added: head/sys/mips/malta/malta_mp.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/mips/malta/malta_mp.c      Fri Sep  9 14:50:44 2016        
(r305664)
@@ -0,0 +1,226 @@
+/*-
+ * Copyright (c) 2016 Ruslan Bukin <[email protected]>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/smp.h>
+#include <sys/systm.h>
+
+#include <machine/cpufunc.h>
+#include <machine/hwfunc.h>
+#include <machine/md_var.h>
+#include <machine/smp.h>
+
+#define        MALTA_MAXCPU    2
+
+unsigned malta_ap_boot = ~0;
+
+#define        C_SW0           (1 << 8)
+#define        C_SW1           (1 << 9)
+#define        C_IRQ0          (1 << 10)
+#define        C_IRQ1          (1 << 11)
+#define        C_IRQ2          (1 << 12)
+#define        C_IRQ3          (1 << 13)
+#define        C_IRQ4          (1 << 14)
+#define        C_IRQ5          (1 << 15)
+
+static inline void
+ehb(void)
+{
+       __asm __volatile(
+       "       .set mips32r2   \n"
+       "       ehb             \n"
+       "       .set mips0      \n");
+}
+
+#define        mttc0(rd, sel, val)                                             
\
+({                                                                     \
+       __asm __volatile(                                               \
+       "       .set push                                       \n"     \
+       "       .set mips32r2                                   \n"     \
+       "       .set noat                                       \n"     \
+       "       move    $1, %0                                  \n"     \
+       "       .word 0x41810000 | (" #rd " << 11) | " #sel "   \n"     \
+       "       .set pop                                        \n"     \
+       :: "r" (val));                                                  \
+})
+
+#define        mftc0(rt, sel)                                                  
\
+({                                                                     \
+       unsigned long __res;                                            \
+       __asm __volatile(                                               \
+       "       .set push                                       \n"     \
+       "       .set mips32r2                                   \n"     \
+       "       .set noat                                       \n"     \
+       "       .word 0x41000800 | (" #rt " << 16) | " #sel "   \n"     \
+       "       move    %0, $1                                  \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (__res));                                                \
+        __res;                                                         \
+})
+
+#define        write_c0_register32(reg, sel, val)                              
\
+({                                                                     \
+       __asm __volatile(                                               \
+       "       .set push                                       \n"     \
+       "       .set mips32                                     \n"     \
+       "       mtc0    %0, $%1, %2                             \n"     \
+       "       .set pop                                        \n"     \
+       :: "r" (val), "i" (reg), "i" (sel));                            \
+})
+
+#define        read_c0_register32(reg, sel)                                    
\
+({                                                                     \
+       uint32_t __retval;                                              \
+       __asm __volatile(                                               \
+       "       .set push                                       \n"     \
+       "       .set mips32                                     \n"     \
+       "       mfc0    %0, $%1, %2                             \n"     \
+       "       .set pop                                        \n"     \
+       : "=r" (__retval) : "i" (reg), "i" (sel));                      \
+       __retval;                                                       \
+})
+
+void
+platform_ipi_send(int cpuid)
+{
+       uint32_t reg;
+
+       /*
+        * Set thread context.
+        * Note this is not global, so we don't need lock.
+        */
+       reg = read_c0_register32(1, 1);
+       reg &= ~(0xff);
+       reg |= cpuid;
+       write_c0_register32(1, 1, reg);
+
+       ehb();
+
+       /* Set cause */
+       reg = mftc0(13, 0);
+       mttc0(13, 0, (reg | C_SW1));
+}
+
+void
+platform_ipi_clear(void)
+{
+       uint32_t reg;
+
+       reg = mips_rd_cause();
+       reg &= ~(C_SW1);
+       mips_wr_cause(reg);
+}
+
+int
+platform_ipi_hardintr_num(void)
+{
+
+       return (-1);
+}
+
+int
+platform_ipi_softintr_num(void)
+{
+
+       return (1);
+}
+
+void
+platform_init_ap(int cpuid)
+{
+       uint32_t clock_int_mask;
+       uint32_t ipi_intr_mask;
+
+       /*
+        * Clear any pending IPIs.
+        */
+       platform_ipi_clear();
+
+       /*
+        * Unmask the clock and ipi interrupts.
+        */
+       ipi_intr_mask = soft_int_mask(platform_ipi_softintr_num());
+       clock_int_mask = hard_int_mask(5);
+       set_intr_mask(ipi_intr_mask | clock_int_mask);
+
+       mips_wbflush();
+}
+
+void
+platform_cpu_mask(cpuset_t *mask)
+{
+       uint32_t i, m;
+
+       CPU_ZERO(mask);
+       for (i = 0, m = 1 ; i < MALTA_MAXCPU; i++, m <<= 1)
+               CPU_SET(i, mask);
+}
+
+struct cpu_group *
+platform_smp_topo(void)
+{
+
+       return (smp_topo_none());
+}
+
+int
+platform_start_ap(int cpuid)
+{
+       int timeout;
+
+       if (atomic_cmpset_32(&malta_ap_boot, ~0, cpuid) == 0)
+               return (-1);
+
+       printf("Waiting for cpu%d to start\n", cpuid);
+
+       timeout = 100;
+       do {
+               DELAY(1000);
+               if (atomic_cmpset_32(&malta_ap_boot, 0, ~0) != 0) {
+                       printf("CPU %d started\n", cpuid);
+                       return (0);
+               }
+       } while (timeout--);
+
+       printf("CPU %d failed to start\n", cpuid);
+
+       return (0);
+}

Modified: head/sys/mips/malta/std.malta
==============================================================================
--- head/sys/mips/malta/std.malta       Fri Sep  9 14:09:50 2016        
(r305663)
+++ head/sys/mips/malta/std.malta       Fri Sep  9 14:50:44 2016        
(r305664)
@@ -1,7 +1,7 @@
 # $FreeBSD$
 files  "../malta/files.malta"
 
-cpu            CPU_MIPS4KC
+cpu            CPU_MALTA
 device         pci
 device         ata
 

Modified: head/sys/mips/mips/locore.S
==============================================================================
--- head/sys/mips/mips/locore.S Fri Sep  9 14:09:50 2016        (r305663)
+++ head/sys/mips/mips/locore.S Fri Sep  9 14:50:44 2016        (r305664)
@@ -158,6 +158,21 @@ VECTOR(_locore, unknown)
 1:
 #endif
 
+#if defined(CPU_MALTA) && defined(SMP)
+       .set push
+       .set mips32r2
+       jal     enable_mvp
+       nop
+       jal     platform_processor_id
+       nop
+       beqz    v0, 1f
+       nop
+       j       malta_ap_wait
+       nop
+       .set pop
+1:
+#endif
+
        /*
         * Initialize stack and call machine startup.
         */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to