From f70575805708cabdedea7498aaa3f710fde4d920 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 31 Jan 2024 03:29:01 +0000 Subject: [PATCH] add lvds1024*800 --- kernel/scripts/dtc/libfdt/fdt_ro.c | 284 +++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 185 insertions(+), 99 deletions(-) diff --git a/kernel/scripts/dtc/libfdt/fdt_ro.c b/kernel/scripts/dtc/libfdt/fdt_ro.c index dfb3236..91cc6fe 100644 --- a/kernel/scripts/dtc/libfdt/fdt_ro.c +++ b/kernel/scripts/dtc/libfdt/fdt_ro.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -76,60 +31,171 @@ return 0; } +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) +{ + int32_t totalsize; + uint32_t absoffset; + size_t len; + int err; + const char *s, *n; + + if (can_assume(VALID_INPUT)) { + s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + + if (lenp) + *lenp = strlen(s); + return s; + } + totalsize = fdt_ro_probe_(fdt); + err = totalsize; + if (totalsize < 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); + if (absoffset >= (unsigned)totalsize) + goto fail; + len = totalsize - absoffset; + + if (fdt_magic(fdt) == FDT_MAGIC) { + if (stroffset < 0) + goto fail; + if (can_assume(LATEST) || fdt_version(fdt) >= 17) { + if ((unsigned)stroffset >= fdt_size_dt_strings(fdt)) + goto fail; + if ((fdt_size_dt_strings(fdt) - stroffset) < len) + len = fdt_size_dt_strings(fdt) - stroffset; + } + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + unsigned int sw_stroffset = -stroffset; + + if ((stroffset >= 0) || + (sw_stroffset > fdt_size_dt_strings(fdt))) + goto fail; + if (sw_stroffset < len) + len = sw_stroffset; + } else { + err = -FDT_ERR_INTERNAL; + goto fail; + } + + s = (const char *)fdt + absoffset; + n = memchr(s, '\0', len); + if (!n) { + /* missing terminating NULL */ + err = -FDT_ERR_TRUNCATED; + goto fail; + } + + if (lenp) + *lenp = n - s; + return s; + +fail: + if (lenp) + *lenp = err; + return NULL; +} + const char *fdt_string(const void *fdt, int stroffset) { - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + return fdt_get_string(fdt, stroffset, NULL); } static int fdt_string_eq_(const void *fdt, int stroffset, const char *s, int len) { - const char *p = fdt_string(fdt, stroffset); + int slen; + const char *p = fdt_get_string(fdt, stroffset, &slen); - return (strlen(p) == len) && (memcmp(p, s, len) == 0); + return p && (slen == len) && (memcmp(p, s, len) == 0); } -uint32_t fdt_get_max_phandle(const void *fdt) +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) { - uint32_t max_phandle = 0; - int offset; + uint32_t max = 0; + int offset = -1; - for (offset = fdt_next_node(fdt, -1, NULL);; - offset = fdt_next_node(fdt, offset, NULL)) { - uint32_t phandle; + while (true) { + uint32_t value; - if (offset == -FDT_ERR_NOTFOUND) - return max_phandle; + offset = fdt_next_node(fdt, offset, NULL); + if (offset < 0) { + if (offset == -FDT_ERR_NOTFOUND) + break; - if (offset < 0) - return (uint32_t)-1; + return offset; + } - phandle = fdt_get_phandle(fdt, offset); - if (phandle == (uint32_t)-1) - continue; + value = fdt_get_phandle(fdt, offset); - if (phandle > max_phandle) - max_phandle = phandle; + if (value > max) + max = value; } + + if (phandle) + *phandle = max; return 0; } +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max; + int err; + + err = fdt_find_max_phandle(fdt, &max); + if (err < 0) + return err; + + if (max == FDT_MAX_PHANDLE) + return -FDT_ERR_NOPHANDLES; + + if (phandle) + *phandle = max + 1; + + return 0; +} + +static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) +{ + unsigned int offset = n * sizeof(struct fdt_reserve_entry); + unsigned int absoffset = fdt_off_mem_rsvmap(fdt) + offset; + + if (!can_assume(VALID_INPUT)) { + if (absoffset < fdt_off_mem_rsvmap(fdt)) + return NULL; + if (absoffset > fdt_totalsize(fdt) - + sizeof(struct fdt_reserve_entry)) + return NULL; + } + return fdt_mem_rsv_(fdt, n); +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { - FDT_CHECK_HEADER(fdt); - *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); - *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); + const struct fdt_reserve_entry *re; + + FDT_RO_PROBE(fdt); + re = fdt_mem_rsv(fdt, n); + if (!can_assume(VALID_INPUT) && !re) + return -FDT_ERR_BADOFFSET; + + *address = fdt64_ld(&re->address); + *size = fdt64_ld(&re->size); return 0; } int fdt_num_mem_rsv(const void *fdt) { - int i = 0; + int i; + const struct fdt_reserve_entry *re; - while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) - i++; - return i; + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { + if (fdt64_ld(&re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; } static int nextprop_(const void *fdt, int offset) @@ -161,7 +227,7 @@ { int depth; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); for (depth = 0; (offset >= 0) && (depth >= 0); @@ -187,7 +253,7 @@ const char *p = path; int offset = 0; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* see if we have an alias */ if (*path != '/') { @@ -237,13 +303,13 @@ const char *nameptr; int err; - if (((err = fdt_check_header(fdt)) != 0) + if (((err = fdt_ro_probe_(fdt)) < 0) || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) goto fail; nameptr = nh->name; - if (fdt_version(fdt) < 0x10) { + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { /* * For old FDT versions, match the naming conventions of V16: * give only the leaf name (after all /). The actual tree @@ -294,7 +360,8 @@ int err; const struct fdt_property *prop; - if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { + if (!can_assume(VALID_INPUT) && + (err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; @@ -303,7 +370,7 @@ prop = fdt_offset_ptr_(fdt, offset); if (lenp) - *lenp = fdt32_to_cpu(prop->len); + *lenp = fdt32_ld(&prop->len); return prop; } @@ -315,7 +382,7 @@ /* Prior to version 16, properties may need realignment * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_version(fdt) < 0x10) { + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { if (lenp) *lenp = -FDT_ERR_BADVERSION; return NULL; @@ -336,11 +403,12 @@ (offset = fdt_next_property_offset(fdt, offset))) { const struct fdt_property *prop; - if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) { + prop = fdt_get_property_by_offset_(fdt, offset, lenp); + if (!can_assume(LIBFDT_FLAWLESS) && !prop) { offset = -FDT_ERR_INTERNAL; break; } - if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff), name, namelen)) { if (poffset) *poffset = offset; @@ -361,7 +429,7 @@ { /* Prior to version 16, properties may need realignment * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_version(fdt) < 0x10) { + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) { if (lenp) *lenp = -FDT_ERR_BADVERSION; return NULL; @@ -392,8 +460,8 @@ return NULL; /* Handle realignment */ - if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 && - fdt32_to_cpu(prop->len) >= 8) + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && + (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) return prop->data + 4; return prop->data; } @@ -406,12 +474,27 @@ prop = fdt_get_property_by_offset_(fdt, offset, lenp); if (!prop) return NULL; - if (namep) - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (namep) { + const char *name; + int namelen; + + if (!can_assume(VALID_INPUT)) { + name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), + &namelen); + if (!name) { + if (lenp) + *lenp = namelen; + return NULL; + } + *namep = name; + } else { + *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); + } + } /* Handle realignment */ - if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 && - fdt32_to_cpu(prop->len) >= 8) + if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 && + (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) return prop->data + 4; return prop->data; } @@ -436,7 +519,7 @@ return 0; } - return fdt32_to_cpu(*php); + return fdt32_ld(php); } const char *fdt_get_alias_namelen(const void *fdt, @@ -462,7 +545,7 @@ int offset, depth, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (buflen < 2) return -FDT_ERR_NOSPACE; @@ -514,7 +597,7 @@ int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; @@ -536,10 +619,12 @@ } } - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (!can_assume(VALID_INPUT)) { + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + } return offset; /* error from fdt_next_node() */ } @@ -551,7 +636,8 @@ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); if (err) - return (err < 0) ? err : -FDT_ERR_INTERNAL; + return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err : + -FDT_ERR_INTERNAL; return nodedepth; } @@ -573,7 +659,7 @@ const void *val; int len; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't @@ -596,10 +682,10 @@ { int offset; - if ((phandle == 0) || (phandle == -1)) + if ((phandle == 0) || (phandle == ~0U)) return -FDT_ERR_BADPHANDLE; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we * potentially scan each property of a node in @@ -752,7 +838,7 @@ { int offset, err; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if -- Gitblit v1.6.2