summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-08-29 20:33:17 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-08-29 20:33:17 +0000
commit3dedeea696f0eea7042acc587783d890538c20c5 (patch)
tree61f281656c57a76b9ad8f60c28e5107d986f5388 /sys/arch
parentb5604b45f5e758b43e5114e50f575ca3de2b0168 (diff)
The low-level guts to support MTP (Multi-Threaded Processing) on the
Fujitsu SPARC64-VI and SPARC64-VII CPUs. Since the two threads on each core share the TLBs of the core we cannot enter different mappings for the same virtual address. Instead we use a scratch register to store the per-cpu pointer. This is very similar to what we do on sun4v. For now we still only attach the first thread of each SPARC64-VI/VII core since we currently don't handle the VMT (Vertical Multi-Threading) of the SPARC64-VI very well.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/include/ctlreg.h4
-rw-r--r--sys/arch/sparc64/sparc64/autoconf.c19
-rw-r--r--sys/arch/sparc64/sparc64/locore.s16
-rw-r--r--sys/arch/sparc64/sparc64/pmap.c31
4 files changed, 66 insertions, 4 deletions
diff --git a/sys/arch/sparc64/include/ctlreg.h b/sys/arch/sparc64/include/ctlreg.h
index 43652728816..a451e2ce00f 100644
--- a/sys/arch/sparc64/include/ctlreg.h
+++ b/sys/arch/sparc64/include/ctlreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ctlreg.h,v 1.23 2009/11/30 22:59:29 kettenis Exp $ */
+/* $OpenBSD: ctlreg.h,v 1.24 2012/08/29 20:33:16 kettenis Exp $ */
/* $NetBSD: ctlreg.h,v 1.28 2001/08/06 23:55:34 eeh Exp $ */
/*
@@ -127,6 +127,8 @@
#define ASI_AFSR 0x4c /* [4u] asynchronous fault status register */
#define ASI_AFAR 0x4d /* [4u] asynchronous fault address register */
+#define ASI_SCRATCH 0x4f /* [VI] scratch registers */
+
#define ASI_ICACHE_DATA 0x66 /* [4u] diagnostic access to D-cache data RAM */
#define ASI_ICACHE_TAG 0x67 /* [4u] diagnostic access to D-cache tag RAM */
#define ASI_FLUSH_I_PAGE_PRIMARY 0x68 /* [4u] flush D-cache page using primary context */
diff --git a/sys/arch/sparc64/sparc64/autoconf.c b/sys/arch/sparc64/sparc64/autoconf.c
index 733a15e4ed9..5dd2b946cde 100644
--- a/sys/arch/sparc64/sparc64/autoconf.c
+++ b/sys/arch/sparc64/sparc64/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.116 2012/06/30 22:00:49 kettenis Exp $ */
+/* $OpenBSD: autoconf.c,v 1.117 2012/08/29 20:33:16 kettenis Exp $ */
/* $NetBSD: autoconf.c,v 1.51 2001/07/24 19:32:11 eeh Exp $ */
/*
@@ -344,6 +344,23 @@ bootstrap(nctx)
cacheinfo.c_dcache_flush_page = no_dcache_flush_page;
}
+#ifdef MULTIPROCESSOR
+ if (impl >= IMPL_OLYMPUS_C && impl <= IMPL_JUPITER) {
+ struct sun4u_patch {
+ u_int32_t addr;
+ u_int32_t insn;
+ } *p;
+
+ extern struct sun4u_patch sun4u_mtp_patch;
+ extern struct sun4u_patch sun4u_mtp_patch_end;
+
+ for (p = &sun4u_mtp_patch; p < &sun4u_mtp_patch_end; p++) {
+ *(u_int32_t *)(vaddr_t)p->addr = p->insn;
+ flush((void *)(vaddr_t)p->addr);
+ }
+ }
+#endif
+
#ifdef SUN4V
if (CPU_ISSUN4V) {
u_int32_t insn;
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index 3f401f849bb..3b10fa2c9a9 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.164 2011/10/12 18:30:09 miod Exp $ */
+/* $OpenBSD: locore.s,v 1.165 2012/08/29 20:33:16 kettenis Exp $ */
/* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */
/*
@@ -106,6 +106,11 @@ _C_LABEL(sun4v_patch):
.globl _C_LABEL(sun4v_mp_patch)
_C_LABEL(sun4v_mp_patch):
.previous
+
+ .section .sun4u_mtp_patch, "ax"
+ .globl _C_LABEL(sun4u_mtp_patch)
+_C_LABEL(sun4u_mtp_patch):
+ .previous
#endif
/*
@@ -120,6 +125,10 @@ _C_LABEL(sun4v_mp_patch):
.section .sun4v_mp_patch, "ax" ;\
.word 999b ;\
ldxa [%g0] ASI_SCRATCHPAD, ci ;\
+ .previous ;\
+ .section .sun4u_mtp_patch, "ax" ;\
+ .word 999b ;\
+ ldxa [%g0] ASI_SCRATCH, ci ;\
.previous
#define GET_CPCB(pcb) \
@@ -9181,4 +9190,9 @@ _C_LABEL(sun4v_patch_end):
.globl _C_LABEL(sun4v_mp_patch_end)
_C_LABEL(sun4v_mp_patch_end):
.previous
+
+ .section .sun4u_mtp_patch, "ax"
+ .globl _C_LABEL(sun4u_mtp_patch_end)
+_C_LABEL(sun4u_mtp_patch_end):
+ .previous
#endif
diff --git a/sys/arch/sparc64/sparc64/pmap.c b/sys/arch/sparc64/sparc64/pmap.c
index b1e31bce64f..2d398b13e1a 100644
--- a/sys/arch/sparc64/sparc64/pmap.c
+++ b/sys/arch/sparc64/sparc64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.77 2012/08/29 19:54:32 kettenis Exp $ */
+/* $OpenBSD: pmap.c,v 1.78 2012/08/29 20:33:16 kettenis Exp $ */
/* $NetBSD: pmap.c,v 1.107 2001/08/31 16:47:41 eeh Exp $ */
#undef NO_VCACHE /* Don't forget the locked TLB in dostart */
/*
@@ -1469,6 +1469,9 @@ sun4u_bootstrap_cpu(paddr_t intstack)
paddr_t pa;
vaddr_t va;
int index;
+ int impl;
+
+ impl = (getver() & VER_IMPL) >> VER_IMPL_SHIFT;
/*
* Establish the 4MB locked mappings for kernel data and text.
@@ -1493,6 +1496,32 @@ sun4u_bootstrap_cpu(paddr_t intstack)
index--;
}
+#ifdef MULTIPROCESSOR
+ if (impl >= IMPL_OLYMPUS_C && impl <= IMPL_JUPITER) {
+ /*
+ * On SPARC64-VI and SPARC64-VII processors, the MMU is
+ * shared between threads, so we can't establish a locked
+ * mapping for the interrupt stack since the mappings would
+ * conflict. Instead we stick the address in a scratch
+ * register, like we do for sun4v.
+ */
+ pa = intstack + (CPUINFO_VA - INTSTACK);
+ pa += offsetof(struct cpu_info, ci_self);
+ va = ldxa(pa, ASI_PHYS_CACHED);
+ stxa(0x00, ASI_SCRATCH, va);
+
+ if ((CPU_JUPITERID % 2) == 1)
+ index--;
+
+ data = SUN4U_TSB_DATA(0, PGSZ_64K, intstack, 1, 1, 1, FORCE_ALIAS, 1, 0);
+ data |= SUN4U_TLB_L;
+ prom_dtlb_load(index, data, va - (CPUINFO_VA - INTSTACK));
+
+ sun4u_set_tsbs();
+ return;
+ }
+#endif
+
/*
* Establish the 64KB locked mapping for the interrupt stack.
*/