Rearrange the exit path so that we don't do a idcache_wbinv_all *twice*
when a process exits.
This commit is contained in:
parent
62d83d05b1
commit
0886c8cc0f
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: cpuswitch.S,v 1.8 2002/08/06 17:44:35 thorpej Exp $ */
|
/* $NetBSD: cpuswitch.S,v 1.9 2002/08/06 19:20:29 thorpej Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994-1998 Mark Brinicombe.
|
* Copyright (c) 1994-1998 Mark Brinicombe.
|
||||||
@ -467,26 +467,26 @@ Lidle_ret:
|
|||||||
teq r1, r6
|
teq r1, r6
|
||||||
beq switch_return
|
beq switch_return
|
||||||
|
|
||||||
|
/* Remember the old process in r0 */
|
||||||
|
mov r0, r1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the curproc on entry to cpu_switch was zero then the
|
* If the curproc on entry to cpu_switch was zero then the
|
||||||
* process that called it was exiting. This means that we do
|
* process that called it was exiting. This means that we do
|
||||||
* not need to save the current context. Instead we can jump
|
* not need to save the current context. Instead we can jump
|
||||||
* straight to restoring the context for the new process.
|
* straight to restoring the context for the new process.
|
||||||
*/
|
*/
|
||||||
teq r1, #0x00000000
|
teq r0, #0x00000000
|
||||||
beq switch_exited
|
beq switch_exited
|
||||||
|
|
||||||
/* rem: r1 = old proc */
|
/* rem: r0 = old proc */
|
||||||
/* rem: r6 = new process */
|
/* rem: r6 = new process */
|
||||||
/* rem: interrupts are enabled */
|
/* rem: interrupts are enabled */
|
||||||
|
|
||||||
/* Stage two : Save old context */
|
/* Stage two : Save old context */
|
||||||
|
|
||||||
/* Remember the old process in r0 */
|
|
||||||
mov r0, r1
|
|
||||||
|
|
||||||
/* Get the user structure for the old process. */
|
/* Get the user structure for the old process. */
|
||||||
ldr r1, [r1, #(P_ADDR)]
|
ldr r1, [r0, #(P_ADDR)]
|
||||||
|
|
||||||
/* Save all the registers in the old process's pcb */
|
/* Save all the registers in the old process's pcb */
|
||||||
add r7, r1, #(PCB_R8)
|
add r7, r1, #(PCB_R8)
|
||||||
@ -512,27 +512,36 @@ Lidle_ret:
|
|||||||
|
|
||||||
/* What else needs to be saved Only FPA stuff when that is supported */
|
/* What else needs to be saved Only FPA stuff when that is supported */
|
||||||
|
|
||||||
|
/* r1 now free! */
|
||||||
|
|
||||||
/* Third phase : restore saved context */
|
/* Third phase : restore saved context */
|
||||||
|
|
||||||
switch_exited:
|
/* rem: r0 = old proc */
|
||||||
/* Don't allow user space access beween the purge and the switch */
|
/* rem: r6 = new process */
|
||||||
|
/* rem: interrupts are enabled */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't allow user space access between the purge and the switch.
|
||||||
|
*/
|
||||||
ldr r3, Lblock_userspace_access
|
ldr r3, Lblock_userspace_access
|
||||||
ldr r2, [r3]
|
mov r1, #0x00000001
|
||||||
orr r0, r2, #1
|
mov r2, #0x00000000
|
||||||
str r0, [r3]
|
str r1, [r3]
|
||||||
|
|
||||||
stmfd sp!, {r0-r3}
|
stmfd sp!, {r0-r3}
|
||||||
ldr r0, Lcpufuncs
|
ldr r1, Lcpufuncs
|
||||||
add lr, pc, #Lcs_cache_purged - . - 8
|
add lr, pc, #Lcs_cache_purged - . - 8
|
||||||
ldr pc, [r0, #CF_IDCACHE_WBINV_ALL]
|
ldr pc, [r1, #CF_IDCACHE_WBINV_ALL]
|
||||||
|
|
||||||
Lcs_cache_purged:
|
Lcs_cache_purged:
|
||||||
ldmfd sp!, {r0-r3}
|
ldmfd sp!, {r0-r3}
|
||||||
|
|
||||||
|
Lcs_cache_purge_skipped:
|
||||||
/* At this point we need to kill IRQ's again. */
|
/* At this point we need to kill IRQ's again. */
|
||||||
IRQdisable
|
IRQdisable
|
||||||
|
|
||||||
/* Interrupts are disabled so we can allow user space accesses again
|
/*
|
||||||
|
* Interrupts are disabled so we can allow user space accesses again
|
||||||
* as none will occur until interrupts are re-enabled after the
|
* as none will occur until interrupts are re-enabled after the
|
||||||
* switch.
|
* switch.
|
||||||
*/
|
*/
|
||||||
@ -591,6 +600,16 @@ switch_return:
|
|||||||
*/
|
*/
|
||||||
ldmfd sp!, {r4-r7, pc}
|
ldmfd sp!, {r4-r7, pc}
|
||||||
|
|
||||||
|
switch_exited:
|
||||||
|
/*
|
||||||
|
* We skip the cache purge because switch_exit() already did
|
||||||
|
* it. Load up registers the way Lcs_cache_purge_skipped
|
||||||
|
* expects. Userspace access already blocked in switch_exit().
|
||||||
|
*/
|
||||||
|
ldr r3, Lblock_userspace_access
|
||||||
|
mov r2, #0x00000000
|
||||||
|
b Lcs_cache_purge_skipped
|
||||||
|
|
||||||
Lproc0:
|
Lproc0:
|
||||||
.word _C_LABEL(proc0)
|
.word _C_LABEL(proc0)
|
||||||
|
|
||||||
@ -620,6 +639,13 @@ ENTRY(switch_exit)
|
|||||||
/* ldr r0, Lcurpcb
|
/* ldr r0, Lcurpcb
|
||||||
str r2, [r0]*/
|
str r2, [r0]*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't allow user space access between the purge and the switch.
|
||||||
|
*/
|
||||||
|
ldr r0, Lblock_userspace_access
|
||||||
|
mov r2, #0x00000001
|
||||||
|
str r2, [r0]
|
||||||
|
|
||||||
/* Switch to proc0 context */
|
/* Switch to proc0 context */
|
||||||
|
|
||||||
stmfd sp!, {r0-r3}
|
stmfd sp!, {r0-r3}
|
||||||
|
Loading…
Reference in New Issue
Block a user