]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-124.1.tar.gz mac-os-x-1001 v124.1
authorApple <opensource@apple.com>
Fri, 8 Aug 2003 23:41:13 +0000 (23:41 +0000)
committerApple <opensource@apple.com>
Fri, 8 Aug 2003 23:41:13 +0000 (23:41 +0000)
bsd/hfs/hfs_lookup.c
iokit/Families/IONDRVSupport/IONDRVFramebuffer.cpp
iokit/Families/IOSCSICDDrive/IOSCSICDDrive.cpp
iokit/IOKit/ndrvsupport/IOMacOSVideo.h
iokit/IOKit/ndrvsupport/IONDRVFramebuffer.h
osfmk/ppc/cache.s
osfmk/ppc/hw_vm.s
osfmk/ppc/machine_routines_asm.s
osfmk/ppc/savearea_asm.s
osfmk/vm/vm_resident.c
osfmk/vm/vm_user.c

index 8ade827fc344d30d67b8ff8a3f15c6932230e945..d627217ca3460c6961ad1558e0360cca9975e8e9 100644 (file)
@@ -569,9 +569,12 @@ hfs_lookup(ap)
                /*
                * Insert name in cache if wanted.
                 * Names with composed chars are not put into the name cache.
+                * Resource forks are not entered in the name cache. This
+                * avoids deadlocks.
                 */
                if ((cnp->cn_flags & MAKEENTRY)
-                   && (cnp->cn_namelen == catInfo.nodeData.cnm_length))        {
+                   && (cnp->cn_namelen == catInfo.nodeData.cnm_length)
+                       && ((H_FORKTYPE(VTOH(target_vp))) != kRsrcFork))        {
                        /*
                         * XXX SER - Might be good idea to bcopy(catInfo.nodeData.fsspec.name, cnp->cn_nameptr)
                         * to "normalize" the name cache. This will avoid polluting the name cache with
index 2fe80f342cab9ddbb32ef400dd6b8acb15667fd3..472e54d9ec7efd66872f422a4c09423cd8e3c332 100644 (file)
@@ -1506,6 +1506,158 @@ UInt32 IONDRVFramebuffer::getConnectionCount( void )
     return 1;
 }
 
+/*
+    File:      DDCPowerOnOffUtils.c <CS3>
+*/
+
+enum{
+    kVCPSendSize                       = 8,
+    kVCPReplySize                      = 64,
+    kI2CDisplayWriteAddress            = 0x6E,
+    kI2CDisplayReadAddress             = 0x6F,
+    // Messed up specification says checksum should be calculated with ACCESS.bus value of 50.
+    kI2CDisplayReadHostCheckSumAddress = 0x50,
+    // Messed up specification says checksum should be calculated with ACCESS.bus value of 50.
+    kI2CDisplayReadHostAddress         = 0x51,
+
+    kI2CVCPGetCode                     = 0x01,
+    kI2CVCPGetLength                   = 0x82,
+    kI2CVCPGetMessageSize              = 0x05,
+
+    kI2CVCPReplyLength                 = 0x88,
+    kI2CNullReplyLength                        = 0x80,
+    kI2CNullReplyCheckSum              = 0xBE,
+
+    kI2CVCPSetCode                     = 0x03,
+    kI2CVCPSetLength                   = 0x84,
+    kI2CVCPReplyCode                   = 0x02,
+            
+    kDDCPowerOn                                = 0x01,
+    kDDCPowerOff                       = 0x04
+};
+enum {
+    kBasicI2CCommTransactionsMask = ( (1<<kVideoNoTransactionType) | (1<<kVideoSimpleI2CType)
+                                    | (1<<kVideoDDCciReplyType) )
+};
+
+void IONDRVFramebuffer::displayI2CPower( bool enable )
+{
+    VDCommunicationRec i2CRecord;
+    VDCommunicationInfoRec i2cInfoRecord;
+    Byte               sendBuffer[8];
+    Byte               replyBuffer[kVCPReplySize];
+    UInt32             supportedCommFlags = 0;
+    // Don't do it if we're told it's not supported
+    bool               setThisDisplay = true;
+
+    // 
+    // Some displays (like Fiji) do not support the reading
+    // of the current power state.  Others (like Mitsubishi
+    // Diamond Pro 710) report that they do not support 
+    // power management calls.
+    //
+    // I'll avoid sending the power command only in the 
+    // case that I get a valid reply that does says 
+    // it does not support the power selector.
+    //
+
+    bzero( &i2cInfoRecord, sizeof(i2cInfoRecord) );
+    if( noErr != doStatus( cscGetCommunicationInfo, &i2cInfoRecord))
+        return;
+    if( kBasicI2CCommTransactionsMask != (i2cInfoRecord.csSupportedTypes & kBasicI2CCommTransactionsMask))
+        return;
+    if( !shouldDoI2CPower)
+        return;
+
+    supportedCommFlags = i2cInfoRecord.csSupportedCommFlags;
+    bzero( &i2CRecord, sizeof(i2CRecord) );
+    bzero( &sendBuffer, sizeof(sendBuffer) );
+    bzero( &replyBuffer, sizeof(replyBuffer) );
+
+    sendBuffer[0]      = kI2CDisplayReadHostAddress;
+    sendBuffer[1]      = kI2CVCPGetLength;
+    sendBuffer[2]      = kI2CVCPGetCode;               // GetVCP command
+    sendBuffer[3]      = 0xD6;
+    sendBuffer[4]      = kI2CDisplayWriteAddress ^
+                            sendBuffer[0] ^ sendBuffer[1] ^
+                            sendBuffer[2] ^ sendBuffer[3];
+
+    i2CRecord.csBusID          = kVideoDefaultBus;
+    i2CRecord.csSendType       = kVideoSimpleI2CType;
+    i2CRecord.csSendAddress    = kI2CDisplayWriteAddress;
+    i2CRecord.csSendBuffer     = &sendBuffer;
+    i2CRecord.csSendSize       = 7;
+    i2CRecord.csReplyType      = kVideoDDCciReplyType;
+    i2CRecord.csReplyAddress   = kI2CDisplayReadAddress;
+    i2CRecord.csReplyBuffer    = &replyBuffer;
+    i2CRecord.csReplySize      = kVCPReplySize;
+
+    if( supportedCommFlags & kVideoReplyMicroSecDelayMask )
+    {
+        // We know some displays are slow, this is an important call to get right
+       i2CRecord.csCommFlags   |= kVideoReplyMicroSecDelayMask;
+        // 50 milliseconds should be enough time for the display to respond.
+       i2CRecord.csMinReplyDelay = 50 * 1000;
+    }
+
+    if( (noErr == doControl( cscDoCommunication, &i2CRecord))
+      && (kI2CDisplayWriteAddress == replyBuffer[0])
+      && (kI2CVCPReplyLength == replyBuffer[1])
+      && (kI2CVCPReplyCode == replyBuffer[2])) {
+       Byte checkSum = kI2CDisplayReadHostCheckSumAddress ^    // host address
+            replyBuffer[0] ^   // source address
+            replyBuffer[1] ^   // message length (0x88)
+            replyBuffer[2] ^   // VCP type code
+            replyBuffer[3] ^   // result code
+            replyBuffer[4] ^   // VCP op code
+            replyBuffer[5] ^   // VCP type code
+            replyBuffer[6] ^   // Max value MSB
+            replyBuffer[7] ^   // Max value LSB
+            replyBuffer[8] ^   // Current value MSB
+            replyBuffer[9];    // Current value LSB
+
+        if( (checkSum == replyBuffer[10]) &&           // Did the check sum match AND
+                        (0 != replyBuffer[3]))         // Are we not supposed to support this feature?
+            setThisDisplay = false;                    // Don't do it if we're told it's not supported
+    }
+        
+    if( setThisDisplay) {
+
+        bzero( &i2CRecord, sizeof(i2CRecord) );
+        bzero( &sendBuffer, sizeof(sendBuffer) );
+        bzero( &replyBuffer, sizeof(replyBuffer) );
+
+        sendBuffer[0]  = kI2CDisplayReadHostAddress;
+        sendBuffer[1]  = kI2CVCPSetLength;
+        sendBuffer[2]  = kI2CVCPSetCode;                       // SetVCP command
+        sendBuffer[3]  = 0xD6;
+        sendBuffer[4]  = 0;                                    // MSB
+        sendBuffer[5]  = enable ? kDDCPowerOn : kDDCPowerOff;  // LSB
+        sendBuffer[6]  = kI2CDisplayWriteAddress ^
+                            sendBuffer[0] ^ sendBuffer[1] ^
+                            sendBuffer[2] ^ sendBuffer[3] ^
+                            sendBuffer[4] ^ sendBuffer[5];
+
+        i2CRecord.csBusID              = kVideoDefaultBus;
+        i2CRecord.csSendAddress                = kI2CDisplayWriteAddress;
+        i2CRecord.csSendType           = kVideoSimpleI2CType;
+        i2CRecord.csSendBuffer         = &sendBuffer;
+        i2CRecord.csSendSize           = 7;
+        i2CRecord.csReplyType          = kVideoNoTransactionType;
+        i2CRecord.csReplyAddress       = 0;
+        i2CRecord.csReplyBuffer                = 0;
+        i2CRecord.csReplySize          = 0;
+
+        if( supportedCommFlags & kVideoReplyMicroSecDelayMask) {
+            // We know some displays are slow, this is an important call to get right
+            i2CRecord.csCommFlags |= kVideoReplyMicroSecDelayMask;
+            // 50 milliseconds should be enough time for the display to respond.
+            i2CRecord.csMinReplyDelay  = 50 * 1000;
+        }
+
+        doControl( cscDoCommunication, &i2CRecord);
+    }
+}
 IOReturn IONDRVFramebuffer::setAttributeForConnection( IOIndex connectIndex,
                                          IOSelect attribute, UInt32 info )
 {
@@ -1513,7 +1665,6 @@ IOReturn IONDRVFramebuffer::setAttributeForConnection( IOIndex connectIndex,
     VDSyncInfoRec      theVDSyncInfoRec;
     VDPowerStateRec    sleepInfo;
 
-
     switch( attribute ) {
 
         case kConnectionSyncEnable:
@@ -1528,6 +1679,8 @@ IOReturn IONDRVFramebuffer::setAttributeForConnection( IOIndex connectIndex,
             sleepInfo.powerReserved2 = 0;
             doControl( cscSetPowerState, &sleepInfo);
 
+            displayI2CPower( ((info>>8) & 0xff) ? false : true );
+
             err = kIOReturnSuccess;
             break;
 
@@ -1668,6 +1821,40 @@ bool IONDRVFramebuffer::hasDDCConnect( IOIndex  connectIndex )
                == kNeedFlags );
 }
 
+// I2C first year for Apple displays.
+// Apple monitors older than this (and Manta)
+// are never called with I2C commands
+enum {
+    kFirstAppleI2CYear = 1999,
+    kAppleVESAVendorID = 0x0610
+};
+
+struct EDID {
+    UInt8      header[8];
+    UInt8      vendorProduct[4];
+    UInt8      serialNumber[4];
+    UInt8      weekOfManufacture;
+    UInt8      yearOfManufacture;
+    UInt8      version;
+    UInt8      revision;
+    UInt8      displayParams[5];
+    UInt8      colorCharacteristics[10];
+    UInt8      establishedTimings[3];
+    UInt16     standardTimings[8];
+    UInt8      descriptors[4][18];
+    UInt8      extension;
+    UInt8      checksum;
+};
+
+static bool IsApplePowerBlock(UInt8 * theBlock)
+{    
+    return( theBlock &&
+            0x00000000         == *(UInt32 *)&theBlock[0] &&
+            0x00               == theBlock[4] &&
+            0x06               == theBlock[5] &&
+            0x10               == theBlock[6] );
+}
+
 IOReturn IONDRVFramebuffer::getDDCBlock( IOIndex /* connectIndex */, 
                                        UInt32 blockNumber,
                                         IOSelect blockType,
@@ -1693,7 +1880,32 @@ IOReturn IONDRVFramebuffer::getDDCBlock( IOIndex /* connectIndex */,
             actualLength = kDDCBlockSize;
         bcopy( ddcRec.ddcBlockData, data, actualLength);
        *length = actualLength;
+
+        if( (1 == blockNumber) && (kIODDCBlockTypeEDID == blockType)
+         && (actualLength >= sizeof( EDID))) do {
+
+            EDID * edid;
+            UInt32 vendor;
+            UInt32 product;
+
+            edid = (EDID *) data;
+            vendor = (edid->vendorProduct[0] << 8) | edid->vendorProduct[1];
+            product = (edid->vendorProduct[3] << 8) | edid->vendorProduct[2];
+            if( kAppleVESAVendorID == vendor) {
+                if( (0x01F4 == product) || (0x9D02 == product))
+                    continue;
+                if( edid->yearOfManufacture && ((edid->yearOfManufacture + 1990) < kFirstAppleI2CYear))
+                    continue;
+            }
+            shouldDoI2CPower =    (IsApplePowerBlock( &edid->descriptors[1][0])
+                                || IsApplePowerBlock( &edid->descriptors[2][0])
+                                || IsApplePowerBlock( &edid->descriptors[3][0]));
+
+        } while( false );
     }
+
+    IOLog("%s: i2cPower %d\n", getName(), shouldDoI2CPower);
+
     return( err);
 }
 
index 2c02c8df6c9b719ed1690fc63762bd92858662b8..52691d0323364db73f790f2a2269a9ba9940c7ef 100644 (file)
@@ -579,6 +579,7 @@ IOSCSICDDrive::readTOC(IOMemoryDescriptor *buffer)
     req->setCDB( &scsiCDB );
     req->setPointers(cx->senseDataDesc, 255, false, true);    
 
+    buffer->retain();                  /* bump the retain count */
     cx->memory = buffer;
 
     req->setPointers( cx->memory, cx->memory->getLength(), false );
index 978c4e0fc4c7e8402c074ad24178a2b33ce40cd3..e18339ca54f9890d12329909bfa1d84a3c70e97a 100644 (file)
@@ -752,7 +752,10 @@ enum {
     kVideoDDCciReplyType        = 2                             /* DDC/ci message (with imbedded length)*/
 };
 
-
+// VDCommunicationRec.csCommFlags and VDCommunicationInfoRec.csSupportedCommFlags
+enum {
+    kVideoReplyMicroSecDelayMask       = (1<<0)                /* If set, the driver should delay csMinReplyDelay micro seconds between send and receive*/
+};
 
 
 struct VDResolutionInfoRec {
@@ -1171,8 +1174,8 @@ enum {
 
 struct VDCommunicationRec {
     SInt32                          csBusID;                    /* kVideoDefaultBus for single headed cards.*/
-    UInt32                          csReserved0;                /* Always zero*/
-    UInt32                          csReserved1;                /* Always zero*/
+    UInt32                         csCommFlags;                /* Always zero*/
+    UInt32                         csMinReplyDelay;            /* Minimum delay between send and reply transactions (units depend on csCommFlags)*/
     UInt32                          csReserved2;                /* Always zero*/
 
     UInt32                          csSendAddress;              /* Usually I2C address (eg 0x6E)*/
@@ -1201,7 +1204,7 @@ struct VDCommunicationInfoRec {
     SInt32                          csMaxBus;                   /* Max bus (usually kVideoDefaultBus).  Used to probe additional busses*/
 
     UInt32                          csSupportedTypes;           /* Bit field for first 32 supported transaction types.  Eg. 0x07 => support for kVideoNoTransactionType, kVideoSimpleI2CType and kVideoDDCciReplyType.*/
-    UInt32                          csReserved1;                /* Always zero*/
+    UInt32                         csSupportedCommFlags;       /* Return the flags csCommFlags understood by this driver. */
     UInt32                          csReserved2;                /* Always zero*/
     UInt32                          csReserved3;                /* Always zero*/
 
index 846c3eedca9c5f9e03a49b653b8d4bcbb182c727..d81e8f29a8801630eb28389fdecc57c45d852727 100644 (file)
@@ -91,8 +91,10 @@ protected:
     struct _VSLService *       vslServices;
 
     UInt32                     accessFlags;
+    UInt8                      shouldDoI2CPower;
 
-    UInt32                     __reserved[32];
+    UInt8                      __reservedB[3];
+    UInt32                     __reservedA[31];
 
 private:
     OSMetaClassDeclareReservedUnused(IONDRVFramebuffer, 0);
@@ -151,6 +153,7 @@ private:
     virtual void getCurrentConfiguration( void );
     static const IOTVector * _undefinedSymbolHandler( void * self, 
                             const char * libraryName, const char * symbolName );
+    void displayI2CPower( bool enable );
 
 public:
     virtual IOReturn doControl( UInt32 code, void * params );
index d21ffeed89c717d86be0e4515926b14edae5c474..c5253d2ef4837a0bda0d7994c768cd9730c42de5 100644 (file)
@@ -200,7 +200,6 @@ ENTRY(invalidate_dcache, TAG_NO_FRAME_USED)
 .L_invalidate_dcache_invalidate_loop:
        subic   r4,     r4,     CACHE_LINE_SIZE
        dcbi    r3,     r4
-       dcbi    r3,     r4
        bdnz    .L_invalidate_dcache_invalidate_loop
 
 .L_invalidate_dcache_done:
@@ -216,7 +215,6 @@ ENTRY(invalidate_dcache, TAG_NO_FRAME_USED)
 .L_invalidate_dcache_one_line:
        xor     r4,r4,r4
        dcbi    0,r3
-       dcbi    0,r3
        b       .L_invalidate_dcache_done
 
 /*
@@ -260,21 +258,15 @@ ENTRY(invalidate_icache, TAG_NO_FRAME_USED)
 .L_invalidate_icache_invalidate_loop:
        subic   r4,     r4,     CACHE_LINE_SIZE
        icbi    r3,     r4
-       icbi    r3,     r4
        bdnz    .L_invalidate_icache_invalidate_loop
 
 .L_invalidate_icache_done:
-       /* Sync restore msr if it was modified */
-       cmpwi   r5,     0
        sync                    /* make sure invalidates have completed */
-       beq+    0f
        mtmsr   r6              /* Restore original translations */
        isync                   /* Ensure data translations are on */
-0:
        blr
 
 .L_invalidate_icache_one_line:
        xor     r4,r4,r4
        icbi    0,r3
-       icbi    0,r3
        b       .L_invalidate_icache_done
index f525675f6a7b3910d65acb8859f665ae003f04a6..c0e8c75c87bdf0ceeccef29f75fd910daa9ef48e 100644 (file)
@@ -574,6 +574,7 @@ tlbhang1:   lwarx   r5,0,r12                                        /* Get the TLBIE lock */
                        
                        eieio                                                           /* Make sure that the tlbie happens first */
                        tlbsync                                                         /* wait for everyone to catch up */
+                       isync                                                           
                        
 its603a:       sync                                                            /* Make sure of it all */
                        stw             r11,0(r12)                                      /* Clear the tlbie lock */
@@ -798,6 +799,7 @@ tlbhangp:   lwarx   r11,0,r12                                       /* Get the TLBIE lock */
                        
                        eieio                                                           /* Make sure that the tlbie happens first */
                        tlbsync                                                         /* wait for everyone to catch up */
+                       isync                                                           
                        
 its603p:       stw             r11,0(r12)                                      /* Clear the lock */
                        srw             r5,r5,r8                                        /* Make a "free slot" mask */
@@ -974,6 +976,7 @@ tlbhangpv:  lwarx   r11,0,r12                                       /* Get the TLBIE lock */
                        
                        eieio                                                           /* Make sure that the tlbie happens first */
                        tlbsync                                                         /* wait for everyone to catch up */
+                       isync                                                           
                        
 its603pv:      stw             r11,0(r12)                                      /* Clear the lock */
                        srw             r5,r5,r8                                        /* Make a "free slot" mask */
@@ -1148,6 +1151,7 @@ tlbhangav:        lwarx   r11,0,r12                                       /* Get the TLBIE lock */
                        
                        eieio                                                           /* Make sure that the tlbie happens first */
                        tlbsync                                                         /* wait for everyone to catch up */
+                       isync                                                           
                        
 its603av:      stw             r11,0(r12)                                      /* Clear the lock */
                        srw             r5,r5,r8                                        /* Make a "free slot" mask */
@@ -1431,6 +1435,7 @@ tlbhangco:        lwarx   r11,0,r12                                       /* Get the TLBIE lock */
                        
                        eieio                                                           /* Make sure that the tlbie happens first */
                        tlbsync                                                         /* wait for everyone to catch up */
+                       isync                                                           
                        
 its603co:      stw             r11,0(r12)                                      /* Clear the lock */
                        srw             r5,r5,r8                                        /* Make a "free slot" mask */
@@ -1667,6 +1672,7 @@ htrtlbhang:       lwarx   r11,0,r12                                       ; Get the TLBIE lock
                        
                        eieio                                                           ; Make sure that the tlbie happens first
                        tlbsync                                                         ; wait for everyone to catch up
+                       isync                                                           
                        
 htr603:                stw             r11,0(r12)                                      ; Clear the lock
                        srw             r5,r5,r8                                        ; Make a "free slot" mask 
@@ -2273,6 +2279,7 @@ tlbhang:  lwarx   r5,0,r9                                         /* Get the TLBIE lock */
                        
                        eieio                                                           /* Make sure that the tlbie happens first */
                        tlbsync                                                         /* wait for everyone to catch up */
+                       isync                                                           
                        
 its603:                rlwinm. r21,r21,0,0,0                           ; See if we just stole an autogenned entry
                        sync                                                            /* Make sure of it all */
@@ -2693,7 +2700,8 @@ rbnFirst: bne-    rbPerm                                          ; This is permanent, do not remove...
                        blt             rbHash                                          ; Nope, length is right
                        subi    r6,r4,32+31                                     ; Back down to correct length
                        
-rbHash:                xor             r2,r8,r5                                        ; Hash into table
+rbHash:                rlwinm  r5,r5,0,10,25                           ; Keep only the page index
+                       xor             r2,r8,r5                                        ; Hash into table
                        and             r2,r2,r4                                        ; Wrap into the table
                        add             r2,r2,r12                                       ; Point right at the PCA
 
@@ -2784,6 +2792,7 @@ rbTlbN:           addic.  r5,r5,-1                                        ; See if we did them all
                        
                        eieio                                                           ; Make sure that the tlbie happens first
                        tlbsync                                                         ; wait for everyone to catch up
+                       isync                                                           
 
 rbits603a:     sync                                                            ; Wait for quiet again
                        stw             r2,0(r12)                                       ; Unlock invalidates
index 48e9187621b73103886fb36440dbd41ee8d47aab..b67ea1091d763ef9f0a3d76fb54c636e954153ad 100644 (file)
@@ -587,6 +587,7 @@ cipurgeTLB: tlbie   r6                                                              ; Purge this entry
                        
                        tlbsync                                                                 ; Sync all TLBs
                        sync
+                       isync
                        
 cinoSMP:       stw             r2,0(r5)                                                ; Unlock TLBIE lock
 
index 425e41ccae13b997b429f22e9334a03438c7f3ec..2d7ef5e3da59d06e3e656ddee3fd9eee04b1b647 100644 (file)
 ENTRY(save_queue,TAG_NO_FRAME_USED)
 
 
-                       mfmsr   r12                                                     /* Get the MSR */
-                       lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
-                       andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
-                       ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
-                       mtmsr   r11                                                     /* Make the MSR current */
-
-                       isync
+                       mfsprg  r9,2                                            ; Get the feature flags
+                       mr              r11,r3                                          ; Save the block
+                       mtcrf   0x04,r9                                         ; Set the features                      
+                       mfmsr   r12                                                     ; Get the MSR
+                       lis             r10,HIGH_ADDR(EXT(saveanchor))  ; Get the high part of the anchor
+                       andi.   r3,r12,0x7FCF                           ; Turn off all translation and rupts
+                       ori             r10,r10,LOW_ADDR(EXT(saveanchor))       ; Bottom half of the anchor 
+
+                       bt              pfNoMSRirb,sqNoMSR                      ; No MSR...
+
+                       mtmsr   r3                                                      ; Translation and all off
+                       isync                                                           ; Toss prefetch
+                       b               sqNoMSRx
+                       
+sqNoMSR:       li              r0,loadMSR                                      ; Get the MSR setter SC
+                       sc                                                                      ; Set it
+sqNoMSRx:
                        
 #if 0
-                       rlwinm. r3,r3,0,0,19                            /* (TEST/DEBUG) */
+                       rlwinm. r3,r11,0,0,19                           /* (TEST/DEBUG) */
                        bne+    notraceit                                       /* (TEST/DEBUG) */
                        BREAKPOINT_TRAP                                         /* (TEST/DEBUG) */
 notraceit:                                                                             /* (TEST/DEBUG) */
 #else
-                       rlwinm  r3,r3,0,0,19                            /* Make sure it's clean and tidy */
+                       rlwinm  r3,r11,0,0,19                           /* Make sure it's clean and tidy */
 #endif
 
-                       lwarx   r9,0,r10                                        ; ?
-
 sqlck:         lwarx   r9,0,r10                                        /* Grab the lock value */
                        li              r8,1                                            /* Use part of the delay time */
                        mr.             r9,r9                                           /* Is it locked? */
@@ -122,14 +130,22 @@ sqlckd:           isync                                                           /* Make sure translation is off */
 ENTRY(save_dequeue,TAG_NO_FRAME_USED)
 
 
+                       mfsprg  r9,2                                            ; Get the feature flags
                        mfmsr   r12                                                     /* Get the MSR */
+                       mtcrf   0x04,r9                                         ; Set the features                      
                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
-                       andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
+                       andi.   r3,r12,0x7FCF                           /* Turn off all translation and 'rupts */
                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
-                       mtmsr   r11                                                     /* Make the MSR current */
-                       isync                                                           /* Make sure translation is off */
 
-                       lwarx   r9,0,r10                                        ; ?
+                       bt              pfNoMSRirb,sdNoMSR                      ; No MSR...
+
+                       mtmsr   r3                                                      ; Translation and all off
+                       isync                                                           ; Toss prefetch
+                       b               sdNoMSRx
+                       
+sdNoMSR:       li              r0,loadMSR                                      ; Get the MSR setter SC
+                       sc                                                                      ; Set it
+sdNoMSRx:
 
 sdqlck:                lwarx   r9,0,r10                                        /* Grab the lock value */
                        li              r8,1                                            /* Use part of the delay time */
@@ -211,14 +227,25 @@ ENTRY(save_get,TAG_NO_FRAME_USED)
                        
                        cmplwi  cr1,r1,0                                        ; Set CR1_ne to indicate we want virtual address
 
-csaveget:      mfmsr   r11                                                     /* Get the MSR */
+csaveget:      mfsprg  r9,2                                            ; Get the feature flags
+                       mfmsr   r11                                                     ; Get the MSR 
+                       mtcrf   0x04,r9                                         ; Set the features                      
                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
-                       andi.   r8,r11,0x7FCF                           /* Turn off all translation and 'rupts */
+                       andi.   r3,r11,0x7FCF                           /* Turn off all translation and 'rupts */
                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
-                       mtmsr   r8                                                      /* Make the MSR current */
-                       isync                                                           ; Make sure it is done
+
+                       bt              pfNoMSRirb,sgNoMSR                      ; No MSR...
+
+                       mtmsr   r3                                                      ; Translation and all off
+                       isync                                                           ; Toss prefetch
+                       b               sgNoMSRx
                        
-                       lwarx   r9,0,r10                                        ; ?
+sgNoMSR:       mr              r9,r0                                           ; Save this
+                       li              r0,loadMSR                                      ; Get the MSR setter SC
+                       sc                                                                      ; Set it
+                       mr              r0,r9                                           ; Restore it
+
+sgNoMSRx:
 
 sglck:         lwarx   r9,0,r10                                        /* Grab the lock value */
                        li              r7,1                                            /* Use part of the delay time */
@@ -313,20 +340,31 @@ notpage0: rlwinm  r6,r3,0,0,19                            /* (TEST/DEBUG) */
 nodoublefret:                                                                  /* (TEST/DEBUG) */              
 #endif
 
+                       mfsprg  r9,2                                            ; Get the feature flags
                        lwz             r7,SAVflags(r3)                         /* Get the flags */
                        rlwinm  r6,r3,0,0,19                            /* Round back down to the savearea page block */
                        andis.  r7,r7,HIGH_ADDR(SAVinuse)       /* Still in use? */
                        mfmsr   r12                                                     /* Get the MSR */
                        bnelr-                                                          /* Still in use, just leave... */
                        lwz             r5,SACvrswap(r6)                        /* Get the conversion to real */
+                       mr              r8,r3                                           ; Save the savearea address
+                       mtcrf   0x04,r9                                         ; Set the features                      
                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
-                       andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
+                       andi.   r3,r12,0x7FCF                           /* Turn off all translation and 'rupts */
                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
-                       mtmsr   r11                                                     /* Make the MSR current */
-                       isync                                                           /* Make sure translation is off */
+
+                       bt              pfNoMSRirb,srNoMSR                      ; No MSR...
+
+                       mtmsr   r3                                                      ; Translation and all off
+                       isync                                                           ; Toss prefetch
+                       b               srNoMSRx
+                       
+srNoMSR:       li              r0,loadMSR                                      ; Get the MSR setter SC
+                       sc                                                                      ; Set it
+srNoMSRx:
 
                        mfsprg  r11,1                                           /* Get the active save area */
-                       xor             r3,r3,r5                                        /* Get the real address of the savearea */
+                       xor             r3,r8,r5                                        /* Get the real address of the savearea */
                        cmplw   r11,r3                                          /* Are we trying to toss the active one? */
                        xor             r6,r6,r5                                        /* Make the savearea block real also */
                        beq-    srbigtimepanic                          /* This is a no-no... */
@@ -335,8 +373,6 @@ nodoublefret:                                                                       /* (TEST/DEBUG) */
                        lis             r8,0x8000                                       /* Build a bit mask and assume first savearea */
                        srw             r8,r8,r7                                        /* Get bit position of do deallocate */
                        
-                       lwarx   r11,0,r10                                       ; ?
-
 srlck:         lwarx   r11,0,r10                                       /* Grab the lock value */
                        li              r7,1                                            /* Use part of the delay time */
                        mr.             r11,r11                                         /* Is it locked? */
@@ -422,20 +458,31 @@ LEXT(save_cpv)
  *                     block and disable for interruptions.
  *                     Note really well: this is only for debugging, don't expect it to always work!
  *
- *                     We take a virtual address in R4 to save the original MSR, and 
+ *                     We take a virtual address in R3 to save the original MSR, and 
  *                     return the virtual address.
  *
  */
 
 ENTRY(save_deb,TAG_NO_FRAME_USED)
 
+                       mfsprg  r9,2                                            ; Get the feature flags
                        mfmsr   r12                                                     /* Get the MSR */
                        lis             r10,HIGH_ADDR(EXT(saveanchor))  /* Get the high part of the anchor */
+                       mtcrf   0x04,r9                                         ; Set the features                      
                        stw             r12,0(r3)                                       /* Save it */
-                       andi.   r11,r12,0x7FCF                          /* Turn off all translation and 'rupts */
+                       andi.   r3,r12,0x7FCF                           /* Turn off all translation and 'rupts */
                        ori             r10,r10,LOW_ADDR(EXT(saveanchor))       /* Bottom half of the anchor */
-                       mtmsr   r11                                                     /* Make the MSR current */
-                       isync                                                           /* Make sure translation is off */
+
+                       bt              pfNoMSRirb,sdbNoMSR                     ; No MSR...
+
+                       mtmsr   r3                                                      ; Translation and all off
+                       isync                                                           ; Toss prefetch
+                       b               sdbNoMSRx
+                       
+sdbNoMSR:      li              r0,loadMSR                                      ; Get the MSR setter SC
+                       sc                                                                      ; Set it
+sdbNoMSRx:
+
                        lwz             r3,SVfree(r10)                          /* Get the physical first in list */
                        andi.   r11,r12,0x7FFF                          /* Clear only interruption */
                        lwz             r5,SACvrswap(r3)                        /* Get the conversion to virtual */
index 51bddcff32553aaac7c84e956cfe817c0539ff78..be2bb397133acb5cebf833a0b251ff68563064d9 100644 (file)
@@ -958,10 +958,8 @@ vm_page_grab_fictitious(void)
        m = (vm_page_t)zget(vm_page_zone);
        if (m) {
                m->free = FALSE;
-#if    MACH_ASSERT || ZONE_DEBUG
                vm_page_init(m, vm_page_fictitious_addr);
                m->fictitious = TRUE;
-#endif /* MACH_ASSERT || ZONE_DEBUG */
        }
 
        c_vm_page_grab_fictitious++;
index 371898e0284b638088c6efe972d5d8ad869f86c4..ec4dcfbf292cff647f7d553d0ae0f64c4ecc423d 100644 (file)
@@ -1924,8 +1924,16 @@ vm_map_get_upl(
 {
        vm_map_entry_t  entry;
        int             caller_flags;
+       int             sync_cow_data = FALSE;
+       vm_object_t     local_object;
+       vm_offset_t     local_offset;
+       vm_offset_t     local_start;
+       kern_return_t   ret;
 
        caller_flags = *flags;
+       if (!(caller_flags & UPL_COPYOUT_FROM)) {
+               sync_cow_data = TRUE;
+       }
        if(upl == NULL)
                return KERN_INVALID_ARGUMENT;
 REDISCOVER_ENTRY:
@@ -1977,49 +1985,105 @@ REDISCOVER_ENTRY:
                        }
                }
                if (entry->is_sub_map) {
+                       vm_map_t        submap;
+
+                       submap = entry->object.sub_map;
+                       local_start = entry->vme_start;
+                       local_offset = entry->offset;
+                       vm_map_reference(submap);
                        vm_map_unlock(map);
-                       return (vm_map_get_upl(entry->object.sub_map, 
-                               entry->offset + (offset - entry->vme_start), 
+
+                       ret = (vm_map_get_upl(submap, 
+                               local_offset + (offset - local_start), 
                                upl_size, upl, page_list, count, 
                                flags, force_data_sync));
+
+                       vm_map_deallocate(submap);
+                       return ret;
                }
                                        
-               if (!(caller_flags & UPL_COPYOUT_FROM)) {
+               if (sync_cow_data) {
                        if (entry->object.vm_object->shadow) {
-                               int     flags;
+                               int             flags;
+
+                               local_object = entry->object.vm_object;
+                               local_start = entry->vme_start;
+                               local_offset = entry->offset;
+                               vm_object_reference(local_object);
                                vm_map_unlock(map);
 
-                               vm_object_reference(entry->object.vm_object);
-                               if(entry->object.vm_object->copy == NULL) {
+                               if(local_object->copy == NULL) {
                                        flags = MEMORY_OBJECT_DATA_SYNC;
                                } else {
                                        flags = MEMORY_OBJECT_COPY_SYNC;
                                }
+
+                               if((local_object->paging_offset) &&
+                                               (local_object->pager == 0)) {
+                                  /* 
+                                   * do a little clean-up for our unorthodox
+                                   * entry into a pager call from a non-pager
+                                   * context.  Normally the pager code 
+                                   * assumes that an object it has been called
+                                   * with has a backing pager and so does
+                                   * not bother to check the pager field
+                                   * before relying on the paging_offset
+                                   */
+                                   vm_object_lock(local_object);
+                                   if (local_object->pager == 0) {
+                                       local_object->paging_offset = 0;
+                                   }
+                                   vm_object_unlock(local_object);
+                               }
                                        
                                memory_object_lock_request(
-                                       entry->object.vm_object,
-                                       (offset - entry->vme_start) 
-                                               + entry->offset,
+                                       local_object, ((offset - local_start) 
+                                               + local_offset) +
+                                               local_object->paging_offset,
                                        (vm_object_size_t)*upl_size, FALSE, 
                                        flags,
                                        VM_PROT_NO_CHANGE, NULL, 0);
-                               vm_map_lock(map);
+                               sync_cow_data = FALSE;
+                               goto REDISCOVER_ENTRY;
                        }
                }
 
                if (force_data_sync) {
+
+                       local_object = entry->object.vm_object;
+                       local_start = entry->vme_start;
+                       local_offset = entry->offset;
+                       vm_object_reference(local_object);
                        vm_map_unlock(map);
-                       vm_object_reference(entry->object.vm_object);
 
+                       if((local_object->paging_offset) && 
+                                       (local_object->pager == 0)) {
+                          /* 
+                           * do a little clean-up for our unorthodox
+                           * entry into a pager call from a non-pager
+                           * context.  Normally the pager code 
+                           * assumes that an object it has been called
+                           * with has a backing pager and so does
+                           * not bother to check the pager field
+                           * before relying on the paging_offset
+                           */
+                           vm_object_lock(local_object);
+                           if (local_object->pager == 0) {
+                               local_object->paging_offset = 0;
+                           }
+                           vm_object_unlock(local_object);
+                       }
+                                       
                        memory_object_lock_request(
-                                                  entry->object.vm_object,
-                                                  (offset - entry->vme_start) 
-                                                  + entry->offset,
-                                                  (vm_object_size_t)*upl_size, FALSE, 
-                                                  MEMORY_OBJECT_DATA_SYNC,
-                                                  VM_PROT_NO_CHANGE, 
-                                                  NULL, 0);
-                       vm_map_lock(map);
+                                  local_object, ((offset - local_start) 
+                                          + local_offset) + 
+                                          local_object->paging_offset,
+                                  (vm_object_size_t)*upl_size, FALSE, 
+                                  MEMORY_OBJECT_DATA_SYNC,
+                                  VM_PROT_NO_CHANGE, 
+                                  NULL, 0);
+                       force_data_sync = FALSE;
+                       goto REDISCOVER_ENTRY;
                }
 
                if(!(entry->object.vm_object->private)) {
@@ -2033,14 +2097,20 @@ REDISCOVER_ENTRY:
                } else {
                        *flags = UPL_DEV_MEMORY | UPL_PHYS_CONTIG;
                }
+               local_object = entry->object.vm_object;
+               local_offset = entry->offset;
+               local_start = entry->vme_start;
+               vm_object_reference(local_object);
                vm_map_unlock(map);
-               return(vm_fault_list_request(entry->object.vm_object, 
-                       ((offset - entry->vme_start) + entry->offset),
+               ret = (vm_fault_list_request(local_object, 
+                       ((offset - local_start) + local_offset),
                        *upl_size,
                        upl,
                        page_list,
                        *count,
                        caller_flags));
+               vm_object_deallocate(local_object);
+               return(ret);
        } 
 
        vm_map_unlock(map);
@@ -2627,7 +2697,7 @@ shared_region_mapping_dealloc(
                sm_info.alternate_base = shared_region->alternate_base;
                sm_info.alternate_next = shared_region->alternate_next;
                sm_info.flags = shared_region->flags;
-               sm_info.self = shared_region;
+               sm_info.self = (vm_offset_t)shared_region;
 
                lsf_remove_regions_mappings(shared_region, &sm_info);
                pmap_remove(((vm_named_entry_t)