]> Git Repo - J-u-boot.git/blame - scripts/dtc/pylibfdt/libfdt.i_shipped
libfdt: Update to latest pylibfdt implementation
[J-u-boot.git] / scripts / dtc / pylibfdt / libfdt.i_shipped
CommitLineData
4549e789 1/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */
cf2064d7
SG
2/*
3 * pylibfdt - Flat Device Tree manipulation in Python
4 * Copyright (C) 2017 Google, Inc.
5 * Written by Simon Glass <[email protected]>
cf2064d7
SG
6 */
7
8%module libfdt
9
c79d18c4
SG
10%include <stdint.i>
11
cf2064d7
SG
12%{
13#define SWIG_FILE_WITH_INIT
14#include "libfdt.h"
3def0cf2
SG
15
16/*
17 * We rename this function here to avoid problems with swig, since we also have
18 * a struct called fdt_property. That struct causes swig to create a class in
19 * libfdt.py called fdt_property(), which confuses things.
20 */
50c59522
SG
21static int fdt_property_stub(void *fdt, const char *name, const char *val,
22 int len)
3def0cf2
SG
23{
24 return fdt_property(fdt, name, val, len);
25}
26
cf2064d7
SG
27%}
28
29%pythoncode %{
30
31import struct
32
33# Error codes, corresponding to FDT_ERR_... in libfdt.h
34(NOTFOUND,
35 EXISTS,
36 NOSPACE,
37 BADOFFSET,
38 BADPATH,
39 BADPHANDLE,
40 BADSTATE,
41 TRUNCATED,
42 BADMAGIC,
43 BADVERSION,
44 BADSTRUCTURE,
45 BADLAYOUT,
46 INTERNAL,
47 BADNCELLS,
48 BADVALUE,
49 BADOVERLAY,
50 NOPHANDLES) = QUIET_ALL = range(1, 18)
51# QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions
52# altogether. All # functions passed this value will return an error instead
53# of raising an exception.
54
55# Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors,
56# instead of raising an exception.
57QUIET_NOTFOUND = (NOTFOUND,)
50c59522 58QUIET_NOSPACE = (NOSPACE,)
cf2064d7
SG
59
60
61class FdtException(Exception):
62 """An exception caused by an error such as one of the codes above"""
63 def __init__(self, err):
64 self.err = err
65
66 def __str__(self):
67 return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err))
68
69def strerror(fdt_err):
70 """Get the string for an error number
71
72 Args:
73 fdt_err: Error number (-ve)
74
75 Returns:
76 String containing the associated error
77 """
78 return fdt_strerror(fdt_err)
79
80def check_err(val, quiet=()):
81 """Raise an error if the return value is -ve
82
83 This is used to check for errors returned by libfdt C functions.
84
85 Args:
86 val: Return value from a libfdt function
87 quiet: Errors to ignore (empty to raise on all errors)
88
89 Returns:
90 val if val >= 0
91
92 Raises
93 FdtException if val < 0
94 """
95 if val < 0:
96 if -val not in quiet:
97 raise FdtException(val)
98 return val
99
100def check_err_null(val, quiet=()):
101 """Raise an error if the return value is NULL
102
103 This is used to check for a NULL return value from certain libfdt C
104 functions
105
106 Args:
107 val: Return value from a libfdt function
108 quiet: Errors to ignore (empty to raise on all errors)
109
110 Returns:
111 val if val is a list, None if not
112
113 Raises
114 FdtException if val indicates an error was reported and the error
115 is not in @quiet.
116 """
117 # Normally a list is returned which contains the data and its length.
118 # If we get just an integer error code, it means the function failed.
119 if not isinstance(val, list):
120 if -val not in quiet:
121 raise FdtException(val)
122 return val
123
50c59522
SG
124class FdtRo(object):
125 """Class for a read-only device-tree
3def0cf2 126
50c59522
SG
127 This is a base class used by FdtRw (read-write access) and FdtSw
128 (sequential-write access). It implements read-only access to the
129 device tree.
cf2064d7 130
50c59522 131 Here are the three classes and when you should use them:
cf2064d7 132
50c59522
SG
133 FdtRo - read-only access to an existing FDT
134 FdtRw - read-write access to an existing FDT (most common case)
135 FdtSw - for creating a new FDT, as well as allowing read-only access
cf2064d7
SG
136 """
137 def __init__(self, data):
138 self._fdt = bytearray(data)
139 check_err(fdt_check_header(self._fdt));
140
3def0cf2
SG
141 def as_bytearray(self):
142 """Get the device tree contents as a bytearray
143
144 This can be passed directly to libfdt functions that access a
145 const void * for the device tree.
146
147 Returns:
148 bytearray containing the device tree
149 """
150 return bytearray(self._fdt)
151
152 def next_node(self, nodeoffset, depth, quiet=()):
153 """Find the next subnode
154
155 Args:
156 nodeoffset: Node offset of previous node
50c59522
SG
157 depth: The depth of the node at nodeoffset. This is used to
158 calculate the depth of the returned node
3def0cf2
SG
159 quiet: Errors to ignore (empty to raise on all errors)
160
161 Returns:
50c59522
SG
162 Typle:
163 Offset of the next node, if any, else a -ve error
164 Depth of the returned node, if any, else undefined
3def0cf2
SG
165
166 Raises:
167 FdtException if no more nodes found or other error occurs
168 """
169 return check_err(fdt_next_node(self._fdt, nodeoffset, depth), quiet)
170
171 def first_subnode(self, nodeoffset, quiet=()):
172 """Find the first subnode of a parent node
173
174 Args:
175 nodeoffset: Node offset of parent node
176 quiet: Errors to ignore (empty to raise on all errors)
177
178 Returns:
179 The offset of the first subnode, if any
180
181 Raises:
182 FdtException if no subnodes found or other error occurs
183 """
184 return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet)
185
186 def next_subnode(self, nodeoffset, quiet=()):
187 """Find the next subnode
188
189 Args:
190 nodeoffset: Node offset of previous subnode
191 quiet: Errors to ignore (empty to raise on all errors)
192
193 Returns:
194 The offset of the next subnode, if any
195
196 Raises:
197 FdtException if no more subnodes found or other error occurs
198 """
199 return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet)
200
201 def magic(self):
202 """Return the magic word from the header
203
204 Returns:
205 Magic word
206 """
50c59522 207 return fdt_magic(self._fdt)
3def0cf2
SG
208
209 def totalsize(self):
210 """Return the total size of the device tree
211
212 Returns:
213 Total tree size in bytes
214 """
50c59522 215 return fdt_totalsize(self._fdt)
3def0cf2
SG
216
217 def off_dt_struct(self):
218 """Return the start of the device-tree struct area
219
220 Returns:
221 Start offset of struct area
222 """
50c59522 223 return fdt_off_dt_struct(self._fdt)
3def0cf2
SG
224
225 def off_dt_strings(self):
226 """Return the start of the device-tree string area
227
228 Returns:
229 Start offset of string area
230 """
50c59522 231 return fdt_off_dt_strings(self._fdt)
3def0cf2
SG
232
233 def off_mem_rsvmap(self):
234 """Return the start of the memory reserve map
235
236 Returns:
237 Start offset of memory reserve map
238 """
50c59522 239 return fdt_off_mem_rsvmap(self._fdt)
3def0cf2
SG
240
241 def version(self):
242 """Return the version of the device tree
243
244 Returns:
245 Version number of the device tree
246 """
50c59522 247 return fdt_version(self._fdt)
3def0cf2
SG
248
249 def last_comp_version(self):
250 """Return the last compatible version of the device tree
251
252 Returns:
253 Last compatible version number of the device tree
254 """
50c59522 255 return fdt_last_comp_version(self._fdt)
3def0cf2
SG
256
257 def boot_cpuid_phys(self):
258 """Return the physical boot CPU ID
259
260 Returns:
261 Physical boot CPU ID
262 """
50c59522 263 return fdt_boot_cpuid_phys(self._fdt)
3def0cf2
SG
264
265 def size_dt_strings(self):
266 """Return the start of the device-tree string area
267
268 Returns:
269 Start offset of string area
270 """
50c59522 271 return fdt_size_dt_strings(self._fdt)
3def0cf2
SG
272
273 def size_dt_struct(self):
274 """Return the start of the device-tree struct area
275
276 Returns:
277 Start offset of struct area
278 """
50c59522 279 return fdt_size_dt_struct(self._fdt)
3def0cf2
SG
280
281 def num_mem_rsv(self, quiet=()):
282 """Return the number of memory reserve-map records
283
284 Returns:
285 Number of memory reserve-map records
286 """
287 return check_err(fdt_num_mem_rsv(self._fdt), quiet)
288
289 def get_mem_rsv(self, index, quiet=()):
290 """Return the indexed memory reserve-map record
291
292 Args:
293 index: Record to return (0=first)
294
295 Returns:
296 Number of memory reserve-map records
297 """
298 return check_err(fdt_get_mem_rsv(self._fdt, index), quiet)
299
93c94b88
SG
300 def subnode_offset(self, parentoffset, name, quiet=()):
301 """Get the offset of a named subnode
302
303 Args:
304 parentoffset: Offset of the parent node to check
305 name: Name of the required subnode, e.g. 'subnode@1'
306 quiet: Errors to ignore (empty to raise on all errors)
307
308 Returns:
309 The node offset of the found node, if any
310
311 Raises
312 FdtException if there is no node with that name, or other error
313 """
314 return check_err(fdt_subnode_offset(self._fdt, parentoffset, name),
315 quiet)
316
cf2064d7
SG
317 def path_offset(self, path, quiet=()):
318 """Get the offset for a given path
319
320 Args:
321 path: Path to the required node, e.g. '/node@3/subnode@1'
322 quiet: Errors to ignore (empty to raise on all errors)
323
324 Returns:
325 Node offset
326
327 Raises
328 FdtException if the path is not valid or not found
329 """
330 return check_err(fdt_path_offset(self._fdt, path), quiet)
331
3def0cf2
SG
332 def get_name(self, nodeoffset):
333 """Get the name of a node
334
335 Args:
336 nodeoffset: Offset of node to check
337
338 Returns:
339 Node name
340
341 Raises:
342 FdtException on error (e.g. nodeoffset is invalid)
343 """
344 return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0]
345
cf2064d7
SG
346 def first_property_offset(self, nodeoffset, quiet=()):
347 """Get the offset of the first property in a node offset
348
349 Args:
350 nodeoffset: Offset to the node to check
351 quiet: Errors to ignore (empty to raise on all errors)
352
353 Returns:
354 Offset of the first property
355
356 Raises
357 FdtException if the associated node has no properties, or some
358 other error occurred
359 """
360 return check_err(fdt_first_property_offset(self._fdt, nodeoffset),
361 quiet)
362
363 def next_property_offset(self, prop_offset, quiet=()):
364 """Get the next property in a node
365
366 Args:
367 prop_offset: Offset of the previous property
368 quiet: Errors to ignore (empty to raise on all errors)
369
370 Returns:
371 Offset of the next property
372
373 Raises:
374 FdtException if the associated node has no more properties, or
375 some other error occurred
376 """
377 return check_err(fdt_next_property_offset(self._fdt, prop_offset),
378 quiet)
379
cf2064d7
SG
380 def get_property_by_offset(self, prop_offset, quiet=()):
381 """Obtains a property that can be examined
382
383 Args:
384 prop_offset: Offset of property (e.g. from first_property_offset())
385 quiet: Errors to ignore (empty to raise on all errors)
386
387 Returns:
388 Property object, or None if not found
389
390 Raises:
391 FdtException on error (e.g. invalid prop_offset or device
392 tree format)
393 """
394 pdata = check_err_null(
395 fdt_get_property_by_offset(self._fdt, prop_offset), quiet)
396 if isinstance(pdata, (int)):
397 return pdata
398 return Property(pdata[0], pdata[1])
399
50c59522
SG
400 def getprop(self, nodeoffset, prop_name, quiet=()):
401 """Get a property from a node
c640ed0c
SG
402
403 Args:
50c59522 404 nodeoffset: Node offset containing property to get
c640ed0c
SG
405 prop_name: Name of property to get
406 quiet: Errors to ignore (empty to raise on all errors)
407
408 Returns:
50c59522
SG
409 Value of property as a Property object (which can be used as a
410 bytearray/string), or -ve error number. On failure, returns an
411 integer error
c640ed0c
SG
412
413 Raises:
50c59522 414 FdtError if any error occurs (e.g. the property is not found)
c640ed0c 415 """
50c59522
SG
416 pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
417 quiet)
c640ed0c
SG
418 if isinstance(pdata, (int)):
419 return pdata
50c59522
SG
420 return Property(prop_name, bytearray(pdata[0]))
421
422 def get_phandle(self, nodeoffset):
423 """Get the phandle of a node
424
425 Args:
426 nodeoffset: Node offset to check
427
428 Returns:
429 phandle of node, or 0 if the node has no phandle or another error
430 occurs
431 """
432 return fdt_get_phandle(self._fdt, nodeoffset)
433
434 def parent_offset(self, nodeoffset, quiet=()):
435 """Get the offset of a node's parent
436
437 Args:
438 nodeoffset: Node offset to check
439 quiet: Errors to ignore (empty to raise on all errors)
440
441 Returns:
442 The offset of the parent node, if any
443
444 Raises:
445 FdtException if no parent found or other error occurs
446 """
447 return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet)
448
449 def node_offset_by_phandle(self, phandle, quiet=()):
450 """Get the offset of a node with the given phandle
451
452 Args:
453 phandle: Phandle to search for
454 quiet: Errors to ignore (empty to raise on all errors)
455
456 Returns:
457 The offset of node with that phandle, if any
458
459 Raises:
460 FdtException if no node found or other error occurs
461 """
462 return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet)
463
464
465class Fdt(FdtRo):
466 """Device tree class, supporting all operations
467
468 The Fdt object is created is created from a device tree binary file,
469 e.g. with something like:
470
471 fdt = Fdt(open("filename.dtb").read())
472
473 Operations can then be performed using the methods in this class. Each
474 method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...).
475
476 All methods raise an FdtException if an error occurs. To avoid this
477 behaviour a 'quiet' parameter is provided for some functions. This
478 defaults to empty, but you can pass a list of errors that you expect.
479 If one of these errors occurs, the function will return an error number
480 (e.g. -NOTFOUND).
481 """
482 def __init__(self, data):
483 FdtRo.__init__(self, data)
c640ed0c 484
3def0cf2
SG
485 @staticmethod
486 def create_empty_tree(size, quiet=()):
487 """Create an empty device tree ready for use
cf2064d7
SG
488
489 Args:
3def0cf2 490 size: Size of device tree in bytes
cf2064d7
SG
491
492 Returns:
3def0cf2 493 Fdt object containing the device tree
cf2064d7 494 """
3def0cf2
SG
495 data = bytearray(size)
496 err = check_err(fdt_create_empty_tree(data, size), quiet)
497 if err:
498 return err
499 return Fdt(data)
cf2064d7 500
50c59522 501 def resize(self, size, quiet=()):
3def0cf2 502 """Move the device tree into a larger or smaller space
cf2064d7 503
3def0cf2
SG
504 This creates a new device tree of size @size and moves the existing
505 device tree contents over to that. It can be used to create more space
50c59522
SG
506 in a device tree. Note that the Fdt object remains the same, but it
507 now has a new bytearray holding the contents.
cf2064d7 508
3def0cf2
SG
509 Args:
510 size: Required new size of device tree in bytes
cf2064d7 511 """
3def0cf2 512 fdt = bytearray(size)
3def0cf2
SG
513 err = check_err(fdt_open_into(self._fdt, fdt, size), quiet)
514 if err:
515 return err
516 self._fdt = fdt
cf2064d7
SG
517
518 def pack(self, quiet=()):
519 """Pack the device tree to remove unused space
520
521 This adjusts the tree in place.
522
523 Args:
524 quiet: Errors to ignore (empty to raise on all errors)
525
50c59522
SG
526 Returns:
527 Error code, or 0 if OK
528
cf2064d7
SG
529 Raises:
530 FdtException if any error occurs
531 """
a1e00855
SG
532 err = check_err(fdt_pack(self._fdt), quiet)
533 if err:
534 return err
535 del self._fdt[self.totalsize():]
536 return err
cf2064d7 537
3def0cf2
SG
538 def set_name(self, nodeoffset, name, quiet=()):
539 """Set the name of a node
540
541 Args:
542 nodeoffset: Node offset of node to update
50c59522 543 name: New node name (string without \0)
3def0cf2
SG
544
545 Returns:
546 Error code, or 0 if OK
547
548 Raises:
549 FdtException if no parent found or other error occurs
550 """
50c59522
SG
551 if chr(0) in name:
552 raise ValueError('Property contains embedded nul characters')
3def0cf2
SG
553 return check_err(fdt_set_name(self._fdt, nodeoffset, name), quiet)
554
555 def setprop(self, nodeoffset, prop_name, val, quiet=()):
556 """Set the value of a property
557
558 Args:
559 nodeoffset: Node offset containing the property to create/update
560 prop_name: Name of property
561 val: Value to write (string or bytearray)
562 quiet: Errors to ignore (empty to raise on all errors)
563
564 Returns:
565 Error code, or 0 if OK
566
567 Raises:
568 FdtException if no parent found or other error occurs
569 """
570 return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val,
571 len(val)), quiet)
572
573 def setprop_u32(self, nodeoffset, prop_name, val, quiet=()):
574 """Set the value of a property
575
576 Args:
577 nodeoffset: Node offset containing the property to create/update
578 prop_name: Name of property
579 val: Value to write (integer)
580 quiet: Errors to ignore (empty to raise on all errors)
581
582 Returns:
583 Error code, or 0 if OK
584
585 Raises:
586 FdtException if no parent found or other error occurs
587 """
588 return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val),
589 quiet)
590
591 def setprop_u64(self, nodeoffset, prop_name, val, quiet=()):
592 """Set the value of a property
593
594 Args:
595 nodeoffset: Node offset containing the property to create/update
596 prop_name: Name of property
597 val: Value to write (integer)
598 quiet: Errors to ignore (empty to raise on all errors)
599
600 Returns:
601 Error code, or 0 if OK
602
603 Raises:
604 FdtException if no parent found or other error occurs
605 """
606 return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val),
607 quiet)
608
609 def setprop_str(self, nodeoffset, prop_name, val, quiet=()):
610 """Set the string value of a property
611
612 The property is set to the string, with a nul terminator added
613
614 Args:
615 nodeoffset: Node offset containing the property to create/update
616 prop_name: Name of property
50c59522
SG
617 val: Value to write (string without nul terminator). Unicode is
618 supposed by encoding to UTF-8
3def0cf2
SG
619 quiet: Errors to ignore (empty to raise on all errors)
620
621 Returns:
622 Error code, or 0 if OK
623
624 Raises:
625 FdtException if no parent found or other error occurs
626 """
50c59522 627 val = val.encode('utf-8') + '\0'
3def0cf2
SG
628 return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name,
629 val, len(val)), quiet)
630
631 def delprop(self, nodeoffset, prop_name):
632 """Delete a property from a node
633
634 Args:
635 nodeoffset: Node offset containing property to delete
636 prop_name: Name of property to delete
637
638 Raises:
639 FdtError if the property does not exist, or another error occurs
640 """
641 return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name))
642
c640ed0c
SG
643 def del_node(self, nodeoffset):
644 """Delete a node
645
646 Args:
647 nodeoffset: Node offset containing property to delete
648
649 Raises:
650 FdtError if the node does not exist, or another error occurs
651 """
652 return check_err(fdt_del_node(self._fdt, nodeoffset))
653
3def0cf2
SG
654
655class Property(bytearray):
cf2064d7
SG
656 """Holds a device tree property name and value.
657
658 This holds a copy of a property taken from the device tree. It does not
659 reference the device tree, so if anything changes in the device tree,
660 a Property object will remain valid.
661
662 Properties:
663 name: Property name
3def0cf2 664 value: Property value as a bytearray
cf2064d7
SG
665 """
666 def __init__(self, name, value):
3def0cf2 667 bytearray.__init__(self, value)
cf2064d7 668 self.name = name
3def0cf2
SG
669
670 def as_cell(self, fmt):
671 return struct.unpack('>' + fmt, self)[0]
672
673 def as_uint32(self):
674 return self.as_cell('L')
675
676 def as_int32(self):
677 return self.as_cell('l')
678
679 def as_uint64(self):
680 return self.as_cell('Q')
681
682 def as_int64(self):
683 return self.as_cell('q')
684
685 def as_str(self):
50c59522
SG
686 """Unicode is supported by decoding from UTF-8"""
687 if self[-1] != 0:
688 raise ValueError('Property lacks nul termination')
689 if 0 in self[:-1]:
690 raise ValueError('Property contains embedded nul characters')
691 return self[:-1].decode('utf-8')
3def0cf2
SG
692
693
50c59522 694class FdtSw(FdtRo):
3def0cf2
SG
695 """Software interface to create a device tree from scratch
696
697 The methods in this class work by adding to an existing 'partial' device
698 tree buffer of a fixed size created by instantiating this class. When the
50c59522 699 tree is complete, call as_fdt() to obtain a device tree ready to be used.
3def0cf2
SG
700
701 Similarly with nodes, a new node is started with begin_node() and finished
702 with end_node().
703
704 The context manager functions can be used to make this a bit easier:
705
706 # First create the device tree with a node and property:
50c59522
SG
707 sw = FdtSw()
708 with sw.add_node('node'):
709 sw.property_u32('reg', 2)
710 fdt = sw.as_fdt()
3def0cf2
SG
711
712 # Now we can use it as a real device tree
713 fdt.setprop_u32(0, 'reg', 3)
50c59522
SG
714
715 The size hint provides a starting size for the space to be used by the
716 device tree. This will be increased automatically as needed as new items
717 are added to the tree.
3def0cf2 718 """
50c59522 719 INC_SIZE = 1024 # Expand size by this much when out of space
3def0cf2 720
50c59522
SG
721 def __init__(self, size_hint=None):
722 """Create a new FdtSw object
3def0cf2 723
50c59522
SG
724 Args:
725 size_hint: A hint as to the initial size to use
726
727 Raises:
728 ValueError if size_hint is negative
3def0cf2 729
50c59522
SG
730 Returns:
731 FdtSw object on success, else integer error code (if not raising)
732 """
733 if not size_hint:
734 size_hint = self.INC_SIZE
735 fdtsw = bytearray(size_hint)
736 err = check_err(fdt_create(fdtsw, size_hint))
737 if err:
738 return err
739 self._fdt = fdtsw
740
741 def as_fdt(self):
3def0cf2
SG
742 """Convert a FdtSw into an Fdt so it can be accessed as normal
743
50c59522
SG
744 Creates a new Fdt object from the work-in-progress device tree. This
745 does not call fdt_finish() on the current object, so it is possible to
746 add more nodes/properties and call as_fdt() again to get an updated
747 tree.
3def0cf2
SG
748
749 Returns:
750 Fdt object allowing access to the newly created device tree
751 """
50c59522
SG
752 fdtsw = bytearray(self._fdt)
753 check_err(fdt_finish(fdtsw))
754 return Fdt(fdtsw)
3def0cf2 755
50c59522
SG
756 def check_space(self, val):
757 """Check if we need to add more space to the FDT
758
759 This should be called with the error code from an operation. If this is
760 -NOSPACE then the FDT will be expanded to have more space, and True will
761 be returned, indicating that the operation needs to be tried again.
762
763 Args:
764 val: Return value from the operation that was attempted
765
766 Returns:
767 True if the operation must be retried, else False
768 """
769 if check_err(val, QUIET_NOSPACE) < 0:
770 self.resize(len(self._fdt) + self.INC_SIZE)
771 return True
772 return False
773
774 def resize(self, size):
3def0cf2
SG
775 """Resize the buffer to accommodate a larger tree
776
777 Args:
778 size: New size of tree
3def0cf2
SG
779
780 Raises:
50c59522 781 FdtException on any error
3def0cf2
SG
782 """
783 fdt = bytearray(size)
50c59522
SG
784 err = check_err(fdt_resize(self._fdt, fdt, size))
785 self._fdt = fdt
3def0cf2 786
50c59522 787 def add_reservemap_entry(self, addr, size):
3def0cf2
SG
788 """Add a new memory reserve map entry
789
790 Once finished adding, you must call finish_reservemap().
791
792 Args:
793 addr: 64-bit start address
794 size: 64-bit size
3def0cf2
SG
795
796 Raises:
50c59522 797 FdtException on any error
3def0cf2 798 """
50c59522
SG
799 while self.check_space(fdt_add_reservemap_entry(self._fdt, addr,
800 size)):
801 pass
3def0cf2 802
50c59522 803 def finish_reservemap(self):
3def0cf2
SG
804 """Indicate that there are no more reserve map entries to add
805
3def0cf2 806 Raises:
50c59522 807 FdtException on any error
3def0cf2 808 """
50c59522
SG
809 while self.check_space(fdt_finish_reservemap(self._fdt)):
810 pass
3def0cf2 811
50c59522 812 def begin_node(self, name):
3def0cf2
SG
813 """Begin a new node
814
815 Use this before adding properties to the node. Then call end_node() to
816 finish it. You can also use the context manager as shown in the FdtSw
817 class comment.
818
819 Args:
820 name: Name of node to begin
3def0cf2
SG
821
822 Raises:
50c59522 823 FdtException on any error
3def0cf2 824 """
50c59522
SG
825 while self.check_space(fdt_begin_node(self._fdt, name)):
826 pass
3def0cf2 827
50c59522 828 def property_string(self, name, string):
3def0cf2
SG
829 """Add a property with a string value
830
831 The string will be nul-terminated when written to the device tree
832
833 Args:
834 name: Name of property to add
835 string: String value of property
3def0cf2
SG
836
837 Raises:
50c59522 838 FdtException on any error
3def0cf2 839 """
50c59522
SG
840 while self.check_space(fdt_property_string(self._fdt, name, string)):
841 pass
3def0cf2 842
50c59522 843 def property_u32(self, name, val):
3def0cf2
SG
844 """Add a property with a 32-bit value
845
846 Write a single-cell value to the device tree
847
848 Args:
849 name: Name of property to add
850 val: Value of property
3def0cf2
SG
851
852 Raises:
50c59522 853 FdtException on any error
3def0cf2 854 """
50c59522
SG
855 while self.check_space(fdt_property_u32(self._fdt, name, val)):
856 pass
3def0cf2 857
50c59522 858 def property_u64(self, name, val):
3def0cf2
SG
859 """Add a property with a 64-bit value
860
861 Write a double-cell value to the device tree in big-endian format
862
863 Args:
864 name: Name of property to add
865 val: Value of property
3def0cf2
SG
866
867 Raises:
50c59522 868 FdtException on any error
3def0cf2 869 """
50c59522
SG
870 while self.check_space(fdt_property_u64(self._fdt, name, val)):
871 pass
3def0cf2 872
50c59522 873 def property_cell(self, name, val):
3def0cf2
SG
874 """Add a property with a single-cell value
875
876 Write a single-cell value to the device tree
877
878 Args:
879 name: Name of property to add
880 val: Value of property
881 quiet: Errors to ignore (empty to raise on all errors)
882
883 Raises:
50c59522 884 FdtException on any error
3def0cf2 885 """
50c59522
SG
886 while self.check_space(fdt_property_cell(self._fdt, name, val)):
887 pass
3def0cf2 888
50c59522 889 def property(self, name, val):
3def0cf2
SG
890 """Add a property
891
892 Write a new property with the given value to the device tree. The value
893 is taken as is and is not nul-terminated
894
895 Args:
896 name: Name of property to add
897 val: Value of property
898 quiet: Errors to ignore (empty to raise on all errors)
899
900 Raises:
50c59522 901 FdtException on any error
3def0cf2 902 """
50c59522
SG
903 while self.check_space(fdt_property_stub(self._fdt, name, val,
904 len(val))):
905 pass
3def0cf2 906
50c59522 907 def end_node(self):
3def0cf2
SG
908 """End a node
909
910 Use this after adding properties to a node to close it off. You can also
911 use the context manager as shown in the FdtSw class comment.
912
913 Args:
914 quiet: Errors to ignore (empty to raise on all errors)
915
916 Raises:
50c59522 917 FdtException on any error
3def0cf2 918 """
50c59522
SG
919 while self.check_space(fdt_end_node(self._fdt)):
920 pass
3def0cf2 921
50c59522 922 def add_node(self, name):
3def0cf2
SG
923 """Create a new context for adding a node
924
925 When used in a 'with' clause this starts a new node and finishes it
926 afterward.
927
928 Args:
929 name: Name of node to add
930 """
50c59522 931 return NodeAdder(self, name)
3def0cf2
SG
932
933
934class NodeAdder():
935 """Class to provide a node context
936
937 This allows you to add nodes in a more natural way:
938
50c59522 939 with fdtsw.add_node('name'):
3def0cf2
SG
940 fdtsw.property_string('test', 'value')
941
942 The node is automatically completed with a call to end_node() when the
943 context exits.
944 """
50c59522
SG
945 def __init__(self, fdtsw, name):
946 self._fdt = fdtsw
3def0cf2
SG
947 self._name = name
948
949 def __enter__(self):
50c59522 950 self._fdt.begin_node(self._name)
3def0cf2
SG
951
952 def __exit__(self, type, value, traceback):
50c59522 953 self._fdt.end_node()
cf2064d7
SG
954%}
955
956%rename(fdt_property) fdt_property_func;
957
50c59522
SG
958/*
959 * fdt32_t is a big-endian 32-bit value defined to uint32_t in libfdt_env.h
960 * so use the same type here.
961 */
962typedef uint32_t fdt32_t;
cf2064d7
SG
963
964%include "libfdt/fdt.h"
965
966%include "typemaps.i"
967
968/* Most functions don't change the device tree, so use a const void * */
969%typemap(in) (const void *)(const void *fdt) {
970 if (!PyByteArray_Check($input)) {
971 SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
972 "', argument " "$argnum"" of type '" "$type""'");
973 }
974 $1 = (void *)PyByteArray_AsString($input);
975 fdt = $1;
976 fdt = fdt; /* avoid unused variable warning */
977}
978
979/* Some functions do change the device tree, so use void * */
980%typemap(in) (void *)(const void *fdt) {
981 if (!PyByteArray_Check($input)) {
982 SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
983 "', argument " "$argnum"" of type '" "$type""'");
984 }
985 $1 = PyByteArray_AsString($input);
986 fdt = $1;
987 fdt = fdt; /* avoid unused variable warning */
988}
989
3def0cf2 990/* typemap used for fdt_get_property_by_offset() */
cf2064d7
SG
991%typemap(out) (struct fdt_property *) {
992 PyObject *buff;
993
994 if ($1) {
995 resultobj = PyString_FromString(
996 fdt_string(fdt1, fdt32_to_cpu($1->nameoff)));
997 buff = PyByteArray_FromStringAndSize(
998 (const char *)($1 + 1), fdt32_to_cpu($1->len));
999 resultobj = SWIG_Python_AppendOutput(resultobj, buff);
1000 }
1001}
1002
1003%apply int *OUTPUT { int *lenp };
1004
1005/* typemap used for fdt_getprop() */
1006%typemap(out) (const void *) {
1007 if (!$1)
1008 $result = Py_None;
1009 else
1010 $result = Py_BuildValue("s#", $1, *arg4);
1011}
1012
3def0cf2
SG
1013/* typemap used for fdt_setprop() */
1014%typemap(in) (const void *val) {
1015 $1 = PyString_AsString($input); /* char *str */
1016}
1017
1018/* typemap used for fdt_add_reservemap_entry() */
1019%typemap(in) uint64_t {
1020 $1 = PyLong_AsUnsignedLong($input);
1021}
1022
1023/* typemaps used for fdt_next_node() */
1024%typemap(in, numinputs=1) int *depth (int depth) {
1025 depth = (int) PyInt_AsLong($input);
1026 $1 = &depth;
1027}
1028
1029%typemap(argout) int *depth {
1030 PyObject *val = Py_BuildValue("i", *arg$argnum);
1031 resultobj = SWIG_Python_AppendOutput(resultobj, val);
1032}
1033
1034%apply int *depth { int *depth };
1035
1036/* typemaps for fdt_get_mem_rsv */
1037%typemap(in, numinputs=0) uint64_t * (uint64_t temp) {
1038 $1 = &temp;
1039}
1040
1041%typemap(argout) uint64_t * {
1042 PyObject *val = PyLong_FromUnsignedLong(*arg$argnum);
1043 if (!result) {
1044 if (PyTuple_GET_SIZE(resultobj) == 0)
1045 resultobj = val;
1046 else
1047 resultobj = SWIG_Python_AppendOutput(resultobj, val);
1048 }
1049}
1050
cf2064d7
SG
1051/* We have both struct fdt_property and a function fdt_property() */
1052%warnfilter(302) fdt_property;
1053
1054/* These are macros in the header so have to be redefined here */
50c59522
SG
1055uint32_t fdt_magic(const void *fdt);
1056uint32_t fdt_totalsize(const void *fdt);
1057uint32_t fdt_off_dt_struct(const void *fdt);
1058uint32_t fdt_off_dt_strings(const void *fdt);
1059uint32_t fdt_off_mem_rsvmap(const void *fdt);
1060uint32_t fdt_version(const void *fdt);
1061uint32_t fdt_last_comp_version(const void *fdt);
1062uint32_t fdt_boot_cpuid_phys(const void *fdt);
1063uint32_t fdt_size_dt_strings(const void *fdt);
1064uint32_t fdt_size_dt_struct(const void *fdt);
1065
3def0cf2
SG
1066int fdt_property_string(void *fdt, const char *name, const char *val);
1067int fdt_property_cell(void *fdt, const char *name, uint32_t val);
1068
1069/*
1070 * This function has a stub since the name fdt_property is used for both a
1071 * function and a struct, which confuses SWIG.
1072 */
50c59522 1073int fdt_property_stub(void *fdt, const char *name, const char *val, int len);
cf2064d7
SG
1074
1075%include <../libfdt/libfdt.h>
This page took 0.302513 seconds and 4 git commands to generate.