Loading...
--- xnu/xnu-12377.121.6/iokit/Kernel/IODeviceTreeSupport.cpp
+++ xnu/xnu-6153.11.26/iokit/Kernel/IODeviceTreeSupport.cpp
@@ -28,7 +28,6 @@
#include <IOKit/IODeviceTreeSupport.h>
#include <libkern/c++/OSContainers.h>
-#include <libkern/c++/OSSharedPtr.h>
#include <IOKit/IODeviceMemory.h>
#include <IOKit/IOService.h>
#include <IOKit/IOCatalogue.h>
@@ -56,30 +55,17 @@
#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;
const OSSymbol * gIODTCompatibleKey;
const OSSymbol * gIODTTypeKey;
const OSSymbol * gIODTModelKey;
-const OSSymbol * gIODTBridgeModelKey;
const OSSymbol * gIODTTargetTypeKey;
const OSSymbol * gIODTSizeCellKey;
@@ -95,20 +81,15 @@
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 );
static void FreePhysicalMemory( vm_offset_t * range );
static bool IODTMapInterruptsSharing( IORegistryEntry * regEntry, OSDictionary * allInts );
-// FIXME: Implementation of this function is hidden from the static analyzer.
-// The analyzer doesn't know that the registry holds retains, and gets confused
-// about releases after calls to 'attachToParent'.
-// Feel free to remove the #ifndef and address the warning!
-#ifndef __clang_analyzer__
IORegistryEntry *
IODeviceTreeAlloc( void * dtTop )
{
@@ -124,10 +105,7 @@
vm_offset_t * dtMap;
unsigned int propSize;
bool intMap;
- bool foundDTNode;
bool freeDT;
- char exBootArg[64];
- const char * found;
gIODTPlane = IORegistryEntry::makePlane( kIODeviceTreePlane );
@@ -136,14 +114,11 @@
gIODTCompatibleKey = OSSymbol::withCStringNoCopy( "compatible" );
gIODTTypeKey = OSSymbol::withCStringNoCopy( "device_type" );
gIODTModelKey = OSSymbol::withCStringNoCopy( "model" );
- gIODTBridgeModelKey = OSSymbol::withCStringNoCopy( "bridge-model" );
gIODTTargetTypeKey = OSSymbol::withCStringNoCopy( "target-type" );
gIODTSizeCellKey = OSSymbol::withCStringNoCopy( "#size-cells" );
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 +140,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,51 +150,32 @@
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 ))
- && (kSuccess == SecureDTGetProperty( mapEntry,
- "DeviceTree", (void const **) &dtMap, &propSize ))
+ freeDT = (kSuccess == DTLookupEntry( NULL, "/chosen/memory-map", &mapEntry ))
+ && (kSuccess == DTGetProperty( mapEntry,
+ "DeviceTree", (void **) &dtMap, &propSize ))
&& ((2 * sizeof(uint32_t)) == propSize);
- freeDT = foundDTNode && !SecureDTIsLockedDown();
-
parent = MakeReferenceTable((DTEntry)dtTop, freeDT );
stack = OSArray::withObjects((const OSObject **) &parent, 1, 10 );
- SecureDTInitEntryIterator((DTEntry)dtTop, &iter );
+ DTInitEntryIterator((DTEntry)dtTop, &iter );
do {
parent = (IORegistryEntry *)stack->getObject( stack->getCount() - 1);
//parent->release();
stack->removeObject( stack->getCount() - 1);
- while (kSuccess == SecureDTIterateEntries( &iter, &dtChild)) {
+ while (kSuccess == DTIterateEntries( &iter, &dtChild)) {
child = MakeReferenceTable( dtChild, freeDT );
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)) {
+
+ if (kSuccess == DTEnterEntry( &iter, dtChild)) {
stack->setObject( parent);
parent = child;
}
@@ -234,10 +183,10 @@
child->release();
}
} while (stack->getCount()
- && (kSuccess == SecureDTExitEntry( &iter, &dtChild)));
+ && (kSuccess == DTExitEntry( &iter, &dtChild)));
stack->release();
- assert(kSuccess != SecureDTExitEntry(&iter, &dtChild));
+ assert(kSuccess != DTExitEntry(&iter, &dtChild));
// parent is now root of the created tree
@@ -253,7 +202,7 @@
if (freeDT) {
// free original device tree
- SecureDTInit(NULL, 0);
+ DTInit(NULL);
IODTFreeLoaderInfo( "DeviceTree",
(void *)dtMap[0], (int) round_page(dtMap[1]));
}
@@ -272,12 +221,14 @@
if (!intMap && child->getProperty( gIODTInterruptParentKey)) {
intMap = true;
}
+#if !(defined(RC_HIDE_N144) || defined(RC_HIDE_N146))
if (!strcmp("sep", child->getName())
|| !strcmp("aop", child->getName())
|| !strcmp("disp0", child->getName())) {
uint32_t aotFlags = 1;
child->setProperty("aot-power", &aotFlags, sizeof(aotFlags));
}
+#endif /* !(defined(RC_HIDE_N144) || defined(RC_HIDE_N146)) */
}
regIter->release();
}
@@ -314,7 +265,6 @@
return parent;
}
-#endif
int
IODTGetLoaderInfo( const char *key, void **infoAddr, int *infoSize )
@@ -388,21 +338,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;
}
@@ -426,9 +372,9 @@
OSData *data;
const OSSymbol *sym;
OpaqueDTPropertyIterator dtIter;
- void const *prop;
+ void *prop;
unsigned int propSize;
- char const *name;
+ char *name;
char location[32];
bool noLocation = true;
bool kernelOnly;
@@ -441,12 +387,12 @@
}
if (regEntry &&
- (kSuccess == SecureDTInitPropertyIterator( dtEntry, &dtIter))) {
- kernelOnly = (kSuccess == SecureDTGetProperty(dtEntry, "kernel-only", &prop, &propSize));
+ (kSuccess == DTInitPropertyIterator( dtEntry, &dtIter))) {
+ kernelOnly = (kSuccess == DTGetProperty(dtEntry, "kernel-only", &prop, &propSize));
propTable = regEntry->getPropertyTable();
- while (kSuccess == SecureDTIterateProperties( &dtIter, &name)) {
- if (kSuccess != SecureDTGetProperty( dtEntry, name, &prop, &propSize )) {
+ while (kSuccess == DTIterateProperties( &dtIter, &name)) {
+ if (kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) {
continue;
}
@@ -455,20 +401,13 @@
data = OSData::withBytes(prop, propSize);
} else {
nameKey = OSSymbol::withCStringNoCopy(name);
- /* There is no OSDataConst or other way to indicate
- * that the OSData is actually immutable. But CTRR
- * will catch any write attempts. */
- data = OSData::withBytesNoCopy((void**)(uintptr_t)prop, propSize);
+ data = OSData::withBytesNoCopy(prop, propSize);
}
assert( nameKey && data );
-#if DEVELOPMENT || DEBUG
-#pragma unused(kernelOnly)
-#else
if (kernelOnly) {
data->setSerializable(false);
}
-#endif
propTable->setObject( nameKey, data);
data->release();
@@ -516,7 +455,7 @@
}
}
-static LIBKERN_RETURNS_NOT_RETAINED IORegistryEntry *
+static IORegistryEntry *
FindPHandle( UInt32 phandle )
{
OSData *data;
@@ -795,7 +734,7 @@
UInt32 * localBits;
UInt32 * localEnd;
IOItemCount index;
- OSData * map = NULL;
+ OSData * map;
OSObject * oneMap;
OSArray * mapped;
OSArray * controllerInts;
@@ -834,8 +773,6 @@
if (0 == skip) {
IOLog("%s: error mapping interrupt[%d]\n",
regEntry->getName(), mapped->getCount());
- OSSafeReleaseNULL(map);
- OSSafeReleaseNULL(controller);
break;
}
} else {
@@ -880,8 +817,8 @@
}
}
- OSSafeReleaseNULL(map);
- OSSafeReleaseNULL(controller);
+ map->release();
+ controller->release();
} while (localBits < localEnd);
}
@@ -950,7 +887,7 @@
do {
// for each name in the property
- nlen = (unsigned int) strnlen(names, lastName - names);
+ nlen = strnlen(names, lastName - names);
if (wild) {
matched = ((nlen >= (keyLen - 1)) && (0 == strncmp(ckey, names, keyLen - 1)));
} else {
@@ -992,16 +929,6 @@
}
bool
-IODTCompareNubName( const IORegistryEntry * regEntry,
- OSString * name, OSSharedPtr<OSString>& matchingName )
-{
- OSString* matchingNameRaw = NULL;
- bool result = IODTCompareNubName(regEntry, name, &matchingNameRaw);
- matchingName.reset(matchingNameRaw, OSNoRetain);
- return result;
-}
-
-bool
IODTMatchNubWithKeys( IORegistryEntry * regEntry,
const char * keys )
{
@@ -1023,7 +950,7 @@
return result;
}
-LIBKERN_RETURNS_RETAINED OSCollectionIterator *
+OSCollectionIterator *
IODTFindMatchingEntries( IORegistryEntry * from,
IOOptionBits options, const char * keys )
{
@@ -1050,12 +977,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 +1005,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 +1061,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 +1078,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 +1132,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 +1153,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 +1173,9 @@
/* end of the road */
*phys = CellsValue( childAddressCells, cell );
*phys += offset;
+ if (regEntry != startEntry) {
+ regEntry->release();
+ }
break;
}
@@ -1277,12 +1191,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 +1272,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 +1298,7 @@
IOPhysicalAddress phys;
IOPhysicalLength len;
OSArray *array;
+ IODeviceMemory *range;
array = NULL;
do{
@@ -1408,7 +1324,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 +1334,6 @@
}
if (range) {
array->setObject( range );
- OSSafeReleaseNULL(range);
}
}
reg += cells;
@@ -1442,7 +1356,7 @@
OSData *ret = NULL;
UInt32 *bits;
UInt32 i;
- UInt32 nlen;
+ size_t nlen;
char *names;
char *lastName;
UInt32 mask;
@@ -1477,7 +1391,7 @@
for (i = 0; (i <= deviceNumber) && (names < lastName); i++) {
if (mask & (1 << i)) {
- nlen = 1 + ((unsigned int) strnlen(names, lastName - names));
+ nlen = 1 + strnlen(names, lastName - names);
if (i == deviceNumber) {
data = OSData::withBytesNoCopy(names, nlen);
if (data) {