1 /* 2 * Copyright (c) 2000, 2024 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 #ifndef _PEXPERT_DEVICE_TREE_H_ 29 #define _PEXPERT_DEVICE_TREE_H_ 30 31 #include <stdbool.h> 32 33 #include <mach/mach_types.h> 34 #include <mach/vm_types.h> 35 36 #include <sys/appleapiopts.h> 37 38 #ifdef __APPLE_API_PRIVATE 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /* 45 * ------------------------------------------------------------------------------- 46 * Foundation Types 47 * ------------------------------------------------------------------------------- 48 */ 49 enum { 50 kDTPathNameSeparator = '/' /* 0x2F */ 51 }; 52 53 54 /* Property Name Definitions (Property Names are C-Strings)*/ 55 enum { 56 kDTMaxPropertyNameLength=31 /* Max length of Property Name (terminator not included) */ 57 }; 58 59 typedef char DTPropertyNameBuf[32]; 60 61 62 /* Entry Name Definitions (Entry Names are C-Strings)*/ 63 enum { 64 kDTMaxEntryNameLength = 63 /* Max length of a C-String Entry Name (terminator not included) */ 65 }; 66 67 /* length of DTEntryNameBuf = kDTMaxEntryNameLength +1*/ 68 typedef char DTEntryNameBuf[kDTMaxEntryNameLength + 1]; 69 70 /* 71 * Structures for a Flattened Device Tree 72 */ 73 74 #define kPropNameLength 32 75 76 typedef struct DeviceTreeNodeProperty { 77 char name[kPropNameLength];// NUL terminated property name 78 uint32_t length; // Length (bytes) of folloing prop value 79 // unsigned long value[1]; // Variable length value of property 80 // Padded to a multiple of a longword? 81 } DeviceTreeNodeProperty; 82 83 typedef struct OpaqueDTEntry { 84 uint32_t nProperties;// Number of props[] elements (0 => end) 85 uint32_t nChildren; // Number of children[] elements 86 // DeviceTreeNodeProperty props[];// array size == nProperties 87 // DeviceTreeNode children[]; // array size == nChildren 88 } DeviceTreeNode; 89 90 typedef const DeviceTreeNode *RealDTEntry; 91 92 typedef struct DTSavedScope { 93 struct DTSavedScope * nextScope; 94 RealDTEntry scope; 95 RealDTEntry entry; 96 unsigned long index; 97 } *DTSavedScopePtr; 98 99 /* Entry Iterator*/ 100 typedef struct OpaqueDTEntryIterator { 101 RealDTEntry outerScope; 102 RealDTEntry currentScope; 103 RealDTEntry currentEntry; 104 DTSavedScopePtr savedScope; 105 unsigned long currentIndex; 106 } OpaqueDTEntryIterator, *DTEntryIterator; 107 108 /* Property Iterator*/ 109 typedef struct OpaqueDTPropertyIterator { 110 RealDTEntry entry; 111 DeviceTreeNodeProperty const *currentProperty; 112 unsigned long currentIndex; 113 } OpaqueDTPropertyIterator, *DTPropertyIterator; 114 115 /* Entry*/ 116 typedef const struct OpaqueDTEntry* DTEntry; 117 118 /* Entry Iterator*/ 119 typedef struct OpaqueDTEntryIterator* DTEntryIterator; 120 121 /* Property Iterator*/ 122 typedef struct OpaqueDTPropertyIterator* DTPropertyIterator; 123 124 125 /* status values*/ 126 enum { 127 kError = -1, 128 kIterationDone = 0, 129 kSuccess = 1 130 }; 131 132 133 #ifndef __MWERKS__ 134 /* 135 * ------------------------------------------------------------------------------- 136 * Device Tree Calls 137 * ------------------------------------------------------------------------------- 138 */ 139 140 /* Used to initalize the device tree functions. */ 141 /* base is the base address of the flatened device tree */ 142 extern void SecureDTInit(void const *base, size_t size); 143 144 /* Whether the device tree is locked down after machine lockdown. */ 145 /* Returns false if there is no meaningful distinction, in */ 146 /* contrast to SecureDTFindEntry. */ 147 extern bool SecureDTIsLockedDown(void); 148 149 /* 150 * ------------------------------------------------------------------------------- 151 * Entry Handling 152 * ------------------------------------------------------------------------------- 153 */ 154 /* Compare two Entry's for equality. */ 155 extern int SecureDTEntryIsEqual(const DTEntry ref1, const DTEntry ref2); 156 157 /* 158 * ------------------------------------------------------------------------------- 159 * LookUp Entry by Name 160 * ------------------------------------------------------------------------------- 161 */ 162 /* 163 * Find Entry 164 * Find the device tree entry that contains propName=propValue. 165 * It currently searches the entire 166 * tree. This function should eventually go in DeviceTree.c. 167 * This only works for string properties where `propValue` is null-terminated. 168 * Returns: kSuccess = entry was found. Entry is in entryH. 169 * kError = entry was not found 170 */ 171 extern int SecureDTFindEntry(const char *propName, const char *propValue, DTEntry *entryH); 172 173 /** 174 * @brief Finds the devicetree node that has the specified property equal to the 175 * specified value. 176 * 177 * This function works with properties of any type; it just checks that the size 178 * and bytes of the value are what the caller wants. 179 * 180 * @note This function also works with properties that don't have a value—just 181 * specify NULL for `propertyValue` and 0 for `propertyValueSize`. 182 * 183 * @param[in] propertyName The name of the property. 184 * @param[in] propertyValue A pointer to some bytes that make up the value. 185 * @param[in] propertyValueSize The number of bytes that make up the value. 186 * @param[out] devicetreeNode A pointer to the target devicetree node, if found. 187 * 188 * @return kSuccess if the node was found and kError otherwise. 189 */ 190 extern int SecureDTFindNodeWithPropertyEqualToValue( 191 const char *const propertyName, 192 const void *const propertyValue, 193 const size_t propertyValueSize, 194 const DeviceTreeNode **const devicetreeNode); 195 196 /** 197 * @brief Finds the devicetree node with the specified phandle. 198 * 199 * This is a convenience wrapper around `SecureDTFindNodeWithPropertyEqualToValue()`. 200 * 201 * @param[in] phandle The phandle of interest. 202 * @param[out] devicetreeNode A pointer to the target devicetree node, if found. 203 * 204 * @return kSuccess if the node was found and kError otherwise. 205 */ 206 extern int SecureDTFindNodeWithPhandle( 207 const uint32_t phandle, 208 const DeviceTreeNode **const devicetreeNode); 209 210 /** 211 * @brief Finds the devicetree node with the specified string property. 212 * 213 * This is a convenience wrapper around `SecureDTFindNodeWithPropertyEqualToValue()`. 214 * 215 * @param[in] propertyName The name of the string property. 216 * @param[in] propertyValue The value of the string property. 217 * @param[out] devicetreeNode A pointer to the target devicetree node, if found. 218 * 219 * @return kSuccess if the node was found and kError otherwise. 220 */ 221 extern int SecureDTFindNodeWithStringProperty( 222 const char *const propertyName, 223 const char *const propertyValue, 224 const DeviceTreeNode **const devicetreeNode); 225 226 /* 227 * Lookup Entry 228 * Locates an entry given a specified subroot (searchPoint) and path name. If the 229 * searchPoint pointer is NULL, the path name is assumed to be an absolute path 230 * name rooted to the root of the device tree. 231 * Returns: kSuccess = entry was found. Entry is in foundEntry. 232 * kError = entry was not found 233 */ 234 extern int SecureDTLookupEntry(const DTEntry searchPoint, const char *pathName, DTEntry *foundEntry); 235 236 /* 237 * ------------------------------------------------------------------------------- 238 * Entry Iteration 239 * ------------------------------------------------------------------------------- 240 */ 241 /* 242 * An Entry Iterator maintains three variables that are of interest to clients. 243 * First is an "OutermostScope" which defines the outer boundry of the iteration. 244 * This is defined by the starting entry and includes that entry plus all of it's 245 * embedded entries. Second is a "currentScope" which is the entry the iterator is 246 * currently in. And third is a "currentPosition" which is the last entry returned 247 * during an iteration. 248 * 249 * Initialize Entry Iterator 250 * Fill out the iterator structure. The outermostScope and currentScope of the iterator 251 * are set to "startEntry". If "startEntry" = NULL, the outermostScope and 252 * currentScope are set to the root entry. The currentPosition for the iterator is 253 * set to "nil". 254 */ 255 extern int SecureDTInitEntryIterator(const DTEntry startEntry, DTEntryIterator iter); 256 257 /* 258 * Enter Child Entry 259 * Move an Entry Iterator into the scope of a specified child entry. The 260 * currentScope of the iterator is set to the entry specified in "childEntry". If 261 * "childEntry" is nil, the currentScope is set to the entry specified by the 262 * currentPosition of the iterator. 263 */ 264 extern int SecureDTEnterEntry(DTEntryIterator iterator, DTEntry childEntry); 265 266 /* 267 * Exit to Parent Entry 268 * Move an Entry Iterator out of the current entry back into the scope of it's parent 269 * entry. The currentPosition of the iterator is reset to the current entry (the 270 * previous currentScope), so the next iteration call will continue where it left off. 271 * This position is returned in parameter "currentPosition". 272 */ 273 extern int SecureDTExitEntry(DTEntryIterator iterator, DTEntry *currentPosition); 274 275 /* 276 * Iterate Entries 277 * Iterate and return entries contained within the entry defined by the current 278 * scope of the iterator. Entries are returned one at a time. When 279 * int == kIterationDone, all entries have been exhausted, and the 280 * value of nextEntry will be Nil. 281 */ 282 extern int SecureDTIterateEntries(DTEntryIterator iterator, DTEntry *nextEntry); 283 284 /* 285 * Restart Entry Iteration 286 * Restart an iteration within the current scope. The iterator is reset such that 287 * iteration of the contents of the currentScope entry can be restarted. The 288 * outermostScope and currentScope of the iterator are unchanged. The currentPosition 289 * for the iterator is set to "nil". 290 */ 291 extern int SecureDTRestartEntryIteration(DTEntryIterator iterator); 292 293 /* 294 * ------------------------------------------------------------------------------- 295 * Get Property Values 296 * ------------------------------------------------------------------------------- 297 */ 298 /* 299 * Get the value of the specified property for the specified entry. 300 * 301 * Get Property 302 */ 303 extern int SecureDTGetProperty(const DTEntry entry, const char *propertyName, 304 void const **propertyValue, unsigned int *propertySize); 305 306 extern int SecureDTGetPropertyRegion(const DTEntry entry, const char *propertyName, 307 void const **propertyValue, unsigned int *propertySize, 308 vm_offset_t const region_start, vm_size_t region_size); 309 310 /* 311 * ------------------------------------------------------------------------------- 312 * Iterating Properties 313 * ------------------------------------------------------------------------------- 314 */ 315 /* 316 * Initialize Property Iterator 317 * Fill out the property iterator structure. The target entry is defined by entry. 318 */ 319 extern int SecureDTInitPropertyIterator(const DTEntry entry, DTPropertyIterator iter); 320 321 /* 322 * Iterate Properites 323 * Iterate and return properties for given entry. 324 * When int == kIterationDone, all properties have been exhausted. 325 */ 326 327 extern int SecureDTIterateProperties(DTPropertyIterator iterator, 328 char const **foundProperty); 329 330 /* 331 * Restart Property Iteration 332 * Used to re-iterate over a list of properties. The Property Iterator is 333 * reset to the beginning of the list of properties for an entry. 334 */ 335 336 extern int SecureDTRestartPropertyIteration(DTPropertyIterator iterator); 337 338 /* 339 * ------------------------------------------------------------------------------- 340 * Conventional Device Tree Types 341 * ------------------------------------------------------------------------------- 342 */ 343 344 /* 345 * Memory Ranges 346 * Used in the chosen/memory-map node, populated by iBoot. 347 */ 348 349 typedef struct DTMemoryMapRange { 350 vm_offset_t paddr; 351 size_t length; 352 } DTMemoryMapRange; 353 354 355 #ifdef __cplusplus 356 } 357 #endif 358 359 #endif /* __MWERKS__ */ 360 361 #endif /* __APPLE_API_PRIVATE */ 362 363 #endif /* _PEXPERT_DEVICE_TREE_H_ */ 364