summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-08-06 02:31:30 +0000
committerjake <jake@FreeBSD.org>2001-08-06 02:31:30 +0000
commit9ce2e785400efba330d4d0593f5eb92310bc1eb3 (patch)
tree035d1df9bfd4a6e27415486bb3889c7cdcc8c36b /sys
parent2cab41002343e798f5aee0df0f15f78ebd8e3ecc (diff)
downloadFreeBSD-src-9ce2e785400efba330d4d0593f5eb92310bc1eb3.zip
FreeBSD-src-9ce2e785400efba330d4d0593f5eb92310bc1eb3.tar.gz
Handle switching switching mmu contexts and mapping the new primary tsb.
Rework some register usage and code placement. Comment.
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/sparc64/swtch.S106
-rw-r--r--sys/sparc64/sparc64/swtch.s106
2 files changed, 184 insertions, 28 deletions
diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S
index f9445c4..28c288f 100644
--- a/sys/sparc64/sparc64/swtch.S
+++ b/sys/sparc64/sparc64/swtch.S
@@ -27,6 +27,7 @@
*/
#include <machine/asmacros.h>
+#include <machine/asi.h>
#include "assym.s"
@@ -70,32 +71,109 @@
.endm
ENTRY(cpu_switch)
+ /*
+ * Choose a new process. If its the same as the current one, do
+ * nothing.
+ */
save %sp, -CCFSZ, %sp
call chooseproc
ldx [PCPU(CURPROC)], %l0
cmp %l0, %o0
be,pn %xcc, 3f
- ldx [%l0 + P_FRAME], %l2
- ldx [%l2 + TF_TSTATE], %l2
- andcc %l2, TSTATE_PEF, %l2
+ EMPTY
+
+ /*
+ * If the process was using floating point, save its context.
+ */
+ ldx [%l0 + P_FRAME], %l1
+ ldx [%l1 + TF_TSTATE], %l1
+ andcc %l1, TSTATE_PEF, %l1
be,pt %xcc, 1f
- ldx [PCPU(CURPCB)], %l1
- savefp %l1 + PCB_FPSTATE, %l3
+ ldx [PCPU(CURPCB)], %l2
+ savefp %l2 + PCB_FPSTATE, %l3
+
+ /*
+ * Flush the windows out to the stack and save the current frame
+ * pointer and program counter.
+ */
1: flushw
wrpr %g0, 0, %cleanwin
- stx %fp, [%l1 + PCB_FP]
- stx %i7, [%l1 + PCB_PC]
+ stx %fp, [%l2 + PCB_FP]
+ stx %i7, [%l2 + PCB_PC]
+
+ /*
+ * Load the new process's frame pointer and program counter, and set
+ * the current process and pcb.
+ */
ldx [%o0 + P_ADDR], %o1
ldx [%o1 + U_PCB + PCB_FP], %fp
ldx [%o1 + U_PCB + PCB_PC], %i7
- ldx [%o0 + P_FRAME], %l2
- ldx [%l2 + TF_TSTATE], %l2
- andcc %l2, TSTATE_PEF, %l2
+ sub %fp, CCFSZ, %sp
+ stx %o0, [PCPU(CURPROC)]
+ stx %o1, [PCPU(CURPCB)]
+
+ /*
+ * Point to the new process's vmspace and load its vm context number.
+ * If its nucleus context we are done.
+ */
+ ldx [%o0 + P_VMSPACE], %o2
+ lduw [%o2 + VM_PMAP + PM_CONTEXT], %o3
+ brz,pn %o3, 3f
+ EMPTY
+
+ /*
+ * If the new process was using floating point, restore its context.
+ */
+ ldx [%o0 + P_FRAME], %o4
+ ldx [%o4 + TF_TSTATE], %o4
+ andcc %o4, TSTATE_PEF, %o4
be,pt %xcc, 2f
- stx %o0, [PCPU(CURPROC)]
- restrfp %o1 + U_PCB + PCB_FPSTATE, %l4
-2: stx %o1, [PCPU(CURPCB)]
- sub %fp, CCFSZ, %sp
+ nop
+ restrfp %o1 + U_PCB + PCB_FPSTATE, %o4
+
+ /*
+ * Point to the current process's vmspace and load the hardware
+ * context number. If its the same as the new process, we are
+ * done.
+ */
+ ldx [%l0 + P_VMSPACE], %l1
+ lduw [%l1 + VM_PMAP + PM_CONTEXT], %l3
+ cmp %l3, %o3
+ be,pn %xcc, 3f
+ EMPTY
+
+ /*
+ * Install the new primary context.
+ */
+2: mov AA_DMMU_PCXR, %o1
+ stxa %o3, [%o1] ASI_DMMU
+ flush %o0
+
+ /*
+ * Map the primary user tsb.
+ */
+ setx TSB_USER_MIN_ADDRESS, %o1, %o0
+ mov AA_DMMU_TAR, %o1
+ stxa %o0, [%o1] ASI_DMMU
+ mov TLB_DAR_TSB_USER_PRIMARY, %o1
+ ldx [%o2 + VM_PMAP + PM_STTE + TTE_DATA], %o3
+ stxa %o3, [%o1] ASI_DTLB_DATA_ACCESS_REG
+ membar #Sync
+
+ /*
+ * If the primary tsb page hasn't been initialized, initialize it
+ * and update the bit in the tte.
+ */
+ andcc %o3, TD_INIT, %g0
+ bnz %xcc, 3f
+ or %o3, TD_INIT, %o3
+ stx %o3, [%o2 + VM_PMAP + PM_STTE + TTE_DATA]
+ call tsb_page_init
+ clr %o1
+
+ /*
+ * Done. Return and load the new process's window from the stack.
+ */
3: ret
restore
END(cpu_switch)
diff --git a/sys/sparc64/sparc64/swtch.s b/sys/sparc64/sparc64/swtch.s
index f9445c4..28c288f 100644
--- a/sys/sparc64/sparc64/swtch.s
+++ b/sys/sparc64/sparc64/swtch.s
@@ -27,6 +27,7 @@
*/
#include <machine/asmacros.h>
+#include <machine/asi.h>
#include "assym.s"
@@ -70,32 +71,109 @@
.endm
ENTRY(cpu_switch)
+ /*
+ * Choose a new process. If its the same as the current one, do
+ * nothing.
+ */
save %sp, -CCFSZ, %sp
call chooseproc
ldx [PCPU(CURPROC)], %l0
cmp %l0, %o0
be,pn %xcc, 3f
- ldx [%l0 + P_FRAME], %l2
- ldx [%l2 + TF_TSTATE], %l2
- andcc %l2, TSTATE_PEF, %l2
+ EMPTY
+
+ /*
+ * If the process was using floating point, save its context.
+ */
+ ldx [%l0 + P_FRAME], %l1
+ ldx [%l1 + TF_TSTATE], %l1
+ andcc %l1, TSTATE_PEF, %l1
be,pt %xcc, 1f
- ldx [PCPU(CURPCB)], %l1
- savefp %l1 + PCB_FPSTATE, %l3
+ ldx [PCPU(CURPCB)], %l2
+ savefp %l2 + PCB_FPSTATE, %l3
+
+ /*
+ * Flush the windows out to the stack and save the current frame
+ * pointer and program counter.
+ */
1: flushw
wrpr %g0, 0, %cleanwin
- stx %fp, [%l1 + PCB_FP]
- stx %i7, [%l1 + PCB_PC]
+ stx %fp, [%l2 + PCB_FP]
+ stx %i7, [%l2 + PCB_PC]
+
+ /*
+ * Load the new process's frame pointer and program counter, and set
+ * the current process and pcb.
+ */
ldx [%o0 + P_ADDR], %o1
ldx [%o1 + U_PCB + PCB_FP], %fp
ldx [%o1 + U_PCB + PCB_PC], %i7
- ldx [%o0 + P_FRAME], %l2
- ldx [%l2 + TF_TSTATE], %l2
- andcc %l2, TSTATE_PEF, %l2
+ sub %fp, CCFSZ, %sp
+ stx %o0, [PCPU(CURPROC)]
+ stx %o1, [PCPU(CURPCB)]
+
+ /*
+ * Point to the new process's vmspace and load its vm context number.
+ * If its nucleus context we are done.
+ */
+ ldx [%o0 + P_VMSPACE], %o2
+ lduw [%o2 + VM_PMAP + PM_CONTEXT], %o3
+ brz,pn %o3, 3f
+ EMPTY
+
+ /*
+ * If the new process was using floating point, restore its context.
+ */
+ ldx [%o0 + P_FRAME], %o4
+ ldx [%o4 + TF_TSTATE], %o4
+ andcc %o4, TSTATE_PEF, %o4
be,pt %xcc, 2f
- stx %o0, [PCPU(CURPROC)]
- restrfp %o1 + U_PCB + PCB_FPSTATE, %l4
-2: stx %o1, [PCPU(CURPCB)]
- sub %fp, CCFSZ, %sp
+ nop
+ restrfp %o1 + U_PCB + PCB_FPSTATE, %o4
+
+ /*
+ * Point to the current process's vmspace and load the hardware
+ * context number. If its the same as the new process, we are
+ * done.
+ */
+ ldx [%l0 + P_VMSPACE], %l1
+ lduw [%l1 + VM_PMAP + PM_CONTEXT], %l3
+ cmp %l3, %o3
+ be,pn %xcc, 3f
+ EMPTY
+
+ /*
+ * Install the new primary context.
+ */
+2: mov AA_DMMU_PCXR, %o1
+ stxa %o3, [%o1] ASI_DMMU
+ flush %o0
+
+ /*
+ * Map the primary user tsb.
+ */
+ setx TSB_USER_MIN_ADDRESS, %o1, %o0
+ mov AA_DMMU_TAR, %o1
+ stxa %o0, [%o1] ASI_DMMU
+ mov TLB_DAR_TSB_USER_PRIMARY, %o1
+ ldx [%o2 + VM_PMAP + PM_STTE + TTE_DATA], %o3
+ stxa %o3, [%o1] ASI_DTLB_DATA_ACCESS_REG
+ membar #Sync
+
+ /*
+ * If the primary tsb page hasn't been initialized, initialize it
+ * and update the bit in the tte.
+ */
+ andcc %o3, TD_INIT, %g0
+ bnz %xcc, 3f
+ or %o3, TD_INIT, %o3
+ stx %o3, [%o2 + VM_PMAP + PM_STTE + TTE_DATA]
+ call tsb_page_init
+ clr %o1
+
+ /*
+ * Done. Return and load the new process's window from the stack.
+ */
3: ret
restore
END(cpu_switch)
OpenPOWER on IntegriCloud