summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/mips/conf/GXEMUL3
-rw-r--r--sys/mips/gxemul/gxemul_machdep.c69
-rw-r--r--sys/mips/gxemul/mpreg.h2
3 files changed, 74 insertions, 0 deletions
diff --git a/sys/mips/conf/GXEMUL b/sys/mips/conf/GXEMUL
index be6a9ae..ea58622 100644
--- a/sys/mips/conf/GXEMUL
+++ b/sys/mips/conf/GXEMUL
@@ -26,6 +26,9 @@ makeoptions MODULES_OVERRIDE=""
options DDB
options KDB
+# Make an SMP-capable kernel by default
+options SMP # Symmetric MultiProcessor Kernel
+
options SCHED_ULE
options INET # InterNETworking
options INET6 # IPv6 communications protocols
diff --git a/sys/mips/gxemul/gxemul_machdep.c b/sys/mips/gxemul/gxemul_machdep.c
index 41745b2..8996919 100644
--- a/sys/mips/gxemul/gxemul_machdep.c
+++ b/sys/mips/gxemul/gxemul_machdep.c
@@ -62,6 +62,11 @@ __FBSDID("$FreeBSD$");
#include <machine/pmap.h>
#include <machine/trap.h>
+#ifdef SMP
+#include <sys/smp.h>
+#include <machine/smp.h>
+#endif
+
#include <mips/gxemul/mpreg.h>
extern int *edata;
@@ -167,3 +172,67 @@ platform_start(__register_t a0, __register_t a1, __register_t a2,
mips_timer_init_params(platform_counter_freq, 0);
}
+
+#ifdef SMP
+void
+platform_ipi_send(int cpuid)
+{
+ GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_ONE, (1 << 16) | cpuid);
+}
+
+void
+platform_ipi_clear(void)
+{
+ GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_READ, 0);
+}
+
+int
+platform_ipi_intrnum(void)
+{
+ return (GXEMUL_MP_DEV_IPI_INTERRUPT - 2);
+}
+
+struct cpu_group *
+platform_smp_topo(void)
+{
+ return (smp_topo_none());
+}
+
+void
+platform_init_ap(int cpuid)
+{
+ int ipi_int_mask, clock_int_mask;
+
+ /*
+ * Unmask the clock and ipi interrupts.
+ */
+ clock_int_mask = hard_int_mask(5);
+ ipi_int_mask = hard_int_mask(platform_ipi_intrnum());
+ set_intr_mask(ipi_int_mask | clock_int_mask);
+}
+
+void
+platform_cpu_mask(cpuset_t *mask)
+{
+ unsigned i, n;
+
+ n = GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_NCPUS);
+ CPU_ZERO(mask);
+ for (i = 0; i < n; i++)
+ CPU_SET(i, mask);
+}
+
+int
+platform_processor_id(void)
+{
+ return (GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_WHOAMI));
+}
+
+int
+platform_start_ap(int cpuid)
+{
+ GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_STARTADDR, (intptr_t)mpentry);
+ GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_START, cpuid);
+ return (0);
+}
+#endif /* SMP */
diff --git a/sys/mips/gxemul/mpreg.h b/sys/mips/gxemul/mpreg.h
index 7e6780a..e09946d 100644
--- a/sys/mips/gxemul/mpreg.h
+++ b/sys/mips/gxemul/mpreg.h
@@ -36,10 +36,12 @@
#define GXEMUL_MP_DEV_START 0x0020
#define GXEMUL_MP_DEV_STARTADDR 0x0030
#define GXEMUL_MP_DEV_STACK 0x0070
+#define GXEMUL_MP_DEV_RANDOM 0x0080
#define GXEMUL_MP_DEV_MEMORY 0x0090
#define GXEMUL_MP_DEV_IPI_ONE 0x00a0
#define GXEMUL_MP_DEV_IPI_MANY 0x00b0
#define GXEMUL_MP_DEV_IPI_READ 0x00c0
+#define GXEMUL_MP_DEV_CYCLES 0x00d0
#define GXEMUL_MP_DEV_FUNCTION(f) \
(volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f))
OpenPOWER on IntegriCloud