/*
* Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
* The 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,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_FREE_COPYRIGHT@
#include <mach/mach_types.h>
#include <mach/machine/vm_types.h>
+#include <kern/debug.h>
#include <kern/kern_types.h>
#include <kern/kalloc.h>
+#include <os/overflow.h>
#include <sys/types.h>
-#ifdef i386
-#include <i386/fakePPCStructs.h>
-#endif
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
-#define round_long(x) (((x) + 3) & -4)
-#define next_prop(x) ((DeviceTreeNodeProperty *) (((int)x) + sizeof(DeviceTreeNodeProperty) + round_long(x->length)))
-
-/* Entry*/
-typedef DeviceTreeNode *RealDTEntry;
-
-typedef struct DTSavedScope {
- struct DTSavedScope * nextScope;
- RealDTEntry scope;
- RealDTEntry entry;
- unsigned long index;
-} *DTSavedScopePtr;
-
-/* Entry Iterator*/
-typedef struct OpaqueDTEntryIterator {
- RealDTEntry outerScope;
- RealDTEntry currentScope;
- RealDTEntry currentEntry;
- DTSavedScopePtr savedScope;
- unsigned long currentIndex;
-} *RealDTEntryIterator;
-
-/* Property Iterator*/
-typedef struct OpaqueDTPropertyIterator {
- RealDTEntry entry;
- DeviceTreeNodeProperty *currentProperty;
- unsigned long currentIndex;
-} *RealDTPropertyIterator;
static int DTInitialized;
static RealDTEntry DTRootNode;
-void DTInit(void *base);
-
/*
* Support Routines
*/
+static inline DeviceTreeNodeProperty*
+next_prop(DeviceTreeNodeProperty* prop)
+{
+ uintptr_t next_addr;
+ if (os_add3_overflow((uintptr_t)prop, prop->length, sizeof(DeviceTreeNodeProperty) + 3, &next_addr)) {
+ panic("Device tree property overflow: prop %p, length 0x%x\n", prop, prop->length);
+ }
+ next_addr &= ~(3ULL);
+ return (DeviceTreeNodeProperty*)next_addr;
+}
+
static RealDTEntry
skipProperties(RealDTEntry entry)
{
DeviceTreeNodeProperty *prop;
- int k;
+ unsigned int k;
if (entry == NULL || entry->nProperties == 0) {
return NULL;
prop = next_prop(prop);
}
}
- return ((RealDTEntry) prop);
+ return (RealDTEntry) prop;
}
static RealDTEntry
skipTree(RealDTEntry root)
{
RealDTEntry entry;
- int k;
+ unsigned int k;
entry = skipProperties(root);
if (entry == NULL) {
static const char *
GetNextComponent(const char *cp, char *bp)
{
+ size_t length = 0;
+ char *origbp = bp;
+
while (*cp != 0) {
if (*cp == kDTPathNameSeparator) {
cp++;
break;
}
+ if (++length > kDTMaxEntryNameLength) {
+ *origbp = '\0';
+ return cp;
+ }
*bp++ = *cp++;
}
*bp = 0;
static RealDTEntry
FindChild(RealDTEntry cur, char *buf)
{
- RealDTEntry child;
- unsigned long index;
- char * str;
- int dummy;
+ RealDTEntry child;
+ unsigned long index;
+ char * str;
+ unsigned int dummy;
if (cur->nChildren == 0) {
return NULL;
DTEntryIsEqual(const DTEntry ref1, const DTEntry ref2)
{
/* equality of pointers */
- return (ref1 == ref2);
+ return ref1 == ref2;
}
-static char *startingP; // needed for find_entry
+static char *startingP; // needed for find_entry
int find_entry(const char *propName, const char *propValue, DTEntry *entryH);
-int DTFindEntry(const char *propName, const char *propValue, DTEntry *entryH)
+int
+DTFindEntry(const char *propName, const char *propValue, DTEntry *entryH)
{
if (!DTInitialized) {
return kError;
}
startingP = (char *)DTRootNode;
- return(find_entry(propName, propValue, entryH));
+ return find_entry(propName, propValue, entryH);
}
-int find_entry(const char *propName, const char *propValue, DTEntry *entryH)
+int
+find_entry(const char *propName, const char *propValue, DTEntry *entryH)
{
- DeviceTreeNode *nodeP = (DeviceTreeNode *) startingP;
- int k;
+ DeviceTreeNode *nodeP = (DeviceTreeNode *) (void *) startingP;
+ unsigned int k;
- if (nodeP->nProperties == 0) return(kError); // End of the list of nodes
+ if (nodeP->nProperties == 0) {
+ return kError; // End of the list of nodes
+ }
startingP = (char *) (nodeP + 1);
// Search current entry
for (k = 0; k < nodeP->nProperties; ++k) {
- DeviceTreeNodeProperty *propP = (DeviceTreeNodeProperty *) startingP;
+ DeviceTreeNodeProperty *propP = (DeviceTreeNodeProperty *) (void *) startingP;
- startingP += sizeof (*propP) + ((propP->length + 3) & -4);
+ startingP += sizeof(*propP) + ((propP->length + 3) & -4);
- if (strcmp (propP->name, propName) == 0) {
- if (strcmp( (char *)(propP + 1), propValue) == 0)
- {
+ if (strcmp(propP->name, propName) == 0) {
+ if (propValue == NULL || strcmp((char *)(propP + 1), propValue) == 0) {
*entryH = (DTEntry)nodeP;
- return(kSuccess);
+ return kSuccess;
}
}
}
// Search child nodes
- for (k = 0; k < nodeP->nChildren; ++k)
- {
- if (find_entry(propName, propValue, entryH) == kSuccess)
- return(kSuccess);
+ for (k = 0; k < nodeP->nChildren; ++k) {
+ if (find_entry(propName, propValue, entryH) == kSuccess) {
+ return kSuccess;
+ }
}
- return(kError);
+ return kError;
}
int
DTLookupEntry(const DTEntry searchPoint, const char *pathName, DTEntry *foundEntry)
{
- DTEntryNameBuf buf;
- RealDTEntry cur;
- const char * cp;
+ DTEntryNameBuf buf;
+ RealDTEntry cur;
+ const char * cp;
if (!DTInitialized) {
return kError;
}
cur = FindChild(cur, buf);
-
} while (cur != NULL);
return kError;
}
int
-DTCreateEntryIterator(const DTEntry startEntry, DTEntryIterator *iterator)
+DTInitEntryIterator(const DTEntry startEntry, DTEntryIterator iter)
{
- RealDTEntryIterator iter;
-
if (!DTInitialized) {
return kError;
}
- iter = (RealDTEntryIterator) kalloc(sizeof(struct OpaqueDTEntryIterator));
if (startEntry != NULL) {
iter->outerScope = (RealDTEntry) startEntry;
iter->currentScope = (RealDTEntry) startEntry;
iter->savedScope = NULL;
iter->currentIndex = 0;
- *iterator = iter;
- return kSuccess;
-}
-
-int
-DTDisposeEntryIterator(DTEntryIterator iterator)
-{
- RealDTEntryIterator iter = iterator;
- DTSavedScopePtr scope;
-
- while ((scope = iter->savedScope) != NULL) {
- iter->savedScope = scope->nextScope;
- kfree(scope, sizeof(struct DTSavedScope));
- }
- kfree(iterator, sizeof(struct OpaqueDTEntryIterator));
return kSuccess;
}
int
-DTEnterEntry(DTEntryIterator iterator, DTEntry childEntry)
+DTEnterEntry(DTEntryIterator iter, DTEntry childEntry)
{
- RealDTEntryIterator iter = iterator;
DTSavedScopePtr newScope;
if (childEntry == NULL) {
newScope->nextScope = iter->savedScope;
newScope->scope = iter->currentScope;
newScope->entry = iter->currentEntry;
- newScope->index = iter->currentIndex;
+ newScope->index = iter->currentIndex;
iter->currentScope = childEntry;
iter->currentEntry = NULL;
}
int
-DTExitEntry(DTEntryIterator iterator, DTEntry *currentPosition)
+DTExitEntry(DTEntryIterator iter, DTEntry *currentPosition)
{
- RealDTEntryIterator iter = iterator;
DTSavedScopePtr newScope;
newScope = iter->savedScope;
}
int
-DTIterateEntries(DTEntryIterator iterator, DTEntry *nextEntry)
+DTIterateEntries(DTEntryIterator iter, DTEntry *nextEntry)
{
- RealDTEntryIterator iter = iterator;
-
if (iter->currentIndex >= iter->currentScope->nChildren) {
*nextEntry = NULL;
return kIterationDone;
}
int
-DTRestartEntryIteration(DTEntryIterator iterator)
+DTRestartEntryIteration(DTEntryIterator iter)
{
- RealDTEntryIterator iter = iterator;
#if 0
// This commented out code allows a second argument (outer)
// which (if true) causes restarting at the outer scope
}
int
-DTGetProperty(const DTEntry entry, const char *propertyName, void **propertyValue, int *propertySize)
+DTGetProperty(const DTEntry entry, const char *propertyName, void **propertyValue, unsigned int *propertySize)
{
DeviceTreeNodeProperty *prop;
- int k;
+ unsigned int k;
if (entry == NULL || entry->nProperties == 0) {
return kError;
prop = (DeviceTreeNodeProperty *) (entry + 1);
for (k = 0; k < entry->nProperties; k++) {
if (strcmp(prop->name, propertyName) == 0) {
- *propertyValue = (void *) (((int)prop)
- + sizeof(DeviceTreeNodeProperty));
+ *propertyValue = (void *) (((uintptr_t)prop)
+ + sizeof(DeviceTreeNodeProperty));
*propertySize = prop->length;
return kSuccess;
}
}
int
-DTCreatePropertyIterator(const DTEntry entry, DTPropertyIterator *iterator)
+DTInitPropertyIterator(const DTEntry entry, DTPropertyIterator iter)
{
- RealDTPropertyIterator iter;
-
- iter = (RealDTPropertyIterator) kalloc(sizeof(struct OpaqueDTPropertyIterator));
iter->entry = entry;
iter->currentProperty = NULL;
iter->currentIndex = 0;
-
- *iterator = iter;
return kSuccess;
}
int
-DTDisposePropertyIterator(DTPropertyIterator iterator)
+DTIterateProperties(DTPropertyIterator iter, char **foundProperty)
{
- kfree(iterator, sizeof(struct OpaqueDTPropertyIterator));
- return kSuccess;
-}
-
-int
-DTIterateProperties(DTPropertyIterator iterator, char **foundProperty)
-{
- RealDTPropertyIterator iter = iterator;
-
if (iter->currentIndex >= iter->entry->nProperties) {
*foundProperty = NULL;
return kIterationDone;
}
int
-DTRestartPropertyIteration(DTPropertyIterator iterator)
+DTRestartPropertyIteration(DTPropertyIterator iter)
{
- RealDTPropertyIterator iter = iterator;
-
iter->currentProperty = NULL;
iter->currentIndex = 0;
return kSuccess;
}
-