summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authormp <mp@FreeBSD.org>2001-10-15 00:37:45 +0000
committermp <mp@FreeBSD.org>2001-10-15 00:37:45 +0000
commitaeada36d1734651f00e54565d66b431bc1aca223 (patch)
tree6dd061609a7ab24673816e9d4b18eea4d197388d /sys/powerpc
parent10bfc1f0b13162f6d2f42de60757f85916908886 (diff)
downloadFreeBSD-src-aeada36d1734651f00e54565d66b431bc1aca223.zip
FreeBSD-src-aeada36d1734651f00e54565d66b431bc1aca223.tar.gz
Save WIP. Partial rewrite of cpu_switch() and savectx(). This makes it closer
to working but still needs some work to properly switch the full context (such as saving the fpu registers, switch stacks, etc.). Also, remove some dead code that was mixed in.
Diffstat (limited to 'sys/powerpc')
-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