summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/amd64/locore.S
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/amd64/locore.S')
-rw-r--r--sys/arch/amd64/amd64/locore.S75
1 files changed, 59 insertions, 16 deletions
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index e185eb4e371..0884e1d11da 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.36 2009/06/02 03:04:54 jordan Exp $ */
+/* $OpenBSD: locore.S,v 1.37 2009/06/05 10:51:44 guenther Exp $ */
/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */
/*
@@ -132,10 +132,20 @@
#include <machine/asm.h>
+#define SET_CURPROC(proc,cpu) \
+ movq CPUVAR(SELF),cpu ; \
+ movq proc,CPUVAR(CURPROC) ; \
+ movq cpu,P_CPU(proc)
+
+#define GET_CURPCB(reg) movq CPUVAR(CURPCB),reg
+#define SET_CURPCB(reg) movq reg,CPUVAR(CURPCB)
+
+
/* XXX temporary kluge; these should not be here */
/* Get definitions for IOM_BEGIN, IOM_END, and IOM_SIZE */
#include <dev/isa/isareg.h>
+
/*
* Initialization
*/
@@ -716,29 +726,43 @@ ENTRY(cpu_switchto)
pushq %r14
pushq %r15
+ movq %rdi, %r13
+ movq %rsi, %r12
+
#ifdef DIAGNOSTIC
xorq %rax,%rax
- cmpq %rax,P_WCHAN(%rsi)
+ cmpq %rax,P_WCHAN(%r12)
jne _C_LABEL(switch_error2)
- cmpb $SRUN,P_STAT(%rsi)
+ cmpb $SRUN,P_STAT(%r12)
jne _C_LABEL(switch_error3)
#endif
- /* No interrupts while loading new state. */
- cli
-
/* Record new proc. */
- movb $SONPROC,P_STAT(%rsi) # p->p_stat = SONPROC
- movq %rsi, CPUVAR(CURPROC)
+ movb $SONPROC,P_STAT(%r12) # p->p_stat = SONPROC
+ SET_CURPROC(%r12,%rcx)
- /* If old proc exited, don't bother saving state. */
- testq %rdi,%rdi
+ /* If old proc exited, don't bother. */
+ testq %r13,%r13
jz switch_exited
+ /*
+ * Save old context.
+ *
+ * Registers:
+ * %rax, %rcx - scratch
+ * %r13 - old proc, then old pcb
+ * %r12 - new proc
+ */
+
+ movq %r13,%rdi
+ call pmap_deactivate
+
+ movq P_ADDR(%r13),%r13
+
/* Save stack pointers. */
- movq P_ADDR(%rdi),%r13
movq %rsp,PCB_RSP(%r13)
movq %rbp,PCB_RBP(%r13)
+
switch_exited:
/*
* Restore saved context.
@@ -746,26 +770,41 @@ switch_exited:
* Registers:
* %rax, %rcx, %rdx - scratch
* %r13 - new pcb
+ * %r12 - new process
*/
+ /* No interrupts while loading new state. */
+ cli
+ movq P_ADDR(%r12),%r13
+
/* Restore stack pointers. */
- movq P_ADDR(%rsi),%r13
movq PCB_RSP(%r13),%rsp
movq PCB_RBP(%r13),%rbp
- movq %r13, CPUVAR(CURPCB)
+#if 0
+ /* Don't bother with the rest if switching to a system process. */
+ testl $P_SYSTEM,P_FLAG(%r12)
+ jnz switch_restored
+#endif
/* Load TSS info. */
+#ifdef MULTIPROCESSOR
movq CPUVAR(GDT),%rax
- movl P_MD_TSS_SEL(%rsi),%edx
+#else
+ movq _C_LABEL(gdtstore)(%rip),%rax
+#endif
+ movl P_MD_TSS_SEL(%r12),%edx
/* Switch TSS. Reset "task busy" flag before */
andl $~0x0200,4(%rax,%rdx, 1)
ltr %dx
- call _C_LABEL(pmap_switch)
- /* %rsi and %rdi no longer valid */
+ movq %r12,%rdi
+ call _C_LABEL(pmap_activate)
+#if 0
+switch_restored:
+#endif
/* Restore cr0 (including FPU state). */
movl PCB_CR0(%r13),%ecx
#ifdef MULTIPROCESSOR
@@ -777,9 +816,13 @@ switch_exited:
#endif
movq %rcx,%cr0
+ SET_CURPCB(%r13)
+
/* Interrupts are okay again. */
sti
+switch_return:
+
popq %r15
popq %r14
popq %r13