Loading...
iokit/Kernel/IODeviceTreeSupport.cpp xnu-12377.121.6 xnu-7195.121.3
--- xnu/xnu-12377.121.6/iokit/Kernel/IODeviceTreeSupport.cpp
+++ xnu/xnu-7195.121.3/iokit/Kernel/IODeviceTreeSupport.cpp
@@ -56,23 +56,11 @@
 
 #define IODTSUPPORTDEBUG 0
 
-struct IODTPersistent {
-	IODTCompareAddressCellFunc  compareFunc;
-};
-
-struct IODTResolvers {
-	unsigned int     alloc;
-	unsigned int     count;
-	IOLock         * lock;
-	IODTPersistent * resolvers;
-};
-
 const IORegistryPlane * gIODTPlane;
 
 static OSArray *    gIODTPHandles;
 static OSArray *    gIODTPHandleMap;
-
-static IODTResolvers *  gIODTResolvers;
+static OSData  *    gIODTResolvers;
 
 const OSSymbol *        gIODTNameKey;
 const OSSymbol *        gIODTUnitKey;
@@ -95,9 +83,9 @@
 const OSSymbol *        gIODTInterruptParentKey;
 const OSSymbol *        gIODTNWInterruptMappingKey;
 
-const OSData *          gIODTAssociatedServiceKey;
-
 OSDictionary   *        gIODTSharedInterrupts;
+
+static IOLock  *    gIODTResolversLock;
 
 static IORegistryEntry * MakeReferenceTable( DTEntry dtEntry, bool copy );
 static void AddPHandle( IORegistryEntry * regEntry );
@@ -126,8 +114,6 @@
 	bool                        intMap;
 	bool                        foundDTNode;
 	bool                        freeDT;
-	char                        exBootArg[64];
-	const char *                found;
 
 	gIODTPlane = IORegistryEntry::makePlane( kIODeviceTreePlane );
 
@@ -142,8 +128,6 @@
 	gIODTAddressCellKey = OSSymbol::withCStringNoCopy( "#address-cells" );
 	gIODTRangeKey               = OSSymbol::withCStringNoCopy( "ranges" );
 	gIODTPersistKey             = OSSymbol::withCStringNoCopy( "IODTPersist" );
-	gIODTAssociatedServiceKey   = OSData::withBytesNoCopy((void *) kIODTAssociatedServiceKey, sizeof(kIODTAssociatedServiceKey));
-
 
 	assert(    gIODTPlane && gIODTCompatibleKey
 	    && gIODTTypeKey && gIODTModelKey
@@ -165,16 +149,9 @@
 
 	gIODTPHandles       = OSArray::withCapacity( 1 );
 	gIODTPHandleMap     = OSArray::withCapacity( 1 );
-
-	gIODTResolvers            = zalloc_permanent_type(IODTResolvers);
-	gIODTResolvers->count     = 0;
-	gIODTResolvers->alloc     = 2;
-	gIODTResolvers->resolvers = IONewZero(IODTPersistent, gIODTResolvers->alloc);
-	gIODTResolvers->lock      = IOLockAlloc();
-
-	if (!PE_parse_boot_argn("exp", exBootArg, sizeof(exBootArg))) {
-		exBootArg[0] = '\0';
-	}
+	gIODTResolvers  = OSData::withCapacity(16);
+
+	gIODTResolversLock = IOLockAlloc();
 
 	gIODTInterruptCellKey
 	        = OSSymbol::withCStringNoCopy("#interrupt-cells");
@@ -182,8 +159,8 @@
 	assert(    gIODTDefaultInterruptController && gIODTNWInterruptMappingKey
 	    && gIODTAAPLInterruptsKey
 	    && gIODTPHandleKey && gIODTInterruptParentKey
-	    && gIODTPHandles && gIODTPHandleMap && gIODTInterruptCellKey
-	    && gIODTResolvers && gIODTResolvers->lock && gIODTResolvers->resolvers
+	    && gIODTPHandles && gIODTPHandleMap && gIODTResolvers && gIODTResolversLock
+	    && gIODTInterruptCellKey
 	    );
 
 	foundDTNode = (kSuccess == SecureDTLookupEntry( NULL, "/chosen/memory-map", &mapEntry ))
@@ -208,23 +185,6 @@
 			child->attachToParent( parent, gIODTPlane);
 
 			AddPHandle( child );
-			// E.g. exp=sgx:3 or exp=sgx:3,5
-			if ((found = strnstr(exBootArg, child->getName(), sizeof(exBootArg)))) {
-				child->setProperty(gIOExclaveAssignedKey, kOSBooleanTrue);
-				uint32_t ep = 0;
-				uint32_t edk_ep = 0;
-				found += strlen(child->getName());
-				if (':' == *found) {
-					char *end;
-					ep = (uint32_t) strtol(found + 1, &end, 0);
-					// Check for optional edk endpoint
-					if (',' == *end) {
-						edk_ep = (uint32_t) strtol(end + 1, &end, 0);
-						child->setProperty("exclave-edk-endpoint", &edk_ep, sizeof(edk_ep));
-					}
-				}
-				child->setProperty("exclave-endpoint", &ep, sizeof(ep));
-			}
 
 			if (kSuccess == SecureDTEnterEntry( &iter, dtChild)) {
 				stack->setObject( parent);
@@ -388,21 +348,17 @@
 	}
 
 	defaultObj = OSDynamicCast( OSData, defaults->getProperty(key));
-
 	if (defaultObj == NULL) {
-		defaults->release();
 		return -1;
 	}
 
 	defaultSize = defaultObj->getLength();
 	if (defaultSize > infoSize) {
-		defaults->release();
 		return -1;
 	}
 
 	memcpy( infoAddr, defaultObj->getBytesNoCopy(), defaultSize );
 
-	defaults->release();
 	return 0;
 }
 
