Commit 5b34436035fc862b5e8d0d2c3eab74ba36f1a7f4
fdt: Fix fdtdec_get_addr_size() for 64-bit
Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Tom Warren <twarren@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
Showing 1 changed file with 36 additions and 20 deletions Side-by-side Diff
... | ... | @@ -88,29 +88,45 @@ |
88 | 88 | fdt_addr_t fdtdec_get_addr_size(const void *blob, int node, |
89 | 89 | const char *prop_name, fdt_size_t *sizep) |
90 | 90 | { |
91 | - const fdt_addr_t *cell; | |
92 | - int len; | |
91 | + const fdt32_t *ptr, *end; | |
92 | + int parent, na, ns, len; | |
93 | + fdt_addr_t addr; | |
93 | 94 | |
94 | 95 | debug("%s: %s: ", __func__, prop_name); |
95 | - cell = fdt_getprop(blob, node, prop_name, &len); | |
96 | - if (cell && ((!sizep && len == sizeof(fdt_addr_t)) || | |
97 | - len == sizeof(fdt_addr_t) * 2)) { | |
98 | - fdt_addr_t addr = fdt_addr_to_cpu(*cell); | |
99 | - if (sizep) { | |
100 | - const fdt_size_t *size; | |
101 | 96 | |
102 | - size = (fdt_size_t *)((char *)cell + | |
103 | - sizeof(fdt_addr_t)); | |
104 | - *sizep = fdt_size_to_cpu(*size); | |
105 | - debug("addr=%08lx, size=%llx\n", | |
106 | - (ulong)addr, (u64)*sizep); | |
107 | - } else { | |
108 | - debug("%08lx\n", (ulong)addr); | |
109 | - } | |
110 | - return addr; | |
97 | + parent = fdt_parent_offset(blob, node); | |
98 | + if (parent < 0) { | |
99 | + debug("(no parent found)\n"); | |
100 | + return FDT_ADDR_T_NONE; | |
111 | 101 | } |
112 | - debug("(not found)\n"); | |
113 | - return FDT_ADDR_T_NONE; | |
102 | + | |
103 | + na = fdt_address_cells(blob, parent); | |
104 | + ns = fdt_size_cells(blob, parent); | |
105 | + | |
106 | + ptr = fdt_getprop(blob, node, prop_name, &len); | |
107 | + if (!ptr) { | |
108 | + debug("(not found)\n"); | |
109 | + return FDT_ADDR_T_NONE; | |
110 | + } | |
111 | + | |
112 | + end = ptr + len / sizeof(*ptr); | |
113 | + | |
114 | + if (ptr + na + ns > end) { | |
115 | + debug("(not enough data: expected %d bytes, got %d bytes)\n", | |
116 | + (na + ns) * 4, len); | |
117 | + return FDT_ADDR_T_NONE; | |
118 | + } | |
119 | + | |
120 | + addr = fdtdec_get_number(ptr, na); | |
121 | + | |
122 | + if (sizep) { | |
123 | + *sizep = fdtdec_get_number(ptr + na, ns); | |
124 | + debug("addr=%pa, size=%pa\n", &addr, sizep); | |
125 | + } else { | |
126 | + debug("%pa\n", &addr); | |
127 | + } | |
128 | + | |
129 | + return addr; | |
114 | 130 | } |
115 | 131 | |
116 | 132 | fdt_addr_t fdtdec_get_addr(const void *blob, int node, |
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe
-
mentioned in commit 236efe