diff options
-rw-r--r-- | sys/powerpc/aim/swtch.S | 185 | ||||
-rw-r--r-- | sys/powerpc/include/pcb.h | 2 | ||||
-rw-r--r-- | sys/powerpc/powerpc/genassym.c | 2 | ||||
-rw-r--r-- | sys/powerpc/powerpc/swtch.S | 185 | ||||
-rw-r--r-- | sys/powerpc/powerpc/swtch.s | 185 |
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 |