@@ -462,13 +418,9 @@
 			}
 			assert( nameKey && data );
 
-#if DEVELOPMENT || DEBUG
-#pragma unused(kernelOnly)
-#else
 			if (kernelOnly) {
 				data->setSerializable(false);
 			}
-#endif
 
 			propTable->setObject( nameKey, data);
 			data->release();
@@ -516,7 +468,7 @@
 	}
 }
 
-static LIBKERN_RETURNS_NOT_RETAINED IORegistryEntry *
+static IORegistryEntry *
 FindPHandle( UInt32 phandle )
 {
 	OSData                      *data;
@@ -795,7 +747,7 @@
 	UInt32 *            localBits;
 	UInt32 *            localEnd;
 	IOItemCount         index;
-	OSData *            map = NULL;
+	OSData *            map;
 	OSObject *          oneMap;
 	OSArray *           mapped;
 	OSArray *           controllerInts;
@@ -834,8 +786,6 @@
 				if (0 == skip) {
 					IOLog("%s: error mapping interrupt[%d]\n",
 					    regEntry->getName(), mapped->getCount());
-					OSSafeReleaseNULL(map);
-					OSSafeReleaseNULL(controller);
 					break;
 				}
 			} else {
@@ -880,8 +830,8 @@
 				}
 			}
 
-			OSSafeReleaseNULL(map);
-			OSSafeReleaseNULL(controller);
+			map->release();
+			controller->release();
 		} while (localBits < localEnd);
 	}
 
@@ -1023,7 +973,7 @@
 	return result;
 }
 
