Commit 5b34436035fc862b5e8d0d2c3eab74ba36f1a7f4

Authored by Thierry Reding
Committed by Tom Warren
1 parent 8b19dff579

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,