xref: /xnu-12377.61.12/pexpert/pexpert/device_tree.h (revision 4d495c6e23c53686cf65f45067f79024cf5dcee8)
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