-LIBKERN_RETURNS_RETAINED OSCollectionIterator *
+OSCollectionIterator *
 IODTFindMatchingEntries( IORegistryEntry * from,
     IOOptionBits options, const char * keys )
 {
@@ -1050,12 +1000,10 @@
 			iter->reset();
 			while ((next = iter->getNextObject())) {
 				// Look for existence of a debug property to skip
-				if (next->propertyExists("AAPL,ignore")) {
+				if (next->getProperty("AAPL,ignore")) {
 					continue;
 				}
-				if (next->propertyHasValue(gIODTTypeKey, gIODTAssociatedServiceKey)) {
-					continue;
-				}
+
 				if (keys) {
 					cmp = IODTMatchNubWithKeys( next, keys );
 					if ((minus && (false == cmp))
@@ -1080,52 +1028,38 @@
 }
 
 
+struct IODTPersistent {
+	IODTCompareAddressCellFunc  compareFunc;
+};
+
 void
 IODTSetResolving( IORegistryEntry *        regEntry,
     IODTCompareAddressCellFunc      compareFunc,
     IODTNVLocationFunc              locationFunc __unused )
 {
+	IODTPersistent       persist;
 	IODTPersistent * entry;
-	IODTPersistent * newResolvers;
 	OSNumber       * num;
-	unsigned int     index;
-
-	IOLockLock(gIODTResolvers->lock);
-
-	entry = gIODTResolvers->resolvers;
-	for (index = 0; index < gIODTResolvers->count; index++) {
+	unsigned int     index, count;
+
+	IOLockLock(gIODTResolversLock);
+
+	count = (gIODTResolvers->getLength() / sizeof(IODTPersistent));
+	entry = (typeof(entry))gIODTResolvers->getBytesNoCopy();
+	for (index = 0; index < count; index++) {
 		if (compareFunc == entry->compareFunc) {
 			break;
 		}
 		entry++;
 	}
-
-	if (index == gIODTResolvers->count) {
-		if (gIODTResolvers->alloc == gIODTResolvers->count) {
-			if (__improbable(os_mul_overflow(gIODTResolvers->alloc, 2,
-			    &gIODTResolvers->alloc))) {
-				panic("IODTSetResolving - gIODTResolvers alloc overflows");
-			}
-
-			newResolvers = IONewZero(IODTPersistent, gIODTResolvers->alloc);
-			if (__improbable(!newResolvers)) {
-				panic("IODTSetResolving - could not allocate new resolvers");
-			}
-
-			bcopy(gIODTResolvers->resolvers, newResolvers,
-			    sizeof(gIODTResolvers->resolvers[0]) * gIODTResolvers->count);
-
-			IODelete(gIODTResolvers->resolvers, IODTPersistent,
-			    gIODTResolvers->count);
-			gIODTResolvers->resolvers = newResolvers;
-		}
-
-		entry = &gIODTResolvers->resolvers[gIODTResolvers->count];
-		entry->compareFunc = compareFunc;
-		gIODTResolvers->count++;
-	}
-
-	IOLockUnlock(gIODTResolvers->lock);
+	if (index == count) {
+		persist.compareFunc = compareFunc;
+		if (!gIODTResolvers->appendBytes(&persist, sizeof(IODTPersistent))) {
+			panic("IODTSetResolving");
+		}
+	}
+
+	IOLockUnlock(gIODTResolversLock);
 
 	num = OSNumber::withNumber(index, 32);
 	regEntry->setProperty(gIODTPersistKey, num);
@@ -1150,7 +1084,7 @@
 
 	return diff;
 }
-#elif defined(__i386__) || defined(__x86_64__)
+#elif defined(__arm__) || defined(__i386__) || defined(__x86_64__)
 static SInt32
 DefaultCompare( UInt32 cellCount, UInt32 left[], UInt32 right[] )
 {
@@ -1167,7 +1101,7 @@
 	if (numCells == 1) {
 		cells[0] += (UInt32)offset;
 	} else {
-#if defined(__arm64__)
+#if defined(__arm64__) || defined(__arm__)
 		UInt64 sum = cells[numCells - 2] + offset;
 		cells[numCells - 2] = (UInt32)sum;
 		if (sum > UINT32_MAX) {
@@ -1221,11 +1155,11 @@
     UInt32 cellsIn[],
     IOPhysicalAddress * phys, IOPhysicalLength * lenOut )
 {
-	IORegistryEntry     * parent = NULL;
+	IORegistryEntry     * parent;
 	IORegistryEntry * regEntry;
 	OSData          * prop;
 	OSNumber    * num;
-	unsigned int  index;
+	unsigned int  index, count;
 	// cells in addresses at regEntry
 	UInt32              sizeCells, addressCells;
 	// cells in addresses below regEntry
@@ -1242,10 +1176,10 @@
 	SInt64              diff, diff2, endDiff;
 	UInt64              len, rangeLen;
 
+	IODTPersistent      *persist;
 	IODTCompareAddressCellFunc  compare;
 
 	regEntry = startEntry;
-	regEntry->retain();
 	IODTGetCellCounts( regEntry, &childSizeCells, &childAddressCells );
 	childCells = childAddressCells + childSizeCells;
 
@@ -1262,6 +1196,9 @@
 			/* end of the road */
 			*phys = CellsValue( childAddressCells, cell );
 			*phys += offset;
+			if (regEntry != startEntry) {
+				regEntry->release();
+			}
 			break;
 		}
 
@@ -1277,12 +1214,14 @@
 			compare = NULL;
 			num = OSDynamicCast(OSNumber, regEntry->getProperty(gIODTPersistKey));
 			if (num) {
-				IOLockLock(gIODTResolvers->lock);
+				IOLockLock(gIODTResolversLock);
 				index = num->unsigned32BitValue();
-				if (index < gIODTResolvers->count) {
-					compare = gIODTResolvers->resolvers[index].compareFunc;
-				}
-				IOLockUnlock(gIODTResolvers->lock);
+				count = gIODTResolvers->getLength() / sizeof(IODTPersistent);
+				if (index < count) {
+					persist = ((IODTPersistent *) gIODTResolvers->getBytesNoCopy()) + index;
+					compare = persist->compareFunc;
+				}
+				IOLockUnlock(gIODTResolversLock);
 			}
 
 			if (!compare && (addressCells == childAddressCells)) {
@@ -1356,15 +1295,14 @@
 			bzero( cell + addressCells, sizeof(UInt32) * sizeCells );
 		} /* else zero length range => pass thru to parent */
 
-		OSSafeReleaseNULL(regEntry);
+		if (regEntry != startEntry) {
+			regEntry->release();
+		}
 		regEntry                = parent;
-		parent = NULL;
 		childSizeCells          = sizeCells;
 		childAddressCells       = addressCells;
 		childCells              = childAddressCells + childSizeCells;
 	}while (ok && regEntry);
-
-	OSSafeReleaseNULL(regEntry);
 
 	return ok;
 }
@@ -1383,6 +1321,7 @@
 	IOPhysicalAddress   phys;
 	IOPhysicalLength    len;
 	OSArray                             *array;
+	IODeviceMemory              *range;
 
 	array = NULL;
 	do{
@@ -1408,7 +1347,6 @@
 
 		for (i = 0; i < num; i++) {
 			if (IODTResolveAddressCell( parentEntry, reg, &phys, &len )) {
-				IODeviceMemory *range;
 				range = NULL;
 				if (parent) {
 					range = IODeviceMemory::withSubRange( parent,
@@ -1419,7 +1357,6 @@
 				}
 				if (range) {
 					array->setObject( range );
-					OSSafeReleaseNULL(range);
 				}
 			}
 			reg += cells;