Simon Glass | a5e1a58 | 2019-10-27 09:47:42 -0600 | [diff] [blame] | 1 | /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 2 | #ifndef LIBFDT_INTERNAL_H |
| 3 | #define LIBFDT_INTERNAL_H |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 4 | /* |
| 5 | * libfdt - Flat Device Tree manipulation |
| 6 | * Copyright (C) 2006 David Gibson, IBM Corporation. |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 7 | */ |
| 8 | #include <fdt.h> |
| 9 | |
| 10 | #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) |
| 11 | #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) |
| 12 | |
Simon Glass | a5e1a58 | 2019-10-27 09:47:42 -0600 | [diff] [blame] | 13 | int fdt_ro_probe_(const void *fdt); |
| 14 | #define FDT_RO_PROBE(fdt) \ |
| 15 | { \ |
| 16 | int totalsize_; \ |
| 17 | if (fdt_chk_basic()) { \ |
| 18 | totalsize_ = fdt_ro_probe_(fdt); \ |
| 19 | if (totalsize_ < 0) \ |
| 20 | return totalsize_; \ |
| 21 | } \ |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 22 | } |
| 23 | |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 24 | int fdt_check_node_offset_(const void *fdt, int offset); |
| 25 | int fdt_check_prop_offset_(const void *fdt, int offset); |
| 26 | const char *fdt_find_string_(const char *strtab, int tabsize, const char *s); |
| 27 | int fdt_node_end_offset_(void *fdt, int nodeoffset); |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 28 | |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 29 | static inline const void *fdt_offset_ptr_(const void *fdt, int offset) |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 30 | { |
| 31 | return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; |
| 32 | } |
| 33 | |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 34 | static inline void *fdt_offset_ptr_w_(void *fdt, int offset) |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 35 | { |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 36 | return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset); |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 37 | } |
| 38 | |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 39 | static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n) |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 40 | { |
| 41 | const struct fdt_reserve_entry *rsv_table = |
| 42 | (const struct fdt_reserve_entry *) |
| 43 | ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); |
| 44 | |
| 45 | return rsv_table + n; |
| 46 | } |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 47 | static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 48 | { |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 49 | return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n); |
Tom Rini | bd39173 | 2017-09-23 12:52:44 -0400 | [diff] [blame] | 50 | } |
| 51 | |
| 52 | #define FDT_SW_MAGIC (~FDT_MAGIC) |
| 53 | |
Simon Glass | a5e1a58 | 2019-10-27 09:47:42 -0600 | [diff] [blame] | 54 | /**********************************************************************/ |
| 55 | /* Checking controls */ |
| 56 | /**********************************************************************/ |
| 57 | |
| 58 | #ifndef FDT_ASSUME_MASK |
| 59 | #define FDT_ASSUME_MASK 0 |
| 60 | #endif |
| 61 | |
| 62 | /* |
| 63 | * Defines assumptions which can be enabled. Each of these can be enabled |
| 64 | * individually. For maximum saftey, don't enable any assumptions! |
| 65 | * |
| 66 | * For minimal code size and no safety, use FDT_ASSUME_PERFECT at your own risk. |
| 67 | * You should have another method of validating the device tree, such as a |
| 68 | * signature or hash check before using libfdt. |
| 69 | * |
| 70 | * For situations where security is not a concern it may be safe to enable |
| 71 | * FDT_ASSUME_FRIENDLY. |
| 72 | */ |
| 73 | enum { |
| 74 | /* |
| 75 | * This does essentially no checks. Only the latest device-tree |
| 76 | * version is correctly handled. Incosistencies or errors in the device |
| 77 | * tree may cause undefined behaviour or crashes. |
| 78 | * |
| 79 | * If an error occurs when modifying the tree it may leave the tree in |
| 80 | * an intermediate (but valid) state. As an example, adding a property |
| 81 | * where there is insufficient space may result in the property name |
| 82 | * being added to the string table even though the property itself is |
| 83 | * not added to the struct section. |
| 84 | * |
| 85 | * Only use this if you have a fully validated device tree with |
| 86 | * the latest supported version and wish to minimise code size. |
| 87 | */ |
| 88 | FDT_ASSUME_PERFECT = 0xff, |
| 89 | |
| 90 | /* |
| 91 | * This assumes that the device tree is sane. i.e. header metadata |
| 92 | * and basic hierarchy are correct. |
| 93 | * |
| 94 | * These checks will be sufficient if you have a valid device tree with |
| 95 | * no internal inconsistencies. With this assumption, libfdt will |
| 96 | * generally not return -FDT_ERR_INTERNAL, -FDT_ERR_BADLAYOUT, etc. |
| 97 | */ |
| 98 | FDT_ASSUME_SANE = 1 << 0, |
| 99 | |
| 100 | /* |
| 101 | * This disables checks for device-tree version and removes all code |
| 102 | * which handles older versions. |
| 103 | * |
| 104 | * Only enable this if you know you have a device tree with the latest |
| 105 | * version. |
| 106 | */ |
| 107 | FDT_ASSUME_LATEST = 1 << 1, |
| 108 | |
| 109 | /* |
| 110 | * This disables any extensive checking of parameters and the device |
| 111 | * tree, making various assumptions about correctness. Normal device |
| 112 | * trees produced by libfdt and the compiler should be handled safely. |
| 113 | * Malicious device trees and complete garbage may cause libfdt to |
| 114 | * behave badly or crash. |
| 115 | */ |
| 116 | FDT_ASSUME_FRIENDLY = 1 << 2, |
| 117 | }; |
| 118 | |
| 119 | /** fdt_chk_basic() - see if basic checking of params and DT data is enabled */ |
| 120 | static inline bool fdt_chk_basic(void) |
| 121 | { |
| 122 | return !(FDT_ASSUME_MASK & FDT_ASSUME_SANE); |
| 123 | } |
| 124 | |
| 125 | /** fdt_chk_version() - see if we need to handle old versions of the DT */ |
| 126 | static inline bool fdt_chk_version(void) |
| 127 | { |
| 128 | return !(FDT_ASSUME_MASK & FDT_ASSUME_LATEST); |
| 129 | } |
| 130 | |
| 131 | /** fdt_chk_extra() - see if extra checking is enabled */ |
| 132 | static inline bool fdt_chk_extra(void) |
| 133 | { |
| 134 | return !(FDT_ASSUME_MASK & FDT_ASSUME_FRIENDLY); |
| 135 | } |
| 136 | |
Rob Herring | cd5f70d | 2018-05-19 14:13:53 +0200 | [diff] [blame] | 137 | #endif /* LIBFDT_INTERNAL_H */ |