diff options
-rw-r--r-- | sys/mips/conf/GXEMUL | 3 | ||||
-rw-r--r-- | sys/mips/gxemul/gxemul_machdep.c | 69 | ||||
-rw-r--r-- | sys/mips/gxemul/mpreg.h | 2 |
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)) |