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.
This commit is contained in:
Mark Peek 2001-10-15 00:37:45 +00:00
parent cd4ca11ce8
commit 422ec2ace1
5 changed files with 76 additions and 483 deletions

View File

@ -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)
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 */
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)
stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
mfcr %r4 /* Save the condition register */
stw %r4,PCB_CR(%r3)
xor 3,3,3
#if 0 /* XXX */
bl lcsplx
#endif
stw 3,PCB_SPL(31) /* save spl */
bl choosethread /* Find a new thread to run */
/* Find a new process */
bl choosethread
mr %r14,$r3 /* Save off the (struct thread *) */
1:
/* record new process */
mfsprg 4,0
stw 3,GD_CURTHREAD(4)
bl pmap_activate /* Activate the new address space */
cmpl 0,31,30 /* is it the same process? */
beq switch_return
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 */
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
lwz 1,PCB_SP(4) /* get new procs SP */
ori 3,3,PSL_EE@l /* interrupts are okay again */
mtmsr 3
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
switch_return:
mr 30,7 /* save proc pointer */
lwz 3,PCB_SPL(4)
#if 0 /* XXX */
bl lcsplx
#endif
mr 3,30 /* get curthread for special fork
returns */
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

View File

@ -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 */

View File

@ -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));

View File

@ -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)
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 */
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)
stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
mfcr %r4 /* Save the condition register */
stw %r4,PCB_CR(%r3)
xor 3,3,3
#if 0 /* XXX */
bl lcsplx
#endif
stw 3,PCB_SPL(31) /* save spl */
bl choosethread /* Find a new thread to run */
/* Find a new process */
bl choosethread
mr %r14,$r3 /* Save off the (struct thread *) */
1:
/* record new process */
mfsprg 4,0
stw 3,GD_CURTHREAD(4)
bl pmap_activate /* Activate the new address space */
cmpl 0,31,30 /* is it the same process? */
beq switch_return
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 */
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
lwz 1,PCB_SP(4) /* get new procs SP */
ori 3,3,PSL_EE@l /* interrupts are okay again */
mtmsr 3
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
switch_return:
mr 30,7 /* save proc pointer */
lwz 3,PCB_SPL(4)
#if 0 /* XXX */
bl lcsplx
#endif
mr 3,30 /* get curthread for special fork
returns */
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

View File

@ -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)
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 */
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)
stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
mfcr %r4 /* Save the condition register */
stw %r4,PCB_CR(%r3)
xor 3,3,3
#if 0 /* XXX */
bl lcsplx
#endif
stw 3,PCB_SPL(31) /* save spl */
bl choosethread /* Find a new thread to run */
/* Find a new process */
bl choosethread
mr %r14,$r3 /* Save off the (struct thread *) */
1:
/* record new process */
mfsprg 4,0
stw 3,GD_CURTHREAD(4)
bl pmap_activate /* Activate the new address space */
cmpl 0,31,30 /* is it the same process? */
beq switch_return
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 */
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
lwz 1,PCB_SP(4) /* get new procs SP */
ori 3,3,PSL_EE@l /* interrupts are okay again */
mtmsr 3
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
switch_return:
mr 30,7 /* save proc pointer */
lwz 3,PCB_SPL(4)
#if 0 /* XXX */
bl lcsplx
#endif
mr 3,30 /* get curthread for special fork
returns */
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