summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/powerpc/aim/swtch.S185
-rw-r--r--sys/powerpc/include/pcb.h2
-rw-r--r--sys/powerpc/powerpc/genassym.c2
-rw-r--r--sys/powerpc/powerpc/swtch.S185
-rw-r--r--sys/powerpc/powerpc/swtch.s185
5 files changed, 76 insertions, 483 deletions
diff --git a/sys/powerpc/aim/swtch.S b/sys/powerpc/aim/swtch.S
index bcdfcae..0a78d61 100644
--- a/sys/powerpc/aim/swtch.S
+++ b/sys/powerpc/aim/swtch.S
@@ -67,178 +67,41 @@
#include <machine/asm.h>
/*
- * Some instructions gas doesn't understand (yet?)
+ * void cpu_switch()
+ * Find a runnable thread and switch to it.
*/
-#define bdneq bdnzf 2,
-
-/*
- * No processes are runnable, so loop waiting for one.
- * Separate label here for accounting purposes.
- */
-#if 0 /* XXX: I think this is now unneeded. Leaving it in just in case. */
-ASENTRY(Idle)
- mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while
- manipulating runque */
- mtmsr 3
-
- lis 8,sched_whichqs@ha
- lwz 9,sched_whichqs@l(8)
-
- or. 9,9,9
- bne- .Lsw1 /* at least one queue non-empty */
-
- ori 3,3,PSL_EE@l /* reenable ints again */
- mtmsr 3
- isync
-
-/* Check if we can use power saving mode */
- lis 8,powersave@ha
- lwz 9,powersave@l(8)
-
- or. 9,9,9
- beq 1f
-
- sync
- oris 3,3,PSL_POW@h /* enter power saving mode */
- mtmsr 3
- isync
-1:
- b _ASM_LABEL(Idle)
-#endif /* XXX */
-
-/*
- * switchexit gets called from cpu_exit to complete the exit procedure.
- */
-ENTRY(switchexit)
-/* First switch to the idle pcb/kernel stack */
-#if 0 /* XXX */
- lis 6,idle_u@ha
- lwz 6,idle_u@l(6)
- mfsprg 7,0
- stw 6,GD_CURPCB(7)
-#endif
- addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */
- /*
- * Schedule the vmspace and stack to be freed (the proc arg is
- * already in r3).
- */
- bl sys_exit
-
-/* Fall through to cpu_switch to actually select another proc */
- li 3,0 /* indicate exited process */
-
-/*
- * void cpu_switch(struct proc *p)
- * Find a runnable process and switch to it.
- */
-/* XXX noprofile? --thorpej@netbsd.org */
ENTRY(cpu_switch)
- mflr 0 /* save lr */
- stw 0,4(1)
- stwu 1,-16(1)
- stw 31,12(1)
- stw 30,8(1)
-
- mr 30,3
- mfsprg 3,0
- xor 31,31,31
- stw 31,GD_CURTHREAD(3) /* Zero to not accumulate cpu time */
- mfsprg 3,0
- lwz 31,GD_CURPCB(3)
-
- xor 3,3,3
-#if 0 /* XXX */
- bl lcsplx
-#endif
- stw 3,PCB_SPL(31) /* save spl */
-
-/* Find a new process */
- bl choosethread
-
-1:
- /* record new process */
- mfsprg 4,0
- stw 3,GD_CURTHREAD(4)
-
- cmpl 0,31,30 /* is it the same process? */
- beq switch_return
-
- or. 30,30,30 /* old process was exiting? */
- beq switch_exited
-
- mfsr 10,USER_SR /* save USER_SR for copyin/copyout */
- mfcr 11 /* save cr */
- mr 12,2 /* save r2 */
- stwu 1,-SFRAMELEN(1) /* still running on old stack */
- stmw 10,8(1)
- lwz 3,TD_PCB(30)
- stw 1,PCB_SP(3) /* save SP */
-
-switch_exited:
- mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while
- actually switching */
- mtmsr 3
-
- /* indicate new pcb */
- lwz 4,TD_PCB(31)
- mfsprg 5,0
- stw 4,GD_CURPCB(5)
-
-#if 0 /* XXX */
- /* save real pmap pointer for spill fill */
- lwz 5,PCB_PMR(4)
- lis 6,curpm@ha
- stwu 5,curpm@l(6)
- stwcx. 5,0,6 /* clear possible reservation */
-#endif
-
- addic. 5,5,64
- li 6,0
- mfsr 8,KERNEL_SR /* save kernel SR */
-1:
- addis 6,6,-0x10000000@ha /* set new procs segment registers */
- or. 6,6,6 /* This is done from the real
- address pmap */
- lwzu 7,-4(5) /* so we don't have to worry */
- mtsrin 7,6 /* about accessibility */
- bne 1b
- mtsr KERNEL_SR,8 /* restore kernel SR */
- isync
+ mflr %r30
+ mfsprg %r3,%r0 /* Get the globaldata pointer */
+ lwz %r4,GD_CURTHREAD(%r3) /* Get the current thread */
+ lwz %r3,TD_PCB(%r4) /* Get a pointer to the PCB */
- lwz 1,PCB_SP(4) /* get new procs SP */
+ stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
+ mfcr %r4 /* Save the condition register */
+ stw %r4,PCB_CR(%r3)
- ori 3,3,PSL_EE@l /* interrupts are okay again */
- mtmsr 3
+ bl choosethread /* Find a new thread to run */
- lmw 10,8(1) /* get other regs */
- lwz 1,0(1) /* get saved SP */
- mr 2,12 /* get saved r2 */
- mtcr 11 /* get saved cr */
- isync
- mtsr USER_SR,10 /* get saved USER_SR */
- isync
+ mr %r14,$r3 /* Save off the (struct thread *) */
-switch_return:
- mr 30,7 /* save proc pointer */
- lwz 3,PCB_SPL(4)
-#if 0 /* XXX */
- bl lcsplx
-#endif
+ bl pmap_activate /* Activate the new address space */
- mr 3,30 /* get curthread for special fork
- returns */
+ mtlr %r30
+ mfsprg %r4,%r0 /* Get the globaldata pointer */
+ stw %r14,GD_CURTHREAD(%r4) /* Store new current thread */
+ lwz %r4,TD_PCB(%r14) /* Grab the new PCB */
- lwz 31,12(1)
- lwz 30,8(1)
- addi 1,1,16
- lwz 0,4(1)
- mtlr 0
+ lmw %r14,PCB_CONTEXT(%r4) /* Load the non-volatile GP regs */
+ lwz %r5,PCB_CR(%r4) /* Load the condition register */
+ mtcr %r5
blr
/*
- * Fake savectx for the time being.
+ * savectx(pcb)
+ * Update pcb, saving current processor state
*/
ENTRY(savectx)
+ stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
+ mfcr %r4 /* Save the condition register */
+ stw %r4,PCB_CONTEXT(%r3)
blr
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 6bc7219..98b6fa9 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -38,6 +38,8 @@
typedef int faultbuf[23];
struct pcb {
+ u_int32_t pcb_context[18]; /* non-volatile r14-r31 */
+ u_int32_t pcb_cr; /* Condition register */
struct pmap *pcb_pm; /* pmap of our vmspace */
struct pmap *pcb_pmreal; /* real address of above */
register_t pcb_sp; /* saved SP */
diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c
index 7f015a9..229d839 100644
--- a/sys/powerpc/powerpc/genassym.c
+++ b/sys/powerpc/powerpc/genassym.c
@@ -88,6 +88,8 @@ ASSYM(FRAME_EXC, offsetof(struct trapframe, exc));
ASSYM(SFRAMELEN, roundup(sizeof(struct switchframe), 16));
+ASSYM(PCB_CONTEXT, offsetof(struct pcb, pcb_context));
+ASSYM(PCB_CR, offsetof(struct pcb, pcb_cr));
ASSYM(PCB_PMR, offsetof(struct pcb, pcb_pmreal));
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
ASSYM(PCB_SPL, offsetof(struct pcb, pcb_spl));
diff --git a/sys/powerpc/powerpc/swtch.S b/sys/powerpc/powerpc/swtch.S
index bcdfcae..0a78d61 100644
--- a/sys/powerpc/powerpc/swtch.S
+++ b/sys/powerpc/powerpc/swtch.S
@@ -67,178 +67,41 @@
#include <machine/asm.h>
/*
- * Some instructions gas doesn't understand (yet?)
+ * void cpu_switch()
+ * Find a runnable thread and switch to it.
*/
-#define bdneq bdnzf 2,
-
-/*
- * No processes are runnable, so loop waiting for one.
- * Separate label here for accounting purposes.
- */
-#if 0 /* XXX: I think this is now unneeded. Leaving it in just in case. */
-ASENTRY(Idle)
- mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while
- manipulating runque */
- mtmsr 3
-
- lis 8,sched_whichqs@ha
- lwz 9,sched_whichqs@l(8)
-
- or. 9,9,9
- bne- .Lsw1 /* at least one queue non-empty */
-
- ori 3,3,PSL_EE@l /* reenable ints again */
- mtmsr 3
- isync
-
-/* Check if we can use power saving mode */
- lis 8,powersave@ha
- lwz 9,powersave@l(8)
-
- or. 9,9,9
- beq 1f
-
- sync
- oris 3,3,PSL_POW@h /* enter power saving mode */
- mtmsr 3
- isync
-1:
- b _ASM_LABEL(Idle)
-#endif /* XXX */
-
-/*
- * switchexit gets called from cpu_exit to complete the exit procedure.
- */
-ENTRY(switchexit)
-/* First switch to the idle pcb/kernel stack */
-#if 0 /* XXX */
- lis 6,idle_u@ha
- lwz 6,idle_u@l(6)
- mfsprg 7,0
- stw 6,GD_CURPCB(7)
-#endif
- addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */
- /*
- * Schedule the vmspace and stack to be freed (the proc arg is
- * already in r3).
- */
- bl sys_exit
-
-/* Fall through to cpu_switch to actually select another proc */
- li 3,0 /* indicate exited process */
-
-/*
- * void cpu_switch(struct proc *p)
- * Find a runnable process and switch to it.
- */
-/* XXX noprofile? --thorpej@netbsd.org */
ENTRY(cpu_switch)
- mflr 0 /* save lr */
- stw 0,4(1)
- stwu 1,-16(1)
- stw 31,12(1)
- stw 30,8(1)
-
- mr 30,3
- mfsprg 3,0
- xor 31,31,31
- stw 31,GD_CURTHREAD(3) /* Zero to not accumulate cpu time */
- mfsprg 3,0
- lwz 31,GD_CURPCB(3)
-
- xor 3,3,3
-#if 0 /* XXX */
- bl lcsplx
-#endif
- stw 3,PCB_SPL(31) /* save spl */
-
-/* Find a new process */
- bl choosethread
-
-1:
- /* record new process */
- mfsprg 4,0
- stw 3,GD_CURTHREAD(4)
-
- cmpl 0,31,30 /* is it the same process? */
- beq switch_return
-
- or. 30,30,30 /* old process was exiting? */
- beq switch_exited
-
- mfsr 10,USER_SR /* save USER_SR for copyin/copyout */
- mfcr 11 /* save cr */
- mr 12,2 /* save r2 */
- stwu 1,-SFRAMELEN(1) /* still running on old stack */
- stmw 10,8(1)
- lwz 3,TD_PCB(30)
- stw 1,PCB_SP(3) /* save SP */
-
-switch_exited:
- mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while
- actually switching */
- mtmsr 3
-
- /* indicate new pcb */
- lwz 4,TD_PCB(31)
- mfsprg 5,0
- stw 4,GD_CURPCB(5)
-
-#if 0 /* XXX */
- /* save real pmap pointer for spill fill */
- lwz 5,PCB_PMR(4)
- lis 6,curpm@ha
- stwu 5,curpm@l(6)
- stwcx. 5,0,6 /* clear possible reservation */
-#endif
-
- addic. 5,5,64
- li 6,0
- mfsr 8,KERNEL_SR /* save kernel SR */
-1:
- addis 6,6,-0x10000000@ha /* set new procs segment registers */
- or. 6,6,6 /* This is done from the real
- address pmap */
- lwzu 7,-4(5) /* so we don't have to worry */
- mtsrin 7,6 /* about accessibility */
- bne 1b
- mtsr KERNEL_SR,8 /* restore kernel SR */
- isync
+ mflr %r30
+ mfsprg %r3,%r0 /* Get the globaldata pointer */
+ lwz %r4,GD_CURTHREAD(%r3) /* Get the current thread */
+ lwz %r3,TD_PCB(%r4) /* Get a pointer to the PCB */
- lwz 1,PCB_SP(4) /* get new procs SP */
+ stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
+ mfcr %r4 /* Save the condition register */
+ stw %r4,PCB_CR(%r3)
- ori 3,3,PSL_EE@l /* interrupts are okay again */
- mtmsr 3
+ bl choosethread /* Find a new thread to run */
- lmw 10,8(1) /* get other regs */
- lwz 1,0(1) /* get saved SP */
- mr 2,12 /* get saved r2 */
- mtcr 11 /* get saved cr */
- isync
- mtsr USER_SR,10 /* get saved USER_SR */
- isync
+ mr %r14,$r3 /* Save off the (struct thread *) */
-switch_return:
- mr 30,7 /* save proc pointer */
- lwz 3,PCB_SPL(4)
-#if 0 /* XXX */
- bl lcsplx
-#endif
+ bl pmap_activate /* Activate the new address space */
- mr 3,30 /* get curthread for special fork
- returns */
+ mtlr %r30
+ mfsprg %r4,%r0 /* Get the globaldata pointer */
+ stw %r14,GD_CURTHREAD(%r4) /* Store new current thread */
+ lwz %r4,TD_PCB(%r14) /* Grab the new PCB */
- lwz 31,12(1)
- lwz 30,8(1)
- addi 1,1,16
- lwz 0,4(1)
- mtlr 0
+ lmw %r14,PCB_CONTEXT(%r4) /* Load the non-volatile GP regs */
+ lwz %r5,PCB_CR(%r4) /* Load the condition register */
+ mtcr %r5
blr
/*
- * Fake savectx for the time being.
+ * savectx(pcb)
+ * Update pcb, saving current processor state
*/
ENTRY(savectx)
+ stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
+ mfcr %r4 /* Save the condition register */
+ stw %r4,PCB_CONTEXT(%r3)
blr
diff --git a/sys/powerpc/powerpc/swtch.s b/sys/powerpc/powerpc/swtch.s
index bcdfcae..0a78d61 100644
--- a/sys/powerpc/powerpc/swtch.s
+++ b/sys/powerpc/powerpc/swtch.s
@@ -67,178 +67,41 @@
#include <machine/asm.h>
/*
- * Some instructions gas doesn't understand (yet?)
+ * void cpu_switch()
+ * Find a runnable thread and switch to it.
*/
-#define bdneq bdnzf 2,
-
-/*
- * No processes are runnable, so loop waiting for one.
- * Separate label here for accounting purposes.
- */
-#if 0 /* XXX: I think this is now unneeded. Leaving it in just in case. */
-ASENTRY(Idle)
- mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while
- manipulating runque */
- mtmsr 3
-
- lis 8,sched_whichqs@ha
- lwz 9,sched_whichqs@l(8)
-
- or. 9,9,9
- bne- .Lsw1 /* at least one queue non-empty */
-
- ori 3,3,PSL_EE@l /* reenable ints again */
- mtmsr 3
- isync
-
-/* Check if we can use power saving mode */
- lis 8,powersave@ha
- lwz 9,powersave@l(8)
-
- or. 9,9,9
- beq 1f
-
- sync
- oris 3,3,PSL_POW@h /* enter power saving mode */
- mtmsr 3
- isync
-1:
- b _ASM_LABEL(Idle)
-#endif /* XXX */
-
-/*
- * switchexit gets called from cpu_exit to complete the exit procedure.
- */
-ENTRY(switchexit)
-/* First switch to the idle pcb/kernel stack */
-#if 0 /* XXX */
- lis 6,idle_u@ha
- lwz 6,idle_u@l(6)
- mfsprg 7,0
- stw 6,GD_CURPCB(7)
-#endif
- addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */
- /*
- * Schedule the vmspace and stack to be freed (the proc arg is
- * already in r3).
- */
- bl sys_exit
-
-/* Fall through to cpu_switch to actually select another proc */
- li 3,0 /* indicate exited process */
-
-/*
- * void cpu_switch(struct proc *p)
- * Find a runnable process and switch to it.
- */
-/* XXX noprofile? --thorpej@netbsd.org */
ENTRY(cpu_switch)
- mflr 0 /* save lr */
- stw 0,4(1)
- stwu 1,-16(1)
- stw 31,12(1)
- stw 30,8(1)
-
- mr 30,3
- mfsprg 3,0
- xor 31,31,31
- stw 31,GD_CURTHREAD(3) /* Zero to not accumulate cpu time */
- mfsprg 3,0
- lwz 31,GD_CURPCB(3)
-
- xor 3,3,3
-#if 0 /* XXX */
- bl lcsplx
-#endif
- stw 3,PCB_SPL(31) /* save spl */
-
-/* Find a new process */
- bl choosethread
-
-1:
- /* record new process */
- mfsprg 4,0
- stw 3,GD_CURTHREAD(4)
-
- cmpl 0,31,30 /* is it the same process? */
- beq switch_return
-
- or. 30,30,30 /* old process was exiting? */
- beq switch_exited
-
- mfsr 10,USER_SR /* save USER_SR for copyin/copyout */
- mfcr 11 /* save cr */
- mr 12,2 /* save r2 */
- stwu 1,-SFRAMELEN(1) /* still running on old stack */
- stmw 10,8(1)
- lwz 3,TD_PCB(30)
- stw 1,PCB_SP(3) /* save SP */
-
-switch_exited:
- mfmsr 3
- andi. 3,3,~PSL_EE@l /* disable interrupts while
- actually switching */
- mtmsr 3
-
- /* indicate new pcb */
- lwz 4,TD_PCB(31)
- mfsprg 5,0
- stw 4,GD_CURPCB(5)
-
-#if 0 /* XXX */
- /* save real pmap pointer for spill fill */
- lwz 5,PCB_PMR(4)
- lis 6,curpm@ha
- stwu 5,curpm@l(6)
- stwcx. 5,0,6 /* clear possible reservation */
-#endif
-
- addic. 5,5,64
- li 6,0
- mfsr 8,KERNEL_SR /* save kernel SR */
-1:
- addis 6,6,-0x10000000@ha /* set new procs segment registers */
- or. 6,6,6 /* This is done from the real
- address pmap */
- lwzu 7,-4(5) /* so we don't have to worry */
- mtsrin 7,6 /* about accessibility */
- bne 1b
- mtsr KERNEL_SR,8 /* restore kernel SR */
- isync
+ mflr %r30
+ mfsprg %r3,%r0 /* Get the globaldata pointer */
+ lwz %r4,GD_CURTHREAD(%r3) /* Get the current thread */
+ lwz %r3,TD_PCB(%r4) /* Get a pointer to the PCB */
- lwz 1,PCB_SP(4) /* get new procs SP */
+ stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
+ mfcr %r4 /* Save the condition register */
+ stw %r4,PCB_CR(%r3)
- ori 3,3,PSL_EE@l /* interrupts are okay again */
- mtmsr 3
+ bl choosethread /* Find a new thread to run */
- lmw 10,8(1) /* get other regs */
- lwz 1,0(1) /* get saved SP */
- mr 2,12 /* get saved r2 */
- mtcr 11 /* get saved cr */
- isync
- mtsr USER_SR,10 /* get saved USER_SR */
- isync
+ mr %r14,$r3 /* Save off the (struct thread *) */
-switch_return:
- mr 30,7 /* save proc pointer */
- lwz 3,PCB_SPL(4)
-#if 0 /* XXX */
- bl lcsplx
-#endif
+ bl pmap_activate /* Activate the new address space */
- mr 3,30 /* get curthread for special fork
- returns */
+ mtlr %r30
+ mfsprg %r4,%r0 /* Get the globaldata pointer */
+ stw %r14,GD_CURTHREAD(%r4) /* Store new current thread */
+ lwz %r4,TD_PCB(%r14) /* Grab the new PCB */
- lwz 31,12(1)
- lwz 30,8(1)
- addi 1,1,16
- lwz 0,4(1)
- mtlr 0
+ lmw %r14,PCB_CONTEXT(%r4) /* Load the non-volatile GP regs */
+ lwz %r5,PCB_CR(%r4) /* Load the condition register */
+ mtcr %r5
blr
/*
- * Fake savectx for the time being.
+ * savectx(pcb)
+ * Update pcb, saving current processor state
*/
ENTRY(savectx)
+ stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
+ mfcr %r4 /* Save the condition register */
+ stw %r4,PCB_CONTEXT(%r3)
blr
OpenPOWER on IntegriCloud