From d52fe63fc81f7e44faaae711812a211a78434976 Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 11 Aug 2003 18:02:04 +0000 Subject: [PATCH] xnu-201.42.3.tar.gz --- bsd/conf/version.minor | 2 +- bsd/conf/version.variant | 1 + bsd/hfs/MacOSStubs.c | 220 ------------- bsd/hfs/hfs.h | 12 +- bsd/hfs/hfs_btreeio.c | 60 ++-- bsd/hfs/hfs_readwrite.c | 2 +- bsd/hfs/hfs_search.c | 149 ++++++++- bsd/hfs/hfs_vfsops.c | 311 +++++++++++------- bsd/hfs/hfs_vfsutils.c | 20 +- bsd/hfs/hfs_vnodeops.c | 5 +- bsd/hfs/hfscommon/BTree/BTree.c | 16 +- bsd/hfs/hfscommon/Misc/FileExtentMapping.c | 23 +- bsd/hfs/hfscommon/Misc/VolumeAllocation.c | 2 - bsd/hfs/hfscommon/headers/FileMgrInternal.h | 11 - bsd/net/dlil.c | 2 + bsd/nfs/nfs_bio.c | 6 +- bsd/nfs/nfs_subs.c | 4 +- bsd/nfs/nfs_vnops.c | 4 + bsd/vfs/vfs_bio.c | 101 +++++- bsd/vfs/vfs_cluster.c | 12 +- .../drvAppleRootDomain/RootDomain.cpp | 111 +++++-- iokit/IOKit/IONVRAM.h | 17 + iokit/IOKit/IOPlatformExpert.h | 13 + iokit/IOKit/pwr_mgt/IOPM.h | 38 ++- iokit/IOKit/pwr_mgt/IOPMPowerSource.h | 12 +- iokit/IOKit/pwr_mgt/IOPMPrivate.h | 39 +++ iokit/IOKit/pwr_mgt/Makefile | 7 +- iokit/IOKit/pwr_mgt/RootDomain.h | 18 +- iokit/Kernel/IONVRAM.cpp | 122 ++++++- iokit/Kernel/IOPlatformExpert.cpp | 25 ++ iokit/KernelConfigTables.cpp | 13 +- iokit/conf/files.ppc | 1 - iokit/conf/version.minor | 2 +- libkern/conf/version.minor | 2 +- libkern/conf/version.variant | 1 + libsa/conf/version.minor | 2 +- libsa/conf/version.variant | 1 + osfmk/conf/kernelversion.minor | 2 +- osfmk/conf/version.minor | 2 +- osfmk/default_pager/dp_backing_store.c | 2 +- osfmk/i386/machine_routines.c | 8 + osfmk/i386/machine_routines.h | 10 + osfmk/mach/memory_object_types.h | 2 +- osfmk/ppc/POWERMAC/video_console.c | 63 ++-- osfmk/ppc/POWERMAC/video_console_entries.h | 2 - osfmk/ppc/asm.h | 15 + osfmk/ppc/exception.h | 9 +- osfmk/ppc/genassym.c | 10 + osfmk/ppc/lowmem_vectors.s | 24 +- osfmk/ppc/machine_routines.c | 54 +++ osfmk/ppc/machine_routines.h | 13 + osfmk/ppc/machine_routines_asm.s | 118 +++++-- osfmk/ppc/model_dep.c | 12 - osfmk/ppc/ppc_init.c | 94 ++++-- osfmk/ppc/ppc_vm_init.c | 25 +- osfmk/ppc/start.s | 127 +++++-- osfmk/vm/vm_pageout.c | 11 +- pexpert/conf/version.minor | 2 +- pexpert/conf/version.variant | 1 + 59 files changed, 1318 insertions(+), 675 deletions(-) create mode 100644 iokit/IOKit/pwr_mgt/IOPMPrivate.h diff --git a/bsd/conf/version.minor b/bsd/conf/version.minor index b8626c4cf..7ed6ff82d 100644 --- a/bsd/conf/version.minor +++ b/bsd/conf/version.minor @@ -1 +1 @@ -4 +5 diff --git a/bsd/conf/version.variant b/bsd/conf/version.variant index e69de29bb..8b1378917 100644 --- a/bsd/conf/version.variant +++ b/bsd/conf/version.variant @@ -0,0 +1 @@ + diff --git a/bsd/hfs/MacOSStubs.c b/bsd/hfs/MacOSStubs.c index 2b8809c6b..e3ad04615 100644 --- a/bsd/hfs/MacOSStubs.c +++ b/bsd/hfs/MacOSStubs.c @@ -58,7 +58,6 @@ #include #include #include -#include #include "hfs.h" #include "hfs_dbg.h" @@ -75,225 +74,6 @@ extern int (**hfs_vnodeop_p)(void *); struct timezone gTimeZone = {8*60,1}; -/*************************************************************************************/ - -/*************************************************************************************/ -/* - * The following two routines work in tandem: StoreBufferMapping stores - * successive buffer address -> buffer pointer mappings in a circular - * match list, advancing the list index forward each time, while LookupBufferMapping - * looks backwards through the list to look up a particular mapping (which is - * typically the entry currently pointed to by gBufferAddress). - * - */ -static void StoreBufferMapping(caddr_t bufferAddress, struct buf *bp) -{ - int i; - - DBG_ASSERT(gBufferListIndex >= 0); - DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); - - simple_lock(&gBufferPtrListLock); - - /* We've got at most BUFFERPTRLISTSIZE tries at this... */ - for (i = BUFFERPTRLISTSIZE; i > 0; --i) { - if (gBufferAddress[gBufferListIndex] == NULL) { - gBufferAddress[gBufferListIndex] = bufferAddress; - gBufferHeaderPtr[gBufferListIndex] = bp; - break; - } - gBufferListIndex = (gBufferListIndex + 1) % BUFFERPTRLISTSIZE; - }; - - if (i == 0) { - panic("StoreBufferMapping: couldn't find an empty slot in buffer list."); - }; - - DBG_ASSERT(gBufferListIndex >= 0); - DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); - - simple_unlock(&gBufferPtrListLock); -} - - -/*static*/ OSErr LookupBufferMapping(caddr_t bufferAddress, struct buf **bpp, int *mappingIndexPtr) -{ - OSErr err = E_NONE; - int i; - int listIndex = gBufferListIndex; - struct buf *bp = NULL; - - DBG_ASSERT(gBufferListIndex >= 0); - DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); - - simple_lock(&gBufferPtrListLock); - - /* We've got at most BUFFERPTRLISTSIZE tries at this... */ - for (i = BUFFERPTRLISTSIZE; i > 0; --i) { - if (gBufferAddress[listIndex] == bufferAddress) { - *mappingIndexPtr = listIndex; - bp = gBufferHeaderPtr[listIndex]; - break; - }; - - listIndex = (listIndex - 1); - if (listIndex < 0) { - listIndex = BUFFERPTRLISTSIZE - 1; - }; - }; - - if (bp == NULL) { - DEBUG_BREAK_MSG(("LookupBufferMapping: couldn't find buffer header for buffer in list.\n")); - err = -1; - }; - - DBG_ASSERT(gBufferListIndex >= 0); - DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); - - simple_unlock(&gBufferPtrListLock); - - *bpp = bp; - return err; -} - - -static void ReleaseMappingEntry(int entryIndex) { - - DBG_ASSERT(gBufferListIndex >= 0); - DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); - - simple_lock(&gBufferPtrListLock); - gBufferAddress[entryIndex] = NULL; - simple_unlock(&gBufferPtrListLock); -}; -#if HFS_DIAGNOSTIC -#define DBG_GETBLOCK 0 -#else -#define DBG_GETBLOCK 0 -#endif - -OSErr GetBlock_glue (UInt16 options, UInt32 blockNum, Ptr *baddress, FileReference fileRefNum, ExtendedVCB * vcb) -{ - int status; - struct buf *bp = NULL; - int readcount = 0; - -#if DBG_GETBLOCK - DBG_IO(("Getting block %ld with options %d and a refnum of %x\n", blockNum, options, fileRefNum )); -#endif - - if ((options & ~(gbReadMask | gbNoReadMask)) != 0) { - DEBUG_BREAK_MSG(("GetBlock_glue: options = 0x%04X.\n", options)); - }; - - *baddress = NULL; - - if (options & gbNoReadMask) { - if (fileRefNum == NULL) { - bp = getblk (VCBTOHFS(vcb)->hfs_devvp, - IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), - IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), - 0, - 0, - BLK_META); - } else { - bp = getblk (fileRefNum, - IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), - IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), - 0, - 0, - BLK_META); - }; - status = E_NONE; - } else { - do { - if (fileRefNum == NULL) { - status = meta_bread (VCBTOHFS(vcb)->hfs_devvp, - IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), - IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), - NOCRED, - &bp); - } else { - status = meta_bread (fileRefNum, - IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), - IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), - NOCRED, - &bp); - }; - if (status != E_NONE) { - if (bp) brelse(bp); - goto Error_Exit; - }; - - if (bp == NULL) { - status = -1; - goto Error_Exit; - }; - - ++readcount; - - if ((options & gbReadMask) && (bp->b_flags & B_CACHE)) { - /* Rats! The block was found in the cache just when we really wanted a - fresh copy off disk... - */ - if (bp->b_flags & B_DIRTY) { - DEBUG_BREAK_MSG(("GetBlock_glue: forced read for dirty block!\n")) - }; - bp->b_flags |= B_INVAL; - brelse(bp); - - /* Fall through and try again until we get a fresh copy from the disk... */ - }; - } while (((options & gbReadMask) != 0) && (readcount <= 1)); - }; - - *baddress = bp->b_data + IOBYTEOFFSETFORBLK(bp->b_blkno, VCBTOHFS(vcb)->hfs_phys_block_size); - StoreBufferMapping(*baddress, bp); - -Error_Exit: ; - return status; -} - - -OSErr RelBlock_glue (Ptr address, UInt16 options ) -{ - int err; - struct buf *bp; - int mappingEntry; - - if (options & ~(rbTrashMask | rbDirtyMask | rbWriteMask) == 0) { - DEBUG_BREAK_MSG(("RelBlock_glue: options = 0x%04X.\n", options)); - }; - - if ((err = LookupBufferMapping(address, &bp, &mappingEntry))) { - DEBUG_BREAK_MSG(("Failed to find buffer pointer for buffer in RelBlock_glue.\n")); - } else { - if (bp->b_flags & B_DIRTY) { - /* The buffer was previously marked dirty (using MarkBlock_glue): - now's the time to write it. */ - options |= rbDirtyMask; - }; - ReleaseMappingEntry(mappingEntry); - if (options & rbTrashMask) { - bp->b_flags |= B_INVAL; - brelse(bp); - } else { - if (options & (rbDirtyMask | rbWriteMask)) { - bp->b_flags |= B_DIRTY; - if (options & rbWriteMask) { - bwrite(bp); - } else { - bdwrite(bp); - } - } else { - brelse(bp); - }; - }; - err = E_NONE; - }; - return err; -} - /* */ /* Creates a new vnode to hold a psuedo file like an extents tree file */ /* */ diff --git a/bsd/hfs/hfs.h b/bsd/hfs/hfs.h index 8ad50af86..c88467a1c 100644 --- a/bsd/hfs/hfs.h +++ b/bsd/hfs/hfs.h @@ -656,7 +656,6 @@ struct hfsfid { #define E_NONE 0 #define kHFSBlockSize 512 -#define kHFSBlockShift 9 /* 2^9 = 512 */ #define IOBLKNOFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBLOCK) / ((BLOCKSIZEINBYTES) >> 9))) #define IOBLKCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \ @@ -676,6 +675,13 @@ struct hfsfid { (IOBLKCNTFORBYTE((STARTINGBYTE),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)) #define IOBYTEOFFSETFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((STARTINGBYTE) - (IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))) + +#define HFS_PRI_SECTOR(blksize) (1024 / (blksize)) +#define HFS_PRI_OFFSET(blksize) ((blksize) > 1024 ? 1024 : 0) + +#define HFS_ALT_SECTOR(blksize, blkcnt) (((blkcnt) - 1) - (512 / (blksize))) +#define HFS_ALT_OFFSET(blksize) ((blksize) > 1024 ? (blksize) - 1024 : 0) + #define MAKE_VREFNUM(x) ((int32_t)((x) & 0xffff)) /* * This is the straight GMT conversion constant: @@ -766,9 +772,9 @@ unsigned long BestBlockSizeFit(unsigned long allocationBlockSize, unsigned long baseMultiple); OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb, - u_long sectors, struct proc *p); + struct proc *p); OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, - u_long embBlkOffset, u_long sectors, struct proc *p); + off_t embeddedOffset, off_t disksize, struct proc *p); OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode); int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode, diff --git a/bsd/hfs/hfs_btreeio.c b/bsd/hfs/hfs_btreeio.c index e050e8ff7..2bb3c7695 100644 --- a/bsd/hfs/hfs_btreeio.c +++ b/bsd/hfs/hfs_btreeio.c @@ -84,18 +84,9 @@ OSStatus GetBTreeBlock(FileReference vp, UInt32 blockNum, GetBlockOptions option struct buf *bp = NULL; if (options & kGetEmptyBlock) - bp = getblk (vp, - IOBLKNOFORBLK(blockNum, VTOHFS(vp)->hfs_phys_block_size), - IOBYTECCNTFORBLK(blockNum, block->blockSize, VTOHFS(vp)->hfs_phys_block_size), - 0, - 0, - BLK_META); + bp = getblk(vp, blockNum, block->blockSize, 0, 0, BLK_META); else - retval = meta_bread(vp, - IOBLKNOFORBLK(blockNum, VTOHFS(vp)->hfs_phys_block_size), - IOBYTECCNTFORBLK(blockNum, block->blockSize, VTOHFS(vp)->hfs_phys_block_size), - NOCRED, - &bp); + retval = meta_bread(vp, blockNum, block->blockSize, NOCRED, &bp); DBG_ASSERT(bp != NULL); DBG_ASSERT(bp->b_data != NULL); @@ -107,7 +98,7 @@ OSStatus GetBTreeBlock(FileReference vp, UInt32 blockNum, GetBlockOptions option if (retval == E_NONE) { block->blockHeader = bp; - block->buffer = bp->b_data + IOBYTEOFFSETFORBLK(bp->b_blkno, VTOHFS(vp)->hfs_phys_block_size); + block->buffer = bp->b_data; block->blockReadFromDisk = (bp->b_flags & B_CACHE) == 0; /* not found in cache ==> came from disk */ #if BYTE_ORDER == LITTLE_ENDIAN @@ -298,27 +289,42 @@ OSStatus ExtendBTreeFile(FileReference vp, FSSize minEOF, FSSize maxEOF) static OSStatus FlushAlternate( ExtendedVCB *vcb ) { - void *maindata; - void *altdata; + struct hfsmount *hfsmp = VCBTOHFS(vcb); + struct vnode *dev_vp = hfsmp->hfs_devvp; + struct buf *pri_bp = NULL; + struct buf *alt_bp = NULL; + int sectorsize; + u_long priIDSector; + u_long altIDSector; int result; + sectorsize = hfsmp->hfs_phys_block_size; + priIDSector = (vcb->hfsPlusIOPosOffset / sectorsize) + + HFS_PRI_SECTOR(sectorsize); + + altIDSector = (vcb->hfsPlusIOPosOffset / sectorsize) + + HFS_ALT_SECTOR(sectorsize, hfsmp->hfs_phys_block_count); + /* Get the main MDB/VolumeHeader block */ - result = GetBlock_glue(gbDefault, - (vcb->hfsPlusIOPosOffset / kHFSBlockSize) + kMasterDirectoryBlock, - (Ptr *)&maindata, kNoFileReference, vcb); - if (result) return (result); - - /* Get the alternate MDB/VolumeHeader block */ - result = GetBlock_glue( gbDefault, vcb->altIDSector, - (Ptr *)&altdata, kNoFileReference, vcb ); + result = meta_bread(dev_vp, priIDSector, sectorsize, NOCRED, &pri_bp); + if (result) + goto exit; - if (result == 0) { - bcopy(maindata, altdata, kMDBSize); + /* Get the alternate MDB/VolumeHeader block */ + result = meta_bread(dev_vp, altIDSector, sectorsize, NOCRED, &alt_bp); + if (result) + goto exit; - result = RelBlock_glue( (Ptr)altdata, rbWriteMask ); - } + bcopy(pri_bp->b_data + HFS_PRI_OFFSET(sectorsize), + alt_bp->b_data + HFS_ALT_OFFSET(sectorsize), kMDBSize); - (void) RelBlock_glue( (Ptr)maindata, rbFreeMask ); + result = VOP_BWRITE(alt_bp); + alt_bp = NULL; +exit: + if (alt_bp) + brelse(alt_bp); + if (pri_bp) + brelse(pri_bp); return (result); } diff --git a/bsd/hfs/hfs_readwrite.c b/bsd/hfs/hfs_readwrite.c index 035cd80f3..825ec1ca5 100644 --- a/bsd/hfs/hfs_readwrite.c +++ b/bsd/hfs/hfs_readwrite.c @@ -2019,7 +2019,7 @@ struct vop_bwrite_args /* { if (((UInt16 *)((char *)bp->b_data + bp->b_bcount - 2))[0] == 0x000e) { /* Prepare the block pointer */ block.blockHeader = bp; - block.buffer = bp->b_data + IOBYTEOFFSETFORBLK(bp->b_blkno, VTOHFS(vp)->hfs_phys_block_size); + block.buffer = bp->b_data; block.blockReadFromDisk = (bp->b_flags & B_CACHE) == 0; /* not found in cache ==> came from disk */ block.blockSize = bp->b_bcount; diff --git a/bsd/hfs/hfs_search.c b/bsd/hfs/hfs_search.c index df7c233c0..979e52414 100644 --- a/bsd/hfs/hfs_search.c +++ b/bsd/hfs/hfs_search.c @@ -53,10 +53,14 @@ static int UnpackSearchAttributeBlock(struct vnode *vp, struct attrlist *alist, searchinfospec_t *searchInfo, void *attributeBuffer); -Boolean CheckCriteria(ExtendedVCB *vcb, - u_long searchBits, struct attrlist *attrList, - CatalogNodeData *cnp, CatalogKey *key, - searchinfospec_t *searchInfo1, searchinfospec_t *searchInfo2); +Boolean CheckCriteria( ExtendedVCB *vcb, + u_long searchBits, + struct attrlist *attrList, + CatalogNodeData *cnp, + CatalogKey *key, + searchinfospec_t *searchInfo1, + searchinfospec_t *searchInfo2, + Boolean lookForDup); static int CheckAccess(CatalogNodeData *cnp, CatalogKey *key, struct proc *p); @@ -79,6 +83,7 @@ static Boolean CompareWideRange( u_int64_t val, u_int64_t low, u_int64_t high ) } //#define CompareRange(val, low, high) ((val >= low) && (val <= high)) +static Boolean IsTargetName( searchinfospec_t * searchInfoPtr, Boolean isHFSPlus ); /************************************************************************/ @@ -129,11 +134,12 @@ struct vop_searchfs_args *ap; /* struct proc *p = current_proc(); CatalogNodeData myCNodeData; CatalogNodeData * myCNodeDataPtr; - CatalogKey * myCurrentKeyPtr; - CatalogRecord * myCurrentDataPtr; - CatPosition * myCatPositionPtr; - BTScanState myBTScanState; + CatalogKey * myCurrentKeyPtr; + CatalogRecord * myCurrentDataPtr; + CatPosition * myCatPositionPtr; + BTScanState myBTScanState; Boolean timerExpired = false; + Boolean doQuickExit = false; u_long lastNodeNum = 0XFFFFFFFF; ExtendedVCB *vcb = VTOVCB(ap->a_vp); int err = E_NONE; @@ -179,9 +185,63 @@ struct vop_searchfs_args *ap; /* if (ap->a_options & SRCHFS_START) { /* Starting a new search. */ + /* make sure our meta data is synced up */ + err = VOP_FSYNC(vcb->catalogRefNum, NOCRED, MNT_WAIT, p); ap->a_options &= ~SRCHFS_START; bzero( (caddr_t)myCatPositionPtr, sizeof( *myCatPositionPtr ) ); err = BTScanInitialize(catalogFCB, 0, 0, 0, kCatSearchBufferSize, &myBTScanState); + +#if 1 // Installer workaround + // hack to get around installer problems when the installer expects search results + // to be in key order. At this point the problem appears to be limited to + // searches for "Library". The idea here is to go get the "Library" at root + // and return it first to the caller then continue the search as normal with + // the exception of taking care not to return a duplicate hit (see CheckCriteria) + if ( err == E_NONE && + (ap->a_searchattrs->commonattr & ATTR_CMN_NAME) != 0 && + IsTargetName( &searchInfo1, isHFSPlus ) ) + { + CatalogRecord rec; + BTreeIterator iterator; + FSBufferDescriptor btrec; + CatalogKey * keyp; + UInt16 reclen; + OSErr result; + + bzero( (caddr_t)&iterator, sizeof( iterator ) ); + keyp = (CatalogKey *) &iterator.key; + (void) BuildCatalogKeyUTF8(vcb, kRootDirID, "Library", kUndefinedStrLen, keyp, NULL); + + btrec.bufferAddress = &rec; + btrec.itemCount = 1; + btrec.itemSize = sizeof( rec ); + + result = BTSearchRecord( catalogFCB, &iterator, kInvalidMRUCacheKey, + &btrec, &reclen, &iterator ); + if ( result == E_NONE ) { + if ( isHFSPlus ) { + // HFSPlus vols have CatalogRecords that map exactly to CatalogNodeData so there is no need + // to copy. + myCNodeDataPtr = (CatalogNodeData *) &rec; + } else { + CopyCatalogNodeData( vcb, &rec, &myCNodeData ); + myCNodeDataPtr = &myCNodeData; + } + + if (CheckCriteria(vcb, ap->a_options, ap->a_searchattrs, myCNodeDataPtr, + keyp, &searchInfo1, &searchInfo2, false) && + CheckAccess(myCNodeDataPtr, keyp, ap->a_uio->uio_procp)) { + + result = InsertMatch(ap->a_vp, ap->a_uio, myCNodeDataPtr, + keyp, ap->a_returnattrs, + attributesBuffer, variableBuffer, + eachReturnBufferSize, ap->a_nummatches); + if (result == E_NONE && *(ap->a_nummatches) >= ap->a_maxmatches) + doQuickExit = true; + } + } + } +#endif // Installer workaround } else { /* Resuming a search. */ err = BTScanInitialize(catalogFCB, myCatPositionPtr->nextNode, @@ -203,7 +263,8 @@ struct vop_searchfs_args *ap; /* (void) hfs_metafilelocking(VTOHFS(ap->a_vp), kHFSCatalogFileID, LK_RELEASE, p); if (err) goto ExitThisRoutine; - + if ( doQuickExit ) + goto QuickExit; /* * Check all the catalog btree records... * return the attributes for matching items @@ -228,7 +289,7 @@ struct vop_searchfs_args *ap; /* } if (CheckCriteria(vcb, ap->a_options, ap->a_searchattrs, myCNodeDataPtr, - myCurrentKeyPtr, &searchInfo1, &searchInfo2) && + myCurrentKeyPtr, &searchInfo1, &searchInfo2, true) && CheckAccess(myCNodeDataPtr, myCurrentKeyPtr, ap->a_uio->uio_procp)) { err = InsertMatch(ap->a_vp, ap->a_uio, myCNodeDataPtr, @@ -261,13 +322,13 @@ struct vop_searchfs_args *ap; /* timerExpired = true; } } - +QuickExit: /* Update catalog position */ myCatPositionPtr->writeCount = myBTScanState.btcb->writeCount; - BTScanTerminate(&myBTScanState, &myCatPositionPtr->nextNode, - &myCatPositionPtr->nextRecord, - &myCatPositionPtr->recordsFound); + BTScanTerminate(&myBTScanState, &myCatPositionPtr->nextNode, + &myCatPositionPtr->nextRecord, + &myCatPositionPtr->recordsFound); if ( err == E_NONE ) { err = EAGAIN; /* signal to the user to call searchfs again */ @@ -360,9 +421,14 @@ CheckAccess(CatalogNodeData *cnp, CatalogKey *key, struct proc *p) } Boolean -CheckCriteria( ExtendedVCB *vcb, u_long searchBits, - struct attrlist *attrList, CatalogNodeData *cnp, CatalogKey *key, - searchinfospec_t *searchInfo1, searchinfospec_t *searchInfo2 ) +CheckCriteria( ExtendedVCB *vcb, + u_long searchBits, + struct attrlist *attrList, + CatalogNodeData *cnp, + CatalogKey *key, + searchinfospec_t *searchInfo1, + searchinfospec_t *searchInfo2, + Boolean lookForDup ) { Boolean matched, atleastone; Boolean isHFSPlus; @@ -416,6 +482,20 @@ CheckCriteria( ExtendedVCB *vcb, u_long searchBits, else /* full HFS name match */ matched = (FastRelString(key->hfs.nodeName, (u_char*)searchInfo1->name) == 0); } + +#if 1 // Installer workaround + if ( lookForDup ) { + HFSCatalogNodeID parentID; + if (isHFSPlus) + parentID = key->hfsPlus.parentID; + else + parentID = key->hfs.parentID; + + if ( matched && parentID == kRootDirID && + IsTargetName( searchInfo1, isHFSPlus ) ) + matched = false; + } +#endif // Installer workaround if ( matched == false || (searchBits & ~SRCHFS_MATCHPARTIALNAMES) == 0 ) goto TestDone; /* no match, or nothing more to compare */ @@ -859,3 +939,38 @@ UnpackSearchAttributeBlock( struct vnode *vp, struct attrlist *alist, searchinfo } +/* this routine was added as part of the work around where some installers would fail */ +/* because they incorrectly assumed search results were in some kind of order. */ +/* This routine is used to indentify the problematic target. At this point we */ +/* only know of one. This routine could be modified for more (I hope not). */ +static Boolean IsTargetName( searchinfospec_t * searchInfoPtr, Boolean isHFSPlus ) +{ + if ( searchInfoPtr->name == NULL ) + return( false ); + + if (isHFSPlus) { + HFSUniStr255 myName = { + 7, /* number of unicode characters */ + { + 'L','i','b','r','a','r','y' + } + }; + if ( FastUnicodeCompare( myName.unicode, myName.length, + (UniChar*)searchInfoPtr->name, + searchInfoPtr->nameLength ) == 0 ) { + return( true ); + } + + } else { + u_char myName[32] = { + 0x07,'L','i','b','r','a','r','y' + }; + if ( FastRelString(myName, (u_char*)searchInfoPtr->name) == 0 ) { + return( true ); + } + } + return( false ); + +} /* IsTargetName */ + + diff --git a/bsd/hfs/hfs_vfsops.c b/bsd/hfs/hfs_vfsops.c index 6329bd207..395b4b1e1 100644 --- a/bsd/hfs/hfs_vfsops.c +++ b/bsd/hfs/hfs_vfsops.c @@ -109,7 +109,6 @@ #include #include #include -#include #include #include #include @@ -135,6 +134,14 @@ int hfs_dbg_err = 0; int hfs_dbg_test = 0; #endif + +/* + * These come from IOKit/storage/IOMediaBSDClient.h + */ +#define DKIOCGETBLOCKSIZE _IOR('d', 24, u_int32_t) +#define DKIOCSETBLOCKSIZE _IOW('d', 24, u_int32_t) +#define DKIOCGETBLOCKCOUNT _IOR('d', 25, u_int64_t) + /* * HFS File System globals: */ @@ -640,7 +647,8 @@ hfs_reload(mountp, cred, p) register struct vnode *vp, *nvp, *devvp; struct hfsnode *hp; struct buf *bp; - int size, error, i; + int sectorsize; + int error, i; struct hfsmount *hfsmp; struct HFSPlusVolumeHeader *vhp; ExtendedVCB *vcb; @@ -666,20 +674,18 @@ hfs_reload(mountp, cred, p) /* * Re-read VolumeHeader from disk. */ - size = kMDBSize; - error = bread( hfsmp->hfs_devvp, - IOBLKNOFORBLK((vcb->hfsPlusIOPosOffset / 512) + kMasterDirectoryBlock, size), - IOBYTECCNTFORBLK(kMasterDirectoryBlock, kMDBSize, size), - NOCRED, - &bp); + sectorsize = hfsmp->hfs_phys_block_size; + + error = meta_bread(hfsmp->hfs_devvp, + (vcb->hfsPlusIOPosOffset / sectorsize) + HFS_PRI_SECTOR(sectorsize), + sectorsize, NOCRED, &bp); if (error) { if (bp != NULL) brelse(bp); return (error); } - vhp = (HFSPlusVolumeHeader *) ((char *)bp->b_data + - IOBYTEOFFSETFORBLK((vcb->hfsPlusIOPosOffset / 512) + kMasterDirectoryBlock, size)); + vhp = (HFSPlusVolumeHeader *) (bp->b_data + HFS_PRI_OFFSET(sectorsize)); if ((ValidVolumeHeader(vhp) != 0) || (vcb->blockSize != SWAP_BE32 (vhp->blockSize))) { brelse(bp); @@ -833,8 +839,10 @@ hfs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p, struct hfs_mo HFSMasterDirectoryBlock *mdbp; int ronly; struct ucred *cred; - u_long diskBlks; - u_long blksize; + u_int64_t disksize; + u_int64_t blkcnt; + u_int32_t blksize; + u_int32_t minblksize; DBG_VFS(("hfs_mountfs: mp = 0x%lX\n", (u_long)mp)); dev = devvp->v_rdev; @@ -857,25 +865,59 @@ hfs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p, struct hfs_mo if ((retval = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p))) return (retval); - blksize = kHFSBlockSize; - DBG_VFS(("hfs_mountfs: size = %d (DEV_BSIZE = %d).\n", blksize, DEV_BSIZE)); + bp = NULL; + hfsmp = NULL; + minblksize = kHFSBlockSize; - bp = NULL; - hfsmp = NULL; + /* Get the real physical block size. */ + if (VOP_IOCTL(devvp, DKIOCGETBLOCKSIZE, (caddr_t)&blksize, 0, cred, p)) { + retval = ENXIO; + goto error_exit; + } + /* Switch to 512 byte sectors (temporarily) */ + if (blksize > 512) { + u_int32_t size512 = 512; + + if (VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, (caddr_t)&size512, FWRITE, cred, p)) { + retval = ENXIO; + goto error_exit; + } + } + /* Get the number of 512 byte physical blocks. */ + if (VOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt, 0, cred, p)) { + retval = ENXIO; + goto error_exit; + } + /* Compute an accurate disk size (i.e. within 512 bytes) */ + disksize = blkcnt * (u_int64_t)512; - /* - * XXX SER Currently we only support 512 block size systems. This might change - * So this is a place holder to remind us that the mdb might not be 512 aligned - * retval = VOP_IOCTL(devvp, DKIOCGETBLOCKSIZE, &blksize, FWRITE, cred, p); - * if (retval) return retval; + /* + * For large volumes use a 4K physical block size. */ + if (blkcnt > (u_int64_t)0x000000007fffffff) { + minblksize = blksize = 4096; + } - /* - * the next three lines should probably be replaced - * with a call to the yet unimplemented function VOP_SETBLOCKSIZE + /* Now switch to our prefered physical block size. */ + if (blksize > 512) { + if (VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, (caddr_t)&blksize, FWRITE, cred, p)) { + retval = ENXIO; + goto error_exit; + } + /* Get the count of physical blocks. */ + if (VOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt, 0, cred, p)) { + retval = ENXIO; + goto error_exit; + } + } + + /* + * At this point: + * minblksize is the minimum physical block size + * blksize has our prefered physical block size + * blkcnt has the total number of physical blocks */ - retval = VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, &blksize, FWRITE, cred, p); - if (retval) return retval; + devvp->v_specsize = blksize; /* cache the IO attributes */ @@ -885,23 +927,16 @@ hfs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p, struct hfs_mo return (retval); } - DBG_VFS(("hfs_mountfs: reading MDB [block no. %d + %d bytes, size %d bytes]...\n", - IOBLKNOFORBLK(kMasterDirectoryBlock, blksize), - IOBYTEOFFSETFORBLK(kMasterDirectoryBlock, blksize), - IOBYTECCNTFORBLK(kMasterDirectoryBlock, kMDBSize, blksize))); - - if ((retval = bread(devvp, IOBLKNOFORBLK(kMasterDirectoryBlock, blksize), - IOBYTECCNTFORBLK(kMasterDirectoryBlock, kMDBSize, blksize), cred, &bp))) { - goto error_exit; - }; - mdbp = (HFSMasterDirectoryBlock*) ((char *)bp->b_data + IOBYTEOFFSETFORBLK(kMasterDirectoryBlock, blksize)); + if ((retval = meta_bread(devvp, HFS_PRI_SECTOR(blksize), blksize, cred, &bp))) { + goto error_exit; + } + mdbp = (HFSMasterDirectoryBlock*) (bp->b_data + HFS_PRI_OFFSET(blksize)); - MALLOC(hfsmp, struct hfsmount *, sizeof(struct hfsmount), M_HFSMNT, M_WAITOK); - bzero(hfsmp, sizeof(struct hfsmount)); + MALLOC(hfsmp, struct hfsmount *, sizeof(struct hfsmount), M_HFSMNT, M_WAITOK); + bzero(hfsmp, sizeof(struct hfsmount)); simple_lock_init(&hfsmp->hfs_renamelock); - DBG_VFS(("hfs_mountfs: Initializing hfsmount structure at 0x%lX...\n", (u_long)hfsmp)); /* * Init the volume information structure */ @@ -911,9 +946,7 @@ hfs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p, struct hfs_mo hfsmp->hfs_raw_dev = devvp->v_rdev; hfsmp->hfs_devvp = devvp; hfsmp->hfs_phys_block_size = blksize; - - /* The hfs_log_block_size field is updated in the respective hfs_MountHFS[Plus]Volume routine */ - hfsmp->hfs_logBlockSize = BestBlockSizeFit(SWAP_BE32 (mdbp->drAlBlkSiz), MAXBSIZE, hfsmp->hfs_phys_block_size); + hfsmp->hfs_phys_block_count = blkcnt; hfsmp->hfs_fs_ronly = ronly; hfsmp->hfs_unknownpermissions = ((mp->mnt_flag & MNT_UNKNOWNPERMISSIONS) != 0); if (args) { @@ -941,82 +974,136 @@ hfs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p, struct hfs_mo hfsmp->hfs_file_mask = UNKNOWNPERMISSIONS & DEFFILEMODE; /* 0666: no --x by default? */ }; }; - - /* See above comment for DKIOCGETBLOCKSIZE - * retval = VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, &blksize, FWRITE, cred, p); - * if (retval) return retval; - */ - - retval = VOP_IOCTL(devvp, DKIOCNUMBLKS, (caddr_t)&diskBlks, 0, cred, p); - if (retval) return retval; - - if (SWAP_BE16 (mdbp->drSigWord) == kHFSPlusSigWord) { - /* Enidan swap volume header in place */ - /* SWAP_HFS_PLUS_VOLUME_HEADER ((HFSPlusVolumeHeader *)bp->b_data); */ - /* mount wrapper-less HFS-Plus volume */ - (void) hfs_getconverter(0, &hfsmp->hfs_get_unicode, &hfsmp->hfs_get_hfsname); - retval = hfs_MountHFSPlusVolume(hfsmp, (HFSPlusVolumeHeader*) bp->b_data, 0, diskBlks, p); - - /* Enidan un-swap volume header in place */ - /* SWAP_HFS_PLUS_VOLUME_HEADER ((HFSPlusVolumeHeader *)bp->b_data); */ - - } else if (SWAP_BE16 (mdbp->drEmbedSigWord) == kHFSPlusSigWord) { - u_long embBlkOffset; - HFSPlusVolumeHeader *vhp; - - embBlkOffset = SWAP_BE16 (mdbp->drAlBlSt) + - (SWAP_BE16 (mdbp->drEmbedExtent.startBlock) * (SWAP_BE32 (mdbp->drAlBlkSiz)/kHFSBlockSize)); - /* calculate virtual number of 512-byte sectors */ - diskBlks = SWAP_BE16 (mdbp->drEmbedExtent.blockCount) * (SWAP_BE32 (mdbp->drAlBlkSiz)/kHFSBlockSize); - - brelse(bp); - bp = NULL; /* done with MDB, go grab Volume Header */ - mdbp = NULL; - - retval = bread( devvp, - IOBLKNOFORBLK(kMasterDirectoryBlock+embBlkOffset, blksize), - IOBYTECCNTFORBLK(kMasterDirectoryBlock+embBlkOffset, kMDBSize, blksize), - cred, - &bp); - if (retval) { + /* Mount a standard HFS disk */ + if ((SWAP_BE16(mdbp->drSigWord) == kHFSSigWord) && + (SWAP_BE16(mdbp->drEmbedSigWord) != kHFSPlusSigWord)) { + if (devvp == rootvp) { + retval = EINVAL; /* Cannot root from HFS standard disks */ goto error_exit; - }; - vhp = (HFSPlusVolumeHeader*) ((char *)bp->b_data + IOBYTEOFFSETFORBLK(kMasterDirectoryBlock, blksize)); - - /* Enidan swap volume header in place */ - /* SWAP_HFS_PLUS_VOLUME_HEADER (vhp); */ - - /* mount embedded HFS Plus volume */ - (void) hfs_getconverter(0, &hfsmp->hfs_get_unicode, &hfsmp->hfs_get_hfsname); - retval = hfs_MountHFSPlusVolume(hfsmp, vhp, embBlkOffset, diskBlks, p); - - /* Enidan un-swap volume header in place */ - /* SWAP_HFS_PLUS_VOLUME_HEADER (vhp); */ - - } else if (devvp != rootvp) { + } + /* HFS disks can only use 512 byte physical blocks */ + if (blksize > kHFSBlockSize) { + blksize = kHFSBlockSize; + if (VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, (caddr_t)&blksize, FWRITE, cred, p)) { + retval = ENXIO; + goto error_exit; + } + if (VOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt, 0, cred, p)) { + retval = ENXIO; + goto error_exit; + } + /* XXX do we need to call vfs_init_io_attributes again ? */ + devvp->v_specsize = blksize; + hfsmp->hfs_phys_block_size = blksize; + hfsmp->hfs_phys_block_count = blkcnt; + } if (args) { hfsmp->hfs_encoding = args->hfs_encoding; HFSTOVCB(hfsmp)->volumeNameEncodingHint = args->hfs_encoding; - /* establish the timezone */ gTimeZone = args->hfs_timezone; } retval = hfs_getconverter(hfsmp->hfs_encoding, &hfsmp->hfs_get_unicode, &hfsmp->hfs_get_hfsname); - if (retval) goto error_exit; + if (retval) + goto error_exit; - /* mount HFS volume */ - retval = hfs_MountHFSVolume( hfsmp, mdbp, diskBlks, p); - + retval = hfs_MountHFSVolume(hfsmp, mdbp, p); if (retval) (void) hfs_relconverter(hfsmp->hfs_encoding); - } else { - /* sorry, we cannot root from HFS */ - retval = EINVAL; - } + } else /* Mount an HFS Plus disk */ { + HFSPlusVolumeHeader *vhp; + off_t embeddedOffset; + + /* Get the embedded Volume Header */ + if (SWAP_BE16(mdbp->drEmbedSigWord) == kHFSPlusSigWord) { + embeddedOffset = SWAP_BE16(mdbp->drAlBlSt) * kHFSBlockSize; + embeddedOffset += (u_int64_t)SWAP_BE16(mdbp->drEmbedExtent.startBlock) * + (u_int64_t)SWAP_BE32(mdbp->drAlBlkSiz); + + disksize = (u_int64_t)SWAP_BE16(mdbp->drEmbedExtent.blockCount) * + (u_int64_t)SWAP_BE32(mdbp->drAlBlkSiz); + + hfsmp->hfs_phys_block_count = disksize / blksize; + + brelse(bp); + bp = NULL; + mdbp = NULL; + + /* + * If the embedded volume doesn't start on a block + * boundary, then switch the device to a 512-byte + * block size so everything will line up on a block + * boundary. + */ + if ((embeddedOffset % blksize) != 0) { + printf("HFS Mount: embedded volume offset not" + " a multiple of physical block size (%d);" + " switching to 512\n", blksize); + blksize = 512; + if (VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, + (caddr_t)&blksize, FWRITE, cred, p)) { + retval = ENXIO; + goto error_exit; + } + if (VOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, + (caddr_t)&blkcnt, 0, cred, p)) { + retval = ENXIO; + goto error_exit; + } + /* XXX do we need to call vfs_init_io_attributes again? */ + devvp->v_specsize = blksize; + /* Note: relative block count adjustment */ + hfsmp->hfs_phys_block_count *= + hfsmp->hfs_phys_block_size / blksize; + hfsmp->hfs_phys_block_size = blksize; + } + + retval = meta_bread(devvp, (embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize), + blksize, cred, &bp); + if (retval) + goto error_exit; + vhp = (HFSPlusVolumeHeader*) (bp->b_data + HFS_PRI_OFFSET(blksize)); + + } else /* pure HFS+ */ { + embeddedOffset = 0; + vhp = (HFSPlusVolumeHeader*) mdbp; + } + + (void) hfs_getconverter(0, &hfsmp->hfs_get_unicode, &hfsmp->hfs_get_hfsname); + + retval = hfs_MountHFSPlusVolume(hfsmp, vhp, embeddedOffset, disksize, p); + /* + * If the backend didn't like our physical blocksize + * then retry with physical blocksize of 512. + */ + if ((retval == ENXIO) && (blksize > 512) && (blksize != minblksize)) { + printf("HFS Mount: could not use physical block size " + "(%d) switching to 512\n", blksize); + blksize = 512; + if (VOP_IOCTL(devvp, DKIOCSETBLOCKSIZE, (caddr_t)&blksize, FWRITE, cred, p)) { + retval = ENXIO; + goto error_exit; + } + if (VOP_IOCTL(devvp, DKIOCGETBLOCKCOUNT, (caddr_t)&blkcnt, 0, cred, p)) { + retval = ENXIO; + goto error_exit; + } + /* XXX do we need to call vfs_init_io_attributes again ? */ + devvp->v_specsize = blksize; + /* Note: relative block count adjustment (in case this is an embedded volume). */ + hfsmp->hfs_phys_block_count *= hfsmp->hfs_phys_block_size / blksize; + hfsmp->hfs_phys_block_size = blksize; + + /* Try again with a smaller block size... */ + retval = hfs_MountHFSPlusVolume(hfsmp, vhp, embeddedOffset, disksize, p); + } + if (retval) + (void) hfs_relconverter(0); + } if ( retval ) { goto error_exit; @@ -1754,15 +1841,19 @@ short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor) FCB *fcb; HFSPlusVolumeHeader *volumeHeader; int retval; - int size = sizeof(HFSPlusVolumeHeader); struct buf *bp; int i; + int sectorsize; + int priIDSector; if (vcb->vcbSigWord != kHFSPlusSigWord) return EINVAL; - retval = bread(hfsmp->hfs_devvp, IOBLKNOFORBLK((vcb->hfsPlusIOPosOffset / 512) + kMasterDirectoryBlock, size), - IOBYTECCNTFORBLK(kMasterDirectoryBlock, kMDBSize, size), NOCRED, &bp); + sectorsize = hfsmp->hfs_phys_block_size; + priIDSector = (vcb->hfsPlusIOPosOffset / sectorsize) + + HFS_PRI_SECTOR(sectorsize); + + retval = meta_bread(hfsmp->hfs_devvp, priIDSector, sectorsize, NOCRED, &bp); if (retval) { DBG_VFS((" hfs_flushvolumeheader bread return error! (%d)\n", retval)); if (bp) brelse(bp); @@ -1773,8 +1864,7 @@ short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor) DBG_ASSERT(bp->b_data != NULL); DBG_ASSERT(bp->b_bcount == size); - volumeHeader = (HFSPlusVolumeHeader *)((char *)bp->b_data + - IOBYTEOFFSETFORBLK((vcb->hfsPlusIOPosOffset / 512) + kMasterDirectoryBlock, size)); + volumeHeader = (HFSPlusVolumeHeader *)((char *)bp->b_data + HFS_PRI_OFFSET(sectorsize)); /* * For embedded HFS+ volumes, update create date if it changed @@ -1785,12 +1875,11 @@ short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor) struct buf *bp2; HFSMasterDirectoryBlock *mdb; - retval = bread(hfsmp->hfs_devvp, IOBLKNOFORBLK(kMasterDirectoryBlock, kMDBSize), - IOBYTECCNTFORBLK(kMasterDirectoryBlock, kMDBSize, kMDBSize), NOCRED, &bp2); + retval = meta_bread(hfsmp->hfs_devvp, HFS_PRI_SECTOR(sectorsize), sectorsize, NOCRED, &bp2); if (retval != E_NONE) { if (bp2) brelse(bp2); } else { - mdb = (HFSMasterDirectoryBlock *)((char *)bp2->b_data + IOBYTEOFFSETFORBLK(kMasterDirectoryBlock, kMDBSize)); + mdb = (HFSMasterDirectoryBlock *)(bp2->b_data + HFS_PRI_OFFSET(sectorsize)); if ( SWAP_BE32 (mdb->drCrDate) != vcb->localCreateDate ) { diff --git a/bsd/hfs/hfs_vfsutils.c b/bsd/hfs/hfs_vfsutils.c index e6cfc9684..e69c2e046 100644 --- a/bsd/hfs/hfs_vfsutils.c +++ b/bsd/hfs/hfs_vfsutils.c @@ -181,7 +181,7 @@ extern OSStatus ReleaseBTreeBlock(FileReference vp, BlockDescPtr blockPtr, Relea //******************************************************************************* OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb, - u_long sectors, struct proc *p) + struct proc *p) { ExtendedVCB *vcb = HFSTOVCB(hfsmp); struct vnode *tmpvnode; @@ -245,8 +245,6 @@ OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb, if (err || (utf8chars == 0)) (void) mac_roman_to_utf8(mdb->drVN, NAME_MAX, &utf8chars, vcb->vcbVN); - vcb->altIDSector = sectors - 2; - // Initialize our dirID/nodePtr cache associated with this volume. err = InitMRUCache( sizeof(UInt32), kDefaultNumMRUCacheBlocks, &(vcb->hintCachePtr) ); ReturnIfError( err ); @@ -331,7 +329,7 @@ CmdDone:; //******************************************************************************* OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, - u_long embBlkOffset, u_long sectors, struct proc *p) + off_t embeddedOffset, off_t disksize, struct proc *p) { register ExtendedVCB *vcb; HFSPlusForkData *fdp; @@ -353,6 +351,14 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, /* don't mount a writable volume if its dirty, it must be cleaned by fsck_hfs */ if (hfsmp->hfs_fs_ronly == 0 && (SWAP_BE32 (vhp->attributes) & kHFSVolumeUnmountedMask) == 0) return (EINVAL); + + /* Make sure we can live with the physical block size. */ + if ((disksize & (hfsmp->hfs_phys_block_size - 1)) || + (embeddedOffset & (hfsmp->hfs_phys_block_size - 1)) || + (SWAP_BE32(vhp->blockSize) < hfsmp->hfs_phys_block_size)) { + return (ENXIO); + } + /* * The VolumeHeader seems OK: transfer info from it into VCB * Note - the VCB starts out clear (all zeros) @@ -387,9 +393,7 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, vcb->checkedDate = SWAP_BE32 (vhp->checkedDate); vcb->encodingsBitmap = SWAP_BE64 (vhp->encodingsBitmap); - vcb->hfsPlusIOPosOffset = embBlkOffset * 512; - - vcb->altIDSector = embBlkOffset + sectors - 2; + vcb->hfsPlusIOPosOffset = embeddedOffset; vcb->localCreateDate = SWAP_BE32 (vhp->createDate); /* in local time, not GMT! */ @@ -3359,6 +3363,8 @@ short MacToVFSError(OSErr err) case fileBoundsErr: /* -1309 */ return EINVAL; /* +22 */ + case fsBTBadNodeSize: + return ENXIO; default: DBG_UTILS(("Unmapped MacOS error: %d\n", err)); return EIO; /* +5 */ diff --git a/bsd/hfs/hfs_vnodeops.c b/bsd/hfs/hfs_vnodeops.c index 3d1d803e5..c818f79e7 100644 --- a/bsd/hfs/hfs_vnodeops.c +++ b/bsd/hfs/hfs_vnodeops.c @@ -3058,7 +3058,7 @@ hfs_symlink(ap) goto out; /* Write the link to disk */ - bp = getblk(vp, 0, roundup((int)hp->fcbEOF, kHFSBlockSize), 0, 0, BLK_META); + bp = getblk(vp, 0, roundup((int)hp->fcbEOF, VTOHFS(vp)->hfs_phys_block_size), 0, 0, BLK_META); bzero(bp->b_data, bp->b_bufsize); bcopy(ap->a_target, bp->b_data, len); bp->b_flags |= B_DIRTY; @@ -3749,7 +3749,8 @@ struct ucred *a_cred; if (H_ISBIGLINK(hp)) MALLOC(hp->h_symlinkptr, char *, hp->fcbEOF, M_TEMP, M_WAITOK); - retval = meta_bread(vp, 0, roundup((int)hp->fcbEOF, kHFSBlockSize), ap->a_cred, &bp); + retval = meta_bread(vp, 0, roundup((int)hp->fcbEOF, VTOHFS(vp)->hfs_phys_block_size), + ap->a_cred, &bp); if (retval) { if (bp) brelse(bp); diff --git a/bsd/hfs/hfscommon/BTree/BTree.c b/bsd/hfs/hfscommon/BTree/BTree.c index 48749f50d..1cd262eef 100644 --- a/bsd/hfs/hfscommon/BTree/BTree.c +++ b/bsd/hfs/hfscommon/BTree/BTree.c @@ -231,15 +231,17 @@ OSStatus BTOpenPath (FCB *filePtr, /////////////////////////// Read Header Node //////////////////////////////// nodeRec.buffer = nil; // so we can call ReleaseNode - nodeRec.blockSize = kMinNodeSize; btreePtr->fileRefNum = GetFileRefNumFromFCB(filePtr); filePtr->fcbBTCBPtr = (Ptr) btreePtr; // attach btree cb to file + /* The minimum node size is the physical block size */ + nodeRec.blockSize = VTOHFS(btreePtr->fileRefNum)->hfs_phys_block_size; + REQUIRE_FILE_LOCK(btreePtr->fileRefNum, false); // it is now safe to call M_ExitOnError (err) - err = setBlockSizeProc (btreePtr->fileRefNum, kMinNodeSize, 1); + err = setBlockSizeProc (btreePtr->fileRefNum, nodeRec.blockSize, 1); M_ExitOnError (err); @@ -297,9 +299,15 @@ OSStatus BTOpenPath (FCB *filePtr, //€€ set kBadClose attribute bit, and UpdateNode - // if nodeSize is 512 then we don't need to release, just CheckNode + // if nodeSize matches then we don't need to release, just CheckNode + + /* b-tree node size must be at least as big as the physical block size */ + if (btreePtr->nodeSize < nodeRec.blockSize) { + err = fsBTBadNodeSize; + goto ErrorExit; + } - if ( btreePtr->nodeSize == kMinNodeSize ) + if ( btreePtr->nodeSize == nodeRec.blockSize ) { err = CheckNode (btreePtr, nodeRec.buffer); if (err) diff --git a/bsd/hfs/hfscommon/Misc/FileExtentMapping.c b/bsd/hfs/hfscommon/Misc/FileExtentMapping.c index 3f17d760e..d989e134a 100644 --- a/bsd/hfs/hfscommon/Misc/FileExtentMapping.c +++ b/bsd/hfs/hfscommon/Misc/FileExtentMapping.c @@ -244,9 +244,7 @@ enum kDataForkType = 0, kResourceForkType = 0xFF, - kPreviousRecord = -1, - - kSectorSize = 512 // Size of a physical sector + kPreviousRecord = -1 }; void HFSToHFSPlusExtents( @@ -599,11 +597,12 @@ OSErr MapFileBlockC ( FCB *fcb, // FCB of file size_t numberOfBytes, // number of contiguous bytes desired off_t offset, // starting offset within file (in bytes) - daddr_t *startSector, // first 512-byte sector (NOT an allocation block) + daddr_t *startSector, // first sector (NOT an allocation block) size_t *availableBytes) // number of contiguous bytes (up to numberOfBytes) { OSErr err; UInt32 allocBlockSize; // Size of the volume's allocation block + UInt32 sectorSize; HFSPlusExtentKey foundKey; HFSPlusExtentRecord foundData; UInt32 foundIndex; @@ -617,6 +616,7 @@ OSErr MapFileBlockC ( off_t tmpOff; allocBlockSize = vcb->blockSize; + sectorSize = VCBTOHFS(vcb)->hfs_phys_block_size; err = SearchExtentFile(vcb, fcb, offset, &foundKey, foundData, &foundIndex, &hint, &nextFABN); if (err == noErr) { @@ -638,17 +638,20 @@ OSErr MapFileBlockC ( dataEnd = fcb->fcbPLen; // Yes, so only map up to PEOF // Compute the number of sectors in an allocation block - sectorsPerBlock = allocBlockSize / kSectorSize; // sectors per allocation block + sectorsPerBlock = allocBlockSize / sectorSize; // sectors per allocation block // // Compute the absolute sector number that contains the offset of the given file // - temp = (daddr_t)((offset - (off_t)((off_t)(firstFABN) * (off_t)(allocBlockSize)))/kSectorSize); // offset in sectors from start of the extent + + // offset in sectors from start of the extent + temp = (daddr_t)((offset - (off_t)((off_t)(firstFABN) * (off_t)(allocBlockSize)))/sectorSize); + // offset in sectors from start of allocation block space temp += startBlock * sectorsPerBlock; // offset in sectors from start of allocation block space - if (vcb->vcbSigWord == kHFSPlusSigWord) - temp += vcb->hfsPlusIOPosOffset/512; /* offset inside wrapper */ - else - temp += vcb->vcbAlBlSt; /* offset in sectors from start of volume */ + if (vcb->vcbSigWord == kHFSPlusSigWord) + temp += vcb->hfsPlusIOPosOffset / sectorSize; /* offset inside wrapper */ + else + temp += vcb->vcbAlBlSt; /* offset in sectors from start of volume */ // Return the desired sector for file position "offset" *startSector = temp; diff --git a/bsd/hfs/hfscommon/Misc/VolumeAllocation.c b/bsd/hfs/hfscommon/Misc/VolumeAllocation.c index e8006d107..8f074d0b1 100644 --- a/bsd/hfs/hfscommon/Misc/VolumeAllocation.c +++ b/bsd/hfs/hfscommon/Misc/VolumeAllocation.c @@ -550,8 +550,6 @@ Exit: return err; } -extern OSErr LookupBufferMapping(caddr_t bufferAddress, struct buf **bpp, int *mappingIndexPtr); - /* _______________________________________________________________________ diff --git a/bsd/hfs/hfscommon/headers/FileMgrInternal.h b/bsd/hfs/hfscommon/headers/FileMgrInternal.h index 370dca4e9..ed67a4cf1 100644 --- a/bsd/hfs/hfscommon/headers/FileMgrInternal.h +++ b/bsd/hfs/hfscommon/headers/FileMgrInternal.h @@ -388,17 +388,6 @@ ReplaceBTreeRecord (FileReference refNum, UInt16 dataSize, UInt32 * newHint); -/* Prototypes for C->Asm glue*/ -EXTERN_API_C( OSErr ) -GetBlock_glue (UInt16 flags, - UInt32 nodeNumber, - Ptr * nodeBuffer, - FileReference refNum, - ExtendedVCB * vcb); - -EXTERN_API_C( OSErr ) -RelBlock_glue (Ptr nodeBuffer, - UInt16 flags); /* Prototypes for exported routines in VolumeAllocation.c*/ EXTERN_API_C( OSErr ) diff --git a/bsd/net/dlil.c b/bsd/net/dlil.c index 001492dfb..f364ed70c 100644 --- a/bsd/net/dlil.c +++ b/bsd/net/dlil.c @@ -47,6 +47,7 @@ #include #include +#include #define DBG_LAYER_BEG DLILDBG_CODE(DBG_DLIL_STATIC, 0) #define DBG_LAYER_END DLILDBG_CODE(DBG_DLIL_STATIC, 2) @@ -558,6 +559,7 @@ void dlil_input_thread(void) * bind it to the master cpu. */ stack_privilege(self); + ml_thread_policy(current_thread(), MACHINE_GROUP, (MACHINE_NETWORK_GROUP|MACHINE_NETWORK_NETISR)); /* The dlil thread is always funneled */ thread_funnel_set(network_flock, TRUE); diff --git a/bsd/nfs/nfs_bio.c b/bsd/nfs/nfs_bio.c index 926de3419..3c4473b44 100644 --- a/bsd/nfs/nfs_bio.c +++ b/bsd/nfs/nfs_bio.c @@ -1278,7 +1278,11 @@ nfs_doio(bp, cr, p) int s; CLR(bp->b_flags, B_INVAL | B_NOCACHE); - SET(bp->b_flags, B_DELWRI); + if (!ISSET(bp->b_flags, B_DELWRI)) { + extern int nbdwrite; + SET(bp->b_flags, B_DELWRI); + nbdwrite++; + } FSDBG(261, bp->b_validoff, bp->b_validend, bp->b_bufsize, bp->b_bcount); /* diff --git a/bsd/nfs/nfs_subs.c b/bsd/nfs/nfs_subs.c index e152a0d18..cea8b0046 100644 --- a/bsd/nfs/nfs_subs.c +++ b/bsd/nfs/nfs_subs.c @@ -1435,8 +1435,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper, dontshrink, xidp) np->n_size = vap->va_size; } else np->n_size = vap->va_size; - if (dontshrink && UBCISVALID(vp) && - np->n_size < ubc_getsize(vp)) { + if (!UBCINFOEXISTS(vp) || + dontshrink && np->n_size < ubc_getsize(vp)) { vap->va_size = np->n_size = orig_size; np->n_attrstamp = 0; } else diff --git a/bsd/nfs/nfs_vnops.c b/bsd/nfs/nfs_vnops.c index 8b64b7d24..dd87f5401 100644 --- a/bsd/nfs/nfs_vnops.c +++ b/bsd/nfs/nfs_vnops.c @@ -3789,6 +3789,10 @@ nfs_writebp(bp, force) s = splbio(); CLR(bp->b_flags, (B_READ|B_DONE|B_ERROR|B_DELWRI)); + if (ISSET(oldflags, B_DELWRI)) { + extern int nbdwrite; + nbdwrite--; + } if (ISSET(oldflags, (B_ASYNC|B_DELWRI))) { reassignbuf(bp, vp); diff --git a/bsd/vfs/vfs_bio.c b/bsd/vfs/vfs_bio.c index 5579b8c9c..573ad97d8 100644 --- a/bsd/vfs/vfs_bio.c +++ b/bsd/vfs/vfs_bio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -103,6 +103,10 @@ static struct buf *getnewbuf(int slpflag, int slptimeo, int *queue); extern int niobuf; /* The number of IO buffer headers for cluster IO */ int blaundrycnt; +/* zone allocated buffer headers */ +static zone_t buf_hdr_zone; +static int buf_hdr_count; + #if TRACE struct proc *traceproc; int tracewhich, tracebuf[TRCSIZ]; @@ -121,6 +125,9 @@ u_long bufhash; /* Definitions for the buffer stats. */ struct bufstats bufstats; +/* Number of delayed write buffers */ +int nbdwrite = 0; + /* * Insq/Remq for the buffer hash lists. */ @@ -132,8 +139,8 @@ struct bufstats bufstats; TAILQ_HEAD(ioqueue, buf) iobufqueue; TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES]; -int needbuffer; -int need_iobuffer; +static int needbuffer; +static int need_iobuffer; /* * Insq/Remq for the buffer free lists. @@ -162,6 +169,9 @@ int need_iobuffer; simple_lock_data_t bufhashlist_slock; /* lock on buffer hash list */ +/* number of per vnode, "in flight" buffer writes */ +#define BUFWRITE_THROTTLE 9 + /* * Time in seconds before a buffer on a list is * considered as a stale buffer @@ -503,6 +513,8 @@ bwrite(bp) sync = !ISSET(bp->b_flags, B_ASYNC); wasdelayed = ISSET(bp->b_flags, B_DELWRI); CLR(bp->b_flags, (B_READ | B_DONE | B_ERROR | B_DELWRI)); + if (wasdelayed) + nbdwrite--; if (!sync) { /* @@ -518,7 +530,7 @@ bwrite(bp) p->p_stats->p_ru.ru_oublock++; /* XXX */ } - trace(TR_BWRITE, pack(vp, bp->b_bcount), bp->b_lblkno); + trace(TR_BUFWRITE, pack(vp, bp->b_bcount), bp->b_lblkno); /* Initiate disk write. Make sure the appropriate party is charged. */ SET(bp->b_flags, B_WRITEINPROG); @@ -571,15 +583,19 @@ vn_bwrite(ap) * written in the order that the writes are requested. * * Described in Leffler, et al. (pp. 208-213). + * + * Note: With the abilitty to allocate additional buffer + * headers, we can get in to the situation where "too" many + * bdwrite()s can create situation where the kernel can create + * buffers faster than the disks can service. Doing a bawrite() in + * cases were we have "too many" outstanding bdwrite()s avoids that. */ void bdwrite(bp) struct buf *bp; { struct proc *p = current_proc(); - kern_return_t kret; - upl_t upl; - upl_page_info_t *pl; + struct vnode *vp = bp->b_vp; /* * If the block hasn't been seen before: @@ -591,8 +607,8 @@ bdwrite(bp) SET(bp->b_flags, B_DELWRI); if (p && p->p_stats) p->p_stats->p_ru.ru_oublock++; /* XXX */ - - reassignbuf(bp, bp->b_vp); + nbdwrite ++; + reassignbuf(bp, vp); } @@ -603,6 +619,28 @@ bdwrite(bp) return; } + /* + * If the vnode has "too many" write operations in progress + * wait for them to finish the IO + */ + while (vp->v_numoutput >= BUFWRITE_THROTTLE) { + vp->v_flag |= VTHROTTLED; + (void)tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "bdwrite", 0); + } + + /* + * If we have too many delayed write buffers, + * more than we can "safely" handle, just fall back to + * doing the async write + */ + if (nbdwrite < 0) + panic("bdwrite: Negative nbdwrite"); + + if (nbdwrite > ((nbuf/4)*3)) { + bawrite(bp); + return; + } + /* Otherwise, the "write" is done, so mark and release the buffer. */ SET(bp->b_flags, B_DONE); brelse(bp); @@ -610,11 +648,30 @@ bdwrite(bp) /* * Asynchronous block write; just an asynchronous bwrite(). + * + * Note: With the abilitty to allocate additional buffer + * headers, we can get in to the situation where "too" many + * bawrite()s can create situation where the kernel can create + * buffers faster than the disks can service. + * We limit the number of "in flight" writes a vnode can have to + * avoid this. */ void bawrite(bp) struct buf *bp; { + struct vnode *vp = bp->b_vp; + + if (vp) { + /* + * If the vnode has "too many" write operations in progress + * wait for them to finish the IO + */ + while (vp->v_numoutput >= BUFWRITE_THROTTLE) { + vp->v_flag |= VTHROTTLED; + (void)tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "bawrite", 0); + } + } SET(bp->b_flags, B_ASYNC); VOP_BWRITE(bp); @@ -729,7 +786,10 @@ brelse(bp) */ if (bp->b_vp) brelvp(bp); - CLR(bp->b_flags, B_DELWRI); + if (ISSET(bp->b_flags, B_DELWRI)) { + CLR(bp->b_flags, B_DELWRI); + nbdwrite--; + } if (bp->b_bufsize <= 0) whichq = BQ_EMPTY; /* no data */ else @@ -1197,9 +1257,6 @@ struct meta_zone_entry meta_zones[] = { }; #endif /* ZALLOC_METADATA */ -zone_t buf_hdr_zone; -int buf_hdr_count; - /* * Initialize the meta data zones */ @@ -1500,6 +1557,7 @@ bcleanbuf(struct buf *bp) { int s; struct ucred *cred; + int hdralloc = 0; s = splbio(); @@ -1509,6 +1567,10 @@ bcleanbuf(struct buf *bp) /* Buffer is no longer on free lists. */ SET(bp->b_flags, B_BUSY); + /* Check whether the buffer header was "allocated" */ + if (ISSET(bp->b_flags, B_HDRALLOC)) + hdralloc = 1; + if (bp->b_hash.le_prev == (struct buf **)0xdeadbeef) panic("bcleanbuf: le_prev is deadbeef"); @@ -1568,6 +1630,8 @@ bcleanbuf(struct buf *bp) bp->b_bufsize = 0; bp->b_data = 0; bp->b_flags = B_BUSY; + if (hdralloc) + SET(bp->b_flags, B_HDRALLOC); bp->b_dev = NODEV; bp->b_blkno = bp->b_lblkno = 0; bp->b_iodone = 0; @@ -1642,7 +1706,7 @@ biodone(bp) struct buf *bp; { boolean_t funnel_state; - int s; + struct vnode *vp; funnel_state = thread_funnel_set(kernel_flock, TRUE); @@ -1661,6 +1725,15 @@ biodone(bp) if (!ISSET(bp->b_flags, B_READ) && !ISSET(bp->b_flags, B_RAW)) vwakeup(bp); /* wake up reader */ + /* Wakeup the throttled write operations as needed */ + vp = bp->b_vp; + if (vp + && (vp->v_flag & VTHROTTLED) + && (vp->v_numoutput <= (BUFWRITE_THROTTLE / 3))) { + vp->v_flag &= ~VTHROTTLED; + wakeup((caddr_t)&vp->v_numoutput); + } + if (ISSET(bp->b_flags, B_CALL)) { /* if necessary, call out */ CLR(bp->b_flags, B_CALL); /* but note callout done */ (*bp->b_iodone)(bp); diff --git a/bsd/vfs/vfs_cluster.c b/bsd/vfs/vfs_cluster.c index 5756a104a..07f0dbbd5 100644 --- a/bsd/vfs/vfs_cluster.c +++ b/bsd/vfs/vfs_cluster.c @@ -86,7 +86,7 @@ * can be outstanding on a single vnode * before we issue a synchronous write */ -#define ASYNC_THROTTLE 6 +#define ASYNC_THROTTLE 9 static int cluster_iodone(bp) @@ -670,7 +670,7 @@ cluster_rd_prefetch(vp, f_offset, size, filesize, devblocksize) if (ubc_page_op(vp, f_offset, 0, 0, 0) == KERN_SUCCESS) { KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 49)) | DBG_FUNC_END, (int)f_offset, 0, 0, 0, 0); - return(0); + return(1); } if (size > (MAX_UPL_TRANSFER * PAGE_SIZE)) size = MAX_UPL_TRANSFER * PAGE_SIZE; @@ -784,7 +784,6 @@ cluster_rd_ahead(vp, b_lblkno, e_lblkno, filesize, devblocksize) daddr_t r_lblkno; off_t f_offset; int size_of_prefetch; - int max_iosize; int max_pages; KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 48)) | DBG_FUNC_START, @@ -805,12 +804,7 @@ cluster_rd_ahead(vp, b_lblkno, e_lblkno, filesize, devblocksize) return; } - vfs_io_attributes(vp, B_READ, &max_iosize, &max_pages); - - if ((max_iosize / PAGE_SIZE) < max_pages) - max_pages = max_iosize / PAGE_SIZE; - if (max_pages > MAX_UPL_TRANSFER) - max_pages = MAX_UPL_TRANSFER; + max_pages = MAX_UPL_TRANSFER; vp->v_ralen = vp->v_ralen ? min(max_pages, vp->v_ralen << 1) : 1; diff --git a/iokit/Drivers/platform/drvAppleRootDomain/RootDomain.cpp b/iokit/Drivers/platform/drvAppleRootDomain/RootDomain.cpp index ebc0a8b23..f9673a3aa 100644 --- a/iokit/Drivers/platform/drvAppleRootDomain/RootDomain.cpp +++ b/iokit/Drivers/platform/drvAppleRootDomain/RootDomain.cpp @@ -24,19 +24,18 @@ #include #include #include -#include +#include #include #include "RootDomainUserClient.h" #include "IOKit/pwr_mgt/IOPowerConnection.h" -extern "C" { -extern void kprintf(const char *, ...); -} +extern "C" void kprintf(const char *, ...); extern const IORegistryPlane * gIOPowerPlane; void PMreceiveCmd ( OSObject *, void *, void *, void *, void * ); static void sleepTimerExpired(thread_call_param_t); +static void wakeupClamshellTimerExpired ( thread_call_param_t us); #define number_of_power_states 5 @@ -186,6 +185,8 @@ static void disk_sync_callout(thread_call_param_t p0, thread_call_param_t p1) bool IOPMrootDomain::start ( IOService * nub ) { + OSDictionary *tmpDict; + super::start(nub); gRootDomain = this; @@ -201,7 +202,12 @@ bool IOPMrootDomain::start ( IOService * nub ) canSleep = true; wrangler = NULL; sleepASAP = false; + ignoringClamshellDuringWakeup = false; + tmpDict = OSDictionary::withCapacity(1); + setProperty(kRootDomainSupportedFeatures, tmpDict); + tmpDict->release(); + pm_vars->PMworkloop = IOWorkLoop::workLoop(); // make the workloop pm_vars->commandQueue = IOCommandQueue::commandQueue(this, PMreceiveCmd); // make a command queue if (! pm_vars->commandQueue || @@ -209,7 +215,7 @@ bool IOPMrootDomain::start ( IOService * nub ) return IOPMNoErr; } extraSleepTimer = thread_call_allocate((thread_call_func_t)sleepTimerExpired, (thread_call_param_t) this); - + clamshellWakeupIgnore = thread_call_allocate((thread_call_func_t)wakeupClamshellTimerExpired, (thread_call_param_t) this); diskSyncCalloutEntry = thread_call_allocate(&disk_sync_callout, (thread_call_param_t) this); patriarch = new IORootParent; // create our parent @@ -305,6 +311,12 @@ static void sleepTimerExpired ( thread_call_param_t us) ((IOPMrootDomain *)us)->handleSleepTimerExpiration(); } + +static void wakeupClamshellTimerExpired ( thread_call_param_t us) +{ + ((IOPMrootDomain *)us)->stopIgnoringClamshellEventsDuringWakeup(); +} + // ********************************************************************************** // handleSleepTimerExpiration @@ -323,6 +335,17 @@ void IOPMrootDomain::handleSleepTimerExpiration ( void ) } +void IOPMrootDomain::stopIgnoringClamshellEventsDuringWakeup(void) +{ + OSObject * state; + + // Allow clamshell-induced sleep now + ignoringClamshellDuringWakeup = false; + + if ((state = getProperty(kAppleClamshellStateKey))) + publishResource(kAppleClamshellStateKey, state); +} + //********************************************************************************* // setAggressiveness // @@ -335,6 +358,7 @@ void IOPMrootDomain::handleSleepTimerExpiration ( void ) IOReturn IOPMrootDomain::setAggressiveness ( unsigned long type, unsigned long newLevel ) { + if ( systemBooting && (type == kPMMinutesToDim) ) { systemBooting = false; // when the login window launches, this method gets called -- system booting is done. IOLog("Root power domain receiving initial preferences\n"); @@ -417,12 +441,26 @@ void IOPMrootDomain::powerChangeDone ( unsigned long previousState ) clock_interval_to_deadline(30, kSecondScale, &deadline); // stay awake for at least 30 seconds thread_call_enter_delayed(extraSleepTimer, deadline); idleSleepPending = true; // this gets turned off when we sleep again + + // Ignore closed clamshell during wakeup and for a few seconds + // after wakeup is complete + ignoringClamshellDuringWakeup = true; + gSleepOrShutdownPending = 0; // sleep transition complete patriarch->wakeSystem(); // get us some power IOLog("System Wake\n"); systemWake(); // tell the tree we're waking - + + // Allow drivers to request extra processing time before clamshell + // sleep if kIOREMSleepEnabledKey is present. + // Ignore clamshell events for at least 5 seconds + if(getProperty(kIOREMSleepEnabledKey)) { + // clamshellWakeupIgnore callout clears ignoreClamshellDuringWakeup bit + clock_interval_to_deadline(5, kSecondScale, &deadline); + if(clamshellWakeupIgnore) thread_call_enter_delayed(clamshellWakeupIgnore, deadline); + } else ignoringClamshellDuringWakeup = false; + propertyPtr = OSDynamicCast(OSNumber,getProperty("WakeEvent")); if ( propertyPtr ) { // find out what woke us theProperty = propertyPtr->unsigned16BitValue(); @@ -486,6 +524,21 @@ void IOPMrootDomain::wakeFromDoze( void ) } +// ********************************************************************************** +// publishFeature +// +// Adds a new feature to the supported features dictionary +// +// +// ********************************************************************************** +void IOPMrootDomain::publishFeature( const char * feature ) +{ + OSDictionary *features = (OSDictionary *)getProperty(kRootDomainSupportedFeatures); + + features->setObject(feature, kOSBooleanTrue); +} + + // ********************************************************************************** // newUserClient // @@ -520,6 +573,28 @@ IOReturn IOPMrootDomain::newUserClient( task_t owningTask, void * /* security_ IOReturn IOPMrootDomain::receivePowerNotification (UInt32 msg) { + if (msg & kIOPMSetDesktopMode) { + desktopMode = (0 != (msg & kIOPMSetValue)); + msg &= ~(kIOPMSetDesktopMode | kIOPMSetValue); + } + if (msg & kIOPMSetACAdaptorConnected) { + acAdaptorConnect = (0 != (msg & kIOPMSetValue)); + msg &= ~(kIOPMSetACAdaptorConnected | kIOPMSetValue); + } + if (msg & kIOPMEnableClamshell) { + ignoringClamshell = false; + } + if (msg & kIOPMDisableClamshell) { + ignoringClamshell = true; + } + + if (msg & kIOPMProcessorSpeedChange) { + IOService *pmu = waitForService(serviceMatching("ApplePMU")); + pmu->callPlatformFunction("prepareForSleep", false, 0, 0, 0, 0); + pm_vars->thePlatform->sleepKernel(); + pmu->callPlatformFunction("recoverFromSleep", false, 0, 0, 0, 0); + } + if (msg & kIOPMSleepNow) { (void) sleepSystem (); } @@ -528,17 +603,17 @@ IOReturn IOPMrootDomain::receivePowerNotification (UInt32 msg) (void) sleepSystem (); } - if (msg & kIOPMClamshellClosed) { - if ( ! ignoringClamshell ) { - (void) sleepSystem (); - } + if (msg & kIOPMOverTemp) { + IOLog("Power Management received emergency overtemp signal. Going to sleep."); + (void) sleepSystem (); } - if (msg & kIOPMEnableClamshell) { - ignoringClamshell = false; - } - if (msg & kIOPMDisableClamshell) { - ignoringClamshell = true; + if (msg & kIOPMClamshellClosed) { + if ( !ignoringClamshell && !ignoringClamshellDuringWakeup + && (!desktopMode || !acAdaptorConnect) ) { + + (void) sleepSystem (); + } } if (msg & kIOPMPowerButton) { // toggle state of sleep/wake @@ -779,11 +854,6 @@ void IOPMrootDomain::setQuickSpinDownTimeout ( void ) void IOPMrootDomain::restoreUserSpinDownTimeout ( void ) { - if(systemBooting) { - IOLog("!!!!! WARNING !!!!! restoreUserSpinDownTimeout called too early\n"); - } - //IOLog("restoreUserSpinDownTimeout, user_spindown = %u\n", user_spindown); - super::setAggressiveness((unsigned long)kPMMinutesToSpinDown,(unsigned long)user_spindown); } @@ -842,6 +912,7 @@ IOReturn IOPMrootDomain::sysPowerDownHandler( void * target, void * refCon, case kIOMessageSystemWillPowerOff: case kIOMessageSystemWillRestart: + ret = kIOReturnUnsupported; break; default: diff --git a/iokit/IOKit/IONVRAM.h b/iokit/IOKit/IONVRAM.h index 50c9df268..866a9b9e1 100644 --- a/iokit/IOKit/IONVRAM.h +++ b/iokit/IOKit/IONVRAM.h @@ -27,6 +27,11 @@ #include #include + +#define kIODTNVRAMOFPartitionName "common" +#define kIODTNVRAMXPRAMPartitionName "APL,MacOS75" +#define kIODTNVRAMFreePartitionName "wwwwwwwwwwww" + enum { kIODTNVRAMImageSize = 0x2000, kIODTNVRAMXPRAMSize = 0x0100, @@ -60,6 +65,8 @@ private: UInt8 *_ofImage; bool _ofImageDirty; OSDictionary *_ofDict; + OSDictionary *_nvramPartitionOffsets; + OSDictionary *_nvramPartitionLengths; UInt32 _xpramPartitionOffset; UInt32 _xpramPartitionSize; UInt8 *_xpramImage; @@ -126,6 +133,16 @@ public: virtual IOReturn writeNVRAMProperty(IORegistryEntry *entry, const OSSymbol *name, OSData *value); + + virtual OSDictionary *getNVRAMPartitions(void); + + virtual IOReturn readNVRAMPartition(const OSSymbol *partitionID, + IOByteCount offset, UInt8 *buffer, + IOByteCount length); + + virtual IOReturn writeNVRAMPartition(const OSSymbol *partitionID, + IOByteCount offset, UInt8 *buffer, + IOByteCount length); }; #endif /* !_IOKIT_IONVRAM_H */ diff --git a/iokit/IOKit/IOPlatformExpert.h b/iokit/IOKit/IOPlatformExpert.h index 05d6e2d19..1147780fd 100644 --- a/iokit/IOKit/IOPlatformExpert.h +++ b/iokit/IOKit/IOPlatformExpert.h @@ -196,6 +196,7 @@ public: /* virtual */ IOReturn readXPRAM(IOByteCount offset, UInt8 * buffer, IOByteCount length); + /* virtual */ IOReturn writeXPRAM(IOByteCount offset, UInt8 * buffer, IOByteCount length); @@ -207,6 +208,18 @@ public: IORegistryEntry * entry, const OSSymbol * name, OSData * value ); + // This returns a dictionary describing all the NVRAM partitions. + // The keys will be the partitionIDs of the form "0x52,nvram". + // The values will be OSNumbers of the partition's byte count. + /* virtual */ OSDictionary *getNVRAMPartitions(void); + + /* virtual */ IOReturn readNVRAMPartition(const OSSymbol * partitionID, + IOByteCount offset, UInt8 * buffer, + IOByteCount length); + + /* virtual */ IOReturn writeNVRAMPartition(const OSSymbol * partitionID, + IOByteCount offset, UInt8 * buffer, + IOByteCount length); OSMetaClassDeclareReservedUnused(IODTPlatformExpert, 0); OSMetaClassDeclareReservedUnused(IODTPlatformExpert, 1); diff --git a/iokit/IOKit/pwr_mgt/IOPM.h b/iokit/IOKit/pwr_mgt/IOPM.h index 891643d7c..9cfe3ea53 100644 --- a/iokit/IOKit/pwr_mgt/IOPM.h +++ b/iokit/IOKit/pwr_mgt/IOPM.h @@ -118,7 +118,9 @@ enum { kIOPMClamshellClosed = (1<<4), // clamshell was closed kIOPMPowerEmergency = (1<<5), // battery dangerously low kIOPMDisableClamshell = (1<<6), // do not sleep on clamshell closure - kIOPMEnableClamshell = (1<<7) // sleep on clamshell closure + kIOPMEnableClamshell = (1<<7), // sleep on clamshell closure + kIOPMProcessorSpeedChange = (1<<8), // change the processor speed + kIOPMOverTemp = (1<<9) // system dangerously hot }; // Return codes @@ -266,9 +268,12 @@ enum { kPMMinutesToSpinDown, kPMMinutesToSleep, kPMEthernetWakeOnLANSettings, + kPMSetProcessorSpeed }; #define kMaxType kPMEthernetWakeOnLANSettings +#define kAppleClamshellStateKey "AppleClamshellState" +#define kIOREMSleepEnabledKey "REMSleepEnabled" #define kIOBatteryInfoKey "IOBatteryInfo" #define kIOBatteryCurrentChargeKey "Current" @@ -276,12 +281,43 @@ enum { #define kIOBatteryFlagsKey "Flags" #define kIOBatteryVoltageKey "Voltage" #define kIOBatteryAmperageKey "Amperage" + enum { kIOBatteryInstalled = (1 << 2), kIOBatteryCharge = (1 << 1), kIOBatteryChargerConnect = (1 << 0) }; +// These flags are deprecated. Use the version with the kIOPM prefix below. +enum { + kACInstalled = kIOBatteryChargerConnect, + kBatteryCharging = kIOBatteryCharge, + kBatteryInstalled = kIOBatteryInstalled, + kUPSInstalled = (1<<3), + kBatteryAtWarn = (1<<4), + kBatteryDepleted = (1<<5), + kACnoChargeCapability = (1<<6), // AC adapter cannot charge battery + kRawLowBattery = (1<<7), // used only by Platform Expert + kForceLowSpeed = (1<<8) // set by Platfm Expert, chk'd by Pwr Plugin}; +}; + +// For use with IOPMPowerSource bFlags +#define IOPM_POWER_SOURCE_REV 2 +enum { + kIOPMACInstalled = kIOBatteryChargerConnect, + kIOPMBatteryCharging = kIOBatteryCharge, + kIOPMBatteryInstalled = kIOBatteryInstalled, + kIOPMUPSInstalled = (1<<3), + kIOPMBatteryAtWarn = (1<<4), + kIOPMBatteryDepleted = (1<<5), + kIOPMACnoChargeCapability = (1<<6), // AC adapter cannot charge battery + kIOPMRawLowBattery = (1<<7), // used only by Platform Expert + kIOPMForceLowSpeed = (1<<8), // set by Platfm Expert, chk'd by Pwr Plugin + kIOPMClosedClamshell = (1<<9), // set by PMU - reflects state of the clamshell + kIOPMClamshellStateOnWake = (1<<10) // used only by Platform Expert +}; + + #if KERNEL && __cplusplus class IOService; diff --git a/iokit/IOKit/pwr_mgt/IOPMPowerSource.h b/iokit/IOKit/pwr_mgt/IOPMPowerSource.h index 20a069fc3..db54beff3 100644 --- a/iokit/IOKit/pwr_mgt/IOPMPowerSource.h +++ b/iokit/IOKit/pwr_mgt/IOPMPowerSource.h @@ -22,20 +22,10 @@ #include #include #include +#include "IOPM.h" class ApplePMU; -// Our flags - -enum { - kBatteryInstalled = (1<<0), - kBatteryCharging = (1<<1), - kACInstalled = (1<<2), - kUPSInstalled = (1<<3), - kBatteryAtWarn = (1<<4), - kBatteryDepleted = (1<<5) -}; - const unsigned long kSecondsPerHour = (60*60); const unsigned long kTenMinutesInSeconds = (10 * 60); diff --git a/iokit/IOKit/pwr_mgt/IOPMPrivate.h b/iokit/IOKit/pwr_mgt/IOPMPrivate.h new file mode 100644 index 000000000..000070686 --- /dev/null +++ b/iokit/IOKit/pwr_mgt/IOPMPrivate.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef _IOKIT_IOPMPRIVATE_H +#define _IOKIT_IOPMPRIVATE_H + +#include + +// Private power commands issued to root domain +// bits 0-7 in IOPM.h + +enum { + kIOPMSetValue = (1<<16), + // don't sleep on clamshell closure on a portable with AC connected + kIOPMSetDesktopMode = (1<<17), + // set state of AC adaptor connected + kIOPMSetACAdaptorConnected = (1<<18), +}; + +#endif /* ! _IOKIT_IOPMPRIVATE_H */ + diff --git a/iokit/IOKit/pwr_mgt/Makefile b/iokit/IOKit/pwr_mgt/Makefile index 855e67178..093e9f94f 100644 --- a/iokit/IOKit/pwr_mgt/Makefile +++ b/iokit/IOKit/pwr_mgt/Makefile @@ -5,7 +5,7 @@ export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir IOKIT_FRAMEDIR = $(FRAMEDIR)/IOKit.framework/Versions/A export INCDIR = $(IOKIT_FRAMEDIR)/Headers -export LCLDIR = $(IOKIT_FRAMEDIR)/PrivateHeaders +export LCLDIR = $(FRAMEDIR)/Kernel.framework/Versions/A/PrivateHeaders/IOKit include $(MakeInc_cmd) include $(MakeInc_def) @@ -16,7 +16,8 @@ NOT_EXPORT_HEADERS = \ IOPMinformee.h \ IOPMinformeeList.h \ IOPMlog.h \ - IOPMpmChild.h + IOPMpmChild.h \ + IOPMPrivate.h INSTINC_SUBDIRS = INSTINC_SUBDIRS_PPC = @@ -29,7 +30,7 @@ EXPINC_SUBDIRS_I386 = ${INSTINC_SUBDIRS_I386} ALL_HEADERS = $(shell (cd $(SOURCE); echo *.h)) INSTALL_MI_LIST = IOPMLibDefs.h IOPM.h -INSTALL_MI_LCL_LIST = "" +INSTALL_MI_LCL_LIST = IOPMPrivate.h INSTALL_MI_DIR = $(MI_DIR) EXPORT_MI_LIST = $(filter-out $(NOT_EXPORT_HEADERS), $(ALL_HEADERS)) diff --git a/iokit/IOKit/pwr_mgt/RootDomain.h b/iokit/IOKit/pwr_mgt/RootDomain.h index 28d95a059..4e89c16fc 100644 --- a/iokit/IOKit/pwr_mgt/RootDomain.h +++ b/iokit/IOKit/pwr_mgt/RootDomain.h @@ -27,6 +27,8 @@ class RootDomainUserClient; +#define kRootDomainSupportedFeatures "Supported Features" + enum { kRootDomainSleepNotSupported = 0x00000000, kRootDomainSleepSupported = 0x00000001, @@ -44,6 +46,7 @@ extern "C" IOReturn rootDomainShutdown ( void ); } +#define IOPM_ROOTDOMAIN_REV 2 class IOPMrootDomain: public IOService { @@ -66,7 +69,9 @@ public: virtual IOOptionBits getSleepSupported(); virtual IOReturn requestPowerDomainState ( IOPMPowerFlags, IOPowerConnection *, unsigned long ); virtual void handleSleepTimerExpiration ( void ); + void stopIgnoringClamshellEventsDuringWakeup ( void ); void wakeFromDoze( void ); + void publishFeature( const char *feature ); private: @@ -75,7 +80,8 @@ private: long longestNonSleepSlider; // pref: longest of other idle times long extraSleepDelay; // sleepSlider - longestNonSleepSlider thread_call_t extraSleepTimer; // used to wait between say display idle and system idle - + thread_call_t clamshellWakeupIgnore; // Used to ignore clamshell close events while we're waking from sleep + virtual void powerChangeDone ( unsigned long ); virtual void command_received ( void *, void * , void * , void *); virtual bool tellChangeDown ( unsigned long stateNum); @@ -98,6 +104,7 @@ private: void adjustPowerState( void ); void restoreUserSpinDownTimeout ( void ); + unsigned int user_spindown; // User's selected disk spindown value unsigned int systemBooting:1; @@ -107,8 +114,13 @@ private: unsigned int canSleep:1; unsigned int idleSleepPending:1; unsigned int sleepASAP:1; - unsigned int reservedA:1; - unsigned int reservedB[2]; + unsigned int desktopMode:1; + + unsigned int acAdaptorConnect:1; + unsigned int ignoringClamshellDuringWakeup:1; + unsigned int reservedA:6; + unsigned char reservedB[3]; + thread_call_t diskSyncCalloutEntry; IOOptionBits platformSleepSupport; }; diff --git a/iokit/Kernel/IONVRAM.cpp b/iokit/Kernel/IONVRAM.cpp index 703dc94f4..017f73c93 100644 --- a/iokit/Kernel/IONVRAM.cpp +++ b/iokit/Kernel/IONVRAM.cpp @@ -42,7 +42,13 @@ bool IODTNVRAM::init(IORegistryEntry *old, const IORegistryPlane *plane) _nvramImage = IONew(UInt8, kIODTNVRAMImageSize); if (_nvramImage == 0) return false; - + + _nvramPartitionOffsets = OSDictionary::withCapacity(1); + if (_nvramPartitionOffsets == 0) return false; + + _nvramPartitionLengths = OSDictionary::withCapacity(1); + if (_nvramPartitionLengths == 0) return false; + _registryPropertiesKey = OSSymbol::withCStringNoCopy("aapl,pci"); if (_registryPropertiesKey == 0) return false; @@ -51,7 +57,11 @@ bool IODTNVRAM::init(IORegistryEntry *old, const IORegistryPlane *plane) void IODTNVRAM::registerNVRAMController(IONVRAMController *nvram) { - UInt32 currentOffset = 0; + char partitionID[18]; + UInt32 partitionOffset, partitionLength; + UInt32 freePartitionOffset, freePartitionSize; + UInt32 currentLength, currentOffset = 0; + OSNumber *partitionOffsetNumber, *partitionLengthNumber; if (_nvramController != 0) return; @@ -59,26 +69,53 @@ void IODTNVRAM::registerNVRAMController(IONVRAMController *nvram) _nvramController->read(0, _nvramImage, kIODTNVRAMImageSize); - // Find the offsets for the OF, XPRAM and NameRegistry partitions in NVRAM. + // Find the offsets for the OF, XPRAM, and NameRegistry partitions. _ofPartitionOffset = 0xFFFFFFFF; _xpramPartitionOffset = 0xFFFFFFFF; _nrPartitionOffset = 0xFFFFFFFF; + freePartitionOffset = 0xFFFFFFFF; + freePartitionSize = 0; if (getPlatform()->getBootROMType()) { // Look through the partitions to find the OF, MacOS partitions. while (currentOffset < kIODTNVRAMImageSize) { - if (strcmp((const char *)_nvramImage + currentOffset + 4, "common") == 0) { - _ofPartitionOffset = currentOffset + 16; - _ofPartitionSize = - (((UInt16 *)(_nvramImage + currentOffset))[1] - 1) * 0x10; - } else if (strcmp((const char *)_nvramImage + currentOffset + 4, "APL,MacOS75") == 0) { - _xpramPartitionOffset = currentOffset + 16; + currentLength = ((UInt16 *)(_nvramImage + currentOffset))[1] * 16; + + partitionOffset = currentOffset + 16; + partitionLength = currentLength - 16; + + if (strncmp((const char *)_nvramImage + currentOffset + 4, + kIODTNVRAMOFPartitionName, 12) == 0) { + _ofPartitionOffset = partitionOffset; + _ofPartitionSize = partitionLength; + } else if (strncmp((const char *)_nvramImage + currentOffset + 4, + kIODTNVRAMXPRAMPartitionName, 12) == 0) { + _xpramPartitionOffset = partitionOffset; _xpramPartitionSize = kIODTNVRAMXPRAMSize; _nrPartitionOffset = _xpramPartitionOffset + _xpramPartitionSize; - _nrPartitionSize = - (((UInt16 *)(_nvramImage + currentOffset))[1] - 1) * 0x10 - - _xpramPartitionSize; + _nrPartitionSize = partitionLength - _xpramPartitionSize; + } else if (strncmp((const char *)_nvramImage + currentOffset + 4, + kIODTNVRAMFreePartitionName, 12) == 0) { + freePartitionOffset = currentOffset; + freePartitionSize = currentLength; + } else { + // Construct the partition ID from the signature and name. + sprintf(partitionID, "0x%02x,", + *(UInt8 *)(_nvramImage + currentOffset)); + strncpy(partitionID + 5, + (const char *)(_nvramImage + currentOffset + 4), 12); + partitionID[17] = '\0'; + + partitionOffsetNumber = OSNumber::withNumber(partitionOffset, 32); + partitionLengthNumber = OSNumber::withNumber(partitionLength, 32); + + // Save the partition offset and length + _nvramPartitionOffsets->setObject(partitionID, partitionOffsetNumber); + _nvramPartitionLengths->setObject(partitionID, partitionLengthNumber); + + partitionOffsetNumber->release(); + partitionLengthNumber->release(); } - currentOffset += ((short *)(_nvramImage + currentOffset))[1] * 16; + currentOffset += currentLength; } } else { // Use the fixed address for old world machines. @@ -335,7 +372,66 @@ IOReturn IODTNVRAM::writeNVRAMProperty(IORegistryEntry *entry, return err; } +OSDictionary *IODTNVRAM::getNVRAMPartitions(void) +{ + return _nvramPartitionLengths; +} + +IOReturn IODTNVRAM::readNVRAMPartition(const OSSymbol *partitionID, + IOByteCount offset, UInt8 *buffer, + IOByteCount length) +{ + OSNumber *partitionOffsetNumber, *partitionLengthNumber; + UInt32 partitionOffset, partitionLength; + + partitionOffsetNumber = + (OSNumber *)_nvramPartitionOffsets->getObject(partitionID); + partitionLengthNumber = + (OSNumber *)_nvramPartitionLengths->getObject(partitionID); + + if ((partitionOffsetNumber == 0) || (partitionLengthNumber == 0)) + return kIOReturnNotFound; + + partitionOffset = partitionOffsetNumber->unsigned32BitValue(); + partitionLength = partitionLengthNumber->unsigned32BitValue(); + + if ((buffer == 0) || (length <= 0) || (offset < 0) || + (offset + length > partitionLength)) + return kIOReturnBadArgument; + + bcopy(_nvramImage + partitionOffset + offset, buffer, length); + + return kIOReturnSuccess; +} +IOReturn IODTNVRAM::writeNVRAMPartition(const OSSymbol *partitionID, + IOByteCount offset, UInt8 *buffer, + IOByteCount length) +{ + OSNumber *partitionOffsetNumber, *partitionLengthNumber; + UInt32 partitionOffset, partitionLength; + + partitionOffsetNumber = + (OSNumber *)_nvramPartitionOffsets->getObject(partitionID); + partitionLengthNumber = + (OSNumber *)_nvramPartitionLengths->getObject(partitionID); + + if ((partitionOffsetNumber == 0) || (partitionLengthNumber == 0)) + return kIOReturnNotFound; + + partitionOffset = partitionOffsetNumber->unsigned32BitValue(); + partitionLength = partitionLengthNumber->unsigned32BitValue(); + + if ((buffer == 0) || (length <= 0) || (offset < 0) || + (offset + length > partitionLength)) + return kIOReturnBadArgument; + + bcopy(buffer, _nvramImage + partitionOffset + offset, length); + + _nvramImageDirty = true; + + return kIOReturnSuccess; +} // Private methods for Open Firmware variable access. diff --git a/iokit/Kernel/IOPlatformExpert.cpp b/iokit/Kernel/IOPlatformExpert.cpp index 0f07f4e75..2d4b2d500 100644 --- a/iokit/Kernel/IOPlatformExpert.cpp +++ b/iokit/Kernel/IOPlatformExpert.cpp @@ -995,6 +995,31 @@ IOReturn IODTPlatformExpert::writeNVRAMProperty( else return kIOReturnNotReady; } +OSDictionary *IODTPlatformExpert::getNVRAMPartitions(void) +{ + if (dtNVRAM) return dtNVRAM->getNVRAMPartitions(); + else return 0; +} + +IOReturn IODTPlatformExpert::readNVRAMPartition(const OSSymbol * partitionID, + IOByteCount offset, UInt8 * buffer, + IOByteCount length) +{ + if (dtNVRAM) return dtNVRAM->readNVRAMPartition(partitionID, offset, + buffer, length); + else return kIOReturnNotReady; +} + +IOReturn IODTPlatformExpert::writeNVRAMPartition(const OSSymbol * partitionID, + IOByteCount offset, UInt8 * buffer, + IOByteCount length) +{ + if (dtNVRAM) return dtNVRAM->writeNVRAMPartition(partitionID, offset, + buffer, length); + else return kIOReturnNotReady; +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super diff --git a/iokit/KernelConfigTables.cpp b/iokit/KernelConfigTables.cpp index 2d74ff7f9..f06533b63 100644 --- a/iokit/KernelConfigTables.cpp +++ b/iokit/KernelConfigTables.cpp @@ -28,13 +28,16 @@ */ const char * gIOKernelKmods = "{ - 'com.apple.kernel' = '5.4'; - 'com.apple.kernel.bsd' = '5.4'; - 'com.apple.kernel.iokit' = '5.4'; - 'com.apple.kernel.libkern' = '5.4'; - 'com.apple.kernel.mach' = '5.4'; + 'com.apple.kernel' = '5.5'; + 'com.apple.kernel.bsd' = '5.5'; + 'com.apple.kernel.iokit' = '5.5'; + 'com.apple.kernel.libkern' = '5.5'; + 'com.apple.kernel.mach' = '5.5'; 'com.apple.iokit.IOADBFamily' = '1.1'; + 'com.apple.iokit.IONVRAMFamily' = '1.1'; 'com.apple.iokit.IOSystemManagementFamily' = '1.1'; + 'com.apple.iokit.ApplePlatformFamily' = '1.0'; + 'com.apple.driver.AppleNMI' = '1.0'; }"; diff --git a/iokit/conf/files.ppc b/iokit/conf/files.ppc index 2321ea052..67dd7cff1 100644 --- a/iokit/conf/files.ppc +++ b/iokit/conf/files.ppc @@ -49,7 +49,6 @@ iokit/Drivers/platform/drvApplePowerExpressPE/PowerExpress.cpp optional iokitcpp iokit/Drivers/platform/drvAppleGrandCentral/GrandCentral.cpp optional disabled-iokitcpp iokit/Drivers/platform/drvAppleOHare/OHare.cpp optional iokitcpp - # ATA driver #iokit/Drivers/ata/drvAppleUltra66ATA/AppleUltra66ATA.cpp optional iokitcpp #iokit/Drivers/ata/drvAppleUltra33ATA/AppleUltra33ATA.cpp optional iokitcpp diff --git a/iokit/conf/version.minor b/iokit/conf/version.minor index b8626c4cf..7ed6ff82d 100644 --- a/iokit/conf/version.minor +++ b/iokit/conf/version.minor @@ -1 +1 @@ -4 +5 diff --git a/libkern/conf/version.minor b/libkern/conf/version.minor index b8626c4cf..7ed6ff82d 100644 --- a/libkern/conf/version.minor +++ b/libkern/conf/version.minor @@ -1 +1 @@ -4 +5 diff --git a/libkern/conf/version.variant b/libkern/conf/version.variant index e69de29bb..8b1378917 100644 --- a/libkern/conf/version.variant +++ b/libkern/conf/version.variant @@ -0,0 +1 @@ + diff --git a/libsa/conf/version.minor b/libsa/conf/version.minor index b8626c4cf..7ed6ff82d 100644 --- a/libsa/conf/version.minor +++ b/libsa/conf/version.minor @@ -1 +1 @@ -4 +5 diff --git a/libsa/conf/version.variant b/libsa/conf/version.variant index e69de29bb..8b1378917 100644 --- a/libsa/conf/version.variant +++ b/libsa/conf/version.variant @@ -0,0 +1 @@ + diff --git a/osfmk/conf/kernelversion.minor b/osfmk/conf/kernelversion.minor index b8626c4cf..7ed6ff82d 100644 --- a/osfmk/conf/kernelversion.minor +++ b/osfmk/conf/kernelversion.minor @@ -1 +1 @@ -4 +5 diff --git a/osfmk/conf/version.minor b/osfmk/conf/version.minor index b8626c4cf..7ed6ff82d 100644 --- a/osfmk/conf/version.minor +++ b/osfmk/conf/version.minor @@ -1 +1 @@ -4 +5 diff --git a/osfmk/default_pager/dp_backing_store.c b/osfmk/default_pager/dp_backing_store.c index 34f601059..e771c10f3 100644 --- a/osfmk/default_pager/dp_backing_store.c +++ b/osfmk/default_pager/dp_backing_store.c @@ -2933,7 +2933,7 @@ vs_cluster_write( vm_page_size, UPL_COMMIT_NOTIFY_EMPTY, pl, - MAX_UPL_TRANSFER, + page_list_count, &empty); if (empty) upl_deallocate(upl); diff --git a/osfmk/i386/machine_routines.c b/osfmk/i386/machine_routines.c index 95ce5958b..cd3021564 100644 --- a/osfmk/i386/machine_routines.c +++ b/osfmk/i386/machine_routines.c @@ -100,6 +100,14 @@ void ml_cause_interrupt(void) panic("ml_cause_interrupt not defined yet on Intel"); } +void ml_thread_policy( + thread_t thread, + unsigned policy_id, + unsigned policy_info) +{ + return; +} + /* Initialize Interrupts */ void ml_install_interrupt_handler( void *nub, diff --git a/osfmk/i386/machine_routines.h b/osfmk/i386/machine_routines.h index 920164a3b..888686b3c 100644 --- a/osfmk/i386/machine_routines.h +++ b/osfmk/i386/machine_routines.h @@ -72,6 +72,16 @@ boolean_t ml_at_interrupt_context(void); /* Generate a fake interrupt */ void ml_cause_interrupt(void); +void ml_thread_policy( + thread_t thread, + unsigned policy_id, + unsigned policy_info); + +#define MACHINE_GROUP 0x00000001 +#define MACHINE_NETWORK_GROUP 0x10000000 +#define MACHINE_NETWORK_WORKLOOP 0x00000001 +#define MACHINE_NETWORK_NETISR 0x00000002 + /* Initialize Interrupts */ void ml_install_interrupt_handler( void *nub, diff --git a/osfmk/mach/memory_object_types.h b/osfmk/mach/memory_object_types.h index 90437610e..1e744897f 100644 --- a/osfmk/mach/memory_object_types.h +++ b/osfmk/mach/memory_object_types.h @@ -264,7 +264,7 @@ typedef struct memory_object_attr_info memory_object_attr_info_data_t; * Universal Page List data structures */ -#define MAX_UPL_TRANSFER 64 +#define MAX_UPL_TRANSFER 256 struct upl_page_info { vm_offset_t phys_addr; diff --git a/osfmk/ppc/POWERMAC/video_console.c b/osfmk/ppc/POWERMAC/video_console.c index cf286337c..907aef682 100644 --- a/osfmk/ppc/POWERMAC/video_console.c +++ b/osfmk/ppc/POWERMAC/video_console.c @@ -155,9 +155,10 @@ static char tab_stops[255]; static int scrreg_top, scrreg_bottom; /* Misc */ -void vc_initialize(void); -void vc_flush_forward_buffer(void); -void vc_store_char(unsigned char); +static void vc_initialize(void); +static void vc_flush_forward_buffer(void); +static void vc_store_char(unsigned char); +static void vc_putchar(char ch); void vcattach(void); @@ -165,14 +166,14 @@ void vcattach(void); /* * For the color support (Michel Pollet) */ -unsigned char vc_color_index_table[33] = +static unsigned char vc_color_index_table[33] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }; -unsigned long vc_color_depth_masks[4] = +static unsigned long vc_color_depth_masks[4] = { 0x000000FF, 0x00007FFF, 0x00FFFFFF }; -unsigned long vc_colors[8][3] = { +static unsigned long vc_colors[8][3] = { { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */ { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */ { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */ @@ -184,10 +185,10 @@ unsigned long vc_colors[8][3] = { { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */ }; -unsigned long vc_color_mask = 0; -unsigned long vc_color_fore = 0; -unsigned long vc_color_back = 0; -int vc_normal_background = 1; +static unsigned long vc_color_mask = 0; +static unsigned long vc_color_fore = 0; +static unsigned long vc_color_back = 0; +static int vc_normal_background = 1; /* @@ -248,23 +249,23 @@ static int vc_forward_scroll = 0; static void (*vc_paintchar) (unsigned char c, int x, int y, int attrs); #ifdef RENDERALLOCATE -unsigned char *renderedFont = NULL; /* rendered font buffer */ +static unsigned char *renderedFont = NULL; /* rendered font buffer */ #else #define REN_MAX_DEPTH 32 /* that's the size for a 32 bits buffer... */ #define REN_MAX_SIZE (128L*1024) -unsigned char renderedFont[REN_MAX_SIZE]; +static unsigned char renderedFont[REN_MAX_SIZE]; #endif /* Rendered Font Size */ -unsigned long vc_rendered_font_size = REN_MAX_SIZE; -long vc_rendered_error = 0; +static unsigned long vc_rendered_font_size = REN_MAX_SIZE; +static long vc_rendered_error = 0; /* If the one bit table was reversed */ -short vc_one_bit_reversed = 0; +static short vc_one_bit_reversed = 0; /* Size of a character in the table (bytes) */ -int vc_rendered_char_size = 0; +static int vc_rendered_char_size = 0; /* # Attribute codes: @@ -1404,7 +1405,7 @@ putc_square(unsigned char ch) } -void +static void vc_putchar(char ch) { if (!ch) { @@ -1459,7 +1460,7 @@ vc_putchar(char ch) /* * Actually draws the buffer, handle the jump scroll */ -void vc_flush_forward_buffer(void) +static void vc_flush_forward_buffer(void) { int start = 0; int todo = 0; @@ -1718,6 +1719,9 @@ void vc_flush_forward_buffer(void) int vcputc(int l, int u, int c) { + if(!vinfo.v_baseaddr) + return; + /* * Either we're really buffering stuff or we're not yet because * the probe hasn't been done. @@ -1734,7 +1738,7 @@ vcputc(int l, int u, int c) * Store characters to be drawn 'later', handle overflows */ -void +static void vc_store_char(unsigned char c) { int flush = 0; @@ -1793,7 +1797,7 @@ vc_store_char(unsigned char c) } } -void +static void vc_initialize(void) { #if 0 @@ -1897,7 +1901,7 @@ static boolean_t vc_graphics_mode; static boolean_t vc_acquired; static boolean_t vc_need_clear; -void vc_blit_rect_8c( int x, int y, +static void vc_blit_rect_8c( int x, int y, int width, int height, int transparent, unsigned char * dataPtr ) { @@ -1922,7 +1926,7 @@ void vc_blit_rect_8c( int x, int y, } -void vc_blit_rect_8m( int x, int y, +static void vc_blit_rect_8m( int x, int y, int width, int height, int transparent, unsigned char * dataPtr ) { @@ -1951,7 +1955,7 @@ void vc_blit_rect_8m( int x, int y, -void vc_blit_rect_16( int x, int y, +static void vc_blit_rect_16( int x, int y, int width, int height, int transparent, unsigned char * dataPtr ) { @@ -1978,7 +1982,7 @@ void vc_blit_rect_16( int x, int y, } } -void vc_blit_rect_32( unsigned int x, unsigned int y, +static void vc_blit_rect_32( unsigned int x, unsigned int y, unsigned int width, unsigned int height, int transparent, unsigned char * dataPtr ) { @@ -2005,10 +2009,13 @@ void vc_blit_rect_32( unsigned int x, unsigned int y, } } -void vc_blit_rect( int x, int y, +static void vc_blit_rect( int x, int y, int width, int height, int transparent, unsigned char * dataPtr ) { + if(!vinfo.v_baseaddr) + return; + switch( vinfo.v_depth) { case 8: vc_blit_rect_8c( x, y, width, height, transparent, dataPtr); @@ -2022,7 +2029,7 @@ void vc_blit_rect( int x, int y, } } -void vc_progress_task( void * arg ) +static void vc_progress_task( void * arg ) { spl_t s; int count = (int) arg; @@ -2076,7 +2083,7 @@ void vc_display_icon( vc_progress_element * desc, } } -boolean_t +static boolean_t vc_progress_set( boolean_t enable ) { spl_t s; @@ -2124,7 +2131,7 @@ Boot_Video boot_video_info; extern int disableConsoleOutput; -void vc_clear_screen( void ) +static void vc_clear_screen( void ) { reversecursor(); vt100_reset(); diff --git a/osfmk/ppc/POWERMAC/video_console_entries.h b/osfmk/ppc/POWERMAC/video_console_entries.h index 4976ee80d..088358905 100644 --- a/osfmk/ppc/POWERMAC/video_console_entries.h +++ b/osfmk/ppc/POWERMAC/video_console_entries.h @@ -76,8 +76,6 @@ */ #include -extern void vc_putchar( - char ch); extern int vcputc( int l, int u, diff --git a/osfmk/ppc/asm.h b/osfmk/ppc/asm.h index 4e3ed2e79..e12d9bfe1 100644 --- a/osfmk/ppc/asm.h +++ b/osfmk/ppc/asm.h @@ -183,6 +183,8 @@ #define risegm 0x00080000 #define eiec 13 #define eiecm 0x00040000 +#define mum 14 +#define mumm 0x00020000 #define nhr 15 #define nhrm 0x00010000 #define ice 16 @@ -218,6 +220,19 @@ #define nopti 31 #define noptim 0x00000001 +; hid1 bits +#define hid1pcem 0xF8000000 +#define hid1prem 0x06000000 +#define hid1pi0 14 +#define hid1pi0m 0x00020000 +#define hid1ps 15 +#define hid1psm 0x00010000 +#define hid1pc0 0x0000F800 +#define hid1pr0 0x00000600 +#define hid1pc1 0x000000F8 +#define hid1pc0 0x0000F800 +#define hid1pr1 0x00000006 + ; msscr0 bits #define shden 0 #define shdenm 0x80000000 diff --git a/osfmk/ppc/exception.h b/osfmk/ppc/exception.h index cddade88b..355c1074f 100644 --- a/osfmk/ppc/exception.h +++ b/osfmk/ppc/exception.h @@ -63,6 +63,10 @@ struct procFeatures { #define pfThermalb 7 #define pfThermInt 0x00800000 #define pfThermIntb 8 +#define pfSlowNap 0x00004000 +#define pfSlowNapb 17 +#define pfNoMuMMCK 0x00002000 +#define pfNoMuMMCKb 18 #define pfLClck 0x00001000 #define pfLClckb 19 #define pfWillNap 0x00000800 @@ -106,7 +110,10 @@ struct procFeatures { unsigned int pfICTRL; unsigned int pfLDSTCR; unsigned int pfLDSTDB; - unsigned int reserved[7]; + unsigned int l2crOriginal; + unsigned int l3crOriginal; + unsigned int pfBootConfig; + unsigned int reserved[4]; }; typedef struct procFeatures procFeatures; diff --git a/osfmk/ppc/genassym.c b/osfmk/ppc/genassym.c index f45e8e2ed..059d57174 100644 --- a/osfmk/ppc/genassym.c +++ b/osfmk/ppc/genassym.c @@ -67,6 +67,7 @@ #include #include #include +#include #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE)0)->MEMBER) @@ -241,6 +242,10 @@ int main(int argc, char *argv[]) DECLARE("pfWillNapb", pfWillNapb); DECLARE("pfNoMSRir", pfNoMSRir); DECLARE("pfNoMSRirb", pfNoMSRirb); + DECLARE("pfSlowNap", pfSlowNap); + DECLARE("pfSlowNapb", pfSlowNapb); + DECLARE("pfNoMuMMCK", pfNoMuMMCK); + DECLARE("pfNoMuMMCKb", pfNoMuMMCKb); DECLARE("pfLClck", pfLClck); DECLARE("pfLClckb", pfLClckb); DECLARE("pfL3pdet", pfL3pdet); @@ -280,6 +285,9 @@ int main(int argc, char *argv[]) DECLARE("pfICTRL", offsetof(struct per_proc_info *, pf.pfICTRL)); DECLARE("pfLDSTCR", offsetof(struct per_proc_info *, pf.pfLDSTCR)); DECLARE("pfLDSTDB", offsetof(struct per_proc_info *, pf.pfLDSTDB)); + DECLARE("pfl2crOriginal", offsetof(struct per_proc_info *, pf.l2crOriginal)); + DECLARE("pfl3crOriginal", offsetof(struct per_proc_info *, pf.l3crOriginal)); + DECLARE("pfBootConfig", offsetof(struct per_proc_info *, pf.pfBootConfig)); DECLARE("pfSize", sizeof(procFeatures)); DECLARE("thrmmaxTemp", offsetof(struct per_proc_info *, thrm.maxTemp)); @@ -954,6 +962,8 @@ int main(int argc, char *argv[]) DECLARE("CPU_SUBTYPE_POWERPC_7400", CPU_SUBTYPE_POWERPC_7400); DECLARE("CPU_SUBTYPE_POWERPC_7450", CPU_SUBTYPE_POWERPC_7450); + DECLARE("shdIBAT", offsetof(struct shadowBAT *, IBATs)); + DECLARE("shdDBAT", offsetof(struct shadowBAT *, DBATs)); return(0); /* For ANSI C :-) */ diff --git a/osfmk/ppc/lowmem_vectors.s b/osfmk/ppc/lowmem_vectors.s index 8fd9a4645..b77de7569 100644 --- a/osfmk/ppc/lowmem_vectors.s +++ b/osfmk/ppc/lowmem_vectors.s @@ -984,7 +984,8 @@ skipz2: stw r6,napTotal+4(r2) ; Save the low total stw r8,napTotal(r2) ; Save the high total stw r3,savesrr0(r13) ; Modify to return to nap/doze exit - + + notNapping: stw r12,saver12(r13) /* Save this one */ bf- featL1ena,skipz3 ; L1 cache is disabled... @@ -1774,20 +1775,27 @@ notDCache: ; fix up to return directly to caller of probe. ; - lwz r30,saver5(r13) ; Get proper DBAT values - lwz r28,saver6(r13) - lwz r27,saver7(r13) - lwz r11,saver8(r13) - lwz r18,saver9(r13) + lis r11,hi16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address + ori r11,r11,lo16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address + + lwz r30,0(r11) ; Pick up DBAT 0 high + lwz r28,4(r11) ; Pick up DBAT 0 low + lwz r27,8(r11) ; Pick up DBAT 1 high + lwz r18,16(r11) ; Pick up DBAT 2 high + lwz r11,24(r11) ; Pick up DBAT 3 high sync mtdbatu 0,r30 ; Restore DBAT 0 high mtdbatl 0,r28 ; Restore DBAT 0 low mtdbatu 1,r27 ; Restore DBAT 1 high - mtdbatu 2,r11 ; Restore DBAT 2 high - mtdbatu 3,r18 ; Restore DBAT 3 high + mtdbatu 2,r18 ; Restore DBAT 2 high + mtdbatu 3,r11 ; Restore DBAT 3 high sync + lwz r27,saver6(r13) ; Get the saved R6 value + mtspr hid0,r27 ; Restore HID0 + isync + lwz r28,savelr(r13) ; Get return point lwz r27,saver0(r13) ; Get the saved MSR li r30,0 ; Get a failure RC diff --git a/osfmk/ppc/machine_routines.c b/osfmk/ppc/machine_routines.c index ad124b421..7ad338922 100644 --- a/osfmk/ppc/machine_routines.c +++ b/osfmk/ppc/machine_routines.c @@ -192,6 +192,16 @@ void ml_cause_interrupt(void) CreateFakeIO(); } +void ml_thread_policy( + thread_t thread, + unsigned policy_id, + unsigned policy_info) +{ + if ((policy_id == MACHINE_GROUP) && + ((per_proc_info[0].pf.Available) & pfSMPcap)) + thread_bind(thread, master_processor); +} + void machine_idle(void) { if (per_proc_info[cpu_number()].interrupts_enabled == TRUE) { @@ -302,6 +312,50 @@ ml_ppc_get_info(ml_ppc_cpu_info_t *cpu_info) } } +#define l2em 0x80000000 +#define l3em 0x80000000 + +extern int real_ncpus; + +int +ml_enable_cache_level(int cache_level, int enable) +{ + int old_mode; + unsigned long available, ccr; + + if (real_ncpus != 1) return -1; + + available = per_proc_info[0].pf.Available; + + if ((cache_level == 2) && (available & pfL2)) { + ccr = per_proc_info[0].pf.l2cr; + old_mode = (ccr & l2em) ? TRUE : FALSE; + if (old_mode != enable) { + if (enable) ccr = per_proc_info[0].pf.l2crOriginal; + else ccr = 0; + per_proc_info[0].pf.l2cr = ccr; + cacheInit(); + } + + return old_mode; + } + + if ((cache_level == 3) && (available & pfL3)) { + ccr = per_proc_info[0].pf.l3cr; + old_mode = (ccr & l3em) ? TRUE : FALSE; + if (old_mode != enable) { + if (enable) ccr = per_proc_info[0].pf.l3crOriginal; + else ccr = 0; + per_proc_info[0].pf.l3cr = ccr; + cacheInit(); + } + + return old_mode; + } + + return -1; +} + void init_ast_check(processor_t processor) {} diff --git a/osfmk/ppc/machine_routines.h b/osfmk/ppc/machine_routines.h index 6dc2d05dd..7bb0b2176 100644 --- a/osfmk/ppc/machine_routines.h +++ b/osfmk/ppc/machine_routines.h @@ -86,6 +86,16 @@ boolean_t ml_at_interrupt_context(void); /* Generate a fake interrupt */ void ml_cause_interrupt(void); +void ml_thread_policy( + thread_t thread, + unsigned policy_id, + unsigned policy_info); + +#define MACHINE_GROUP 0x00000001 +#define MACHINE_NETWORK_GROUP 0x10000000 +#define MACHINE_NETWORK_WORKLOOP 0x00000001 +#define MACHINE_NETWORK_NETISR 0x00000002 + #ifdef MACH_KERNEL_PRIVATE /* check pending timers */ void machine_clock_assist(void); @@ -185,4 +195,7 @@ unsigned int ml_throttle( void ml_get_timebase(unsigned long long *timstamp); void ml_sense__nmi(void); +int ml_enable_cache_level(int cache_level, int enable); +void ml_set_processor_speed(unsigned long speed); + #endif /* _PPC_MACHINE_ROUTINES_H_ */ diff --git a/osfmk/ppc/machine_routines_asm.s b/osfmk/ppc/machine_routines_asm.s index 86af4274b..a03a716d9 100644 --- a/osfmk/ppc/machine_routines_asm.s +++ b/osfmk/ppc/machine_routines_asm.s @@ -72,18 +72,19 @@ mprNoMSR: mr r0,r5 li r3,0 mprNoMSRx: + + mfspr r6, hid0 ; Get a copy of hid0 + ; ; We need to insure that there is no more than 1 BAT register that ; can get a hit. There could be repercussions beyond the ken ; of mortal man. It is best not to tempt fate. ; + +; Note: we will reload these from the shadow BATs later + li r10,0 ; Clear a register - mfdbatu r5,0 ; Save DBAT 0 high - mfdbatl r6,0 ; Save DBAT 0 low - mfdbatu r7,1 ; Save DBAT 1 high - mfdbatu r8,2 ; Save DBAT 2 high - mfdbatu r9,3 ; Save DBAT 3 high sync ; Make sure all is well @@ -98,6 +99,9 @@ mprNoMSRx: mtdbatu 0,r10 ; Now the upper sync ; Just make sure + dcbf 0,r12 ; Make sure we kill the cache to avoid paradoxes + sync + ori r11,r2,lo16(MASK(MSR_DR)) ; Turn on data translation mtmsr r11 ; Do it for real isync ; Make sure of it @@ -111,6 +115,21 @@ mprNoMSRx: sync ; Get caught up yet again isync ; Do not go further till we are here + mtmsr r2 ; Turn translation back off + isync + + mtspr hid0, r6 ; Restore HID0 + isync + + lis r10,hi16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address + ori r10,r10,lo16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address + + lwz r5,0(r10) ; Pick up DBAT 0 high + lwz r6,4(r10) ; Pick up DBAT 0 low + lwz r7,8(r10) ; Pick up DBAT 1 high + lwz r8,16(r10) ; Pick up DBAT 2 high + lwz r9,24(r10) ; Pick up DBAT 3 high + mtdbatu 0,r5 ; Restore DBAT 0 high mtdbatl 0,r6 ; Restore DBAT 0 low mtdbatu 1,r7 ; Restore DBAT 1 high @@ -345,7 +364,8 @@ yesnap: mftbu r9 ; Get the upper timebase bne- yesnap ; Yeah, need to get it again... stw r8,napStamp(r12) ; Set high order time stamp stw r7,napStamp+4(r12) ; Set low order nap stamp - + + ; ; We have to open up interruptions here because book 4 says that we should ; turn on only the POW bit and that we should have interrupts enabled @@ -698,15 +718,20 @@ cinoL1: mfspr r8,l2cr ; Get the L2CR lwz r3,pfl2cr(r12) ; Get the L2CR value + rlwinm. r0,r8,0,l2e,l2e ; Was the L2 enabled? + bne ciflushl2 ; Yes, force flush + cmplwi r8, 0 ; Was the L2 all the way off? + beq ciinvdl2 ; Yes, force invalidate lis r0,hi16(l2sizm|l2clkm|l2ramm|l2ohm) ; Get confiuration bits xor r2,r8,r3 ; Get changing bits? ori r0,r0,lo16(l2slm|l2dfm|l2bypm) ; More config bits and. r0,r0,r2 ; Did any change? bne- ciinvdl2 ; Yes, just invalidate and get PLL synced... +ciflushl2: bf pfL2fab,ciswfl2 ; Flush not in hardware... - mr r10,r3 ; Take a copy now + mr r10,r8 ; Take a copy now bf 31,cinol2lck ; Skip if pfLClck not set... @@ -728,7 +753,7 @@ cihwfl2: mfspr r10,l2cr ; Get back the L2CR ciswfl2: lwz r0,pfl2Size(r12) ; Get the L2 size - oris r2,r3,hi16(l2dom) ; Set L2 to data only mode + oris r2,r8,hi16(l2dom) ; Set L2 to data only mode b ciswfl2doa ; Branch to next line... @@ -755,11 +780,11 @@ ciswfldl2a: lwz r0,0(r10) ; Load something to flush something addi r10,r10,32 ; Next line bdnz ciswfldl2a ; Do the lot... -ciinvdl2: rlwinm r3,r3,0,l2e+1,31 ; Clear the enable bit +ciinvdl2: rlwinm r8,r3,0,l2e+1,31 ; Use the saved L2CR and clear the enable bit b cinla ; Branch to next line... .align 5 -cinlc: mtspr l2cr,r3 ; Disable L2 +cinlc: mtspr l2cr,r8 ; Disable L2 sync isync b ciinvl2 ; It is off, go invalidate it... @@ -772,7 +797,11 @@ cinlb: sync ; Finish memory stuff ciinvl2: sync isync - oris r2,r3,hi16(l2im) ; Get the invalidate flag set + + cmplwi r3, 0 ; Should the L2 be all the way off? + beq cinol2 ; Yes, done with L2 + + oris r2,r8,hi16(l2im) ; Get the invalidate flag set mtspr l2cr,r2 ; Start the invalidate sync @@ -787,7 +816,7 @@ ciinvdl2b: rlwinm. r2,r2,0,l2ip,l2ip ; Is the invalidate still going? bne+ ciinvdl2a ; Assume so, this will take a looong time... sync - mtspr l2cr,r3 ; Turn off the invalidate request + mtspr l2cr,r8 ; Turn off the invalidate request cinol2: @@ -798,14 +827,19 @@ cinol2: mfspr r8,l3cr ; Get the L3CR lwz r3,pfl3cr(r12) ; Get the L3CR value + rlwinm. r0,r8,0,l3e,l3e ; Was the L3 enabled? + bne ciflushl3 ; Yes, force flush + cmplwi r8, 0 ; Was the L3 all the way off? + beq ciinvdl3 ; Yes, force invalidate lis r0,hi16(l3pem|l3sizm|l3dxm|l3clkm|l3spom|l3ckspm) ; Get configuration bits xor r2,r8,r3 ; Get changing bits? ori r0,r0,lo16(l3pspm|l3repm|l3rtm|l3cyam|l3dmemm|l3dmsizm) ; More config bits and. r0,r0,r2 ; Did any change? bne- ciinvdl3 ; Yes, just invalidate and get PLL synced... +ciflushl3: sync ; 7450 book says do this even though not needed - mr r10,r3 ; Take a copy now + mr r10,r8 ; Take a copy now bf 31,cinol3lck ; Skip if pfL23lck not set... @@ -825,32 +859,42 @@ cihwfl3: mfspr r10,l3cr ; Get back the L3CR rlwinm. r10,r10,0,l3hwf,l3hwf ; Is the flush over? bne+ cihwfl3 ; Nope, keep going... -ciinvdl3: rlwinm r3,r3,0,l3e+1,31 ; Clear the enable bit +ciinvdl3: rlwinm r8,r3,0,l3e+1,31 ; Use saved L3CR value and clear the enable bit sync ; Make sure of life, liberty, and justice - mtspr l3cr,r3 ; Disable L3 + mtspr l3cr,r8 ; Disable L3 sync - ori r3,r3,lo16(l3im) ; Get the invalidate flag set + cmplwi r3, 0 ; Should the L3 be all the way off? + beq cinol3 ; Yes, done with L3 - mtspr l3cr,r3 ; Start the invalidate + ori r8,r8,lo16(l3im) ; Get the invalidate flag set -ciinvdl3b: mfspr r3,l3cr ; Get the L3CR - rlwinm. r3,r3,0,l3i,l3i ; Is the invalidate still going? + mtspr l3cr,r8 ; Start the invalidate + +ciinvdl3b: mfspr r8,l3cr ; Get the L3CR + rlwinm. r8,r8,0,l3i,l3i ; Is the invalidate still going? bne+ ciinvdl3b ; Assume so... sync - bf pfL3pdetb, ciinvdl3nopdet - mfspr r3,l3pdet ; ? - rlwimi r3,r3,28,0,23 ; ? - oris r3,r3,0xF000 ; ? - ori r3,r3,0x0080 ; ? - mtspr l3pdet,r3 ; ? + lwz r10, pfBootConfig(r12) ; ? + rlwinm. r10, r10, 24, 28, 31 ; ? + beq ciinvdl3nopdet ; ? + + mfspr r8,l3pdet ; ? + srw r2, r8, r10 ; ? + rlwimi r2, r8, 0, 24, 31 ; ? + subfic r10, r10, 32 ; ? + li r8, -1 ; ? + ori r2, r2, 0x0080 ; ? + slw r8, r8, r10 ; ? + or r8, r2, r8 ; ? + mtspr l3pdet, r8 ; ? isync ciinvdl3nopdet: - mfspr r3,l3cr ; Get the L3CR - rlwinm r3,r3,0,l3clken+1,l3clken-1 ; Clear the clock enable bit - mtspr l3cr,r3 ; Disable the clock + mfspr r8,l3cr ; Get the L3CR + rlwinm r8,r8,0,l3clken+1,l3clken-1 ; Clear the clock enable bit + mtspr l3cr,r8 ; Disable the clock li r2,128 ; ? ciinvdl3c: addi r2,r2,-1 ; ? @@ -862,15 +906,15 @@ ciinvdl3c: addi r2,r2,-1 ; ? mtspr msssr0,r10 ; ? sync - oris r3,r3,hi16(l3em|l3clkenm) ; Turn on enable bit - mtspr l3cr,r3 ; Enable it + mtspr l3cr,r3 ; Enable it as desired sync cinol3: bf pfL2b,cinol2a ; No level 2 cache to enable lwz r3,pfl2cr(r12) ; Get the L2CR value - oris r3,r3,hi16(l2em) ; Turn on enable bit - mtspr l2cr,r3 ; Enable it + cmplwi r3, 0 ; Should the L2 be all the way off? + beq cinol2a : Yes, done with L2 + mtspr l2cr,r3 ; Enable it as desired sync ; @@ -1186,3 +1230,13 @@ LEXT(ml_sense_nmi) blr ; Leave... +/* +** ml_set_processor_speed() +** +*/ +; Force a line boundry here + .align 5 + .globl EXT(ml_set_processor_speed) + +LEXT(ml_set_processor_speed) + blr diff --git a/osfmk/ppc/model_dep.c b/osfmk/ppc/model_dep.c index dbc07fd51..8241a6434 100644 --- a/osfmk/ppc/model_dep.c +++ b/osfmk/ppc/model_dep.c @@ -536,18 +536,6 @@ Debugger(const char *message) { } printf("\nNo debugger configured - dumping debug information\n"); - mfdbatu(store[0],0); - mfdbatl(store[1],0); - mfdbatu(store[2],1); - mfdbatl(store[3],1); - mfdbatu(store[4],2); - mfdbatl(store[5],2); - mfdbatu(store[6],3); - mfdbatl(store[7],3); - printf("DBAT0: %08X %08X\n", store[0], store[1]); - printf("DBAT1: %08X %08X\n", store[2], store[3]); - printf("DBAT2: %08X %08X\n", store[4], store[5]); - printf("DBAT3: %08X %08X\n", store[6], store[7]); printf("MSR=%08X\n",mfmsr()); print_backtrace(NULL); splx(spl); diff --git a/osfmk/ppc/ppc_init.c b/osfmk/ppc/ppc_init.c index 4219840d4..d75761a1a 100644 --- a/osfmk/ppc/ppc_init.c +++ b/osfmk/ppc/ppc_init.c @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -169,46 +170,75 @@ void ppc_init(boot_args *args) /* DBAT[2] maps the I/O Segment 1:1 */ /* DBAT[3] maps the Video Segment 1:1 */ + + /* Initialize shadow IBATs */ + shadow_BAT.IBATs[0].upper=BAT_INVALID; + shadow_BAT.IBATs[0].lower=BAT_INVALID; + shadow_BAT.IBATs[1].upper=BAT_INVALID; + shadow_BAT.IBATs[1].lower=BAT_INVALID; + shadow_BAT.IBATs[2].upper=BAT_INVALID; + shadow_BAT.IBATs[2].lower=BAT_INVALID; + shadow_BAT.IBATs[3].upper=BAT_INVALID; + shadow_BAT.IBATs[3].lower=BAT_INVALID; + + /* Initialize shadow DBATs */ + shadow_BAT.DBATs[0].upper=BAT_INVALID; + shadow_BAT.DBATs[0].lower=BAT_INVALID; + shadow_BAT.DBATs[1].upper=BAT_INVALID; + shadow_BAT.DBATs[1].lower=BAT_INVALID; + shadow_BAT.DBATs[2].upper=BAT_INVALID; + shadow_BAT.DBATs[2].lower=BAT_INVALID; + shadow_BAT.DBATs[3].upper=BAT_INVALID; + shadow_BAT.DBATs[3].lower=BAT_INVALID; + + /* If v_baseAddr is non zero, use DBAT3 to map the video segment */ videoAddr = args->Video.v_baseAddr & 0xF0000000; if (videoAddr) { - /* start off specifying 1-1 mapping of video seg */ - bat.upper.word = videoAddr; - bat.lower.word = videoAddr; - - bat.upper.bits.bl = 0x7ff; /* size = 256M */ - bat.upper.bits.vs = 1; - bat.upper.bits.vp = 0; - - bat.lower.bits.wimg = PTE_WIMG_IO; - bat.lower.bits.pp = 2; /* read/write access */ - - sync();isync(); - mtdbatu(3, BAT_INVALID); /* invalidate old mapping */ - mtdbatl(3, bat.lower.word); - mtdbatu(3, bat.upper.word); - sync();isync(); + /* start off specifying 1-1 mapping of video seg */ + bat.upper.word = videoAddr; + bat.lower.word = videoAddr; + + bat.upper.bits.bl = 0x7ff; /* size = 256M */ + bat.upper.bits.vs = 1; + bat.upper.bits.vp = 0; + + bat.lower.bits.wimg = PTE_WIMG_IO; + bat.lower.bits.pp = 2; /* read/write access */ + + shadow_BAT.DBATs[3].upper = bat.upper.word; + shadow_BAT.DBATs[3].lower = bat.lower.word; + + sync();isync(); + + mtdbatu(3, BAT_INVALID); /* invalidate old mapping */ + mtdbatl(3, bat.lower.word); + mtdbatu(3, bat.upper.word); + sync();isync(); } /* Use DBAT2 to map the io segment */ addr = get_io_base_addr() & 0xF0000000; if (addr != videoAddr) { - /* start off specifying 1-1 mapping of io seg */ - bat.upper.word = addr; - bat.lower.word = addr; - - bat.upper.bits.bl = 0x7ff; /* size = 256M */ - bat.upper.bits.vs = 1; - bat.upper.bits.vp = 0; - - bat.lower.bits.wimg = PTE_WIMG_IO; - bat.lower.bits.pp = 2; /* read/write access */ - - sync();isync(); - mtdbatu(2, BAT_INVALID); /* invalidate old mapping */ - mtdbatl(2, bat.lower.word); - mtdbatu(2, bat.upper.word); - sync();isync(); + /* start off specifying 1-1 mapping of io seg */ + bat.upper.word = addr; + bat.lower.word = addr; + + bat.upper.bits.bl = 0x7ff; /* size = 256M */ + bat.upper.bits.vs = 1; + bat.upper.bits.vp = 0; + + bat.lower.bits.wimg = PTE_WIMG_IO; + bat.lower.bits.pp = 2; /* read/write access */ + + shadow_BAT.DBATs[2].upper = bat.upper.word; + shadow_BAT.DBATs[2].lower = bat.lower.word; + + sync();isync(); + mtdbatu(2, BAT_INVALID); /* invalidate old mapping */ + mtdbatl(2, bat.lower.word); + mtdbatu(2, bat.upper.word); + sync();isync(); } if (!PE_parse_boot_arg("diag", &dgWork.dgFlags)) dgWork.dgFlags=0; /* Set diagnostic flags */ diff --git a/osfmk/ppc/ppc_vm_init.c b/osfmk/ppc/ppc_vm_init.c index cfbaab033..b700ba2ff 100644 --- a/osfmk/ppc/ppc_vm_init.c +++ b/osfmk/ppc/ppc_vm_init.c @@ -286,31 +286,14 @@ void ppc_vm_init(unsigned int mem_limit, boot_args *args) } #endif - /* Initialize shadow IBATs */ - shadow_BAT.IBATs[0].upper=BAT_INVALID; - shadow_BAT.IBATs[0].lower=BAT_INVALID; - shadow_BAT.IBATs[1].upper=BAT_INVALID; - shadow_BAT.IBATs[1].lower=BAT_INVALID; - shadow_BAT.IBATs[2].upper=BAT_INVALID; - shadow_BAT.IBATs[2].lower=BAT_INVALID; - shadow_BAT.IBATs[3].upper=BAT_INVALID; - shadow_BAT.IBATs[3].lower=BAT_INVALID; - - LoadIBATs((unsigned int *)&shadow_BAT.IBATs[0]); /* Load up real IBATs from shadows */ +/* + * Note: the shadow BAT registers were already loaded in ppc_init.c + */ - /* Initialize shadow DBATs */ - shadow_BAT.DBATs[0].upper=BAT_INVALID; - shadow_BAT.DBATs[0].lower=BAT_INVALID; - shadow_BAT.DBATs[1].upper=BAT_INVALID; - shadow_BAT.DBATs[1].lower=BAT_INVALID; - mfdbatu(shadow_BAT.DBATs[2].upper,2); - mfdbatl(shadow_BAT.DBATs[2].lower,2); - mfdbatu(shadow_BAT.DBATs[3].upper,3); - mfdbatl(shadow_BAT.DBATs[3].lower,3); + LoadIBATs((unsigned int *)&shadow_BAT.IBATs[0]); /* Load up real IBATs from shadows */ LoadDBATs((unsigned int *)&shadow_BAT.DBATs[0]); /* Load up real DBATs from shadows */ - sync();isync(); #if DEBUG for(i=0; i<4; i++) kprintf("DBAT%1d: %08X %08X\n", i, shadow_BAT.DBATs[i].upper, shadow_BAT.DBATs[i].lower); diff --git a/osfmk/ppc/start.s b/osfmk/ppc/start.s index 233064634..21a82ccdc 100644 --- a/osfmk/ppc/start.s +++ b/osfmk/ppc/start.s @@ -59,6 +59,7 @@ #define PROCESSOR_VERSION_7400 12 /* ? */ #define PROCESSOR_VERSION_7410 0x800C /* ? */ #define PROCESSOR_VERSION_7450 0x8000 /* ? */ +#define PROCESSOR_VERSION_7455 0x8001 /* ? */ /* * Interrupt and bootup stack for initial processor @@ -436,17 +437,6 @@ callcpu: ; Specific processor initialization routines ; -; 750CX - -init750CX: - bf firstBoot, init750 ; No init for wakeup.... - mfspr r13,hid1 ; Get HID1 - li r14,lo16(0xFD5F) ; Get valid - rlwinm r13,r13,4,28,31 ; Isolate - slw r14,r14,r13 ; Position - rlwimi r17,r14,15-pfCanNapb,pfCanNapb,pfCanNapb ; Set it - b init750 ; Join common... - ; 750 init750: @@ -465,6 +455,7 @@ i750hl2: slw r14,r14,r15 ; Set 256KB, 512KB, or 1MB beq- init750l2none ; Not a valid setting... + stw r13,pfl2crOriginal(r30) ; Shadow the L2CR stw r13,pfl2cr(r30) ; Shadow the L2CR stw r14,pfl2Size(r30) ; Set the L2 size b init750l2done ; Done with L2 @@ -478,13 +469,27 @@ init750l2done: blr ; Return... init750nb: - lwz r11,pfHID0(r30) ; Get HID0 + lwz r11,pfHID0(r30) ; Get HID0 sync mtspr hid0,r11 ; Set the HID isync sync blr +; 750CX + +init750CX: + bf firstBoot, init750 ; No init for wakeup.... + mfspr r13,hid1 ; Get HID1 + li r14,lo16(0xFD5F) ; Get valid + rlwinm r13,r13,4,28,31 ; Isolate + slw r14,r14,r13 ; Position + rlwimi r17,r14,15-pfCanNapb,pfCanNapb,pfCanNapb ; Set it + b init750 ; Join common... + + +; 7400 + init7400: bf firstBoot,i7400nb ; Do different if not initial boot... mfspr r13,l2cr ; Get the L2CR rlwinm. r0,r13,0,l2e,l2e ; Any L2? @@ -496,6 +501,7 @@ i7400hl2: lis r14,hi16(256*1024) ; Base L2 size rlwinm r15,r15,4,30,31 slw r14,r14,r15 ; Set 256KB, 512KB, 1MB, or 2MB + stw r13,pfl2crOriginal(r30) ; Shadow the L2CR stw r13,pfl2cr(r30) ; Shadow the L2CR stw r14,pfl2Size(r30) ; Set the L2 size @@ -512,6 +518,8 @@ i7400hl2: lis r14,hi16(256*1024) ; Base L2 size blr ; Return... i7400nb: + li r11,0 + mtspr l2cr,r11 ; Make sure L2CR is zero lwz r11,pfHID0(r30) ; Get HID0 sync mtspr hid0,r11 ; Set the HID @@ -535,20 +543,23 @@ i7400nb: init7410: li r13,0 ; Clear mtspr 1016,r13 ; Turn off direct cache b init7400 ; Join up with common.... - -; 7450 -init7450: bf firstBoot,i7450nb ; Do different if not initial boot... + +; 745X - Any 7450 family processor + +init745X: + bf firstBoot,init745Xnb ; Do different if not initial boot... mfspr r13,l2cr ; Get the L2CR rlwinm. r0,r13,0,l2e,l2e ; Any L2? - bne+ i7450hl2 ; Yes... + bne+ init745Xhl2 ; Yes... rlwinm r17,r17,0,pfL2b+1,pfL2b-1 ; No L2, turn off feature -i7450hl2: lis r14,hi16(256*1024) ; Base L2 size +init745Xhl2: lis r14,hi16(256*1024) ; Base L2 size rlwinm r15,r13,22,12,13 ; Convert to 256k, 512k, or 768k add r14,r14,r15 ; Add in minimum + stw r13,pfl2crOriginal(r30) ; Shadow the L2CR stw r13,pfl2cr(r30) ; Shadow the L2CR stw r14,pfl2Size(r30) ; Set the L2 size @@ -556,25 +567,26 @@ i7450hl2: lis r14,hi16(256*1024) ; Base L2 size mfspr r13,l3cr ; Get the L3CR rlwinm. r0,r13,0,l3e,l3e ; Any L3? - bne+ i7450hl3 ; Yes... + bne+ init745Xhl3 ; Yes... rlwinm r17,r17,0,pfL3b+1,pfL3b-1 ; No L3, turn off feature -i7450hl3: cmplwi cr0,r13,0 ; No L3 if L3CR is zero - beq- init7450none ; Go turn off the features... +init745Xhl3: cmplwi cr0,r13,0 ; No L3 if L3CR is zero + beq- init745Xnone ; Go turn off the features... lis r14,hi16(1024*1024) ; Base L3 size rlwinm r15,r13,4,31,31 ; Get size multiplier slw r14,r14,r15 ; Set 1 or 2MB + stw r13,pfl3crOriginal(r30) ; Shadow the L3CR stw r13,pfl3cr(r30) ; Shadow the L3CR stw r14,pfl3Size(r30) ; Set the L3 size - b init7450fin ; Return.... + b init745Xfin ; Return.... -init7450none: +init745Xnone: rlwinm r17,r17,0,pfL3fab+1,pfL3b-1 ; No 3rd level cache or assist rlwinm r11,r17,pfWillNapb-pfCanNapb,pfCanNapb,pfCanNapb ; Set pfCanNap if pfWillNap is set or r17,r17,r11 -init7450fin: +init745Xfin: rlwinm r17,r17,0,pfWillNapb+1,pfWillNapb-1 ; Make sure pfWillNap is not set mfspr r11,hid0 ; Get the current HID0 @@ -591,10 +603,12 @@ init7450fin: stw r11,pfLDSTCR(r30) ; Save the LDSTCR value mfspr r11,ldstdb ; Get the ldstdb register stw r11,pfLDSTDB(r30) ; Save the LDSTDB value + mfspr r11,pir ; Get the pir register + stw r11,pfBootConfig(r30) ; Save the BootConfig value blr ; Return.... -i7450nb: lwz r11,pfHID0(r30) ; Get HID0 +init745Xnb: lwz r11,pfHID0(r30) ; Get HID0 sync mtspr hid0,r11 ; Set the HID isync @@ -624,6 +638,21 @@ i7450nb: lwz r11,pfHID0(r30) ; Get HID0 sync blr +; 7450 - Specific + +init7450: + bf firstBoot, init745X ; Not boot, use standard init + + mfspr r13, pir ; Get BootConfig from PIR + rlwinm. r14, r13, 0, 20, 23 ; Is the pdet value zero + bne init7450done ; No, done for now + + ori r13, r13, 0x0400 ; Force pdet value to 4 + mtspr pir, r13 ; Write back the BootConfig + +init7450done: + b init745X ; Continue with standard init + ; ; Processor to feature table @@ -833,7 +862,7 @@ processor_types: .long 0xFFFFFF00 ; Just revisions 1.xx .short PROCESSOR_VERSION_7450 .short 0x0100 - .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfL3pdet + .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa .long init7450 .long CPU_SUBTYPE_POWERPC_7450 .long 105 @@ -848,7 +877,7 @@ processor_types: .long 0xFFFFFFFF ; Just revision 2.0 .short PROCESSOR_VERSION_7450 .short 0x0200 - .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfL3pdet + .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa .long init7450 .long CPU_SUBTYPE_POWERPC_7450 .long 105 @@ -863,7 +892,7 @@ processor_types: .long 0xFFFF0000 ; All other revisions .short PROCESSOR_VERSION_7450 .short 0 - .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa | pfL3pdet + .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa .long init7450 .long CPU_SUBTYPE_POWERPC_7450 .long 105 @@ -872,6 +901,50 @@ processor_types: .long 32*1024 .long 32*1024 +; 7455 (1.xx) Just like 7450 2.0 + + .align 2 + .long 0xFFFFFF00 ; Just revisions 1.xx + .short PROCESSOR_VERSION_7455 + .short 0x0100 + .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa + .long init745X + .long CPU_SUBTYPE_POWERPC_7450 + .long 105 + .long 90 + .long 32 + .long 32*1024 + .long 32*1024 + +; 7455 (2.0) + + .align 2 + .long 0xFFFFFFFF ; Just revision 2.0 + .short PROCESSOR_VERSION_7455 + .short 0x0200 + .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfWillNap | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa + .long init745X + .long CPU_SUBTYPE_POWERPC_7450 + .long 105 + .long 90 + .long 32 + .long 32*1024 + .long 32*1024 + +; 7455 (2.1) + + .align 2 + .long 0xFFFF0000 ; All other revisions + .short PROCESSOR_VERSION_7455 + .short 0 + .long pfFloat | pfAltivec | pfSMPcap | pfCanSleep | pfCanNap | pfNoMSRir | pfLClck | pfL1i | pfL1d | pfL2 | pfL2fa | pfL2i | pfL3 | pfL3fa + .long init745X + .long CPU_SUBTYPE_POWERPC_7450 + .long 105 + .long 90 + .long 32 + .long 32*1024 + .long 32*1024 ; Default dumb loser machine diff --git a/osfmk/vm/vm_pageout.c b/osfmk/vm/vm_pageout.c index b5c35da62..57ecaa12b 100644 --- a/osfmk/vm/vm_pageout.c +++ b/osfmk/vm/vm_pageout.c @@ -1876,13 +1876,14 @@ vm_pageout(void) static upl_t upl_create( - boolean_t internal) + boolean_t internal, + vm_size_t size) { upl_t upl; if(internal) { upl = (upl_t)kalloc(sizeof(struct upl) - + (sizeof(struct upl_page_info)*MAX_UPL_TRANSFER)); + + (sizeof(struct upl_page_info)*(size/page_size))); } else { upl = (upl_t)kalloc(sizeof(struct upl)); } @@ -1927,7 +1928,7 @@ upl_destroy( if(upl->flags & UPL_INTERNAL) { kfree((vm_offset_t)upl, sizeof(struct upl) + - (sizeof(struct upl_page_info) * MAX_UPL_TRANSFER)); + (sizeof(struct upl_page_info) * (upl->size/page_size))); } else { kfree((vm_offset_t)upl, sizeof(struct upl)); } @@ -2043,12 +2044,12 @@ vm_object_upl_request( } if(upl_ptr) { if(cntrl_flags & UPL_SET_INTERNAL) { - upl = upl_create(TRUE); + upl = upl_create(TRUE, size); user_page_list = (upl_page_info_t *) (((vm_offset_t)upl) + sizeof(struct upl)); upl->flags |= UPL_INTERNAL; } else { - upl = upl_create(FALSE); + upl = upl_create(FALSE, size); } if(object->phys_contiguous) { upl->size = size; diff --git a/pexpert/conf/version.minor b/pexpert/conf/version.minor index b8626c4cf..7ed6ff82d 100644 --- a/pexpert/conf/version.minor +++ b/pexpert/conf/version.minor @@ -1 +1 @@ -4 +5 diff --git a/pexpert/conf/version.variant b/pexpert/conf/version.variant index e69de29bb..8b1378917 100644 --- a/pexpert/conf/version.variant +++ b/pexpert/conf/version.variant @@ -0,0 +1 @@ + -- 2.45.2