[BACK]Return to process.S CVS log [TXT][DIR] Up to [local] / sys / arch / m88k / m88k

Annotation of sys/arch/m88k/m88k/process.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: process.S,v 1.16 2007/05/12 19:59:52 miod Exp $       */
                      2: /*
                      3:  * Copyright (c) 1996 Nivas Madhur
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *      This product includes software developed by Nivas Madhur.
                     17:  * 4. The name of the author may not be used to endorse or promote products
                     18:  *    derived from this software without specific prior written permission
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     21:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     22:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     23:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     24:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     25:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     26:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     27:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     28:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     29:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     30:  *
                     31:  */
                     32:
                     33: #include "assym.h"
                     34: #include <machine/asm.h>
                     35: #include <machine/psl.h>
                     36: #include <machine/intr.h>
                     37:
                     38: #ifdef DIAGNOSTIC
                     39:        data
                     40:        align   4
                     41: ASLOCAL(swchanpanic)
                     42:        string  "switch wchan %x\0"
                     43:        align   4
                     44: ASLOCAL(swsrunpanic)
                     45:        string  "switch SRUN %x\0"
                     46:
                     47:        text
                     48:        align   8
                     49: ASLOCAL(Lswchanpanic)
                     50:        or.u    r2, r0, hi16(_ASM_LABEL(swchanpanic))
                     51:        or      r2, r2, lo16(_ASM_LABEL(swchanpanic))
                     52:        bsr.n   _C_LABEL(panic)
                     53:         or     r3, r0, r9
                     54:
                     55: ASLOCAL(Lswsrunpanic)
                     56:        or.u    r2, r0, hi16(_ASM_LABEL(swsrunpanic))
                     57:        or      r2, r2, lo16(_ASM_LABEL(swsrunpanic))
                     58:        bsr.n   _C_LABEL(panic)
                     59:         or     r3, r0, r9
                     60: #endif
                     61:
                     62: /*
                     63:  * void switch_exit(struct proc *p)
                     64:  *
                     65:  * Do the final work to exit from a process. After switching to the
                     66:  * idle stack and pcb, invoke exit2() on behalf of the exiting process,
                     67:  * then continue into cpu_switch() to select another process to run.
                     68:  */
                     69:
                     70: ENTRY(switch_exit)
                     71:        /*
                     72:         * Disable interrupts since we are about to change the kernel
                     73:         * stack.
                     74:         */
                     75:        ldcr    r3, PSR
                     76:        set     r3, r3, 1<PSR_INTERRUPT_DISABLE_BIT>
                     77:        stcr    r3, PSR
                     78:        FLUSH_PIPELINE
                     79:
                     80:        /*
                     81:         * Change pcb to idle u. area, i.e., set r31 to top of stack
                     82:         * and set curpcb to point to the cpu's idle stack.
                     83:         * r2 contains proc *p.
                     84:         */
                     85:        ldcr    r10, CPU
                     86:        ld      r30, r10, CI_IDLE_PCB
                     87:        addu    r31, r30, USIZE                         /* now on idle stack */
                     88:        st      r30, r10, CI_CURPCB                     /* curpcb = idle_pcb */
                     89:
                     90:        /* Schedule the vmspace and stack to be freed. */
                     91:        bsr.n   _C_LABEL(exit2)
                     92:         st     r0, r10, CI_CURPROC                     /* curproc = NULL */
                     93:
                     94:        /*
                     95:         * exit2() has acquired the scheduler lock for us. Jump into
                     96:         * cpu_switch(), after the context save since we do not need
                     97:         * to save anything.
                     98:         */
                     99:        br      _ASM_LABEL(cpu_switch_search)
                    100:
                    101: /*
                    102:  * void cpu_switch(struct proc *p)
                    103:  *
                    104:  * Find a runnable process and switch to it. On entry, the scheduler lock is
                    105:  * held; it has to be released before returning to the process.
                    106:  *
                    107:  * Note that this code ignores its proc parameter and assumes it has the
                    108:  * same value as curproc. This may change in mi_switch() in the future,
                    109:  * be careful.
                    110:  */
                    111: ENTRY(cpu_switch)
                    112:        /*
                    113:         * Disable interrupts, we do not want to be disturbed while
                    114:         * saving context.
                    115:         */
                    116:        ldcr    r2, PSR
                    117:        set     r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
                    118:        stcr    r2, PSR
                    119:        FLUSH_PIPELINE
                    120:
                    121:        /*
                    122:         * Save state of previous process in its pcb, and pmap_deactivate()
                    123:         * the process.
                    124:         */
                    125:        ldcr    r2,  CPU
                    126:        ld      r2,  r2,  CI_CURPCB
                    127:        st      r1,  r2,  PCB_PC                /* save return address */
                    128:        bsr     _ASM_LABEL(__savectx)
                    129:        /* note that we don't need to recover r1 at this point */
                    130:
                    131:        ldcr    r11, CPU
                    132:        ld      r2,  r11, CI_CURPROC
                    133:
                    134:        /*
                    135:         * Note that we can still use curpcb as our stack after
                    136:         * pmap_deactivate() has been called, as it does not affect the u
                    137:         * area mappings.
                    138:         */
                    139:        bsr.n   _C_LABEL(pmap_deactivate)
                    140:         st     r0,  r11, CI_CURPROC            /* curproc = NULL */
                    141:
                    142: #ifdef MULTIPROCESSOR
                    143:        /*
                    144:         * We need to switch to the processor's idle stack now (in case the
                    145:         * process we are using the stack of gets scheduled on another
                    146:         * processor).
                    147:         */
                    148:        ldcr    r10, CPU
                    149:        ld      r30, r10, CI_IDLE_PCB
                    150:        addu    r31, r30, USIZE                         /* now on idle stack */
                    151:        st      r30, r10, CI_CURPCB                     /* curpcb = idle_pcb */
                    152: #endif
                    153:
                    154: ASLOCAL(cpu_switch_search)
                    155:        /*
                    156:         * This is the start of the idle loop. Find the highest-priority
                    157:         * queue that isn't empty, then take the first proc from that queue.
                    158:         */
                    159:        or.u    r7, r0, hi16(_C_LABEL(whichqs))
                    160:        ld      r7, r7, lo16(_C_LABEL(whichqs))
                    161:        bcnd    ne0, r7, _ASM_LABEL(cpu_switch_found)
                    162:
                    163: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
                    164:        bsr     _C_LABEL(sched_unlock_idle)
                    165: #endif
                    166:
                    167: #ifdef MULTIPROCESSOR
                    168: ASGLOBAL(cpu_switch_idle)
                    169: #else
                    170: ASLOCAL(cpu_switch_idle)
                    171: #endif
                    172:        /*
                    173:         * There were no runnable processes. Enable all interrupts and
                    174:         * busy-wait for this to change.
                    175:         * Note that, besides doing setipl(IPL_NONE), this will actually enable
                    176:         * interrupts in the psr. Bootstrap of secondary processors
                    177:         * relies upon this.
                    178:         */
                    179:        ldcr    r2, PSR
                    180:        clr     r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
                    181:        stcr    r2, PSR
                    182:        FLUSH_PIPELINE
                    183:
                    184:        bsr.n   _C_LABEL(setipl)
                    185:         or     r2, r0, IPL_NONE
                    186:
                    187:        or.u    r7, r0, hi16(_C_LABEL(whichqs))
                    188:        ld      r7, r7, lo16(_C_LABEL(whichqs))
                    189:        bcnd    eq0, r7, _ASM_LABEL(cpu_switch_idle)
                    190:        /* XXX run fancy things here, such as page zeroing... */
                    191:
                    192: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
                    193:        bsr     _C_LABEL(sched_lock_idle)
                    194: #endif
                    195:
                    196: ASLOCAL(cpu_switch_found)
                    197:        /*
                    198:         * Disable interrupts.
                    199:         */
                    200:        ldcr    r2, PSR
                    201:        set     r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
                    202:        stcr    r2, PSR
                    203:        FLUSH_PIPELINE
                    204:
                    205:        /*
                    206:         * An interrupt could have occured between the last whichqs check
                    207:         * and the call to setipl(). Check again that whichqs is nonzero.
                    208:         */
                    209:        or.u    r7, r0, hi16(_C_LABEL(whichqs)) /* reload whichqs */
                    210:        ld      r7, r7, lo16(_C_LABEL(whichqs))
                    211:        bcnd    eq0, r7, _ASM_LABEL(cpu_switch_search)
                    212:
                    213:        /* XXX use ff1, like powerpc... needs *runqueue() adjustments */
                    214:        xor     r6, r6, r6              /* set r6 to 0 */
                    215: 1:     bb1     0,  r7, 2f              /* if rightmost bit set, done */
                    216:        extu    r7, r7, 0<1>            /* else, right shift whichqs, */
                    217:        br.n    1b                      /* increment r6, and repeat */
                    218:         addu   r6, r6, 1
                    219: 2:
                    220:        or.u    r7, r0, hi16(_C_LABEL(qs))
                    221:        or      r7, r7, lo16(_C_LABEL(qs))
                    222:
                    223:        /*
                    224:         * Need to make
                    225:         *      p->p_forw->p_back = p->p_back and
                    226:         *      p->p_back->p_forw = p->p_forw where
                    227:         *      p is q->p_forw.
                    228:         * Remember that q->p_forw == p and p->p_back == q.
                    229:         */
                    230:
                    231:        lda.d   r8,  r7[r6]     /* r8 = &qs[ff1(whichqs)] */
                    232:        ld      r9,  r8, P_FORW /* r8 is q, r9 is p */
                    233:
                    234:        ld      r12, r9, P_FORW /* r12 = p->p_forw */
                    235:        st      r8, r12, P_BACK /* p->p_forw->p_back = q (p->p_back) */
                    236:        st      r12, r8, P_FORW /* q->p_forw = p->p_forw */
                    237:        lda.d   r8,  r7[r6]     /* reload r8 with qs[ff1(whichqs)] */
                    238:        ld      r12, r8, P_FORW /* q->p_forw */
                    239:        cmp     r12, r12, r8    /* q == q->p_forw; anyone left on queue? */
                    240:        bb1     ne,  r12, 3f    /* yes, skip clearing bit in whichqs  */
                    241:
                    242:        or      r12, r0, 1
                    243:        mak     r12, r12, r6
                    244:        or.u    r7,  r0, hi16(_C_LABEL(whichqs))
                    245:        ld      r8,  r7, lo16(_C_LABEL(whichqs))
                    246:        and.c   r8,  r8, r12    /* whichqs &= ~the bit */
                    247:        st      r8,  r7, lo16(_C_LABEL(whichqs))
                    248: 3:
                    249: #ifdef DIAGNOSTIC
                    250:        ld      r2, r9, P_WCHAN
                    251:        bcnd    ne0, r2, _ASM_LABEL(Lswchanpanic)
                    252:        ld.b    r2, r9, P_STAT
                    253:        cmp     r2, r2, SRUN
                    254:        bb1     ne, r2, _ASM_LABEL(Lswsrunpanic)
                    255: #endif
                    256:
                    257:        ldcr    r11, CPU
                    258:        st      r0,  r11, CI_WANT_RESCHED               /* clear want_resched */
                    259:
                    260:        st      r9,  r11, CI_CURPROC                    /* curproc = p */
                    261:        or      r2,  r0,  SONPROC
                    262:        st.b    r2,  r9,  P_STAT
                    263: #ifdef MULTIPROCESSOR
                    264:        st      r11, r9,  P_CPU                         /* p->p_cpu = curcpu */
                    265: #endif
                    266:
                    267:        ld      r3,  r9,  P_ADDR
                    268:        st      r0,  r9,  P_BACK                        /* p->p_back = 0 */
                    269:        st      r3,  r11, CI_CURPCB                     /* curpcb = p->p_addr */
                    270:
                    271:        /* pmap_activate() the process' pmap */
                    272:        bsr.n   _C_LABEL(pmap_activate)
                    273:         or     r2, r0, r9
                    274:
                    275:        ldcr    r10,  CPU
                    276:        ld      r10,  r10, CI_CURPCB
                    277:
                    278:        /* restore from the current context */
                    279:        ld      r2,  r10, PCB_FCR62
                    280:        ld      r3,  r10, PCB_FCR63
                    281:        fstcr   r2,  fcr62
                    282:        fstcr   r3,  fcr63
                    283:        ld      r15, r10, PCB_R15
                    284:        ld      r16, r10, PCB_R16
                    285:        ld      r17, r10, PCB_R17
                    286:        ld      r18, r10, PCB_R18
                    287:        ld      r19, r10, PCB_R19
                    288:        ld      r20, r10, PCB_R20
                    289:        ld      r21, r10, PCB_R21
                    290:        ld      r22, r10, PCB_R22
                    291:        ld      r23, r10, PCB_R23
                    292:        ld      r24, r10, PCB_R24
                    293:        ld      r25, r10, PCB_R25
                    294:        ld      r26, r10, PCB_R26
                    295:        ld      r27, r10, PCB_R27
                    296:        ld      r28, r10, PCB_R28
                    297:        ld      r29, r10, PCB_R29
                    298:        ld      r30, r10, PCB_R30       /* restore frame pointer & stack */
                    299:        ld      r31, r10, PCB_SP
                    300: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
                    301:        bsr.n   _C_LABEL(sched_unlock_idle)
                    302:         or     r14, r10, r0
                    303:        ld      r1,  r14, PCB_PC
                    304:        ld      r14, r14, PCB_R14
                    305: #else
                    306:        ld      r1,  r10, PCB_PC
                    307:        ld      r14, r10, PCB_R14
                    308: #endif
                    309:
                    310:        /*
                    311:         * Enable interrupts again.
                    312:         */
                    313:        ldcr    r2, PSR
                    314:        clr     r2, r2, 1<PSR_INTERRUPT_DISABLE_BIT>
                    315:        stcr    r2, PSR
                    316:        FLUSH_PIPELINE
                    317:
                    318:        jmp     r1
                    319:
                    320: /*
                    321:  * savectx(pcb)
                    322:  * Update pcb, saving current processor state.
                    323:  */
                    324: ENTRY(savectx)
                    325:        /*
                    326:         * Save preserved general register set.
                    327:         */
                    328:        st      r1,  r2,  PCB_PC                /* save return address */
                    329: ASLOCAL(__savectx)
                    330:        st      r14, r2,  PCB_R14
                    331:        st      r15, r2,  PCB_R15
                    332:        st      r16, r2,  PCB_R16
                    333:        st      r17, r2,  PCB_R17
                    334:        st      r18, r2,  PCB_R18
                    335:        st      r19, r2,  PCB_R19
                    336:        st      r20, r2,  PCB_R20
                    337:        st      r21, r2,  PCB_R21
                    338:        st      r22, r2,  PCB_R22
                    339:        st      r23, r2,  PCB_R23
                    340:        st      r24, r2,  PCB_R24
                    341:        st      r25, r2,  PCB_R25
                    342:        st      r26, r2,  PCB_R26
                    343:        st      r27, r2,  PCB_R27
                    344:        st      r28, r2,  PCB_R28
                    345:        st      r29, r2,  PCB_R29
                    346:        st      r30, r2,  PCB_R30       /* save frame pointer & stack pointer */
                    347:        st      r31, r2,  PCB_SP
                    348:
                    349:        /*
                    350:         * Save FP state.
                    351:         */
                    352:        fldcr   r4,  fcr62
                    353:        fldcr   r5,  fcr63
                    354:        st      r4,  r2, PCB_FCR62
                    355:        jmp.n   r1
                    356:         st     r5,  r2, PCB_FCR63

CVSweb