Annotation of XNU/osfmk/ppc/savearea_asm.s, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: #include <assym.s>
        !            23: #include <debug.h>
        !            24: #include <cpus.h>
        !            25: #include <db_machine_commands.h>
        !            26: #include <mach_rt.h>
        !            27:        
        !            28: #include <mach_debug.h>
        !            29: #include <ppc/asm.h>
        !            30: #include <ppc/proc_reg.h>
        !            31: #include <ppc/exception.h>
        !            32: #include <ppc/Performance.h>
        !            33: #include <ppc/exception.h>
        !            34: #include <ppc/pmap_internals.h>
        !            35: #include <mach/ppc/vm_param.h>
        !            36:        
        !            37:                        .text
        !            38: 
        !            39: /*
        !            40:  *                     This routine will add a savearea block to the free list.
        !            41:  *                     Note really well: we can take NO exceptions of any kind,
        !            42:  *                     including a PTE miss once the savearea lock is held. That's
        !            43:  *                     a guaranteed deadlock.  That means we must disable for interrutions
        !            44:  *                     and turn all translation off.
        !            45:  *
        !            46:  *                     Note that the savearea list should NEVER be empty
        !            47:  */
        !            48: 
        !            49: ENTRY(save_queue,TAG_NO_FRAME_USED)
        !            50: 
        !            51: 
        !            52:                        mfmsr   r12                                                     /* Get the MSR */
        !            53:                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
        !            54:                        andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
        !            55:                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
        !            56:                        mtmsr   r11                                                     /* Make the MSR current */
        !            57: 
        !            58:                        isync
        !            59:                        
        !            60: #if 0
        !            61:                        rlwinm. r3,r3,0,0,19                            /* (TEST/DEBUG) */
        !            62:                        bne+    notraceit                                       /* (TEST/DEBUG) */
        !            63:                        BREAKPOINT_TRAP                                         /* (TEST/DEBUG) */
        !            64: notraceit:                                                                             /* (TEST/DEBUG) */
        !            65: #else
        !            66:                        rlwinm  r3,r3,0,0,19                            /* Make sure it's clean and tidy */
        !            67: #endif
        !            68: 
        !            69:                        lwarx   r9,0,r10                                        ; ?
        !            70: 
        !            71: sqlck:         lwarx   r9,0,r10                                        /* Grab the lock value */
        !            72:                        li              r8,1                                            /* Use part of the delay time */
        !            73:                        mr.             r9,r9                                           /* Is it locked? */
        !            74:                        bne-    sqlcks                                          /* Yeah, wait for it to clear... */
        !            75:                        stwcx.  r8,0,r10                                        /* Try to seize that there durn lock */
        !            76:                        beq+    sqlckd                                          /* Got it... */
        !            77:                        b               sqlck                                           /* Collision, try again... */
        !            78:                        
        !            79: sqlcks:                lwz             r9,SVlock(r10)                          /* Get that lock in here */
        !            80:                        mr.             r9,r9                                           /* Is it free yet? */
        !            81:                        beq+    sqlck                                           /* Yeah, try for it again... */
        !            82:                        b               sqlcks                                          /* Sniff away... */
        !            83:                        
        !            84: sqlckd:                isync                                                           /* Make sure translation is off */
        !            85:                        lwz             r7,SVfree(r10)                          /* Get the free save area list anchor */
        !            86:                        lwz             r6,SVcount(r10)                         /* Get the total count of saveareas */
        !            87:                        stw             r3,SVfree(r10)                          /* Queue in the new one */
        !            88:                        addi    r6,r6,sac_cnt                           /* Count the ones we are linking in */
        !            89:                        stw             r7,SACnext(r3)                          /* Queue the old first one off of us */
        !            90:                        li              r8,0                                            /* Get a free lock value */
        !            91:                        stw             r6,SVcount(r10)                         /* Save the new count */
        !            92:                        
        !            93:                        sync                                                            /* Make sure everything is done */
        !            94:                        stw             r8,SVlock(r10)                          /* Unlock the savearea chain */
        !            95:                        
        !            96:                        mtmsr   r12                                                     /* Restore interrupts and translation */
        !            97:                        isync                                                           /* Dump any speculations */
        !            98: 
        !            99: #if 0
        !           100:                        lis             r0,HIGH_ADDR(CutTrace)          /* (TEST/DEBUG) */
        !           101:                        li              r2,0x2201                                       ; (TEST/DEBUG)
        !           102:                        oris    r0,r0,LOW_ADDR(CutTrace)        /* (TEST/DEBUG) */
        !           103:                        sc                                                                      /* (TEST/DEBUG) */
        !           104: #endif
        !           105: 
        !           106:                        blr                                                                     /* Leave... */
        !           107: 
        !           108: 
        !           109: /*
        !           110:  *                     This routine will find and remove an empty savearea block from the free list.
        !           111:  *                     Note really well: we can take NO exceptions of any kind,
        !           112:  *                     including a PTE miss once the savearea lock is held. That's
        !           113:  *                     a guaranteed deadlock.  That means we must disable for interrutions
        !           114:  *                     and turn all translation off.
        !           115:  *
        !           116:  *                     We pass back the virtual address of the one we just released
        !           117:  *                     or a zero if none to free.
        !           118:  *
        !           119:  *                     Note that the savearea list should NEVER be empty
        !           120:  */
        !           121: 
        !           122: ENTRY(save_dequeue,TAG_NO_FRAME_USED)
        !           123: 
        !           124: 
        !           125:                        mfmsr   r12                                                     /* Get the MSR */
        !           126:                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
        !           127:                        andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
        !           128:                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
        !           129:                        mtmsr   r11                                                     /* Make the MSR current */
        !           130:                        isync                                                           /* Make sure translation is off */
        !           131: 
        !           132:                        lwarx   r9,0,r10                                        ; ?
        !           133: 
        !           134: sdqlck:                lwarx   r9,0,r10                                        /* Grab the lock value */
        !           135:                        li              r8,1                                            /* Use part of the delay time */
        !           136:                        mr.             r9,r9                                           /* Is it locked? */
        !           137:                        bne-    sdqlcks                                         /* Yeah, wait for it to clear... */
        !           138:                        stwcx.  r8,0,r10                                        /* Try to seize that there durn lock */
        !           139:                        beq+    sdqlckd                                         /* Got it... */
        !           140:                        b               sdqlck                                          /* Collision, try again... */
        !           141:                        
        !           142: sdqlcks:       lwz             r9,SVlock(r10)                          /* Get that lock in here */
        !           143:                        mr.             r9,r9                                           /* Is it free yet? */
        !           144:                        beq+    sdqlck                                          /* Yeah, try for it again... */
        !           145:                        b               sdqlcks                                         /* Sniff away... */
        !           146:                        
        !           147: 
        !           148: sdqlckd:       lwz             r3,SVfree(r10)                          /* Get the free save area list anchor */
        !           149:                        la              r5,SVfree(r10)                          /* Remember that the we're just starting out */
        !           150:                        lwz             r6,SVcount(r10)                         /* Get the total count of saveareas for later */
        !           151:                        lis             r8,sac_empty>>16                        /* Get the empty block indication */
        !           152:                        
        !           153: sdqchk:                lwz             r4,SACalloc(r3)                         /* Get the allocation flags */
        !           154:                        lwz             r9,SACflags(r3)                         /* Get the flags */
        !           155:                        lwz             r7,SACnext(r3)                          /* Point on to the next one */
        !           156:                        andis.  r9,r9,hi16(sac_perm)            /* Is this permanently allocated? */
        !           157:                        cmplw   cr1,r4,r8                                       /* Does this look empty? */
        !           158:                        bne-    sdqperm                                         /* It's permanent, can't release... */
        !           159:                        beq-    cr1,sdqfnd                                      /* Yeah, empty... */
        !           160: 
        !           161: sdqperm:       la              r5,SACnext(r3)                          /* Remember the last guy */
        !           162:                        mr.             r3,r7                                           /* Any more left? */
        !           163:                        bne+    sdqchk                                          /* Yeah... */
        !           164:                        b               sdqunlk                                         /* Nope, just go unlock and leave... */
        !           165:                        
        !           166: sdqfnd:                subi    r6,r6,sac_cnt                           /* Back off the number of saveareas in here */
        !           167:                        stw             r7,0(r5)                                        /* Dequeue our guy */
        !           168:                        lwz             r9,SACvrswap(r3)                        /* Get addressing conversion */
        !           169:                        stw             r6,SVcount(r10)                         /* Back off the count for this block */
        !           170:                        xor             r3,r3,r9                                        /* Flip to virtual addressing */
        !           171: 
        !           172: sdqunlk:       li              r8,0                                            /* Get a free lock value */                     
        !           173:                        sync                                                            /* Make sure everything is done */
        !           174:                        stw             r8,SVlock(r10)                          /* Unlock the savearea chain */
        !           175:                        
        !           176:                        mtmsr   r12                                                     /* Restore interrupts and translation */
        !           177:                        isync                                                           /* Dump any speculations */
        !           178: 
        !           179: #if 0
        !           180:                        lis             r0,HIGH_ADDR(CutTrace)          /* (TEST/DEBUG) */
        !           181:                        li              r2,0x2202                                       ; (TEST/DEBUG)
        !           182:                        oris    r0,r0,LOW_ADDR(CutTrace)        /* (TEST/DEBUG) */
        !           183:                        sc                                                                      /* (TEST/DEBUG) */
        !           184: #endif
        !           185: 
        !           186:                        blr                                                                     /* Leave... */
        !           187: 
        !           188: 
        !           189: 
        !           190: /*
        !           191:  *                     This routine will obtain a savearea from the free list.
        !           192:  *                     Note really well: we can take NO exceptions of any kind,
        !           193:  *                     including a PTE miss once the savearea lock is held. That's
        !           194:  *                     a guaranteed deadlock.  That means we must disable for interrutions
        !           195:  *                     and turn all translation off.
        !           196:  *
        !           197:  *                     We pass back the virtual address of the one we just obtained
        !           198:  *                     or a zero if none to allocate.
        !           199:  *
        !           200:  *                     Note that the savearea list should NEVER be empty
        !           201:  *                     NOTE!!! NEVER USE R0, R2, or R12 IN HERE THAT WAY WE DON'T NEED A
        !           202:  *                     STACK FRAME IN FPU_SAVE, FPU_SWITCH, VEC_SAVE, OR VEC_SWITCH.
        !           203:  */
        !           204: 
        !           205: ENTRY(save_get_phys,TAG_NO_FRAME_USED)
        !           206:                        
        !           207:                        cmplw   cr1,r1,r1                                       ; Set CR1_eq to indicate we want physical address
        !           208:                        b               csaveget                                        ; Join the common...
        !           209: 
        !           210: ENTRY(save_get,TAG_NO_FRAME_USED)
        !           211:                        
        !           212:                        cmplwi  cr1,r1,0                                        ; Set CR1_ne to indicate we want virutal address
        !           213: 
        !           214: csaveget:      mfmsr   r11                                                     /* Get the MSR */
        !           215:                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
        !           216:                        andi.   r8,r11,0x7FCF                           /* Turn off all translation and 'rupts */
        !           217:                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
        !           218:                        mtmsr   r8                                                      /* Make the MSR current */
        !           219:                        isync                                                           ; Make sure it is done
        !           220:                        
        !           221:                        lwarx   r9,0,r10                                        ; ?
        !           222: 
        !           223: sglck:         lwarx   r9,0,r10                                        /* Grab the lock value */
        !           224:                        li              r7,1                                            /* Use part of the delay time */
        !           225:                        mr.             r9,r9                                           /* Is it locked? */
        !           226:                        bne-    sglcks                                          /* Yeah, wait for it to clear... */
        !           227:                        stwcx.  r7,0,r10                                        /* Try to seize that there durn lock */
        !           228:                        beq+    sglckd                                          /* Got it... */
        !           229:                        b               sglck                                           /* Collision, try again... */
        !           230:                        
        !           231: sglcks:                lwz             r9,SVlock(r10)                          /* Get that lock in here */
        !           232:                        mr.             r9,r9                                           /* Is it free yet? */
        !           233:                        beq+    sglck                                           /* Yeah, try for it again... */
        !           234:                        b               sglcks                                          /* Sniff away... */
        !           235:                        
        !           236: sglckd:                isync                                                           /* Make sure translation is off */
        !           237:                        lwz             r8,SVfree(r10)                          /* Get the head of the save area list */
        !           238:                        lwz             r9,SVinuse(r10)                         /* Get the inuse field */
        !           239: 
        !           240:                        lwz             r7,SACalloc(r8)                         /* Pick up the allocation bits */
        !           241:                        lwz             r5,SACvrswap(r8)                        /* Get real to virtual translation */
        !           242:                        mr.             r7,r7                                           /* Can we use the first one? */
        !           243:                        blt             use1st                                          /* Yeah... */
        !           244:                        
        !           245:                        andis.  r7,r7,0x8000                            /* Show we used the second and remember if it was the last */
        !           246:                        addi    r3,r8,0x0800                            /* Point to the first one */
        !           247:                        b               gotsave                                         /* We have the area now... */
        !           248: 
        !           249: use1st:                andis.  r7,r7,0x4000                            /* Mark first gone and remember if empty */
        !           250:                        mr              r3,r8                                           /* Set the save area */
        !           251:                        
        !           252: gotsave:       stw             r7,SACalloc(r8)                         /* Put back the allocation bits */
        !           253:                        bne             nodqsave                                        /* There's still an empty slot, don't dequeue... */
        !           254: 
        !           255:                        lwz             r4,SACnext(r8)                          /* Get the next in line */
        !           256:                        stw             r4,SVfree(r10)                          /* Dequeue our now empty save area block */
        !           257:                        
        !           258: nodqsave:      lis             r6,HIGH_ADDR(SAVattach)         /* Show that it is attached for now */
        !           259:                        li              r4,0                                            /* Clear this for the lock */
        !           260:                        stw             r6,SAVflags(r3)                         /* Set the flags to attached */
        !           261:                        addi    r9,r9,1                                         /* Bump up the inuse count */
        !           262:                        stw             r4,SAVprev(r3)                          /* Make sure that backchain is clear */
        !           263:                        stw             r9,SVinuse(r10)                         /* Set the inuse field */
        !           264:                        sync                                                            /* Make sure all stores are done */
        !           265:                        stw             r4,SVlock(r10)                          /* Unlock both save and trace areas */
        !           266:                        mtmsr   r11                                                     /* Restore translation and exceptions */
        !           267:                        isync                                                           /* Make sure about it */
        !           268:        
        !           269: #if 0
        !           270:                        mr              r11,r0                                          /* (TEST/DEBUG) */
        !           271:                        mr              r7,r2                                           /* (TEST/DEBUG) */
        !           272:                        lis             r0,HIGH_ADDR(CutTrace)          /* (TEST/DEBUG) */
        !           273:                        li              r2,0x2203                                       ; (TEST/DEBUG)
        !           274:                        oris    r0,r0,LOW_ADDR(CutTrace)        /* (TEST/DEBUG) */
        !           275:                        sc                                                                      /* (TEST/DEBUG) */
        !           276:                        mr              r0,r11                                          /* (TEST/DEBUG) */
        !           277:                        mr              r2,r7                                           /* (TEST/DEBUG) */
        !           278: #endif                 
        !           279:                        
        !           280:                        li              r7,0                                            ; NOTE WELL: we set R7 to zero for vector and float saving code in cswtch.s
        !           281:                        beqlr-  cr1                                                     ; Return now if we want the physical address
        !           282:                        xor             r3,r3,r5                                        /* Get the virtual address */
        !           283:                        blr                                                                     /* Leave... */
        !           284:                
        !           285: 
        !           286: /*
        !           287:  *                     This routine will return a savearea to the free list.
        !           288:  *                     Note really well: we can take NO exceptions of any kind,
        !           289:  *                     including a PTE miss once the savearea lock is held. That's
        !           290:  *                     a guaranteed deadlock.  That means we must disable for interrutions
        !           291:  *                     and turn all translation off.
        !           292:  *
        !           293:  *                     We take a virtual address.
        !           294:  *
        !           295:  */
        !           296: 
        !           297: ENTRY(save_ret,TAG_NO_FRAME_USED)
        !           298: 
        !           299: #if 0
        !           300:                        cmplwi  r3,0x1000                                       ; (TEST/DEBUG)
        !           301:                        bgt+    notpage0                                        ; (TEST/DEBUG)
        !           302:                        BREAKPOINT_TRAP                                         /* (TEST/DEBUG) */
        !           303: 
        !           304: notpage0:      rlwinm  r6,r3,0,0,19                            /* (TEST/DEBUG) */
        !           305:                        rlwinm  r7,r3,21,31,31                          /* (TEST/DEBUG) */
        !           306:                        lis             r8,0x8000                                       /* (TEST/DEBUG) */
        !           307:                        lwz             r6,SACalloc(r6)                         /* (TEST/DEBUG) */
        !           308:                        srw             r8,r8,r7                                        /* (TEST/DEBUG) */
        !           309:                        and.    r8,r8,r6                                        /* (TEST/DEBUG) */
        !           310:                        beq+    nodoublefret                            /* (TEST/DEBUG) */
        !           311:                        BREAKPOINT_TRAP                                         /* (TEST/DEBUG) */
        !           312:                        
        !           313: nodoublefret:                                                                  /* (TEST/DEBUG) */              
        !           314: #endif
        !           315: 
        !           316:                        lwz             r7,SAVflags(r3)                         /* Get the flags */
        !           317:                        rlwinm  r6,r3,0,0,19                            /* Round back down to the savearea page block */
        !           318:                        andis.  r7,r7,HIGH_ADDR(SAVinuse)       /* Still in use? */
        !           319:                        mfmsr   r12                                                     /* Get the MSR */
        !           320:                        bnelr-                                                          /* Still in use, just leave... */
        !           321:                        lwz             r5,SACvrswap(r6)                        /* Get the conversion to real */
        !           322:                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
        !           323:                        andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
        !           324:                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
        !           325:                        mtmsr   r11                                                     /* Make the MSR current */
        !           326:                        isync                                                           /* Make sure translation is off */
        !           327: 
        !           328:                        mfsprg  r11,1                                           /* Get the active save area */
        !           329:                        xor             r3,r3,r5                                        /* Get the real address of the savearea */
        !           330:                        cmplw   r11,r3                                          /* Are we trying to toss the active one? */
        !           331:                        xor             r6,r6,r5                                        /* Make the savearea block real also */
        !           332:                        beq-    srbigtimepanic                          /* This is a no-no... */
        !           333: 
        !           334:                        rlwinm  r7,r3,21,31,31                          /* Get position of savearea in block */
        !           335:                        lis             r8,0x8000                                       /* Build a bit mask and assume first savearea */
        !           336:                        srw             r8,r8,r7                                        /* Get bit position of do deallocate */
        !           337:                        
        !           338:                        lwarx   r11,0,r10                                       ; ?
        !           339: 
        !           340: srlck:         lwarx   r11,0,r10                                       /* Grab the lock value */
        !           341:                        li              r7,1                                            /* Use part of the delay time */
        !           342:                        mr.             r11,r11                                         /* Is it locked? */
        !           343:                        bne-    srlcks                                          /* Yeah, wait for it to clear... */
        !           344:                        stwcx.  r7,0,r10                                        /* Try to seize that there durn lock */
        !           345:                        beq+    srlckd                                          /* Got it... */
        !           346:                        b               srlck                                           /* Collision, try again... */
        !           347:                        
        !           348: srlcks:                lwz             r11,SVlock(r10)                         /* Get that lock in here */
        !           349:                        mr.             r11,r11                                         /* Is it free yet? */
        !           350:                        beq+    srlck                                           /* Yeah, try for it again... */
        !           351:                        b               srlcks                                          /* Sniff away... */
        !           352:                                        
        !           353: srlckd:                isync                                                           /* Toss preexecutions */
        !           354:                        lwz             r11,SACalloc(r6)                        /* Get the allocation for this block */
        !           355:                        lwz             r7,SVinuse(r10)                         /* Get the in use count */
        !           356:                        or              r11,r11,r8                                      /* Turn on our bit */
        !           357:                        subi    r7,r7,1                                         /* We released one, adjust count */
        !           358:                        cmplw   r11,r8                                          /* Is our's the only one free? */
        !           359:                        stw             r7,SVinuse(r10)                         /* Save out count */
        !           360:                        stw             r11,SACalloc(r6)                        /* Save it out */
        !           361:                        bne+    srtrest                                         /* Nope, then the block is already on the free list */
        !           362: 
        !           363:                        lwz             r11,SVfree(r10)                         /* Get the old head of the free list */
        !           364:                        stw             r6,SVfree(r10)                          /* Point the head at us now */
        !           365:                        stw             r11,SACnext(r6)                         /* Point us at the old last */
        !           366:                
        !           367: srtrest:       li              r8,0                                            /* Get set to clear the savearea lock */
        !           368:                        sync                                                            /* Make sure it's all out there */
        !           369:                        stw             r8,SVlock(r10)                          /* Unlock it */
        !           370:                        mtmsr   r12                                                     /* Restore interruptions and translation */
        !           371:                        isync
        !           372: 
        !           373: #if 0
        !           374:                        lis             r0,HIGH_ADDR(CutTrace)          /* (TEST/DEBUG) */
        !           375:                        li              r2,0x2204                                       ; (TEST/DEBUG)
        !           376:                        oris    r0,r0,LOW_ADDR(CutTrace)        /* (TEST/DEBUG) */
        !           377:                        sc                                                                      /* (TEST/DEBUG) */
        !           378: #endif
        !           379: 
        !           380:                        blr                                                                     /* Go away... */
        !           381: 
        !           382: srbigtimepanic:
        !           383:                        lis             r6,HIGH_ADDR(EXT(panic))        /* First half of panic call */
        !           384:                        lis             r3,HIGH_ADDR(EXT(srfreeactive)) /* First half of panic string */
        !           385:                        ori             r6,r6,LOW_ADDR(EXT(panic))      /* Second half of panic call */
        !           386:                        ori             r3,r3,LOW_ADDR(EXT(srfreeactive))       /* Second half of panic string */
        !           387:                        mtlr    r6                                                      /* Get the address of the panic routine */
        !           388:                        mtmsr   r12                                                     /* Restore interruptions and translation */
        !           389:                        isync
        !           390:                        blrl                                                            /* Panic... */
        !           391: 
        !           392:                        .data
        !           393: EXT(srfreeactive):
        !           394:                        STRINGD "save_ret: Attempting to release the active savearea!!!!"
        !           395:                        .text
        !           396: 
        !           397: 
        !           398: /*
        !           399:  *                     This routine will return the virtual address of the first free savearea
        !           400:  *                     block and disable for interruptions.
        !           401:  *                     Note really well: this is only for debugging, don't expect it to always work!
        !           402:  *
        !           403:  *                     We take a virtual address in R4 to save the original MSR, and 
        !           404:  *                     return the virtual address.
        !           405:  *
        !           406:  */
        !           407: 
        !           408: ENTRY(save_deb,TAG_NO_FRAME_USED)
        !           409: 
        !           410:                        mfmsr   r12                                                     /* Get the MSR */
        !           411:                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
        !           412:                        stw             r12,0(r3)                                       /* Save it */
        !           413:                        andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
        !           414:                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
        !           415:                        mtmsr   r11                                                     /* Make the MSR current */
        !           416:                        isync                                                           /* Make sure translation is off */
        !           417:                        lwz             r3,SVfree(r10)                          /* Get the physical first in list */
        !           418:                        andi.   r11,r12,0x7FFF                          /* Clear only interruption */
        !           419:                        lwz             r5,SACvrswap(r3)                        /* Get the conversion to virtual */
        !           420:                        mtmsr   r11                                                     /* Restore DAT but not INT */
        !           421:                        xor             r3,r3,r5                                        /* Make it virtual */
        !           422:                        isync
        !           423:                        blr
        !           424:                        
        !           425:                        
        !           426:                        
        !           427: 
        !           428: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.