1*630b011fSAntonio Nino Diaz /* 2*630b011fSAntonio Nino Diaz * libfdt - Flat Device Tree manipulation 3*630b011fSAntonio Nino Diaz * Copyright (C) 2006 David Gibson, IBM Corporation. 4*630b011fSAntonio Nino Diaz * 5*630b011fSAntonio Nino Diaz * libfdt is dual licensed: you can use it either under the terms of 6*630b011fSAntonio Nino Diaz * the GPL, or the BSD license, at your option. 7*630b011fSAntonio Nino Diaz * 8*630b011fSAntonio Nino Diaz * a) This library is free software; you can redistribute it and/or 9*630b011fSAntonio Nino Diaz * modify it under the terms of the GNU General Public License as 10*630b011fSAntonio Nino Diaz * published by the Free Software Foundation; either version 2 of the 11*630b011fSAntonio Nino Diaz * License, or (at your option) any later version. 12*630b011fSAntonio Nino Diaz * 13*630b011fSAntonio Nino Diaz * This library is distributed in the hope that it will be useful, 14*630b011fSAntonio Nino Diaz * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*630b011fSAntonio Nino Diaz * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*630b011fSAntonio Nino Diaz * GNU General Public License for more details. 17*630b011fSAntonio Nino Diaz * 18*630b011fSAntonio Nino Diaz * You should have received a copy of the GNU General Public 19*630b011fSAntonio Nino Diaz * License along with this library; if not, write to the Free 20*630b011fSAntonio Nino Diaz * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 21*630b011fSAntonio Nino Diaz * MA 02110-1301 USA 22*630b011fSAntonio Nino Diaz * 23*630b011fSAntonio Nino Diaz * Alternatively, 24*630b011fSAntonio Nino Diaz * 25*630b011fSAntonio Nino Diaz * b) Redistribution and use in source and binary forms, with or 26*630b011fSAntonio Nino Diaz * without modification, are permitted provided that the following 27*630b011fSAntonio Nino Diaz * conditions are met: 28*630b011fSAntonio Nino Diaz * 29*630b011fSAntonio Nino Diaz * 1. Redistributions of source code must retain the above 30*630b011fSAntonio Nino Diaz * copyright notice, this list of conditions and the following 31*630b011fSAntonio Nino Diaz * disclaimer. 32*630b011fSAntonio Nino Diaz * 2. Redistributions in binary form must reproduce the above 33*630b011fSAntonio Nino Diaz * copyright notice, this list of conditions and the following 34*630b011fSAntonio Nino Diaz * disclaimer in the documentation and/or other materials 35*630b011fSAntonio Nino Diaz * provided with the distribution. 36*630b011fSAntonio Nino Diaz * 37*630b011fSAntonio Nino Diaz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 38*630b011fSAntonio Nino Diaz * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 39*630b011fSAntonio Nino Diaz * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 40*630b011fSAntonio Nino Diaz * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 41*630b011fSAntonio Nino Diaz * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 42*630b011fSAntonio Nino Diaz * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43*630b011fSAntonio Nino Diaz * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44*630b011fSAntonio Nino Diaz * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45*630b011fSAntonio Nino Diaz * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46*630b011fSAntonio Nino Diaz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 47*630b011fSAntonio Nino Diaz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 48*630b011fSAntonio Nino Diaz * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 49*630b011fSAntonio Nino Diaz * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50*630b011fSAntonio Nino Diaz */ 51*630b011fSAntonio Nino Diaz #include "libfdt_env.h" 52*630b011fSAntonio Nino Diaz 53*630b011fSAntonio Nino Diaz #include <fdt.h> 54*630b011fSAntonio Nino Diaz #include <libfdt.h> 55*630b011fSAntonio Nino Diaz 56*630b011fSAntonio Nino Diaz #include "libfdt_internal.h" 57*630b011fSAntonio Nino Diaz 58*630b011fSAntonio Nino Diaz /* 59*630b011fSAntonio Nino Diaz * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks 60*630b011fSAntonio Nino Diaz * that the given buffer contains what appears to be a flattened 61*630b011fSAntonio Nino Diaz * device tree with sane information in its header. 62*630b011fSAntonio Nino Diaz */ 63*630b011fSAntonio Nino Diaz int fdt_ro_probe_(const void *fdt) 64*630b011fSAntonio Nino Diaz { 65*630b011fSAntonio Nino Diaz if (fdt_magic(fdt) == FDT_MAGIC) { 66*630b011fSAntonio Nino Diaz /* Complete tree */ 67*630b011fSAntonio Nino Diaz if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) 68*630b011fSAntonio Nino Diaz return -FDT_ERR_BADVERSION; 69*630b011fSAntonio Nino Diaz if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) 70*630b011fSAntonio Nino Diaz return -FDT_ERR_BADVERSION; 71*630b011fSAntonio Nino Diaz } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { 72*630b011fSAntonio Nino Diaz /* Unfinished sequential-write blob */ 73*630b011fSAntonio Nino Diaz if (fdt_size_dt_struct(fdt) == 0) 74*630b011fSAntonio Nino Diaz return -FDT_ERR_BADSTATE; 75*630b011fSAntonio Nino Diaz } else { 76*630b011fSAntonio Nino Diaz return -FDT_ERR_BADMAGIC; 77*630b011fSAntonio Nino Diaz } 78*630b011fSAntonio Nino Diaz 79*630b011fSAntonio Nino Diaz return 0; 80*630b011fSAntonio Nino Diaz } 81*630b011fSAntonio Nino Diaz 82*630b011fSAntonio Nino Diaz static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off) 83*630b011fSAntonio Nino Diaz { 84*630b011fSAntonio Nino Diaz return (off >= hdrsize) && (off <= totalsize); 85*630b011fSAntonio Nino Diaz } 86*630b011fSAntonio Nino Diaz 87*630b011fSAntonio Nino Diaz static int check_block_(uint32_t hdrsize, uint32_t totalsize, 88*630b011fSAntonio Nino Diaz uint32_t base, uint32_t size) 89*630b011fSAntonio Nino Diaz { 90*630b011fSAntonio Nino Diaz if (!check_off_(hdrsize, totalsize, base)) 91*630b011fSAntonio Nino Diaz return 0; /* block start out of bounds */ 92*630b011fSAntonio Nino Diaz if ((base + size) < base) 93*630b011fSAntonio Nino Diaz return 0; /* overflow */ 94*630b011fSAntonio Nino Diaz if (!check_off_(hdrsize, totalsize, base + size)) 95*630b011fSAntonio Nino Diaz return 0; /* block end out of bounds */ 96*630b011fSAntonio Nino Diaz return 1; 97*630b011fSAntonio Nino Diaz } 98*630b011fSAntonio Nino Diaz 99*630b011fSAntonio Nino Diaz size_t fdt_header_size_(uint32_t version) 100*630b011fSAntonio Nino Diaz { 101*630b011fSAntonio Nino Diaz if (version <= 1) 102*630b011fSAntonio Nino Diaz return FDT_V1_SIZE; 103*630b011fSAntonio Nino Diaz else if (version <= 2) 104*630b011fSAntonio Nino Diaz return FDT_V2_SIZE; 105*630b011fSAntonio Nino Diaz else if (version <= 3) 106*630b011fSAntonio Nino Diaz return FDT_V3_SIZE; 107*630b011fSAntonio Nino Diaz else if (version <= 16) 108*630b011fSAntonio Nino Diaz return FDT_V16_SIZE; 109*630b011fSAntonio Nino Diaz else 110*630b011fSAntonio Nino Diaz return FDT_V17_SIZE; 111*630b011fSAntonio Nino Diaz } 112*630b011fSAntonio Nino Diaz 113*630b011fSAntonio Nino Diaz int fdt_check_header(const void *fdt) 114*630b011fSAntonio Nino Diaz { 115*630b011fSAntonio Nino Diaz size_t hdrsize; 116*630b011fSAntonio Nino Diaz 117*630b011fSAntonio Nino Diaz if (fdt_magic(fdt) != FDT_MAGIC) 118*630b011fSAntonio Nino Diaz return -FDT_ERR_BADMAGIC; 119*630b011fSAntonio Nino Diaz hdrsize = fdt_header_size(fdt); 120*630b011fSAntonio Nino Diaz if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) 121*630b011fSAntonio Nino Diaz || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)) 122*630b011fSAntonio Nino Diaz return -FDT_ERR_BADVERSION; 123*630b011fSAntonio Nino Diaz if (fdt_version(fdt) < fdt_last_comp_version(fdt)) 124*630b011fSAntonio Nino Diaz return -FDT_ERR_BADVERSION; 125*630b011fSAntonio Nino Diaz 126*630b011fSAntonio Nino Diaz if ((fdt_totalsize(fdt) < hdrsize) 127*630b011fSAntonio Nino Diaz || (fdt_totalsize(fdt) > INT_MAX)) 128*630b011fSAntonio Nino Diaz return -FDT_ERR_TRUNCATED; 129*630b011fSAntonio Nino Diaz 130*630b011fSAntonio Nino Diaz /* Bounds check memrsv block */ 131*630b011fSAntonio Nino Diaz if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt))) 132*630b011fSAntonio Nino Diaz return -FDT_ERR_TRUNCATED; 133*630b011fSAntonio Nino Diaz 134*630b011fSAntonio Nino Diaz /* Bounds check structure block */ 135*630b011fSAntonio Nino Diaz if (fdt_version(fdt) < 17) { 136*630b011fSAntonio Nino Diaz if (!check_off_(hdrsize, fdt_totalsize(fdt), 137*630b011fSAntonio Nino Diaz fdt_off_dt_struct(fdt))) 138*630b011fSAntonio Nino Diaz return -FDT_ERR_TRUNCATED; 139*630b011fSAntonio Nino Diaz } else { 140*630b011fSAntonio Nino Diaz if (!check_block_(hdrsize, fdt_totalsize(fdt), 141*630b011fSAntonio Nino Diaz fdt_off_dt_struct(fdt), 142*630b011fSAntonio Nino Diaz fdt_size_dt_struct(fdt))) 143*630b011fSAntonio Nino Diaz return -FDT_ERR_TRUNCATED; 144*630b011fSAntonio Nino Diaz } 145*630b011fSAntonio Nino Diaz 146*630b011fSAntonio Nino Diaz /* Bounds check strings block */ 147*630b011fSAntonio Nino Diaz if (!check_block_(hdrsize, fdt_totalsize(fdt), 148*630b011fSAntonio Nino Diaz fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt))) 149*630b011fSAntonio Nino Diaz return -FDT_ERR_TRUNCATED; 150*630b011fSAntonio Nino Diaz 151*630b011fSAntonio Nino Diaz return 0; 152*630b011fSAntonio Nino Diaz } 153*630b011fSAntonio Nino Diaz 154*630b011fSAntonio Nino Diaz const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) 155*630b011fSAntonio Nino Diaz { 156*630b011fSAntonio Nino Diaz unsigned absoffset = offset + fdt_off_dt_struct(fdt); 157*630b011fSAntonio Nino Diaz 158*630b011fSAntonio Nino Diaz if ((absoffset < offset) 159*630b011fSAntonio Nino Diaz || ((absoffset + len) < absoffset) 160*630b011fSAntonio Nino Diaz || (absoffset + len) > fdt_totalsize(fdt)) 161*630b011fSAntonio Nino Diaz return NULL; 162*630b011fSAntonio Nino Diaz 163*630b011fSAntonio Nino Diaz if (fdt_version(fdt) >= 0x11) 164*630b011fSAntonio Nino Diaz if (((offset + len) < offset) 165*630b011fSAntonio Nino Diaz || ((offset + len) > fdt_size_dt_struct(fdt))) 166*630b011fSAntonio Nino Diaz return NULL; 167*630b011fSAntonio Nino Diaz 168*630b011fSAntonio Nino Diaz return fdt_offset_ptr_(fdt, offset); 169*630b011fSAntonio Nino Diaz } 170*630b011fSAntonio Nino Diaz 171*630b011fSAntonio Nino Diaz uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) 172*630b011fSAntonio Nino Diaz { 173*630b011fSAntonio Nino Diaz const fdt32_t *tagp, *lenp; 174*630b011fSAntonio Nino Diaz uint32_t tag; 175*630b011fSAntonio Nino Diaz int offset = startoffset; 176*630b011fSAntonio Nino Diaz const char *p; 177*630b011fSAntonio Nino Diaz 178*630b011fSAntonio Nino Diaz *nextoffset = -FDT_ERR_TRUNCATED; 179*630b011fSAntonio Nino Diaz tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); 180*630b011fSAntonio Nino Diaz if (!tagp) 181*630b011fSAntonio Nino Diaz return FDT_END; /* premature end */ 182*630b011fSAntonio Nino Diaz tag = fdt32_to_cpu(*tagp); 183*630b011fSAntonio Nino Diaz offset += FDT_TAGSIZE; 184*630b011fSAntonio Nino Diaz 185*630b011fSAntonio Nino Diaz *nextoffset = -FDT_ERR_BADSTRUCTURE; 186*630b011fSAntonio Nino Diaz switch (tag) { 187*630b011fSAntonio Nino Diaz case FDT_BEGIN_NODE: 188*630b011fSAntonio Nino Diaz /* skip name */ 189*630b011fSAntonio Nino Diaz do { 190*630b011fSAntonio Nino Diaz p = fdt_offset_ptr(fdt, offset++, 1); 191*630b011fSAntonio Nino Diaz } while (p && (*p != '\0')); 192*630b011fSAntonio Nino Diaz if (!p) 193*630b011fSAntonio Nino Diaz return FDT_END; /* premature end */ 194*630b011fSAntonio Nino Diaz break; 195*630b011fSAntonio Nino Diaz 196*630b011fSAntonio Nino Diaz case FDT_PROP: 197*630b011fSAntonio Nino Diaz lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); 198*630b011fSAntonio Nino Diaz if (!lenp) 199*630b011fSAntonio Nino Diaz return FDT_END; /* premature end */ 200*630b011fSAntonio Nino Diaz /* skip-name offset, length and value */ 201*630b011fSAntonio Nino Diaz offset += sizeof(struct fdt_property) - FDT_TAGSIZE 202*630b011fSAntonio Nino Diaz + fdt32_to_cpu(*lenp); 203*630b011fSAntonio Nino Diaz if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && 204*630b011fSAntonio Nino Diaz ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) 205*630b011fSAntonio Nino Diaz offset += 4; 206*630b011fSAntonio Nino Diaz break; 207*630b011fSAntonio Nino Diaz 208*630b011fSAntonio Nino Diaz case FDT_END: 209*630b011fSAntonio Nino Diaz case FDT_END_NODE: 210*630b011fSAntonio Nino Diaz case FDT_NOP: 211*630b011fSAntonio Nino Diaz break; 212*630b011fSAntonio Nino Diaz 213*630b011fSAntonio Nino Diaz default: 214*630b011fSAntonio Nino Diaz return FDT_END; 215*630b011fSAntonio Nino Diaz } 216*630b011fSAntonio Nino Diaz 217*630b011fSAntonio Nino Diaz if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) 218*630b011fSAntonio Nino Diaz return FDT_END; /* premature end */ 219*630b011fSAntonio Nino Diaz 220*630b011fSAntonio Nino Diaz *nextoffset = FDT_TAGALIGN(offset); 221*630b011fSAntonio Nino Diaz return tag; 222*630b011fSAntonio Nino Diaz } 223*630b011fSAntonio Nino Diaz 224*630b011fSAntonio Nino Diaz int fdt_check_node_offset_(const void *fdt, int offset) 225*630b011fSAntonio Nino Diaz { 226*630b011fSAntonio Nino Diaz if ((offset < 0) || (offset % FDT_TAGSIZE) 227*630b011fSAntonio Nino Diaz || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) 228*630b011fSAntonio Nino Diaz return -FDT_ERR_BADOFFSET; 229*630b011fSAntonio Nino Diaz 230*630b011fSAntonio Nino Diaz return offset; 231*630b011fSAntonio Nino Diaz } 232*630b011fSAntonio Nino Diaz 233*630b011fSAntonio Nino Diaz int fdt_check_prop_offset_(const void *fdt, int offset) 234*630b011fSAntonio Nino Diaz { 235*630b011fSAntonio Nino Diaz if ((offset < 0) || (offset % FDT_TAGSIZE) 236*630b011fSAntonio Nino Diaz || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) 237*630b011fSAntonio Nino Diaz return -FDT_ERR_BADOFFSET; 238*630b011fSAntonio Nino Diaz 239*630b011fSAntonio Nino Diaz return offset; 240*630b011fSAntonio Nino Diaz } 241*630b011fSAntonio Nino Diaz 242*630b011fSAntonio Nino Diaz int fdt_next_node(const void *fdt, int offset, int *depth) 243*630b011fSAntonio Nino Diaz { 244*630b011fSAntonio Nino Diaz int nextoffset = 0; 245*630b011fSAntonio Nino Diaz uint32_t tag; 246*630b011fSAntonio Nino Diaz 247*630b011fSAntonio Nino Diaz if (offset >= 0) 248*630b011fSAntonio Nino Diaz if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0) 249*630b011fSAntonio Nino Diaz return nextoffset; 250*630b011fSAntonio Nino Diaz 251*630b011fSAntonio Nino Diaz do { 252*630b011fSAntonio Nino Diaz offset = nextoffset; 253*630b011fSAntonio Nino Diaz tag = fdt_next_tag(fdt, offset, &nextoffset); 254*630b011fSAntonio Nino Diaz 255*630b011fSAntonio Nino Diaz switch (tag) { 256*630b011fSAntonio Nino Diaz case FDT_PROP: 257*630b011fSAntonio Nino Diaz case FDT_NOP: 258*630b011fSAntonio Nino Diaz break; 259*630b011fSAntonio Nino Diaz 260*630b011fSAntonio Nino Diaz case FDT_BEGIN_NODE: 261*630b011fSAntonio Nino Diaz if (depth) 262*630b011fSAntonio Nino Diaz (*depth)++; 263*630b011fSAntonio Nino Diaz break; 264*630b011fSAntonio Nino Diaz 265*630b011fSAntonio Nino Diaz case FDT_END_NODE: 266*630b011fSAntonio Nino Diaz if (depth && ((--(*depth)) < 0)) 267*630b011fSAntonio Nino Diaz return nextoffset; 268*630b011fSAntonio Nino Diaz break; 269*630b011fSAntonio Nino Diaz 270*630b011fSAntonio Nino Diaz case FDT_END: 271*630b011fSAntonio Nino Diaz if ((nextoffset >= 0) 272*630b011fSAntonio Nino Diaz || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) 273*630b011fSAntonio Nino Diaz return -FDT_ERR_NOTFOUND; 274*630b011fSAntonio Nino Diaz else 275*630b011fSAntonio Nino Diaz return nextoffset; 276*630b011fSAntonio Nino Diaz } 277*630b011fSAntonio Nino Diaz } while (tag != FDT_BEGIN_NODE); 278*630b011fSAntonio Nino Diaz 279*630b011fSAntonio Nino Diaz return offset; 280*630b011fSAntonio Nino Diaz } 281*630b011fSAntonio Nino Diaz 282*630b011fSAntonio Nino Diaz int fdt_first_subnode(const void *fdt, int offset) 283*630b011fSAntonio Nino Diaz { 284*630b011fSAntonio Nino Diaz int depth = 0; 285*630b011fSAntonio Nino Diaz 286*630b011fSAntonio Nino Diaz offset = fdt_next_node(fdt, offset, &depth); 287*630b011fSAntonio Nino Diaz if (offset < 0 || depth != 1) 288*630b011fSAntonio Nino Diaz return -FDT_ERR_NOTFOUND; 289*630b011fSAntonio Nino Diaz 290*630b011fSAntonio Nino Diaz return offset; 291*630b011fSAntonio Nino Diaz } 292*630b011fSAntonio Nino Diaz 293*630b011fSAntonio Nino Diaz int fdt_next_subnode(const void *fdt, int offset) 294*630b011fSAntonio Nino Diaz { 295*630b011fSAntonio Nino Diaz int depth = 1; 296*630b011fSAntonio Nino Diaz 297*630b011fSAntonio Nino Diaz /* 298*630b011fSAntonio Nino Diaz * With respect to the parent, the depth of the next subnode will be 299*630b011fSAntonio Nino Diaz * the same as the last. 300*630b011fSAntonio Nino Diaz */ 301*630b011fSAntonio Nino Diaz do { 302*630b011fSAntonio Nino Diaz offset = fdt_next_node(fdt, offset, &depth); 303*630b011fSAntonio Nino Diaz if (offset < 0 || depth < 1) 304*630b011fSAntonio Nino Diaz return -FDT_ERR_NOTFOUND; 305*630b011fSAntonio Nino Diaz } while (depth > 1); 306*630b011fSAntonio Nino Diaz 307*630b011fSAntonio Nino Diaz return offset; 308*630b011fSAntonio Nino Diaz } 309*630b011fSAntonio Nino Diaz 310*630b011fSAntonio Nino Diaz const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) 311*630b011fSAntonio Nino Diaz { 312*630b011fSAntonio Nino Diaz int len = strlen(s) + 1; 313*630b011fSAntonio Nino Diaz const char *last = strtab + tabsize - len; 314*630b011fSAntonio Nino Diaz const char *p; 315*630b011fSAntonio Nino Diaz 316*630b011fSAntonio Nino Diaz for (p = strtab; p <= last; p++) 317*630b011fSAntonio Nino Diaz if (memcmp(p, s, len) == 0) 318*630b011fSAntonio Nino Diaz return p; 319*630b011fSAntonio Nino Diaz return NULL; 320*630b011fSAntonio Nino Diaz } 321*630b011fSAntonio Nino Diaz 322*630b011fSAntonio Nino Diaz int fdt_move(const void *fdt, void *buf, int bufsize) 323*630b011fSAntonio Nino Diaz { 324*630b011fSAntonio Nino Diaz FDT_RO_PROBE(fdt); 325*630b011fSAntonio Nino Diaz 326*630b011fSAntonio Nino Diaz if (fdt_totalsize(fdt) > bufsize) 327*630b011fSAntonio Nino Diaz return -FDT_ERR_NOSPACE; 328*630b011fSAntonio Nino Diaz 329*630b011fSAntonio Nino Diaz memmove(buf, fdt, fdt_totalsize(fdt)); 330*630b011fSAntonio Nino Diaz return 0; 331*630b011fSAntonio Nino Diaz } 332