From bcbdab70a2863355aa1b9a39abdd973202abc818 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 16 Apr 2020 18:30:16 +0900 Subject: [PATCH 01/23] libfdt: migrate fdt_ro.c to a wrapper of scripts/dtc/libfdt/fdt_ro.c There is no essential difference between scripts/dtc/libfdt/fdt_ro.c and lib/libfdt/fdt_ro.c Migrate to a simple wrapper like the other files. Signed-off-by: Masahiro Yamada --- lib/libfdt/Makefile | 6 +- lib/libfdt/fdt_ro.c | 925 +----------------------------------------- tools/Makefile | 5 +- tools/libfdt/fdt_ro.c | 2 + 4 files changed, 6 insertions(+), 932 deletions(-) create mode 100644 tools/libfdt/fdt_ro.c diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile index 5d3ae4e2f1..878659f99e 100644 --- a/lib/libfdt/Makefile +++ b/lib/libfdt/Makefile @@ -3,9 +3,9 @@ # (C) Copyright 2000-2007 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# Use upstream code. obj-y += \ fdt.o \ + fdt_ro.o \ fdt_wip.o \ fdt_strerror.o \ fdt_sw.o \ @@ -15,10 +15,6 @@ obj-y += \ obj-$(CONFIG_OF_LIBFDT_OVERLAY) += fdt_overlay.o -# Locally modified for U-Boot. -# TODO: split out the local modifiction. -obj-y += fdt_ro.o - # U-Boot own file obj-y += fdt_region.o diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index be03aea9eb..7ede074537 100644 --- a/lib/libfdt/fdt_ro.c +++ b/lib/libfdt/fdt_ro.c @@ -1,925 +1,2 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2006 David Gibson, IBM Corporation. - */ #include - -#ifndef USE_HOSTCC -#include -#include -#else -#include "fdt_host.h" -#endif - -#include "libfdt_internal.h" - -static int fdt_nodename_eq_(const void *fdt, int offset, - const char *s, int len) -{ - int olen; - const char *p = fdt_get_name(fdt, offset, &olen); - - if (!p || (fdt_chk_extra() && olen < len)) - /* short match */ - return 0; - - if (memcmp(p, s, len) != 0) - return 0; - - if (p[len] == '\0') - return 1; - else if (!memchr(s, '@', len) && (p[len] == '@')) - return 1; - else - 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 (!fdt_chk_extra()) { - 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 >= totalsize) - goto fail; - len = totalsize - absoffset; - - if (fdt_magic(fdt) == FDT_MAGIC) { - if (stroffset < 0) - goto fail; - if (!fdt_chk_version() || fdt_version(fdt) >= 17) { - if (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) { - if ((stroffset >= 0) - || (stroffset < -fdt_size_dt_strings(fdt))) - goto fail; - if ((-stroffset) < len) - len = -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 fdt_get_string(fdt, stroffset, NULL); -} - -static int fdt_string_eq_(const void *fdt, int stroffset, - const char *s, int len) -{ - int slen; - const char *p = fdt_get_string(fdt, stroffset, &slen); - - return p && (slen == len) && (memcmp(p, s, len) == 0); -} - -int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) -{ - uint32_t max = 0; - int offset = -1; - - while (true) { - uint32_t value; - - offset = fdt_next_node(fdt, offset, NULL); - if (offset < 0) { - if (offset == -FDT_ERR_NOTFOUND) - break; - - return offset; - } - - value = fdt_get_phandle(fdt, offset); - - 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) -{ - int offset = n * sizeof(struct fdt_reserve_entry); - int absoffset = fdt_off_mem_rsvmap(fdt) + offset; - - if (fdt_chk_extra()) { - 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) -{ - const struct fdt_reserve_entry *re; - - FDT_RO_PROBE(fdt); - re = fdt_mem_rsv(fdt, n); - if (fdt_chk_extra() && !re) - return -FDT_ERR_BADOFFSET; - - *address = fdt64_to_cpu(re->address); - *size = fdt64_to_cpu(re->size); - return 0; -} - -int fdt_num_mem_rsv(const void *fdt) -{ - int i; - const struct fdt_reserve_entry *re; - - for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { - if (fdt64_to_cpu(re->size) == 0) - return i; - } - return -FDT_ERR_TRUNCATED; -} - -static int nextprop_(const void *fdt, int offset) -{ - uint32_t tag; - int nextoffset; - - do { - tag = fdt_next_tag(fdt, offset, &nextoffset); - - switch (tag) { - case FDT_END: - if (nextoffset >= 0) - return -FDT_ERR_BADSTRUCTURE; - else - return nextoffset; - - case FDT_PROP: - return offset; - } - offset = nextoffset; - } while (tag == FDT_NOP); - - return -FDT_ERR_NOTFOUND; -} - -int fdt_subnode_offset_namelen(const void *fdt, int offset, - const char *name, int namelen) -{ - int depth; - - FDT_RO_PROBE(fdt); - - for (depth = 0; - (offset >= 0) && (depth >= 0); - offset = fdt_next_node(fdt, offset, &depth)) - if ((depth == 1) - && fdt_nodename_eq_(fdt, offset, name, namelen)) - return offset; - - if (depth < 0) - return -FDT_ERR_NOTFOUND; - return offset; /* error */ -} - -int fdt_subnode_offset(const void *fdt, int parentoffset, - const char *name) -{ - return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); -} - -int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) -{ - const char *end = path + namelen; - const char *p = path; - int offset = 0; - - FDT_RO_PROBE(fdt); - - /* see if we have an alias */ - if (*path != '/') { - const char *q = memchr(path, '/', end - p); - - if (!q) - q = end; - - p = fdt_get_alias_namelen(fdt, p, q - p); - if (!p) - return -FDT_ERR_BADPATH; - offset = fdt_path_offset(fdt, p); - - p = q; - } - - while (p < end) { - const char *q; - - while (*p == '/') { - p++; - if (p == end) - return offset; - } - q = memchr(p, '/', end - p); - if (! q) - q = end; - - offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); - if (offset < 0) - return offset; - - p = q; - } - - return offset; -} - -int fdt_path_offset(const void *fdt, const char *path) -{ - return fdt_path_offset_namelen(fdt, path, strlen(path)); -} - -const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) -{ - const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); - const char *nameptr; - int err; - - if (fdt_chk_extra() && - (((err = fdt_ro_probe_(fdt)) < 0) - || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))) - goto fail; - - nameptr = nh->name; - - if (fdt_chk_version() && fdt_version(fdt) < 0x10) { - /* - * For old FDT versions, match the naming conventions of V16: - * give only the leaf name (after all /). The actual tree - * contents are loosely checked. - */ - const char *leaf; - leaf = strrchr(nameptr, '/'); - if (leaf == NULL) { - err = -FDT_ERR_BADSTRUCTURE; - goto fail; - } - nameptr = leaf+1; - } - - if (len) - *len = strlen(nameptr); - - return nameptr; - - fail: - if (len) - *len = err; - return NULL; -} - -int fdt_first_property_offset(const void *fdt, int nodeoffset) -{ - int offset; - - if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) - return offset; - - return nextprop_(fdt, offset); -} - -int fdt_next_property_offset(const void *fdt, int offset) -{ - if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) - return offset; - - return nextprop_(fdt, offset); -} - -static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, - int offset, - int *lenp) -{ - int err; - const struct fdt_property *prop; - - if (fdt_chk_basic() && (err = fdt_check_prop_offset_(fdt, offset)) < 0) { - if (lenp) - *lenp = err; - return NULL; - } - - prop = fdt_offset_ptr_(fdt, offset); - - if (lenp) - *lenp = fdt32_to_cpu(prop->len); - - return prop; -} - -const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - int offset, - int *lenp) -{ - /* Prior to version 16, properties may need realignment - * and this API does not work. fdt_getprop_*() will, however. */ - - if (fdt_chk_version() && fdt_version(fdt) < 0x10) { - if (lenp) - *lenp = -FDT_ERR_BADVERSION; - return NULL; - } - - return fdt_get_property_by_offset_(fdt, offset, lenp); -} - -static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, - int offset, - const char *name, - int namelen, - int *lenp, - int *poffset) -{ - for (offset = fdt_first_property_offset(fdt, offset); - (offset >= 0); - (offset = fdt_next_property_offset(fdt, offset))) { - const struct fdt_property *prop; - - prop = fdt_get_property_by_offset_(fdt, offset, lenp); - if (fdt_chk_extra() && !prop) { - offset = -FDT_ERR_INTERNAL; - break; - } - if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), - name, namelen)) { - if (poffset) - *poffset = offset; - return prop; - } - } - - if (lenp) - *lenp = offset; - return NULL; -} - - -const struct fdt_property *fdt_get_property_namelen(const void *fdt, - int offset, - const char *name, - int namelen, int *lenp) -{ - /* Prior to version 16, properties may need realignment - * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_chk_version() && fdt_version(fdt) < 0x10) { - if (lenp) - *lenp = -FDT_ERR_BADVERSION; - return NULL; - } - - return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp, - NULL); -} - - -const struct fdt_property *fdt_get_property(const void *fdt, - int nodeoffset, - const char *name, int *lenp) -{ - return fdt_get_property_namelen(fdt, nodeoffset, name, - strlen(name), lenp); -} - -const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - const char *name, int namelen, int *lenp) -{ - int poffset; - const struct fdt_property *prop; - - prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp, - &poffset); - if (!prop) - return NULL; - - /* Handle realignment */ - if (fdt_chk_version() && fdt_version(fdt) < 0x10 && - (poffset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8) - return prop->data + 4; - return prop->data; -} - -const void *fdt_getprop_by_offset(const void *fdt, int offset, - const char **namep, int *lenp) -{ - const struct fdt_property *prop; - - prop = fdt_get_property_by_offset_(fdt, offset, lenp); - if (!prop) - return NULL; - if (namep) { - const char *name; - int namelen; - - if (fdt_chk_extra()) { - name = fdt_get_string(fdt, fdt32_to_cpu(prop->nameoff), - &namelen); - if (!name) { - if (lenp) - *lenp = namelen; - return NULL; - } - *namep = name; - } else { - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - } - } - - /* Handle realignment */ - if (fdt_chk_version() && fdt_version(fdt) < 0x10 && - (offset + sizeof(*prop)) % 8 && fdt32_to_cpu(prop->len) >= 8) - return prop->data + 4; - return prop->data; -} - -const void *fdt_getprop(const void *fdt, int nodeoffset, - const char *name, int *lenp) -{ - return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); -} - -uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) -{ - const fdt32_t *php; - int len; - - /* FIXME: This is a bit sub-optimal, since we potentially scan - * over all the properties twice. */ - php = fdt_getprop(fdt, nodeoffset, "phandle", &len); - if (!php || (len != sizeof(*php))) { - php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); - if (!php || (len != sizeof(*php))) - return 0; - } - - return fdt32_to_cpu(*php); -} - -const char *fdt_get_alias_namelen(const void *fdt, - const char *name, int namelen) -{ - int aliasoffset; - - aliasoffset = fdt_path_offset(fdt, "/aliases"); - if (aliasoffset < 0) - return NULL; - - return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); -} - -const char *fdt_get_alias(const void *fdt, const char *name) -{ - return fdt_get_alias_namelen(fdt, name, strlen(name)); -} - -int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) -{ - int pdepth = 0, p = 0; - int offset, depth, namelen; - const char *name; - - FDT_RO_PROBE(fdt); - - if (buflen < 2) - return -FDT_ERR_NOSPACE; - - for (offset = 0, depth = 0; - (offset >= 0) && (offset <= nodeoffset); - offset = fdt_next_node(fdt, offset, &depth)) { - while (pdepth > depth) { - do { - p--; - } while (buf[p-1] != '/'); - pdepth--; - } - - if (pdepth >= depth) { - name = fdt_get_name(fdt, offset, &namelen); - if (!name) - return namelen; - if ((p + namelen + 1) <= buflen) { - memcpy(buf + p, name, namelen); - p += namelen; - buf[p++] = '/'; - pdepth++; - } - } - - if (offset == nodeoffset) { - if (pdepth < (depth + 1)) - return -FDT_ERR_NOSPACE; - - if (p > 1) /* special case so that root path is "/", not "" */ - p--; - buf[p] = '\0'; - return 0; - } - } - - 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() */ -} - -int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, - int supernodedepth, int *nodedepth) -{ - int offset, depth; - int supernodeoffset = -FDT_ERR_INTERNAL; - - FDT_RO_PROBE(fdt); - - if (supernodedepth < 0) - return -FDT_ERR_NOTFOUND; - - for (offset = 0, depth = 0; - (offset >= 0) && (offset <= nodeoffset); - offset = fdt_next_node(fdt, offset, &depth)) { - if (depth == supernodedepth) - supernodeoffset = offset; - - if (offset == nodeoffset) { - if (nodedepth) - *nodedepth = depth; - - if (supernodedepth > depth) - return -FDT_ERR_NOTFOUND; - else - return supernodeoffset; - } - } - - if (fdt_chk_extra()) { - 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() */ -} - -int fdt_node_depth(const void *fdt, int nodeoffset) -{ - int nodedepth; - int err; - - err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); - if (err) - return (!fdt_chk_extra() || err < 0) ? err : -FDT_ERR_INTERNAL; - return nodedepth; -} - -int fdt_parent_offset(const void *fdt, int nodeoffset) -{ - int nodedepth = fdt_node_depth(fdt, nodeoffset); - - if (nodedepth < 0) - return nodedepth; - return fdt_supernode_atdepth_offset(fdt, nodeoffset, - nodedepth - 1, NULL); -} - -int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, - const char *propname, - const void *propval, int proplen) -{ - int offset; - const void *val; - int len; - - 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 - * find what we want, we scan over them again making our way - * to the next node. Still it's the easiest to implement - * approach; performance can come later. */ - for (offset = fdt_next_node(fdt, startoffset, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - val = fdt_getprop(fdt, offset, propname, &len); - if (val && (len == proplen) - && (memcmp(val, propval, len) == 0)) - return offset; - } - - return offset; /* error from fdt_next_node() */ -} - -int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) -{ - int offset; - - if ((phandle == 0) || (phandle == -1)) - return -FDT_ERR_BADPHANDLE; - - FDT_RO_PROBE(fdt); - - /* FIXME: The algorithm here is pretty horrible: we - * potentially scan each property of a node in - * fdt_get_phandle(), then if that didn't find what - * we want, we scan over them again making our way to the next - * node. Still it's the easiest to implement approach; - * performance can come later. */ - for (offset = fdt_next_node(fdt, -1, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - if (fdt_get_phandle(fdt, offset) == phandle) - return offset; - } - - return offset; /* error from fdt_next_node() */ -} - -int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) -{ - int len = strlen(str); - const char *p; - - while (listlen >= len) { - if (memcmp(str, strlist, len+1) == 0) - return 1; - p = memchr(strlist, '\0', listlen); - if (!p) - return 0; /* malformed strlist.. */ - listlen -= (p-strlist) + 1; - strlist = p + 1; - } - return 0; -} - -int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property) -{ - const char *list, *end; - int length, count = 0; - - list = fdt_getprop(fdt, nodeoffset, property, &length); - if (!list) - return length; - - end = list + length; - - while (list < end) { - length = strnlen(list, end - list) + 1; - - /* Abort if the last string isn't properly NUL-terminated. */ - if (list + length > end) - return -FDT_ERR_BADVALUE; - - list += length; - count++; - } - - return count; -} - -int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, - const char *string) -{ - int length, len, idx = 0; - const char *list, *end; - - list = fdt_getprop(fdt, nodeoffset, property, &length); - if (!list) - return length; - - len = strlen(string) + 1; - end = list + length; - - while (list < end) { - length = strnlen(list, end - list) + 1; - - /* Abort if the last string isn't properly NUL-terminated. */ - if (list + length > end) - return -FDT_ERR_BADVALUE; - - if (length == len && memcmp(list, string, length) == 0) - return idx; - - list += length; - idx++; - } - - return -FDT_ERR_NOTFOUND; -} - -const char *fdt_stringlist_get(const void *fdt, int nodeoffset, - const char *property, int idx, - int *lenp) -{ - const char *list, *end; - int length; - - list = fdt_getprop(fdt, nodeoffset, property, &length); - if (!list) { - if (lenp) - *lenp = length; - - return NULL; - } - - end = list + length; - - while (list < end) { - length = strnlen(list, end - list) + 1; - - /* Abort if the last string isn't properly NUL-terminated. */ - if (list + length > end) { - if (lenp) - *lenp = -FDT_ERR_BADVALUE; - - return NULL; - } - - if (idx == 0) { - if (lenp) - *lenp = length - 1; - - return list; - } - - list += length; - idx--; - } - - if (lenp) - *lenp = -FDT_ERR_NOTFOUND; - - return NULL; -} - -int fdt_node_check_compatible(const void *fdt, int nodeoffset, - const char *compatible) -{ - const void *prop; - int len; - - prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); - if (!prop) - return len; - - return !fdt_stringlist_contains(prop, len, compatible); -} - -int fdt_node_offset_by_compatible(const void *fdt, int startoffset, - const char *compatible) -{ - int offset, err; - - 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 - * that didn't find what we want, we scan over them again - * making our way to the next node. Still it's the easiest to - * implement approach; performance can come later. */ - for (offset = fdt_next_node(fdt, startoffset, NULL); - offset >= 0; - offset = fdt_next_node(fdt, offset, NULL)) { - err = fdt_node_check_compatible(fdt, offset, compatible); - if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) - return err; - else if (err == 0) - return offset; - } - - return offset; /* error from fdt_next_node() */ -} - -#if !defined(CHECK_LEVEL) || CHECK_LEVEL > 0 -int fdt_check_full(const void *fdt, size_t bufsize) -{ - int err; - int num_memrsv; - int offset, nextoffset = 0; - uint32_t tag; - unsigned depth = 0; - const void *prop; - const char *propname; - - if (bufsize < FDT_V1_SIZE) - return -FDT_ERR_TRUNCATED; - err = fdt_check_header(fdt); - if (err != 0) - return err; - if (bufsize < fdt_totalsize(fdt)) - return -FDT_ERR_TRUNCATED; - - num_memrsv = fdt_num_mem_rsv(fdt); - if (num_memrsv < 0) - return num_memrsv; - - while (1) { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - - if (nextoffset < 0) - return nextoffset; - - switch (tag) { - case FDT_NOP: - break; - - case FDT_END: - if (depth != 0) - return -FDT_ERR_BADSTRUCTURE; - return 0; - - case FDT_BEGIN_NODE: - depth++; - if (depth > INT_MAX) - return -FDT_ERR_BADSTRUCTURE; - break; - - case FDT_END_NODE: - if (depth == 0) - return -FDT_ERR_BADSTRUCTURE; - depth--; - break; - - case FDT_PROP: - prop = fdt_getprop_by_offset(fdt, offset, &propname, - &err); - if (!prop) - return err; - break; - - default: - return -FDT_ERR_INTERNAL; - } - } -} -#endif +#include "../../scripts/dtc/libfdt/fdt_ro.c" diff --git a/tools/Makefile b/tools/Makefile index c2b2634004..1f7d4d1fae 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -63,11 +63,10 @@ FIT_CIPHER_OBJS-$(CONFIG_FIT_CIPHER) := common/image-cipher.o # The following files are synced with upstream DTC. # Use synced versions from scripts/dtc/libfdt/. -LIBFDT_SRCS_SYNCED := fdt.c fdt_wip.c fdt_sw.c fdt_rw.c \ +LIBFDT_SRCS_SYNCED := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c \ fdt_strerror.c fdt_empty_tree.c fdt_addresses.c fdt_overlay.c -# The following files are locally modified for U-Boot (unfotunately). # Use U-Boot own versions from lib/libfdt/. -LIBFDT_SRCS_UNSYNCED := fdt_ro.c fdt_region.c +LIBFDT_SRCS_UNSYNCED := fdt_region.c LIBFDT_OBJS := $(addprefix libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_SYNCED))) \ $(addprefix lib/libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_UNSYNCED))) diff --git a/tools/libfdt/fdt_ro.c b/tools/libfdt/fdt_ro.c new file mode 100644 index 0000000000..8a9735a48c --- /dev/null +++ b/tools/libfdt/fdt_ro.c @@ -0,0 +1,2 @@ +#include "fdt_host.h" +#include "../scripts/dtc/libfdt/fdt_ro.c" From 3e69db1223b9db82705fcc96b76caf0d8a468d12 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 16 Apr 2020 18:30:17 +0900 Subject: [PATCH 02/23] fdt_region: move fdt_region.c to common/ from lib/libfdt/ My goal is to sync lib/libfdt/ with scripts/dtc/libfdt/, that is, make lib/libfdt/ contain only wrapper files. fdt_region.c was written only for U-Boot to implement the verified boot. So, this belongs to the same group as common/fdt_support.c, which is a collection of U-Boot own fdt helpers. Move lib/libfdt/fdt_region.c to common/fdt_region.c . This is necessary only when CONFIG_(SPL_TPL_)_FIT_SIGNATURE is enabled. Signed-off-by: Masahiro Yamada --- common/Makefile | 1 + lib/libfdt/Makefile | 3 - lib/libfdt/fdt_region.c | 656 ---------------------------------------- tools/Makefile | 12 +- 4 files changed, 5 insertions(+), 667 deletions(-) delete mode 100644 lib/libfdt/fdt_region.c diff --git a/common/Makefile b/common/Makefile index 3471c47be5..2e7a090588 100644 --- a/common/Makefile +++ b/common/Makefile @@ -110,6 +110,7 @@ obj-y += image.o obj-$(CONFIG_ANDROID_AB) += android_ab.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o +obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o obj-$(CONFIG_$(SPL_TPL_)IMAGE_SIGN_INFO) += image-sig.o diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile index 878659f99e..1fe50ecbe5 100644 --- a/lib/libfdt/Makefile +++ b/lib/libfdt/Makefile @@ -15,8 +15,5 @@ obj-y += \ obj-$(CONFIG_OF_LIBFDT_OVERLAY) += fdt_overlay.o -# U-Boot own file -obj-y += fdt_region.o - ccflags-y := -I$(srctree)/scripts/dtc/libfdt \ -DFDT_ASSUME_MASK=$(CONFIG_$(SPL_TPL_)OF_LIBFDT_ASSUME_MASK) diff --git a/lib/libfdt/fdt_region.c b/lib/libfdt/fdt_region.c deleted file mode 100644 index 7e9fa9272e..0000000000 --- a/lib/libfdt/fdt_region.c +++ /dev/null @@ -1,656 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause -/* - * libfdt - Flat Device Tree manipulation - * Copyright (C) 2013 Google, Inc - * Written by Simon Glass - */ - -#include - -#ifndef USE_HOSTCC -#include -#include -#else -#include "fdt_host.h" -#endif - -#define FDT_MAX_DEPTH 32 - -static int str_in_list(const char *str, char * const list[], int count) -{ - int i; - - for (i = 0; i < count; i++) - if (!strcmp(list[i], str)) - return 1; - - return 0; -} - -int fdt_find_regions(const void *fdt, char * const inc[], int inc_count, - char * const exc_prop[], int exc_prop_count, - struct fdt_region region[], int max_regions, - char *path, int path_len, int add_string_tab) -{ - int stack[FDT_MAX_DEPTH] = { 0 }; - char *end; - int nextoffset = 0; - uint32_t tag; - int count = 0; - int start = -1; - int depth = -1; - int want = 0; - int base = fdt_off_dt_struct(fdt); - - end = path; - *end = '\0'; - do { - const struct fdt_property *prop; - const char *name; - const char *str; - int include = 0; - int stop_at = 0; - int offset; - int len; - - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); - stop_at = nextoffset; - - switch (tag) { - case FDT_PROP: - include = want >= 2; - stop_at = offset; - prop = fdt_get_property_by_offset(fdt, offset, NULL); - str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - if (str_in_list(str, exc_prop, exc_prop_count)) - include = 0; - break; - - case FDT_NOP: - include = want >= 2; - stop_at = offset; - break; - - case FDT_BEGIN_NODE: - depth++; - if (depth == FDT_MAX_DEPTH) - return -FDT_ERR_BADSTRUCTURE; - name = fdt_get_name(fdt, offset, &len); - if (end - path + 2 + len >= path_len) - return -FDT_ERR_NOSPACE; - if (end != path + 1) - *end++ = '/'; - strcpy(end, name); - end += len; - stack[depth] = want; - if (want == 1) - stop_at = offset; - if (str_in_list(path, inc, inc_count)) - want = 2; - else if (want) - want--; - else - stop_at = offset; - include = want; - break; - - case FDT_END_NODE: - /* Depth must never go below -1 */ - if (depth < 0) - return -FDT_ERR_BADSTRUCTURE; - include = want; - want = stack[depth--]; - while (end > path && *--end != '/') - ; - *end = '\0'; - break; - - case FDT_END: - include = 1; - break; - } - - if (include && start == -1) { - /* Should we merge with previous? */ - if (count && count <= max_regions && - offset == region[count - 1].offset + - region[count - 1].size - base) - start = region[--count].offset - base; - else - start = offset; - } - - if (!include && start != -1) { - if (count < max_regions) { - region[count].offset = base + start; - region[count].size = stop_at - start; - } - count++; - start = -1; - } - } while (tag != FDT_END); - - if (nextoffset != fdt_size_dt_struct(fdt)) - return -FDT_ERR_BADLAYOUT; - - /* Add a region for the END tag and the string table */ - if (count < max_regions) { - region[count].offset = base + start; - region[count].size = nextoffset - start; - if (add_string_tab) - region[count].size += fdt_size_dt_strings(fdt); - } - count++; - - return count; -} - -/** - * fdt_add_region() - Add a new region to our list - * @info: State information - * @offset: Start offset of region - * @size: Size of region - * - * The region is added if there is space, but in any case we increment the - * count. If permitted, and the new region overlaps the last one, we merge - * them. - */ -static int fdt_add_region(struct fdt_region_state *info, int offset, int size) -{ - struct fdt_region *reg; - - reg = info->region ? &info->region[info->count - 1] : NULL; - if (info->can_merge && info->count && - info->count <= info->max_regions && - reg && offset <= reg->offset + reg->size) { - reg->size = offset + size - reg->offset; - } else if (info->count++ < info->max_regions) { - if (reg) { - reg++; - reg->offset = offset; - reg->size = size; - } - } else { - return -1; - } - - return 0; -} - -static int region_list_contains_offset(struct fdt_region_state *info, - const void *fdt, int target) -{ - struct fdt_region *reg; - int num; - - target += fdt_off_dt_struct(fdt); - for (reg = info->region, num = 0; num < info->count; reg++, num++) { - if (target >= reg->offset && target < reg->offset + reg->size) - return 1; - } - - return 0; -} - -/** - * fdt_add_alias_regions() - Add regions covering the aliases that we want - * - * The /aliases node is not automatically included by fdtgrep unless the - * command-line arguments cause to be included (or not excluded). However - * aliases are special in that we generally want to include those which - * reference a node that fdtgrep includes. - * - * In fact we want to include only aliases for those nodes still included in - * the fdt, and drop the other aliases since they point to nodes that will not - * be present. - * - * This function scans the aliases and adds regions for those which we want - * to keep. - * - * @fdt: Device tree to scan - * @region: List of regions - * @count: Number of regions in the list so far (i.e. starting point for this - * function) - * @max_regions: Maximum number of regions in @region list - * @info: Place to put the region state - * @return number of regions after processing, or -FDT_ERR_NOSPACE if we did - * not have enough room in the regions table for the regions we wanted to add. - */ -int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count, - int max_regions, struct fdt_region_state *info) -{ - int base = fdt_off_dt_struct(fdt); - int node, node_end, offset; - int did_alias_header; - - node = fdt_subnode_offset(fdt, 0, "aliases"); - if (node < 0) - return -FDT_ERR_NOTFOUND; - - /* - * Find the next node so that we know where the /aliases node ends. We - * need special handling if /aliases is the last node. - */ - node_end = fdt_next_subnode(fdt, node); - if (node_end == -FDT_ERR_NOTFOUND) - /* Move back to the FDT_END_NODE tag of '/' */ - node_end = fdt_size_dt_struct(fdt) - sizeof(fdt32_t) * 2; - else if (node_end < 0) /* other error */ - return node_end; - node_end -= sizeof(fdt32_t); /* Move to FDT_END_NODE tag of /aliases */ - - did_alias_header = 0; - info->region = region; - info->count = count; - info->can_merge = 0; - info->max_regions = max_regions; - - for (offset = fdt_first_property_offset(fdt, node); - offset >= 0; - offset = fdt_next_property_offset(fdt, offset)) { - const struct fdt_property *prop; - const char *name; - int target, next; - - prop = fdt_get_property_by_offset(fdt, offset, NULL); - name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - target = fdt_path_offset(fdt, name); - if (!region_list_contains_offset(info, fdt, target)) - continue; - next = fdt_next_property_offset(fdt, offset); - if (next < 0) - next = node_end; - - if (!did_alias_header) { - fdt_add_region(info, base + node, 12); - did_alias_header = 1; - } - fdt_add_region(info, base + offset, next - offset); - } - - /* Add the FDT_END_NODE tag */ - if (did_alias_header) - fdt_add_region(info, base + node_end, sizeof(fdt32_t)); - - return info->count < max_regions ? info->count : -FDT_ERR_NOSPACE; -} - -/** - * fdt_include_supernodes() - Include supernodes required by this node - * @info: State information - * @depth: Current stack depth - * - * When we decided to include a node or property which is not at the top - * level, this function forces the inclusion of higher level nodes. For - * example, given this tree: - * - * / { - * testing { - * } - * } - * - * If we decide to include testing then we need the root node to have a valid - * tree. This function adds those regions. - */ -static int fdt_include_supernodes(struct fdt_region_state *info, int depth) -{ - int base = fdt_off_dt_struct(info->fdt); - int start, stop_at; - int i; - - /* - * Work down the stack looking for supernodes that we didn't include. - * The algortihm here is actually pretty simple, since we know that - * no previous subnode had to include these nodes, or if it did, we - * marked them as included (on the stack) already. - */ - for (i = 0; i <= depth; i++) { - if (!info->stack[i].included) { - start = info->stack[i].offset; - - /* Add the FDT_BEGIN_NODE tag of this supernode */ - fdt_next_tag(info->fdt, start, &stop_at); - if (fdt_add_region(info, base + start, stop_at - start)) - return -1; - - /* Remember that this supernode is now included */ - info->stack[i].included = 1; - info->can_merge = 1; - } - - /* Force (later) generation of the FDT_END_NODE tag */ - if (!info->stack[i].want) - info->stack[i].want = WANT_NODES_ONLY; - } - - return 0; -} - -enum { - FDT_DONE_NOTHING, - FDT_DONE_MEM_RSVMAP, - FDT_DONE_STRUCT, - FDT_DONE_END, - FDT_DONE_STRINGS, - FDT_DONE_ALL, -}; - -int fdt_first_region(const void *fdt, - int (*h_include)(void *priv, const void *fdt, int offset, - int type, const char *data, int size), - void *priv, struct fdt_region *region, - char *path, int path_len, int flags, - struct fdt_region_state *info) -{ - struct fdt_region_ptrs *p = &info->ptrs; - - /* Set up our state */ - info->fdt = fdt; - info->can_merge = 1; - info->max_regions = 1; - info->start = -1; - p->want = WANT_NOTHING; - p->end = path; - *p->end = '\0'; - p->nextoffset = 0; - p->depth = -1; - p->done = FDT_DONE_NOTHING; - - return fdt_next_region(fdt, h_include, priv, region, - path, path_len, flags, info); -} - -/*********************************************************************** - * - * Theory of operation - * - * Note: in this description 'included' means that a node (or other part - * of the tree) should be included in the region list, i.e. it will have - * a region which covers its part of the tree. - * - * This function maintains some state from the last time it is called. - * It checks the next part of the tree that it is supposed to look at - * (p.nextoffset) to see if that should be included or not. When it - * finds something to include, it sets info->start to its offset. This - * marks the start of the region we want to include. - * - * Once info->start is set to the start (i.e. not -1), we continue - * scanning until we find something that we don't want included. This - * will be the end of a region. At this point we can close off the - * region and add it to the list. So we do so, and reset info->start - * to -1. - * - * One complication here is that we want to merge regions. So when we - * come to add another region later, we may in fact merge it with the - * previous one if one ends where the other starts. - * - * The function fdt_add_region() will return -1 if it fails to add the - * region, because we already have a region ready to be returned, and - * the new one cannot be merged in with it. In this case, we must return - * the region we found, and wait for another call to this function. - * When it comes, we will repeat the processing of the tag and again - * try to add a region. This time it will succeed. - * - * The current state of the pointers (stack, offset, etc.) is maintained - * in a ptrs member. At the start of every loop iteration we make a copy - * of it. The copy is then updated as the tag is processed. Only if we - * get to the end of the loop iteration (and successfully call - * fdt_add_region() if we need to) can we commit the changes we have - * made to these pointers. For example, if we see an FDT_END_NODE tag, - * we will decrement the depth value. But if we need to add a region - * for this tag (let's say because the previous tag is included and this - * FDT_END_NODE tag is not included) then we will only commit the result - * if we were able to add the region. That allows us to retry again next - * time. - * - * We keep track of a variable called 'want' which tells us what we want - * to include when there is no specific information provided by the - * h_include function for a particular property. This basically handles - * the inclusion of properties which are pulled in by virtue of the node - * they are in. So if you include a node, its properties are also - * included. In this case 'want' will be WANT_NODES_AND_PROPS. The - * FDT_REG_DIRECT_SUBNODES feature also makes use of 'want'. While we - * are inside the subnode, 'want' will be set to WANT_NODES_ONLY, so - * that only the subnode's FDT_BEGIN_NODE and FDT_END_NODE tags will be - * included, and properties will be skipped. If WANT_NOTHING is - * selected, then we will just rely on what the h_include() function - * tells us. - * - * Using 'want' we work out 'include', which tells us whether this - * current tag should be included or not. As you can imagine, if the - * value of 'include' changes, that means we are on a boundary between - * nodes to include and nodes to exclude. At this point we either close - * off a previous region and add it to the list, or mark the start of a - * new region. - * - * Apart from the nodes, we have mem_rsvmap, the FDT_END tag and the - * string list. Each of these dealt with as a whole (i.e. we create a - * region for each if it is to be included). For mem_rsvmap we don't - * allow it to merge with the first struct region. For the stringlist, - * we don't allow it to merge with the last struct region (which - * contains at minimum the FDT_END tag). - * - *********************************************************************/ - -int fdt_next_region(const void *fdt, - int (*h_include)(void *priv, const void *fdt, int offset, - int type, const char *data, int size), - void *priv, struct fdt_region *region, - char *path, int path_len, int flags, - struct fdt_region_state *info) -{ - int base = fdt_off_dt_struct(fdt); - int last_node = 0; - const char *str; - - info->region = region; - info->count = 0; - if (info->ptrs.done < FDT_DONE_MEM_RSVMAP && - (flags & FDT_REG_ADD_MEM_RSVMAP)) { - /* Add the memory reserve map into its own region */ - if (fdt_add_region(info, fdt_off_mem_rsvmap(fdt), - fdt_off_dt_struct(fdt) - - fdt_off_mem_rsvmap(fdt))) - return 0; - info->can_merge = 0; /* Don't allow merging with this */ - info->ptrs.done = FDT_DONE_MEM_RSVMAP; - } - - /* - * Work through the tags one by one, deciding whether each needs to - * be included or not. We set the variable 'include' to indicate our - * decision. 'want' is used to track what we want to include - it - * allows us to pick up all the properties (and/or subnode tags) of - * a node. - */ - while (info->ptrs.done < FDT_DONE_STRUCT) { - const struct fdt_property *prop; - struct fdt_region_ptrs p; - const char *name; - int include = 0; - int stop_at = 0; - uint32_t tag; - int offset; - int val; - int len; - - /* - * Make a copy of our pointers. If we make it to the end of - * this block then we will commit them back to info->ptrs. - * Otherwise we can try again from the same starting state - * next time we are called. - */ - p = info->ptrs; - - /* - * Find the tag, and the offset of the next one. If we need to - * stop including tags, then by default we stop *after* - * including the current tag - */ - offset = p.nextoffset; - tag = fdt_next_tag(fdt, offset, &p.nextoffset); - stop_at = p.nextoffset; - - switch (tag) { - case FDT_PROP: - stop_at = offset; - prop = fdt_get_property_by_offset(fdt, offset, NULL); - str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - val = h_include(priv, fdt, last_node, FDT_IS_PROP, str, - strlen(str) + 1); - if (val == -1) { - include = p.want >= WANT_NODES_AND_PROPS; - } else { - include = val; - /* - * Make sure we include the } for this block. - * It might be more correct to have this done - * by the call to fdt_include_supernodes() in - * the case where it adds the node we are - * currently in, but this is equivalent. - */ - if ((flags & FDT_REG_SUPERNODES) && val && - !p.want) - p.want = WANT_NODES_ONLY; - } - - /* Value grepping is not yet supported */ - break; - - case FDT_NOP: - include = p.want >= WANT_NODES_AND_PROPS; - stop_at = offset; - break; - - case FDT_BEGIN_NODE: - last_node = offset; - p.depth++; - if (p.depth == FDT_MAX_DEPTH) - return -FDT_ERR_BADSTRUCTURE; - name = fdt_get_name(fdt, offset, &len); - if (p.end - path + 2 + len >= path_len) - return -FDT_ERR_NOSPACE; - - /* Build the full path of this node */ - if (p.end != path + 1) - *p.end++ = '/'; - strcpy(p.end, name); - p.end += len; - info->stack[p.depth].want = p.want; - info->stack[p.depth].offset = offset; - - /* - * If we are not intending to include this node unless - * it matches, make sure we stop *before* its tag. - */ - if (p.want == WANT_NODES_ONLY || - !(flags & (FDT_REG_DIRECT_SUBNODES | - FDT_REG_ALL_SUBNODES))) { - stop_at = offset; - p.want = WANT_NOTHING; - } - val = h_include(priv, fdt, offset, FDT_IS_NODE, path, - p.end - path + 1); - - /* Include this if requested */ - if (val) { - p.want = (flags & FDT_REG_ALL_SUBNODES) ? - WANT_ALL_NODES_AND_PROPS : - WANT_NODES_AND_PROPS; - } - - /* If not requested, decay our 'p.want' value */ - else if (p.want) { - if (p.want != WANT_ALL_NODES_AND_PROPS) - p.want--; - - /* Not including this tag, so stop now */ - } else { - stop_at = offset; - } - - /* - * Decide whether to include this tag, and update our - * stack with the state for this node - */ - include = p.want; - info->stack[p.depth].included = include; - break; - - case FDT_END_NODE: - include = p.want; - if (p.depth < 0) - return -FDT_ERR_BADSTRUCTURE; - - /* - * If we don't want this node, stop right away, unless - * we are including subnodes - */ - if (!p.want && !(flags & FDT_REG_DIRECT_SUBNODES)) - stop_at = offset; - p.want = info->stack[p.depth].want; - p.depth--; - while (p.end > path && *--p.end != '/') - ; - *p.end = '\0'; - break; - - case FDT_END: - /* We always include the end tag */ - include = 1; - p.done = FDT_DONE_STRUCT; - break; - } - - /* If this tag is to be included, mark it as region start */ - if (include && info->start == -1) { - /* Include any supernodes required by this one */ - if (flags & FDT_REG_SUPERNODES) { - if (fdt_include_supernodes(info, p.depth)) - return 0; - } - info->start = offset; - } - - /* - * If this tag is not to be included, finish up the current - * region. - */ - if (!include && info->start != -1) { - if (fdt_add_region(info, base + info->start, - stop_at - info->start)) - return 0; - info->start = -1; - info->can_merge = 1; - } - - /* If we have made it this far, we can commit our pointers */ - info->ptrs = p; - } - - /* Add a region for the END tag and a separate one for string table */ - if (info->ptrs.done < FDT_DONE_END) { - if (info->ptrs.nextoffset != fdt_size_dt_struct(fdt)) - return -FDT_ERR_BADSTRUCTURE; - - if (fdt_add_region(info, base + info->start, - info->ptrs.nextoffset - info->start)) - return 0; - info->ptrs.done++; - } - if (info->ptrs.done < FDT_DONE_STRINGS) { - if (flags & FDT_REG_ADD_STRING_TAB) { - info->can_merge = 0; - if (fdt_off_dt_strings(fdt) < - base + info->ptrs.nextoffset) - return -FDT_ERR_BADLAYOUT; - if (fdt_add_region(info, fdt_off_dt_strings(fdt), - fdt_size_dt_strings(fdt))) - return 0; - } - info->ptrs.done++; - } - - return info->count > 0 ? 0 : -FDT_ERR_NOTFOUND; -} diff --git a/tools/Makefile b/tools/Makefile index 1f7d4d1fae..1f9144f028 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -63,13 +63,8 @@ FIT_CIPHER_OBJS-$(CONFIG_FIT_CIPHER) := common/image-cipher.o # The following files are synced with upstream DTC. # Use synced versions from scripts/dtc/libfdt/. -LIBFDT_SRCS_SYNCED := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c \ - fdt_strerror.c fdt_empty_tree.c fdt_addresses.c fdt_overlay.c -# Use U-Boot own versions from lib/libfdt/. -LIBFDT_SRCS_UNSYNCED := fdt_region.c - -LIBFDT_OBJS := $(addprefix libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_SYNCED))) \ - $(addprefix lib/libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_UNSYNCED))) +LIBFDT_OBJS := $(addprefix libfdt/, fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o \ + fdt_strerror.o fdt_empty_tree.o fdt_addresses.o fdt_overlay.o) RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \ rsa-sign.o rsa-verify.o rsa-checksum.o \ @@ -86,6 +81,7 @@ dumpimage-mkimage-objs := aisimage.o \ $(FIT_OBJS-y) \ $(FIT_SIG_OBJS-y) \ $(FIT_CIPHER_OBJS-y) \ + common/fdt_region.o \ common/bootm.o \ lib/crc32.o \ default_image.o \ @@ -210,7 +206,7 @@ hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela hostprogs-$(CONFIG_RISCV) += prelink-riscv hostprogs-y += fdtgrep -fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o +fdtgrep-objs += $(LIBFDT_OBJS) common/fdt_region.o fdtgrep.o ifneq ($(TOOLS_ONLY),y) hostprogs-y += spl_size_limit From 64045a6a173e6cf74a9c30bbe21a93d105be289e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 16 Apr 2020 18:30:18 +0900 Subject: [PATCH 03/23] libfdt: split fdt_region declarations out to fdt_region APIs are not part of libfdt. They are U-Boot extension for the verified boot. Split the declarations related to fdt_region out of . This allows to become a simple wrapper file, like Linux does. Signed-off-by: Masahiro Yamada --- common/fdt_region.c | 657 +++++++++++++++++++++++++++++++++++++++++ common/image-fit-sig.c | 1 + include/fdt_region.h | 304 +++++++++++++++++++ include/linux/libfdt.h | 299 ------------------- tools/fdtgrep.c | 1 + tools/image-host.c | 1 + 6 files changed, 964 insertions(+), 299 deletions(-) create mode 100644 common/fdt_region.c create mode 100644 include/fdt_region.h diff --git a/common/fdt_region.c b/common/fdt_region.c new file mode 100644 index 0000000000..bf0a9be730 --- /dev/null +++ b/common/fdt_region.c @@ -0,0 +1,657 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2013 Google, Inc + * Written by Simon Glass + */ + +#include +#include + +#ifndef USE_HOSTCC +#include +#include +#else +#include "fdt_host.h" +#endif + +#define FDT_MAX_DEPTH 32 + +static int str_in_list(const char *str, char * const list[], int count) +{ + int i; + + for (i = 0; i < count; i++) + if (!strcmp(list[i], str)) + return 1; + + return 0; +} + +int fdt_find_regions(const void *fdt, char * const inc[], int inc_count, + char * const exc_prop[], int exc_prop_count, + struct fdt_region region[], int max_regions, + char *path, int path_len, int add_string_tab) +{ + int stack[FDT_MAX_DEPTH] = { 0 }; + char *end; + int nextoffset = 0; + uint32_t tag; + int count = 0; + int start = -1; + int depth = -1; + int want = 0; + int base = fdt_off_dt_struct(fdt); + + end = path; + *end = '\0'; + do { + const struct fdt_property *prop; + const char *name; + const char *str; + int include = 0; + int stop_at = 0; + int offset; + int len; + + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + stop_at = nextoffset; + + switch (tag) { + case FDT_PROP: + include = want >= 2; + stop_at = offset; + prop = fdt_get_property_by_offset(fdt, offset, NULL); + str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (str_in_list(str, exc_prop, exc_prop_count)) + include = 0; + break; + + case FDT_NOP: + include = want >= 2; + stop_at = offset; + break; + + case FDT_BEGIN_NODE: + depth++; + if (depth == FDT_MAX_DEPTH) + return -FDT_ERR_BADSTRUCTURE; + name = fdt_get_name(fdt, offset, &len); + if (end - path + 2 + len >= path_len) + return -FDT_ERR_NOSPACE; + if (end != path + 1) + *end++ = '/'; + strcpy(end, name); + end += len; + stack[depth] = want; + if (want == 1) + stop_at = offset; + if (str_in_list(path, inc, inc_count)) + want = 2; + else if (want) + want--; + else + stop_at = offset; + include = want; + break; + + case FDT_END_NODE: + /* Depth must never go below -1 */ + if (depth < 0) + return -FDT_ERR_BADSTRUCTURE; + include = want; + want = stack[depth--]; + while (end > path && *--end != '/') + ; + *end = '\0'; + break; + + case FDT_END: + include = 1; + break; + } + + if (include && start == -1) { + /* Should we merge with previous? */ + if (count && count <= max_regions && + offset == region[count - 1].offset + + region[count - 1].size - base) + start = region[--count].offset - base; + else + start = offset; + } + + if (!include && start != -1) { + if (count < max_regions) { + region[count].offset = base + start; + region[count].size = stop_at - start; + } + count++; + start = -1; + } + } while (tag != FDT_END); + + if (nextoffset != fdt_size_dt_struct(fdt)) + return -FDT_ERR_BADLAYOUT; + + /* Add a region for the END tag and the string table */ + if (count < max_regions) { + region[count].offset = base + start; + region[count].size = nextoffset - start; + if (add_string_tab) + region[count].size += fdt_size_dt_strings(fdt); + } + count++; + + return count; +} + +/** + * fdt_add_region() - Add a new region to our list + * @info: State information + * @offset: Start offset of region + * @size: Size of region + * + * The region is added if there is space, but in any case we increment the + * count. If permitted, and the new region overlaps the last one, we merge + * them. + */ +static int fdt_add_region(struct fdt_region_state *info, int offset, int size) +{ + struct fdt_region *reg; + + reg = info->region ? &info->region[info->count - 1] : NULL; + if (info->can_merge && info->count && + info->count <= info->max_regions && + reg && offset <= reg->offset + reg->size) { + reg->size = offset + size - reg->offset; + } else if (info->count++ < info->max_regions) { + if (reg) { + reg++; + reg->offset = offset; + reg->size = size; + } + } else { + return -1; + } + + return 0; +} + +static int region_list_contains_offset(struct fdt_region_state *info, + const void *fdt, int target) +{ + struct fdt_region *reg; + int num; + + target += fdt_off_dt_struct(fdt); + for (reg = info->region, num = 0; num < info->count; reg++, num++) { + if (target >= reg->offset && target < reg->offset + reg->size) + return 1; + } + + return 0; +} + +/** + * fdt_add_alias_regions() - Add regions covering the aliases that we want + * + * The /aliases node is not automatically included by fdtgrep unless the + * command-line arguments cause to be included (or not excluded). However + * aliases are special in that we generally want to include those which + * reference a node that fdtgrep includes. + * + * In fact we want to include only aliases for those nodes still included in + * the fdt, and drop the other aliases since they point to nodes that will not + * be present. + * + * This function scans the aliases and adds regions for those which we want + * to keep. + * + * @fdt: Device tree to scan + * @region: List of regions + * @count: Number of regions in the list so far (i.e. starting point for this + * function) + * @max_regions: Maximum number of regions in @region list + * @info: Place to put the region state + * @return number of regions after processing, or -FDT_ERR_NOSPACE if we did + * not have enough room in the regions table for the regions we wanted to add. + */ +int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count, + int max_regions, struct fdt_region_state *info) +{ + int base = fdt_off_dt_struct(fdt); + int node, node_end, offset; + int did_alias_header; + + node = fdt_subnode_offset(fdt, 0, "aliases"); + if (node < 0) + return -FDT_ERR_NOTFOUND; + + /* + * Find the next node so that we know where the /aliases node ends. We + * need special handling if /aliases is the last node. + */ + node_end = fdt_next_subnode(fdt, node); + if (node_end == -FDT_ERR_NOTFOUND) + /* Move back to the FDT_END_NODE tag of '/' */ + node_end = fdt_size_dt_struct(fdt) - sizeof(fdt32_t) * 2; + else if (node_end < 0) /* other error */ + return node_end; + node_end -= sizeof(fdt32_t); /* Move to FDT_END_NODE tag of /aliases */ + + did_alias_header = 0; + info->region = region; + info->count = count; + info->can_merge = 0; + info->max_regions = max_regions; + + for (offset = fdt_first_property_offset(fdt, node); + offset >= 0; + offset = fdt_next_property_offset(fdt, offset)) { + const struct fdt_property *prop; + const char *name; + int target, next; + + prop = fdt_get_property_by_offset(fdt, offset, NULL); + name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + target = fdt_path_offset(fdt, name); + if (!region_list_contains_offset(info, fdt, target)) + continue; + next = fdt_next_property_offset(fdt, offset); + if (next < 0) + next = node_end; + + if (!did_alias_header) { + fdt_add_region(info, base + node, 12); + did_alias_header = 1; + } + fdt_add_region(info, base + offset, next - offset); + } + + /* Add the FDT_END_NODE tag */ + if (did_alias_header) + fdt_add_region(info, base + node_end, sizeof(fdt32_t)); + + return info->count < max_regions ? info->count : -FDT_ERR_NOSPACE; +} + +/** + * fdt_include_supernodes() - Include supernodes required by this node + * @info: State information + * @depth: Current stack depth + * + * When we decided to include a node or property which is not at the top + * level, this function forces the inclusion of higher level nodes. For + * example, given this tree: + * + * / { + * testing { + * } + * } + * + * If we decide to include testing then we need the root node to have a valid + * tree. This function adds those regions. + */ +static int fdt_include_supernodes(struct fdt_region_state *info, int depth) +{ + int base = fdt_off_dt_struct(info->fdt); + int start, stop_at; + int i; + + /* + * Work down the stack looking for supernodes that we didn't include. + * The algortihm here is actually pretty simple, since we know that + * no previous subnode had to include these nodes, or if it did, we + * marked them as included (on the stack) already. + */ + for (i = 0; i <= depth; i++) { + if (!info->stack[i].included) { + start = info->stack[i].offset; + + /* Add the FDT_BEGIN_NODE tag of this supernode */ + fdt_next_tag(info->fdt, start, &stop_at); + if (fdt_add_region(info, base + start, stop_at - start)) + return -1; + + /* Remember that this supernode is now included */ + info->stack[i].included = 1; + info->can_merge = 1; + } + + /* Force (later) generation of the FDT_END_NODE tag */ + if (!info->stack[i].want) + info->stack[i].want = WANT_NODES_ONLY; + } + + return 0; +} + +enum { + FDT_DONE_NOTHING, + FDT_DONE_MEM_RSVMAP, + FDT_DONE_STRUCT, + FDT_DONE_END, + FDT_DONE_STRINGS, + FDT_DONE_ALL, +}; + +int fdt_first_region(const void *fdt, + int (*h_include)(void *priv, const void *fdt, int offset, + int type, const char *data, int size), + void *priv, struct fdt_region *region, + char *path, int path_len, int flags, + struct fdt_region_state *info) +{ + struct fdt_region_ptrs *p = &info->ptrs; + + /* Set up our state */ + info->fdt = fdt; + info->can_merge = 1; + info->max_regions = 1; + info->start = -1; + p->want = WANT_NOTHING; + p->end = path; + *p->end = '\0'; + p->nextoffset = 0; + p->depth = -1; + p->done = FDT_DONE_NOTHING; + + return fdt_next_region(fdt, h_include, priv, region, + path, path_len, flags, info); +} + +/*********************************************************************** + * + * Theory of operation + * + * Note: in this description 'included' means that a node (or other part + * of the tree) should be included in the region list, i.e. it will have + * a region which covers its part of the tree. + * + * This function maintains some state from the last time it is called. + * It checks the next part of the tree that it is supposed to look at + * (p.nextoffset) to see if that should be included or not. When it + * finds something to include, it sets info->start to its offset. This + * marks the start of the region we want to include. + * + * Once info->start is set to the start (i.e. not -1), we continue + * scanning until we find something that we don't want included. This + * will be the end of a region. At this point we can close off the + * region and add it to the list. So we do so, and reset info->start + * to -1. + * + * One complication here is that we want to merge regions. So when we + * come to add another region later, we may in fact merge it with the + * previous one if one ends where the other starts. + * + * The function fdt_add_region() will return -1 if it fails to add the + * region, because we already have a region ready to be returned, and + * the new one cannot be merged in with it. In this case, we must return + * the region we found, and wait for another call to this function. + * When it comes, we will repeat the processing of the tag and again + * try to add a region. This time it will succeed. + * + * The current state of the pointers (stack, offset, etc.) is maintained + * in a ptrs member. At the start of every loop iteration we make a copy + * of it. The copy is then updated as the tag is processed. Only if we + * get to the end of the loop iteration (and successfully call + * fdt_add_region() if we need to) can we commit the changes we have + * made to these pointers. For example, if we see an FDT_END_NODE tag, + * we will decrement the depth value. But if we need to add a region + * for this tag (let's say because the previous tag is included and this + * FDT_END_NODE tag is not included) then we will only commit the result + * if we were able to add the region. That allows us to retry again next + * time. + * + * We keep track of a variable called 'want' which tells us what we want + * to include when there is no specific information provided by the + * h_include function for a particular property. This basically handles + * the inclusion of properties which are pulled in by virtue of the node + * they are in. So if you include a node, its properties are also + * included. In this case 'want' will be WANT_NODES_AND_PROPS. The + * FDT_REG_DIRECT_SUBNODES feature also makes use of 'want'. While we + * are inside the subnode, 'want' will be set to WANT_NODES_ONLY, so + * that only the subnode's FDT_BEGIN_NODE and FDT_END_NODE tags will be + * included, and properties will be skipped. If WANT_NOTHING is + * selected, then we will just rely on what the h_include() function + * tells us. + * + * Using 'want' we work out 'include', which tells us whether this + * current tag should be included or not. As you can imagine, if the + * value of 'include' changes, that means we are on a boundary between + * nodes to include and nodes to exclude. At this point we either close + * off a previous region and add it to the list, or mark the start of a + * new region. + * + * Apart from the nodes, we have mem_rsvmap, the FDT_END tag and the + * string list. Each of these dealt with as a whole (i.e. we create a + * region for each if it is to be included). For mem_rsvmap we don't + * allow it to merge with the first struct region. For the stringlist, + * we don't allow it to merge with the last struct region (which + * contains at minimum the FDT_END tag). + * + *********************************************************************/ + +int fdt_next_region(const void *fdt, + int (*h_include)(void *priv, const void *fdt, int offset, + int type, const char *data, int size), + void *priv, struct fdt_region *region, + char *path, int path_len, int flags, + struct fdt_region_state *info) +{ + int base = fdt_off_dt_struct(fdt); + int last_node = 0; + const char *str; + + info->region = region; + info->count = 0; + if (info->ptrs.done < FDT_DONE_MEM_RSVMAP && + (flags & FDT_REG_ADD_MEM_RSVMAP)) { + /* Add the memory reserve map into its own region */ + if (fdt_add_region(info, fdt_off_mem_rsvmap(fdt), + fdt_off_dt_struct(fdt) - + fdt_off_mem_rsvmap(fdt))) + return 0; + info->can_merge = 0; /* Don't allow merging with this */ + info->ptrs.done = FDT_DONE_MEM_RSVMAP; + } + + /* + * Work through the tags one by one, deciding whether each needs to + * be included or not. We set the variable 'include' to indicate our + * decision. 'want' is used to track what we want to include - it + * allows us to pick up all the properties (and/or subnode tags) of + * a node. + */ + while (info->ptrs.done < FDT_DONE_STRUCT) { + const struct fdt_property *prop; + struct fdt_region_ptrs p; + const char *name; + int include = 0; + int stop_at = 0; + uint32_t tag; + int offset; + int val; + int len; + + /* + * Make a copy of our pointers. If we make it to the end of + * this block then we will commit them back to info->ptrs. + * Otherwise we can try again from the same starting state + * next time we are called. + */ + p = info->ptrs; + + /* + * Find the tag, and the offset of the next one. If we need to + * stop including tags, then by default we stop *after* + * including the current tag + */ + offset = p.nextoffset; + tag = fdt_next_tag(fdt, offset, &p.nextoffset); + stop_at = p.nextoffset; + + switch (tag) { + case FDT_PROP: + stop_at = offset; + prop = fdt_get_property_by_offset(fdt, offset, NULL); + str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + val = h_include(priv, fdt, last_node, FDT_IS_PROP, str, + strlen(str) + 1); + if (val == -1) { + include = p.want >= WANT_NODES_AND_PROPS; + } else { + include = val; + /* + * Make sure we include the } for this block. + * It might be more correct to have this done + * by the call to fdt_include_supernodes() in + * the case where it adds the node we are + * currently in, but this is equivalent. + */ + if ((flags & FDT_REG_SUPERNODES) && val && + !p.want) + p.want = WANT_NODES_ONLY; + } + + /* Value grepping is not yet supported */ + break; + + case FDT_NOP: + include = p.want >= WANT_NODES_AND_PROPS; + stop_at = offset; + break; + + case FDT_BEGIN_NODE: + last_node = offset; + p.depth++; + if (p.depth == FDT_MAX_DEPTH) + return -FDT_ERR_BADSTRUCTURE; + name = fdt_get_name(fdt, offset, &len); + if (p.end - path + 2 + len >= path_len) + return -FDT_ERR_NOSPACE; + + /* Build the full path of this node */ + if (p.end != path + 1) + *p.end++ = '/'; + strcpy(p.end, name); + p.end += len; + info->stack[p.depth].want = p.want; + info->stack[p.depth].offset = offset; + + /* + * If we are not intending to include this node unless + * it matches, make sure we stop *before* its tag. + */ + if (p.want == WANT_NODES_ONLY || + !(flags & (FDT_REG_DIRECT_SUBNODES | + FDT_REG_ALL_SUBNODES))) { + stop_at = offset; + p.want = WANT_NOTHING; + } + val = h_include(priv, fdt, offset, FDT_IS_NODE, path, + p.end - path + 1); + + /* Include this if requested */ + if (val) { + p.want = (flags & FDT_REG_ALL_SUBNODES) ? + WANT_ALL_NODES_AND_PROPS : + WANT_NODES_AND_PROPS; + } + + /* If not requested, decay our 'p.want' value */ + else if (p.want) { + if (p.want != WANT_ALL_NODES_AND_PROPS) + p.want--; + + /* Not including this tag, so stop now */ + } else { + stop_at = offset; + } + + /* + * Decide whether to include this tag, and update our + * stack with the state for this node + */ + include = p.want; + info->stack[p.depth].included = include; + break; + + case FDT_END_NODE: + include = p.want; + if (p.depth < 0) + return -FDT_ERR_BADSTRUCTURE; + + /* + * If we don't want this node, stop right away, unless + * we are including subnodes + */ + if (!p.want && !(flags & FDT_REG_DIRECT_SUBNODES)) + stop_at = offset; + p.want = info->stack[p.depth].want; + p.depth--; + while (p.end > path && *--p.end != '/') + ; + *p.end = '\0'; + break; + + case FDT_END: + /* We always include the end tag */ + include = 1; + p.done = FDT_DONE_STRUCT; + break; + } + + /* If this tag is to be included, mark it as region start */ + if (include && info->start == -1) { + /* Include any supernodes required by this one */ + if (flags & FDT_REG_SUPERNODES) { + if (fdt_include_supernodes(info, p.depth)) + return 0; + } + info->start = offset; + } + + /* + * If this tag is not to be included, finish up the current + * region. + */ + if (!include && info->start != -1) { + if (fdt_add_region(info, base + info->start, + stop_at - info->start)) + return 0; + info->start = -1; + info->can_merge = 1; + } + + /* If we have made it this far, we can commit our pointers */ + info->ptrs = p; + } + + /* Add a region for the END tag and a separate one for string table */ + if (info->ptrs.done < FDT_DONE_END) { + if (info->ptrs.nextoffset != fdt_size_dt_struct(fdt)) + return -FDT_ERR_BADSTRUCTURE; + + if (fdt_add_region(info, base + info->start, + info->ptrs.nextoffset - info->start)) + return 0; + info->ptrs.done++; + } + if (info->ptrs.done < FDT_DONE_STRINGS) { + if (flags & FDT_REG_ADD_STRING_TAB) { + info->can_merge = 0; + if (fdt_off_dt_strings(fdt) < + base + info->ptrs.nextoffset) + return -FDT_ERR_BADLAYOUT; + if (fdt_add_region(info, fdt_off_dt_strings(fdt), + fdt_size_dt_strings(fdt))) + return 0; + } + info->ptrs.done++; + } + + return info->count > 0 ? 0 : -FDT_ERR_NOTFOUND; +} diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c index 490566ca90..3e73578594 100644 --- a/common/image-fit-sig.c +++ b/common/image-fit-sig.c @@ -11,6 +11,7 @@ #include DECLARE_GLOBAL_DATA_PTR; #endif /* !USE_HOSTCC*/ +#include #include #include #include diff --git a/include/fdt_region.h b/include/fdt_region.h new file mode 100644 index 0000000000..ff7a1ccb9a --- /dev/null +++ b/include/fdt_region.h @@ -0,0 +1,304 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _FDT_REGION_H +#define _FDT_REGION_H + +#ifndef SWIG /* Not available in Python */ +struct fdt_region { + int offset; + int size; +}; + +/* + * Flags for fdt_find_regions() + * + * Add a region for the string table (always the last region) + */ +#define FDT_REG_ADD_STRING_TAB (1 << 0) + +/* + * Add all supernodes of a matching node/property, useful for creating a + * valid subset tree + */ +#define FDT_REG_SUPERNODES (1 << 1) + +/* Add the FDT_BEGIN_NODE tags of subnodes, including their names */ +#define FDT_REG_DIRECT_SUBNODES (1 << 2) + +/* Add all subnodes of a matching node */ +#define FDT_REG_ALL_SUBNODES (1 << 3) + +/* Add a region for the mem_rsvmap table (always the first region) */ +#define FDT_REG_ADD_MEM_RSVMAP (1 << 4) + +/* Indicates what an fdt part is (node, property, value) */ +#define FDT_IS_NODE (1 << 0) +#define FDT_IS_PROP (1 << 1) +#define FDT_IS_VALUE (1 << 2) /* not supported */ +#define FDT_IS_COMPAT (1 << 3) /* used internally */ +#define FDT_NODE_HAS_PROP (1 << 4) /* node contains prop */ + +#define FDT_ANY_GLOBAL (FDT_IS_NODE | FDT_IS_PROP | FDT_IS_VALUE | \ + FDT_IS_COMPAT) +#define FDT_IS_ANY 0x1f /* all the above */ + +/* We set a reasonable limit on the number of nested nodes */ +#define FDT_MAX_DEPTH 32 + +/* Decribes what we want to include from the current tag */ +enum want_t { + WANT_NOTHING, + WANT_NODES_ONLY, /* No properties */ + WANT_NODES_AND_PROPS, /* Everything for one level */ + WANT_ALL_NODES_AND_PROPS /* Everything for all levels */ +}; + +/* Keeps track of the state at parent nodes */ +struct fdt_subnode_stack { + int offset; /* Offset of node */ + enum want_t want; /* The 'want' value here */ + int included; /* 1 if we included this node, 0 if not */ +}; + +struct fdt_region_ptrs { + int depth; /* Current tree depth */ + int done; /* What we have completed scanning */ + enum want_t want; /* What we are currently including */ + char *end; /* Pointer to end of full node path */ + int nextoffset; /* Next node offset to check */ +}; + +/* The state of our finding algortihm */ +struct fdt_region_state { + struct fdt_subnode_stack stack[FDT_MAX_DEPTH]; /* node stack */ + struct fdt_region *region; /* Contains list of regions found */ + int count; /* Numnber of regions found */ + const void *fdt; /* FDT blob */ + int max_regions; /* Maximum regions to find */ + int can_merge; /* 1 if we can merge with previous region */ + int start; /* Start position of current region */ + struct fdt_region_ptrs ptrs; /* Pointers for what we are up to */ +}; + +/** + * fdt_find_regions() - find regions in device tree + * + * Given a list of nodes to include and properties to exclude, find + * the regions of the device tree which describe those included parts. + * + * The intent is to get a list of regions which will be invariant provided + * those parts are invariant. For example, if you request a list of regions + * for all nodes but exclude the property "data", then you will get the + * same region contents regardless of any change to "data" properties. + * + * This function can be used to produce a byte-stream to send to a hashing + * function to verify that critical parts of the FDT have not changed. + * + * Nodes which are given in 'inc' are included in the region list, as + * are the names of the immediate subnodes nodes (but not the properties + * or subnodes of those subnodes). + * + * For eaxample "/" means to include the root node, all root properties + * and the FDT_BEGIN_NODE and FDT_END_NODE of all subnodes of /. The latter + * ensures that we capture the names of the subnodes. In a hashing situation + * it prevents the root node from changing at all Any change to non-excluded + * properties, names of subnodes or number of subnodes would be detected. + * + * When used with FITs this provides the ability to hash and sign parts of + * the FIT based on different configurations in the FIT. Then it is + * impossible to change anything about that configuration (include images + * attached to the configuration), but it may be possible to add new + * configurations, new images or new signatures within the existing + * framework. + * + * Adding new properties to a device tree may result in the string table + * being extended (if the new property names are different from those + * already added). This function can optionally include a region for + * the string table so that this can be part of the hash too. + * + * The device tree header is not included in the list. + * + * @fdt: Device tree to check + * @inc: List of node paths to included + * @inc_count: Number of node paths in list + * @exc_prop: List of properties names to exclude + * @exc_prop_count: Number of properties in exclude list + * @region: Returns list of regions + * @max_region: Maximum length of region list + * @path: Pointer to a temporary string for the function to use for + * building path names + * @path_len: Length of path, must be large enough to hold the longest + * path in the tree + * @add_string_tab: 1 to add a region for the string table + * @return number of regions in list. If this is >max_regions then the + * region array was exhausted. You should increase max_regions and try + * the call again. + */ +int fdt_find_regions(const void *fdt, char * const inc[], int inc_count, + char * const exc_prop[], int exc_prop_count, + struct fdt_region region[], int max_regions, + char *path, int path_len, int add_string_tab); + +/** + * fdt_first_region() - find regions in device tree + * + * Given a nodes and properties to include and properties to exclude, find + * the regions of the device tree which describe those included parts. + * + * The use for this function is twofold. Firstly it provides a convenient + * way of performing a structure-aware grep of the tree. For example it is + * possible to grep for a node and get all the properties associated with + * that node. Trees can be subsetted easily, by specifying the nodes that + * are required, and then writing out the regions returned by this function. + * This is useful for small resource-constrained systems, such as boot + * loaders, which want to use an FDT but do not need to know about all of + * it. + * + * Secondly it makes it easy to hash parts of the tree and detect changes. + * The intent is to get a list of regions which will be invariant provided + * those parts are invariant. For example, if you request a list of regions + * for all nodes but exclude the property "data", then you will get the + * same region contents regardless of any change to "data" properties. + * + * This function can be used to produce a byte-stream to send to a hashing + * function to verify that critical parts of the FDT have not changed. + * Note that semantically null changes in order could still cause false + * hash misses. Such reordering might happen if the tree is regenerated + * from source, and nodes are reordered (the bytes-stream will be emitted + * in a different order and many hash functions will detect this). However + * if an existing tree is modified using libfdt functions, such as + * fdt_add_subnode() and fdt_setprop(), then this problem is avoided. + * + * The nodes/properties to include/exclude are defined by a function + * provided by the caller. This function is called for each node and + * property, and must return: + * + * 0 - to exclude this part + * 1 - to include this part + * -1 - for FDT_IS_PROP only: no information is available, so include + * if its containing node is included + * + * The last case is only used to deal with properties. Often a property is + * included if its containing node is included - this is the case where + * -1 is returned.. However if the property is specifically required to be + * included/excluded, then 0 or 1 can be returned. Note that including a + * property when the FDT_REG_SUPERNODES flag is given will force its + * containing node to be included since it is not valid to have a property + * that is not in a node. + * + * Using the information provided, the inclusion of a node can be controlled + * either by a node name or its compatible string, or any other property + * that the function can determine. + * + * As an example, including node "/" means to include the root node and all + * root properties. A flag provides a way of also including supernodes (of + * which there is none for the root node), and another flag includes + * immediate subnodes, so in this case we would get the FDT_BEGIN_NODE and + * FDT_END_NODE of all subnodes of /. + * + * The subnode feature helps in a hashing situation since it prevents the + * root node from changing at all. Any change to non-excluded properties, + * names of subnodes or number of subnodes would be detected. + * + * When used with FITs this provides the ability to hash and sign parts of + * the FIT based on different configurations in the FIT. Then it is + * impossible to change anything about that configuration (include images + * attached to the configuration), but it may be possible to add new + * configurations, new images or new signatures within the existing + * framework. + * + * Adding new properties to a device tree may result in the string table + * being extended (if the new property names are different from those + * already added). This function can optionally include a region for + * the string table so that this can be part of the hash too. This is always + * the last region. + * + * The FDT also has a mem_rsvmap table which can also be included, and is + * always the first region if so. + * + * The device tree header is not included in the region list. Since the + * contents of the FDT are changing (shrinking, often), the caller will need + * to regenerate the header anyway. + * + * @fdt: Device tree to check + * @h_include: Function to call to determine whether to include a part or + * not: + * + * @priv: Private pointer as passed to fdt_find_regions() + * @fdt: Pointer to FDT blob + * @offset: Offset of this node / property + * @type: Type of this part, FDT_IS_... + * @data: Pointer to data (node name, property name, compatible + * string, value (not yet supported) + * @size: Size of data, or 0 if none + * @return 0 to exclude, 1 to include, -1 if no information is + * available + * @priv: Private pointer passed to h_include + * @region: Returns list of regions, sorted by offset + * @max_regions: Maximum length of region list + * @path: Pointer to a temporary string for the function to use for + * building path names + * @path_len: Length of path, must be large enough to hold the longest + * path in the tree + * @flags: Various flags that control the region algortihm, see + * FDT_REG_... + * @return number of regions in list. If this is >max_regions then the + * region array was exhausted. You should increase max_regions and try + * the call again. Only the first max_regions elements are available in the + * array. + * + * On error a -ve value is return, which can be: + * + * -FDT_ERR_BADSTRUCTURE (too deep or more END tags than BEGIN tags + * -FDT_ERR_BADLAYOUT + * -FDT_ERR_NOSPACE (path area is too small) + */ +int fdt_first_region(const void *fdt, + int (*h_include)(void *priv, const void *fdt, int offset, + int type, const char *data, int size), + void *priv, struct fdt_region *region, + char *path, int path_len, int flags, + struct fdt_region_state *info); + +/** fdt_next_region() - find next region + * + * See fdt_first_region() for full description. This function finds the + * next region according to the provided parameters, which must be the same + * as passed to fdt_first_region(). + * + * This function can additionally return -FDT_ERR_NOTFOUND when there are no + * more regions + */ +int fdt_next_region(const void *fdt, + int (*h_include)(void *priv, const void *fdt, int offset, + int type, const char *data, int size), + void *priv, struct fdt_region *region, + char *path, int path_len, int flags, + struct fdt_region_state *info); + +/** + * fdt_add_alias_regions() - find aliases that point to existing regions + * + * Once a device tree grep is complete some of the nodes will be present + * and some will have been dropped. This function checks all the alias nodes + * to figure out which points point to nodes which are still present. These + * aliases need to be kept, along with the nodes they reference. + * + * Given a list of regions function finds the aliases that still apply and + * adds more regions to the list for these. This function is called after + * fdt_next_region() has finished returning regions and requires the same + * state. + * + * @fdt: Device tree file to reference + * @region: List of regions that will be kept + * @count: Number of regions + * @max_regions: Number of entries that can fit in @region + * @info: Region state as returned from fdt_next_region() + * @return new number of regions in @region (i.e. count + the number added) + * or -FDT_ERR_NOSPACE if there was not enough space. + */ +int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count, + int max_regions, struct fdt_region_state *info); +#endif /* SWIG */ + +#endif /* _FDT_REGION_H */ diff --git a/include/linux/libfdt.h b/include/linux/libfdt.h index eeb2344971..39dbc88aa5 100644 --- a/include/linux/libfdt.h +++ b/include/linux/libfdt.h @@ -8,305 +8,6 @@ #include "../../scripts/dtc/libfdt/libfdt.h" /* U-Boot local hacks */ - -#ifndef SWIG /* Not available in Python */ -struct fdt_region { - int offset; - int size; -}; - -/* - * Flags for fdt_find_regions() - * - * Add a region for the string table (always the last region) - */ -#define FDT_REG_ADD_STRING_TAB (1 << 0) - -/* - * Add all supernodes of a matching node/property, useful for creating a - * valid subset tree - */ -#define FDT_REG_SUPERNODES (1 << 1) - -/* Add the FDT_BEGIN_NODE tags of subnodes, including their names */ -#define FDT_REG_DIRECT_SUBNODES (1 << 2) - -/* Add all subnodes of a matching node */ -#define FDT_REG_ALL_SUBNODES (1 << 3) - -/* Add a region for the mem_rsvmap table (always the first region) */ -#define FDT_REG_ADD_MEM_RSVMAP (1 << 4) - -/* Indicates what an fdt part is (node, property, value) */ -#define FDT_IS_NODE (1 << 0) -#define FDT_IS_PROP (1 << 1) -#define FDT_IS_VALUE (1 << 2) /* not supported */ -#define FDT_IS_COMPAT (1 << 3) /* used internally */ -#define FDT_NODE_HAS_PROP (1 << 4) /* node contains prop */ - -#define FDT_ANY_GLOBAL (FDT_IS_NODE | FDT_IS_PROP | FDT_IS_VALUE | \ - FDT_IS_COMPAT) -#define FDT_IS_ANY 0x1f /* all the above */ - -/* We set a reasonable limit on the number of nested nodes */ -#define FDT_MAX_DEPTH 32 - -/* Decribes what we want to include from the current tag */ -enum want_t { - WANT_NOTHING, - WANT_NODES_ONLY, /* No properties */ - WANT_NODES_AND_PROPS, /* Everything for one level */ - WANT_ALL_NODES_AND_PROPS /* Everything for all levels */ -}; - -/* Keeps track of the state at parent nodes */ -struct fdt_subnode_stack { - int offset; /* Offset of node */ - enum want_t want; /* The 'want' value here */ - int included; /* 1 if we included this node, 0 if not */ -}; - -struct fdt_region_ptrs { - int depth; /* Current tree depth */ - int done; /* What we have completed scanning */ - enum want_t want; /* What we are currently including */ - char *end; /* Pointer to end of full node path */ - int nextoffset; /* Next node offset to check */ -}; - -/* The state of our finding algortihm */ -struct fdt_region_state { - struct fdt_subnode_stack stack[FDT_MAX_DEPTH]; /* node stack */ - struct fdt_region *region; /* Contains list of regions found */ - int count; /* Numnber of regions found */ - const void *fdt; /* FDT blob */ - int max_regions; /* Maximum regions to find */ - int can_merge; /* 1 if we can merge with previous region */ - int start; /* Start position of current region */ - struct fdt_region_ptrs ptrs; /* Pointers for what we are up to */ -}; - -/** - * fdt_find_regions() - find regions in device tree - * - * Given a list of nodes to include and properties to exclude, find - * the regions of the device tree which describe those included parts. - * - * The intent is to get a list of regions which will be invariant provided - * those parts are invariant. For example, if you request a list of regions - * for all nodes but exclude the property "data", then you will get the - * same region contents regardless of any change to "data" properties. - * - * This function can be used to produce a byte-stream to send to a hashing - * function to verify that critical parts of the FDT have not changed. - * - * Nodes which are given in 'inc' are included in the region list, as - * are the names of the immediate subnodes nodes (but not the properties - * or subnodes of those subnodes). - * - * For eaxample "/" means to include the root node, all root properties - * and the FDT_BEGIN_NODE and FDT_END_NODE of all subnodes of /. The latter - * ensures that we capture the names of the subnodes. In a hashing situation - * it prevents the root node from changing at all Any change to non-excluded - * properties, names of subnodes or number of subnodes would be detected. - * - * When used with FITs this provides the ability to hash and sign parts of - * the FIT based on different configurations in the FIT. Then it is - * impossible to change anything about that configuration (include images - * attached to the configuration), but it may be possible to add new - * configurations, new images or new signatures within the existing - * framework. - * - * Adding new properties to a device tree may result in the string table - * being extended (if the new property names are different from those - * already added). This function can optionally include a region for - * the string table so that this can be part of the hash too. - * - * The device tree header is not included in the list. - * - * @fdt: Device tree to check - * @inc: List of node paths to included - * @inc_count: Number of node paths in list - * @exc_prop: List of properties names to exclude - * @exc_prop_count: Number of properties in exclude list - * @region: Returns list of regions - * @max_region: Maximum length of region list - * @path: Pointer to a temporary string for the function to use for - * building path names - * @path_len: Length of path, must be large enough to hold the longest - * path in the tree - * @add_string_tab: 1 to add a region for the string table - * @return number of regions in list. If this is >max_regions then the - * region array was exhausted. You should increase max_regions and try - * the call again. - */ -int fdt_find_regions(const void *fdt, char * const inc[], int inc_count, - char * const exc_prop[], int exc_prop_count, - struct fdt_region region[], int max_regions, - char *path, int path_len, int add_string_tab); - -/** - * fdt_first_region() - find regions in device tree - * - * Given a nodes and properties to include and properties to exclude, find - * the regions of the device tree which describe those included parts. - * - * The use for this function is twofold. Firstly it provides a convenient - * way of performing a structure-aware grep of the tree. For example it is - * possible to grep for a node and get all the properties associated with - * that node. Trees can be subsetted easily, by specifying the nodes that - * are required, and then writing out the regions returned by this function. - * This is useful for small resource-constrained systems, such as boot - * loaders, which want to use an FDT but do not need to know about all of - * it. - * - * Secondly it makes it easy to hash parts of the tree and detect changes. - * The intent is to get a list of regions which will be invariant provided - * those parts are invariant. For example, if you request a list of regions - * for all nodes but exclude the property "data", then you will get the - * same region contents regardless of any change to "data" properties. - * - * This function can be used to produce a byte-stream to send to a hashing - * function to verify that critical parts of the FDT have not changed. - * Note that semantically null changes in order could still cause false - * hash misses. Such reordering might happen if the tree is regenerated - * from source, and nodes are reordered (the bytes-stream will be emitted - * in a different order and many hash functions will detect this). However - * if an existing tree is modified using libfdt functions, such as - * fdt_add_subnode() and fdt_setprop(), then this problem is avoided. - * - * The nodes/properties to include/exclude are defined by a function - * provided by the caller. This function is called for each node and - * property, and must return: - * - * 0 - to exclude this part - * 1 - to include this part - * -1 - for FDT_IS_PROP only: no information is available, so include - * if its containing node is included - * - * The last case is only used to deal with properties. Often a property is - * included if its containing node is included - this is the case where - * -1 is returned.. However if the property is specifically required to be - * included/excluded, then 0 or 1 can be returned. Note that including a - * property when the FDT_REG_SUPERNODES flag is given will force its - * containing node to be included since it is not valid to have a property - * that is not in a node. - * - * Using the information provided, the inclusion of a node can be controlled - * either by a node name or its compatible string, or any other property - * that the function can determine. - * - * As an example, including node "/" means to include the root node and all - * root properties. A flag provides a way of also including supernodes (of - * which there is none for the root node), and another flag includes - * immediate subnodes, so in this case we would get the FDT_BEGIN_NODE and - * FDT_END_NODE of all subnodes of /. - * - * The subnode feature helps in a hashing situation since it prevents the - * root node from changing at all. Any change to non-excluded properties, - * names of subnodes or number of subnodes would be detected. - * - * When used with FITs this provides the ability to hash and sign parts of - * the FIT based on different configurations in the FIT. Then it is - * impossible to change anything about that configuration (include images - * attached to the configuration), but it may be possible to add new - * configurations, new images or new signatures within the existing - * framework. - * - * Adding new properties to a device tree may result in the string table - * being extended (if the new property names are different from those - * already added). This function can optionally include a region for - * the string table so that this can be part of the hash too. This is always - * the last region. - * - * The FDT also has a mem_rsvmap table which can also be included, and is - * always the first region if so. - * - * The device tree header is not included in the region list. Since the - * contents of the FDT are changing (shrinking, often), the caller will need - * to regenerate the header anyway. - * - * @fdt: Device tree to check - * @h_include: Function to call to determine whether to include a part or - * not: - * - * @priv: Private pointer as passed to fdt_find_regions() - * @fdt: Pointer to FDT blob - * @offset: Offset of this node / property - * @type: Type of this part, FDT_IS_... - * @data: Pointer to data (node name, property name, compatible - * string, value (not yet supported) - * @size: Size of data, or 0 if none - * @return 0 to exclude, 1 to include, -1 if no information is - * available - * @priv: Private pointer passed to h_include - * @region: Returns list of regions, sorted by offset - * @max_regions: Maximum length of region list - * @path: Pointer to a temporary string for the function to use for - * building path names - * @path_len: Length of path, must be large enough to hold the longest - * path in the tree - * @flags: Various flags that control the region algortihm, see - * FDT_REG_... - * @return number of regions in list. If this is >max_regions then the - * region array was exhausted. You should increase max_regions and try - * the call again. Only the first max_regions elements are available in the - * array. - * - * On error a -ve value is return, which can be: - * - * -FDT_ERR_BADSTRUCTURE (too deep or more END tags than BEGIN tags - * -FDT_ERR_BADLAYOUT - * -FDT_ERR_NOSPACE (path area is too small) - */ -int fdt_first_region(const void *fdt, - int (*h_include)(void *priv, const void *fdt, int offset, - int type, const char *data, int size), - void *priv, struct fdt_region *region, - char *path, int path_len, int flags, - struct fdt_region_state *info); - -/** fdt_next_region() - find next region - * - * See fdt_first_region() for full description. This function finds the - * next region according to the provided parameters, which must be the same - * as passed to fdt_first_region(). - * - * This function can additionally return -FDT_ERR_NOTFOUND when there are no - * more regions - */ -int fdt_next_region(const void *fdt, - int (*h_include)(void *priv, const void *fdt, int offset, - int type, const char *data, int size), - void *priv, struct fdt_region *region, - char *path, int path_len, int flags, - struct fdt_region_state *info); - -/** - * fdt_add_alias_regions() - find aliases that point to existing regions - * - * Once a device tree grep is complete some of the nodes will be present - * and some will have been dropped. This function checks all the alias nodes - * to figure out which points point to nodes which are still present. These - * aliases need to be kept, along with the nodes they reference. - * - * Given a list of regions function finds the aliases that still apply and - * adds more regions to the list for these. This function is called after - * fdt_next_region() has finished returning regions and requires the same - * state. - * - * @fdt: Device tree file to reference - * @region: List of regions that will be kept - * @count: Number of regions - * @max_regions: Number of entries that can fit in @region - * @info: Region state as returned from fdt_next_region() - * @return new number of regions in @region (i.e. count + the number added) - * or -FDT_ERR_NOSPACE if there was not enough space. - */ -int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count, - int max_regions, struct fdt_region_state *info); -#endif /* SWIG */ - extern struct fdt_header *working_fdt; /* Pointer to the working fdt */ #endif /* _INCLUDE_LIBFDT_H_ */ diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c index 2a8058f57f..7e168a1e6b 100644 --- a/tools/fdtgrep.c +++ b/tools/fdtgrep.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "fdt_host.h" #include "libfdt_internal.h" diff --git a/tools/image-host.c b/tools/image-host.c index 5bb68965e7..9a83b7f675 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -10,6 +10,7 @@ #include "mkimage.h" #include +#include #include #include From 55a98d96bd740ecff5d26a0253eed1d5341c614e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 17:51:30 -0600 Subject: [PATCH 04/23] buildman: Fix test for new 9.2 kernel The naming is slightly different on kernel.org now. Update the regex so that the test still passes. Signed-off-by: Simon Glass --- tools/buildman/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/buildman/test.py b/tools/buildman/test.py index d32b22653f..8b6d138f70 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -583,7 +583,7 @@ class TestBuild(unittest.TestCase): url = self.toolchains.LocateArchUrl('arm') self.assertRegexpMatches(url, 'https://www.kernel.org/pub/tools/' 'crosstool/files/bin/x86_64/.*/' - 'x86_64-gcc-.*-nolibc_arm-.*linux-gnueabi.tar.xz') + 'x86_64-gcc-.*-nolibc[-_]arm-.*linux-gnueabi.tar.xz') def testGetEnvArgs(self): """Test the GetEnvArgs() function""" From 97944d3f7d03c83274d34eccf6a380548a16f444 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 17:51:31 -0600 Subject: [PATCH 05/23] buildman: Correct operation of -A flag This was broken when -a was removed and unfortunately there are no tests for this. Fix it. Signed-off-by: Simon Glass --- tools/buildman/control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 30c030fd16..7ee036824f 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -207,7 +207,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, sys.exit(col.Color(col.RED, 'No matching boards found')) if options.print_prefix: - err = ShowToolchainInfo(boards, toolchains) + err = ShowToolchainPrefix(boards, toolchains) if err: sys.exit(col.Color(col.RED, err)) return 0 From 88daaef19f985b6ba2f9c0f62eed5378d6d40ebd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 17:51:32 -0600 Subject: [PATCH 06/23] buildman: Make sure that -o is given with -w It is a bad idea to use the default output directory ('..') with -w since it does a build in that directory and writes various files these. Require that -o is given to avoid this problem. Signed-off-by: Simon Glass --- tools/buildman/README | 3 ++- tools/buildman/cmdline.py | 3 +-- tools/buildman/control.py | 4 ++++ tools/buildman/func_test.py | 6 ++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/buildman/README b/tools/buildman/README index f3a0dc7288..b2f983c715 100644 --- a/tools/buildman/README +++ b/tools/buildman/README @@ -1091,7 +1091,8 @@ the -w option, for example: buildman -o /tmp/build --board sandbox -w -This will write the full build into /tmp/build including object files. +This will write the full build into /tmp/build including object files. You must +specify the output directory with -o when using -w. Other options diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py index 1377b9d2be..680c072d66 100644 --- a/tools/buildman/cmdline.py +++ b/tools/buildman/cmdline.py @@ -76,8 +76,7 @@ def ParseArgs(): default=False, help="Do a dry run (describe actions, but do nothing)") parser.add_option('-N', '--no-subdirs', action='store_true', dest='no_subdirs', default=False, help="Don't create subdirectories when building current source for a single board") - parser.add_option('-o', '--output-dir', type='string', - dest='output_dir', default='..', + parser.add_option('-o', '--output-dir', type='string', dest='output_dir', help='Directory where all builds happen and buildman has its workspace (default is ../)') parser.add_option('-O', '--override-toolchain', type='string', help="Override host toochain to use for sandbox (e.g. 'clang-7')") diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 7ee036824f..7c8d7520fb 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -175,6 +175,10 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, if options.incremental: print(col.Color(col.RED, 'Warning: -I has been removed. See documentation')) + if not options.output_dir: + if options.work_in_output: + sys.exit(col.Color(col.RED, '-w requires that you specify -o')) + options.output_dir = '..' # Work out what subset of the boards we are building if not boards: diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 1fbc6f6b00..8d3325d66f 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -569,3 +569,9 @@ class TestFunctional(unittest.TestCase): self._RunControl('-b', self._test_branch, '-o', self._output_dir, '-w', clean_dir=False, boards=board_list) self.assertIn("single commit", str(e.exception)) + + board_list = board.Boards() + board_list.AddBoard(board.Board(*boards[0])) + with self.assertRaises(SystemExit) as e: + self._RunControl('-w', clean_dir=False) + self.assertIn("specify -o", str(e.exception)) From 166a98a426616aa3e9c35d94ea3aaf8e67994e33 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 17:51:33 -0600 Subject: [PATCH 07/23] buildman: Use out-env for environment output At present the environment used by U-Boot is written to the 'env' directory. This is fine when the output directory is not the same as the source directory, but when it is (as with -w) it conflicts with the source directory of the same name. Rename 'env' to 'out-env' to fix this. Signed-off-by: Simon Glass --- tools/buildman/builderthread.py | 2 +- tools/buildman/func_test.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index fc6e1ab25d..063bbc0145 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -333,7 +333,7 @@ class BuilderThread(threading.Thread): # Write out the image and function size information and an objdump env = result.toolchain.MakeEnvironment(self.builder.full_path) - with open(os.path.join(build_dir, 'env'), 'w') as fd: + with open(os.path.join(build_dir, 'out-env'), 'w') as fd: for var in sorted(env.keys()): print('%s="%s"' % (var, env[var]), file=fd) lines = [] diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 8d3325d66f..e11dc8f899 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -546,6 +546,13 @@ class TestFunctional(unittest.TestCase): self.assertEqual(self._builder.count, self._total_builds) self.assertEqual(self._builder.fail, 0) + def testEnvironment(self): + """Test that the done and environment files are written to out-env""" + self._RunControl('-o', self._output_dir) + board0_dir = os.path.join(self._output_dir, 'current', 'board0') + self.assertTrue(os.path.exists(os.path.join(board0_dir, 'done'))) + self.assertTrue(os.path.exists(os.path.join(board0_dir, 'out-env'))) + def testWorkInOutput(self): """Test the -w option which should write directly to the output dir""" board_list = board.Boards() From 60b285f8c3bcd1f169fa72ad58387509673eec8b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 17:51:34 -0600 Subject: [PATCH 08/23] buildman: Write output files when using -w At present buildman does not write its own output files (err, done, the environment) when using -w. However this is useful for when the build is run with -s to check it. In fact ProduceResultSummary() reads the result from those files rather than using the 'result' info directly. So ProcessResult() does not work with -w at present. It does not print any output. Fix this by writing output files even when -w is used. Signed-off-by: Simon Glass --- tools/buildman/builder.py | 5 +++++ tools/buildman/builderthread.py | 29 ++++++++++++++++------------- tools/buildman/func_test.py | 4 ++++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index 30ebe1d820..1b61e3a837 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -479,6 +479,9 @@ class Builder: Args: commit_upto: Commit number to use (0..self.count-1) """ + if self.work_in_output: + return self._working_dir + commit_dir = None if self.commits: commit = self.commits[commit_upto] @@ -502,6 +505,8 @@ class Builder: target: Target name """ output_dir = self._GetOutputDir(commit_upto) + if self.work_in_output: + return output_dir return os.path.join(output_dir, target) def GetDoneFile(self, commit_upto, target): diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index 063bbc0145..f673f386e4 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -280,8 +280,6 @@ class BuilderThread(threading.Thread): work_in_output: Use the output directory as the work directory and don't write to a separate output directory. """ - if work_in_output: - return # Fatal error if result.return_code < 0: return @@ -379,7 +377,8 @@ class BuilderThread(threading.Thread): capture_stderr=True, cwd=result.out_dir, raise_on_error=False, env=env) ubootenv = os.path.join(result.out_dir, 'uboot.env') - self.CopyFiles(result.out_dir, build_dir, '', ['uboot.env']) + if not work_in_output: + self.CopyFiles(result.out_dir, build_dir, '', ['uboot.env']) # Write out the image sizes file. This is similar to the output # of binutil's 'size' utility, but it omits the header line and @@ -391,17 +390,21 @@ class BuilderThread(threading.Thread): with open(sizes, 'w') as fd: print('\n'.join(lines), file=fd) - # Write out the configuration files, with a special case for SPL - for dirname in ['', 'spl', 'tpl']: - self.CopyFiles(result.out_dir, build_dir, dirname, ['u-boot.cfg', - 'spl/u-boot-spl.cfg', 'tpl/u-boot-tpl.cfg', '.config', - 'include/autoconf.mk', 'include/generated/autoconf.h']) + if not work_in_output: + # Write out the configuration files, with a special case for SPL + for dirname in ['', 'spl', 'tpl']: + self.CopyFiles( + result.out_dir, build_dir, dirname, + ['u-boot.cfg', 'spl/u-boot-spl.cfg', 'tpl/u-boot-tpl.cfg', + '.config', 'include/autoconf.mk', + 'include/generated/autoconf.h']) - # Now write the actual build output - if keep_outputs: - self.CopyFiles(result.out_dir, build_dir, '', ['u-boot*', '*.bin', - '*.map', '*.img', 'MLO', 'SPL', 'include/autoconf.mk', - 'spl/u-boot-spl*']) + # Now write the actual build output + if keep_outputs: + self.CopyFiles( + result.out_dir, build_dir, '', + ['u-boot*', '*.bin', '*.map', '*.img', 'MLO', 'SPL', + 'include/autoconf.mk', 'spl/u-boot-spl*']) def CopyFiles(self, out_dir, build_dir, dirname, patterns): """Copy files from the build directory to the output. diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index e11dc8f899..29b28f5a9f 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -561,6 +561,10 @@ class TestFunctional(unittest.TestCase): boards=board_list) self.assertTrue( os.path.exists(os.path.join(self._output_dir, 'u-boot'))) + self.assertTrue( + os.path.exists(os.path.join(self._output_dir, 'done'))) + self.assertTrue( + os.path.exists(os.path.join(self._output_dir, 'out-env'))) def testWorkInOutputFail(self): """Test the -w option failures""" From 0d7a8c40333a018e6e7c4dcf64cf6ca3d7ea4ff6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:52 -0600 Subject: [PATCH 09/23] patman: Rename the main module Python does not like the module name being the same as the module directory. To allow patman modules to be used from other tools, rename it. Signed-off-by: Simon Glass --- tools/patman/{patman.py => main.py} | 27 ++++++++++++++------------- tools/patman/patman | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) rename tools/patman/{patman.py => main.py} (93%) diff --git a/tools/patman/patman.py b/tools/patman/main.py similarity index 93% rename from tools/patman/patman.py rename to tools/patman/main.py index 7f4ac9aef4..f3d9c0c434 100755 --- a/tools/patman/patman.py +++ b/tools/patman/main.py @@ -12,19 +12,20 @@ import re import sys import unittest +if __name__ == "__main__": + # Allow 'from patman import xxx to work' + our_path = os.path.dirname(os.path.realpath(__file__)) + sys.path.append(os.path.join(our_path, '..')) + # Our modules -try: - from patman import checkpatch, command, gitutil, patchstream, \ - project, settings, terminal, test -except ImportError: - import checkpatch - import command - import gitutil - import patchstream - import project - import settings - import terminal - import test +from patman import checkpatch +from patman import command +from patman import gitutil +from patman import patchstream +from patman import project +from patman import settings +from patman import terminal +from patman import test parser = OptionParser() @@ -85,7 +86,7 @@ if __name__ != "__main__": # Run our meagre tests elif options.test: import doctest - import func_test + from patman import func_test sys.argv = [sys.argv[0]] result = unittest.TestResult() diff --git a/tools/patman/patman b/tools/patman/patman index 6cc3d7a56a..11a5d8e18a 120000 --- a/tools/patman/patman +++ b/tools/patman/patman @@ -1 +1 @@ -patman.py \ No newline at end of file +main.py \ No newline at end of file From 515ce965d6e4681768fea877c299f4f90426ac65 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:53 -0600 Subject: [PATCH 10/23] rmboard: Move to Python 3 This script already works with Python 3. Make it use that by default so that it can import the patman libraries. Signed-off-by: Simon Glass --- tools/rmboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/rmboard.py b/tools/rmboard.py index df4f04b01c..1feface61d 100755 --- a/tools/rmboard.py +++ b/tools/rmboard.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#! /usr/bin/python3 # SPDX-License-Identifier: GPL-2.0+ # Copyright 2019 Google LLC # From 83a45187715e719bfe520b9ca0373bd8b5bee8aa Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:54 -0600 Subject: [PATCH 11/23] patman: Drop references to __future__ We don't need these now that the tools using Python 3. Drop them. Signed-off-by: Simon Glass --- tools/binman/binman.py | 2 -- tools/binman/cbfs_util.py | 2 -- tools/binman/cbfs_util_test.py | 2 -- tools/binman/control.py | 2 -- tools/binman/elf.py | 2 -- tools/binman/entry.py | 2 -- tools/binman/etype/section.py | 2 -- tools/binman/ftest.py | 2 -- tools/binman/image.py | 2 -- tools/buildman/buildman.py | 2 -- tools/dtoc/dtoc.py | 2 -- tools/dtoc/test_dtoc.py | 2 -- tools/dtoc/test_fdt.py | 2 -- tools/patman/series.py | 2 -- tools/patman/settings.py | 2 -- tools/patman/terminal.py | 2 -- tools/patman/test_util.py | 2 -- tools/patman/tools.py | 2 -- tools/patman/tout.py | 2 -- tools/rmboard.py | 2 -- 20 files changed, 40 deletions(-) diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 9e6fd72117..ec152e9b3b 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -9,8 +9,6 @@ """See README for more information""" -from __future__ import print_function - from distutils.sysconfig import get_python_lib import glob import multiprocessing diff --git a/tools/binman/cbfs_util.py b/tools/binman/cbfs_util.py index 99d77878c9..34c5116688 100644 --- a/tools/binman/cbfs_util.py +++ b/tools/binman/cbfs_util.py @@ -15,8 +15,6 @@ Currently supported: raw and stage types with compression, padding empty areas with empty files, fixed-offset files """ -from __future__ import print_function - from collections import OrderedDict import io import struct diff --git a/tools/binman/cbfs_util_test.py b/tools/binman/cbfs_util_test.py index ddc2e09e35..4aa2494fee 100755 --- a/tools/binman/cbfs_util_test.py +++ b/tools/binman/cbfs_util_test.py @@ -9,8 +9,6 @@ These create and read various CBFSs and compare the results with expected values and with cbfstool """ -from __future__ import print_function - import io import os import shutil diff --git a/tools/binman/control.py b/tools/binman/control.py index 68ad5fc2c0..82bc90d802 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -5,8 +5,6 @@ # Creates binary images from input files controlled by a description # -from __future__ import print_function - from collections import OrderedDict import os import sys diff --git a/tools/binman/elf.py b/tools/binman/elf.py index de1ce73f2a..29fdac1b8f 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -5,8 +5,6 @@ # Handle various things related to ELF images # -from __future__ import print_function - from collections import namedtuple, OrderedDict import command import io diff --git a/tools/binman/entry.py b/tools/binman/entry.py index b6f1b2c93f..1244d36c20 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -4,8 +4,6 @@ # Base class for all entries # -from __future__ import print_function - from collections import namedtuple import importlib import os diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 89b7bf67fa..87b3ddce86 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -8,8 +8,6 @@ Sections are entries which can contain other entries. This allows hierarchical images to be created. """ -from __future__ import print_function - from collections import OrderedDict import re import sys diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 872b855444..67f976e5d0 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -6,8 +6,6 @@ # # python -m unittest func_test.TestFunctional.testHelp -from __future__ import print_function - import hashlib from optparse import OptionParser import os diff --git a/tools/binman/image.py b/tools/binman/image.py index 2beab7fd4d..3e961733f9 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -5,8 +5,6 @@ # Class for an image, the output of binman # -from __future__ import print_function - from collections import OrderedDict import fnmatch from operator import attrgetter diff --git a/tools/buildman/buildman.py b/tools/buildman/buildman.py index 30a8690f93..0add628a63 100755 --- a/tools/buildman/buildman.py +++ b/tools/buildman/buildman.py @@ -6,8 +6,6 @@ """See README for more information""" -from __future__ import print_function - import multiprocessing import os import re diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py index f31cba900e..8e05b43431 100755 --- a/tools/dtoc/dtoc.py +++ b/tools/dtoc/dtoc.py @@ -25,8 +25,6 @@ options. For more information about the use of this options and tool please see doc/driver-model/of-plat.rst """ -from __future__ import print_function - from optparse import OptionParser import os import sys diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index d733b70655..9db97489d4 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -9,8 +9,6 @@ This includes unit tests for some functions and functional tests for the dtoc tool. """ -from __future__ import print_function - import collections import os import struct diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 3316757e61..4f39a5589f 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -4,8 +4,6 @@ # Written by Simon Glass # -from __future__ import print_function - from optparse import OptionParser import glob import os diff --git a/tools/patman/series.py b/tools/patman/series.py index 6d9d48b123..3869696abc 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -2,8 +2,6 @@ # Copyright (c) 2011 The Chromium OS Authors. # -from __future__ import print_function - import itertools import os diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 5dc83a8500..9ac96c485d 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -2,8 +2,6 @@ # Copyright (c) 2011 The Chromium OS Authors. # -from __future__ import print_function - try: import configparser as ConfigParser except: diff --git a/tools/patman/terminal.py b/tools/patman/terminal.py index 5c9e3eea20..c709438bdc 100644 --- a/tools/patman/terminal.py +++ b/tools/patman/terminal.py @@ -7,8 +7,6 @@ This module handles terminal interaction including ANSI color codes. """ -from __future__ import print_function - import os import re import shutil diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 09f258c26b..4338dbcd28 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -3,8 +3,6 @@ # Copyright (c) 2016 Google, Inc # -from __future__ import print_function - from contextlib import contextmanager import glob import os diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 3feddb292f..7b21a128f3 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -3,8 +3,6 @@ # Copyright (c) 2016 Google, Inc # -from __future__ import print_function - import command import glob import os diff --git a/tools/patman/tout.py b/tools/patman/tout.py index 2a384851b0..ee3c519c80 100644 --- a/tools/patman/tout.py +++ b/tools/patman/tout.py @@ -4,8 +4,6 @@ # Terminal output logging. # -from __future__ import print_function - import sys import terminal diff --git a/tools/rmboard.py b/tools/rmboard.py index 1feface61d..446e5d6ee2 100755 --- a/tools/rmboard.py +++ b/tools/rmboard.py @@ -23,8 +23,6 @@ This script works by: Search for ## to update the commit message manually. """ -from __future__ import print_function - import glob import os import re From c3a13cc3331846a900f0bf6d003357d5c6b7dbe3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:55 -0600 Subject: [PATCH 12/23] patman: Drop Python 2 StringIO code We can rely on Python 3 now, so drop the workaround for importing StringIO. Signed-off-by: Simon Glass --- tools/patman/func_test.py | 5 +---- tools/patman/settings.py | 5 +---- tools/patman/test_util.py | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index 76319fff37..748e225446 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -12,10 +12,7 @@ import sys import tempfile import unittest -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO import gitutil import patchstream diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 9ac96c485d..21e8fc41a9 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -34,10 +34,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser): - Merge general default settings/aliases with project-specific ones. # Sample config used for tests below... - >>> try: - ... from StringIO import StringIO - ... except ImportError: - ... from io import StringIO + >>> from io import StringIO >>> sample_config = ''' ... [alias] ... me: Peter P. diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 4338dbcd28..4d0085e2ed 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -10,10 +10,7 @@ import sys import command -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO PYTHON = 'python%d' % sys.version_info[0] From 7ec3dc57b33e2fa5f1da1ade259937f5631532c0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:56 -0600 Subject: [PATCH 13/23] buildman: Rename the main module Python does not like the module name being the same as the module directory. To allow buildman modules to be used from other tools, rename it. Signed-off-by: Simon Glass --- tools/buildman/buildman | 2 +- tools/buildman/{buildman.py => main.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tools/buildman/{buildman.py => main.py} (100%) diff --git a/tools/buildman/buildman b/tools/buildman/buildman index e4fba2d4b0..11a5d8e18a 120000 --- a/tools/buildman/buildman +++ b/tools/buildman/buildman @@ -1 +1 @@ -buildman.py \ No newline at end of file +main.py \ No newline at end of file diff --git a/tools/buildman/buildman.py b/tools/buildman/main.py similarity index 100% rename from tools/buildman/buildman.py rename to tools/buildman/main.py From 4d25fe2d952dd66d0f6c3f0dfdd4303e85d65333 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:57 -0600 Subject: [PATCH 14/23] dtoc: Rename the main module Python does not like the module name being the same as the module directory. To allow dtoc modules to be used from other tools, rename it. Signed-off-by: Simon Glass --- tools/dtoc/dtoc | 2 +- tools/dtoc/{dtoc.py => main.py} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename tools/dtoc/{dtoc.py => main.py} (98%) diff --git a/tools/dtoc/dtoc b/tools/dtoc/dtoc index 896ca44e62..11a5d8e18a 120000 --- a/tools/dtoc/dtoc +++ b/tools/dtoc/dtoc @@ -1 +1 @@ -dtoc.py \ No newline at end of file +main.py \ No newline at end of file diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/main.py similarity index 98% rename from tools/dtoc/dtoc.py rename to tools/dtoc/main.py index 8e05b43431..b1eee21f17 100755 --- a/tools/dtoc/dtoc.py +++ b/tools/dtoc/main.py @@ -77,7 +77,7 @@ def run_tests(args): def RunTestCoverage(): """Run the tests and check that we get 100% coverage""" sys.argv = [sys.argv[0]] - test_util.RunTestCoverage('tools/dtoc/dtoc.py', '/dtoc.py', + test_util.RunTestCoverage('tools/dtoc/dtoc', '/main.py', ['tools/patman/*.py', '*/fdt*', '*test*'], options.build_dir) From c07ab6effb76e7e4c9989012a4c0413c22577326 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:58 -0600 Subject: [PATCH 15/23] binman: Rename the main module Python does not like the module name being the same as the module directory. To allow buildman modules to be used from other tools, rename it. Signed-off-by: Simon Glass --- tools/binman/binman | 2 +- tools/binman/ftest.py | 6 +++--- tools/binman/{binman.py => main.py} | 4 ++-- tools/patman/test_util.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename tools/binman/{binman.py => main.py} (98%) diff --git a/tools/binman/binman b/tools/binman/binman index 979b7e4d4b..11a5d8e18a 120000 --- a/tools/binman/binman +++ b/tools/binman/binman @@ -1 +1 @@ -binman.py \ No newline at end of file +main.py \ No newline at end of file diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 67f976e5d0..0e2b50771e 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -15,7 +15,7 @@ import sys import tempfile import unittest -import binman +import main import cbfs_util import cmdline import command @@ -1428,14 +1428,14 @@ class TestFunctional(unittest.TestCase): def testEntryDocs(self): """Test for creation of entry documentation""" with test_util.capture_sys_output() as (stdout, stderr): - control.WriteEntryDocs(binman.GetEntryModules()) + control.WriteEntryDocs(main.GetEntryModules()) self.assertTrue(len(stdout.getvalue()) > 0) def testEntryDocsMissing(self): """Test handling of missing entry documentation""" with self.assertRaises(ValueError) as e: with test_util.capture_sys_output() as (stdout, stderr): - control.WriteEntryDocs(binman.GetEntryModules(), 'u_boot') + control.WriteEntryDocs(main.GetEntryModules(), 'u_boot') self.assertIn('Documentation is missing for modules: u_boot', str(e.exception)) diff --git a/tools/binman/binman.py b/tools/binman/main.py similarity index 98% rename from tools/binman/binman.py rename to tools/binman/main.py index ec152e9b3b..daff7ae4d3 100755 --- a/tools/binman/binman.py +++ b/tools/binman/main.py @@ -155,8 +155,8 @@ def RunTestCoverage(): glob_list = GetEntryModules(False) all_set = set([os.path.splitext(os.path.basename(item))[0] for item in glob_list if '_testing' not in item]) - test_util.RunTestCoverage('tools/binman/binman.py', None, - ['*test*', '*binman.py', 'tools/patman/*', 'tools/dtoc/*'], + test_util.RunTestCoverage('tools/binman/binman', None, + ['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*'], args.build_dir, all_set) def RunBinman(args): diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 4d0085e2ed..76dbc21e3a 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -41,7 +41,7 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): glob_list = [] glob_list += exclude_list glob_list += ['*libfdt.py', '*site-packages*', '*dist-packages*'] - test_cmd = 'test' if 'binman.py' in prog else '-t' + test_cmd = 'test' if 'binman' in prog else '-t' cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools %s-coverage run ' '--omit "%s" %s %s -P1' % (build_dir, PYTHON, ','.join(glob_list), prog, test_cmd)) From 76160801b0121515d6d33e4e26a54d34296687b4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:08:59 -0600 Subject: [PATCH 16/23] Add a 'make tcheck' option to test tools Running all the unit tests takes a while and is not useful when you are just modifying the tools. Add an option to run only the tools tests. Signed-off-by: Simon Glass --- Makefile | 6 +++++- test/run | 26 ++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index b8a4b5058a..b56250ab7d 100644 --- a/Makefile +++ b/Makefile @@ -512,7 +512,7 @@ dt_h := include/generated/dt.h no-dot-config-targets := clean clobber mrproper distclean \ help %docs check% coccicheck \ - ubootversion backup tests check qcheck + ubootversion backup tests check qcheck tcheck config-targets := 0 mixed-targets := 0 @@ -2098,6 +2098,7 @@ help: @echo '' @echo ' check - Run all automated tests that use sandbox' @echo ' qcheck - Run quick automated tests that use sandbox' + @echo ' tcheck - Run quick automated tests on tools' @echo '' @echo 'Other generic targets:' @echo ' all - Build all necessary images depending on configuration' @@ -2143,6 +2144,9 @@ tests check: qcheck: $(srctree)/test/run quick +tcheck: + $(srctree)/test/run tools + # Documentation targets # --------------------------------------------------------------------------- DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \ diff --git a/test/run b/test/run index d635622c10..27331a8e40 100755 --- a/test/run +++ b/test/run @@ -15,22 +15,29 @@ run_test() { # SKip slow tests if requested [ "$1" == "quick" ] && mark_expr="not slow" +[ "$1" == "quick" ] && skip=--skip-net-tests +[ "$1" == "tools" ] && tools_only=y failures=0 -# Run all tests that the standard sandbox build can support -run_test "sandbox" ./test/py/test.py --bd sandbox --build -m "${mark_expr}" +if [ -z "$tools_only" ]; then + # Run all tests that the standard sandbox build can support + run_test "sandbox" ./test/py/test.py --bd sandbox --build \ + -m "${mark_expr}" +fi # Run tests which require sandbox_spl run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build \ - -k 'test_ofplatdata or test_handoff' + -k 'test_ofplatdata or test_handoff' -# Run tests for the flat-device-tree version of sandbox. This is a special -# build which does not enable CONFIG_OF_LIVE for the live device tree, so we can -# check that functionality is the same. The standard sandbox build (above) uses -# CONFIG_OF_LIVE. -run_test "sandbox_flattree" ./test/py/test.py --bd sandbox_flattree --build \ - -k test_ut +if [ -z "$tools_only" ]; then + # Run tests for the flat-device-tree version of sandbox. This is a special + # build which does not enable CONFIG_OF_LIVE for the live device tree, so we can + # check that functionality is the same. The standard sandbox build (above) uses + # CONFIG_OF_LIVE. + run_test "sandbox_flattree" ./test/py/test.py --bd sandbox_flattree \ + --build -k test_ut +fi # Set up a path to dtc (device-tree compiler) and libfdt.py, a library it # provides and which is built by the sandbox_spl config. Also set up the path @@ -43,7 +50,6 @@ TOOLS_DIR=build-sandbox_spl/tools run_test "binman" ./tools/binman/binman --toolpath ${TOOLS_DIR} test run_test "patman" ./tools/patman/patman --test -[ "$1" == "quick" ] && skip=--skip-net-tests run_test "buildman" ./tools/buildman/buildman -t ${skip} run_test "fdt" ./tools/dtoc/test_fdt -t run_test "dtoc" ./tools/dtoc/dtoc -t From 428e773011b319b50db0ff7d5cf331ec37f75175 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:09:00 -0600 Subject: [PATCH 17/23] patman: Drop the python2 code in test coverage We don't need to run test coverage with Python 2 now. Drop the special-case code. Signed-off-by: Simon Glass --- tools/patman/test_util.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 76dbc21e3a..6575b11c1a 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -12,8 +12,6 @@ import command from io import StringIO -PYTHON = 'python%d' % sys.version_info[0] - def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): """Run tests and check that we get 100% coverage @@ -42,11 +40,14 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): glob_list += exclude_list glob_list += ['*libfdt.py', '*site-packages*', '*dist-packages*'] test_cmd = 'test' if 'binman' in prog else '-t' - cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools %s-coverage run ' - '--omit "%s" %s %s -P1' % (build_dir, PYTHON, ','.join(glob_list), + prefix = '' + if build_dir: + prefix = 'PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools ' % build_dir + cmd = ('%spython3-coverage run ' + '--omit "%s" %s %s -P1' % (prefix, ','.join(glob_list), prog, test_cmd)) os.system(cmd) - stdout = command.Output('%s-coverage' % PYTHON, 'report') + stdout = command.Output('python3-coverage', 'report') lines = stdout.splitlines() if required: # Convert '/path/to/name.py' just the module name 'name' @@ -65,8 +66,8 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): print(coverage) if coverage != '100%': print(stdout) - print("Type '%s-coverage html' to get a report in " - 'htmlcov/index.html' % PYTHON) + print("Type 'python3-coverage html' to get a report in " + 'htmlcov/index.html') print('Coverage error: %s, but should be 100%%' % coverage) ok = False if not ok: From ce0dc2edfc51dba5134d50a49ac8a18667fb55b2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:09:01 -0600 Subject: [PATCH 18/23] patman: Move test running/reporting to test_util This code is useful in other tools. Move it into a common file so it can be shared. Signed-off-by: Simon Glass --- tools/binman/main.py | 76 +++-------------------------- tools/patman/test_util.py | 100 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 69 deletions(-) diff --git a/tools/binman/main.py b/tools/binman/main.py index daff7ae4d3..a17764cdb0 100755 --- a/tools/binman/main.py +++ b/tools/binman/main.py @@ -11,7 +11,6 @@ from distutils.sysconfig import get_python_lib import glob -import multiprocessing import os import site import sys @@ -37,11 +36,6 @@ sys.path.append(get_python_lib()) import cmdline import command -use_concurrent = True -try: - from concurrencytest import ConcurrentTestSuite, fork_for_tests -except: - use_concurrent = False import control import test_util @@ -71,73 +65,17 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): import doctest result = unittest.TestResult() - for module in []: - suite = doctest.DocTestSuite(module) - suite.run(result) - - sys.argv = [sys.argv[0]] - if debug: - sys.argv.append('-D') - if verbosity: - sys.argv.append('-v%d' % verbosity) - if toolpath: - for path in toolpath: - sys.argv += ['--toolpath', path] + test_name = args and args[0] or None # Run the entry tests first ,since these need to be the first to import the # 'entry' module. - test_name = args and args[0] or None - suite = unittest.TestSuite() - loader = unittest.TestLoader() - for module in (entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt, - elf_test.TestElf, image_test.TestImage, - cbfs_util_test.TestCbfs): - # Test the test module about our arguments, if it is interested - if hasattr(module, 'setup_test_args'): - setup_test_args = getattr(module, 'setup_test_args') - setup_test_args(preserve_indir=test_preserve_dirs, - preserve_outdirs=test_preserve_dirs and test_name is not None, - toolpath=toolpath, verbosity=verbosity) - if test_name: - try: - suite.addTests(loader.loadTestsFromName(test_name, module)) - except AttributeError: - continue - else: - suite.addTests(loader.loadTestsFromTestCase(module)) - if use_concurrent and processes != 1: - concurrent_suite = ConcurrentTestSuite(suite, - fork_for_tests(processes or multiprocessing.cpu_count())) - concurrent_suite.run(result) - else: - suite.run(result) + test_util.RunTestSuites( + result, debug, verbosity, test_preserve_dirs, processes, test_name, + toolpath, + [entry_test.TestEntry, ftest.TestFunctional, fdt_test.TestFdt, + elf_test.TestElf, image_test.TestImage, cbfs_util_test.TestCbfs]) - # Remove errors which just indicate a missing test. Since Python v3.5 If an - # ImportError or AttributeError occurs while traversing name then a - # synthetic test that raises that error when run will be returned. These - # errors are included in the errors accumulated by result.errors. - if test_name: - errors = [] - for test, err in result.errors: - if ("has no attribute '%s'" % test_name) not in err: - errors.append((test, err)) - result.testsRun -= 1 - result.errors = errors - - print(result) - for test, err in result.errors: - print(test.id(), err) - for test, err in result.failures: - print(err, result.failures) - if result.skipped: - print('%d binman test%s SKIPPED:' % - (len(result.skipped), 's' if len(result.skipped) > 1 else '')) - for skip_info in result.skipped: - print('%s: %s' % (skip_info[0], skip_info[1])) - if result.errors or result.failures: - print('binman tests FAILED') - return 1 - return 0 + return test_util.ReportResult('binman', test_name, result) def GetEntryModules(include_testing=True): """Get a set of entry class implementations diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 6575b11c1a..bb5a298e39 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -5,13 +5,21 @@ from contextlib import contextmanager import glob +import multiprocessing import os import sys +import unittest import command from io import StringIO +use_concurrent = True +try: + from concurrencytest import ConcurrentTestSuite, fork_for_tests +except: + use_concurrent = False + def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): """Run tests and check that we get 100% coverage @@ -86,3 +94,95 @@ def capture_sys_output(): yield capture_out, capture_err finally: sys.stdout, sys.stderr = old_out, old_err + + +def ReportResult(toolname:str, test_name: str, result: unittest.TestResult): + """Report the results from a suite of tests + + Args: + toolname: Name of the tool that ran the tests + test_name: Name of test that was run, or None for all + result: A unittest.TestResult object containing the results + """ + # Remove errors which just indicate a missing test. Since Python v3.5 If an + # ImportError or AttributeError occurs while traversing name then a + # synthetic test that raises that error when run will be returned. These + # errors are included in the errors accumulated by result.errors. + if test_name: + errors = [] + + for test, err in result.errors: + if ("has no attribute '%s'" % test_name) not in err: + errors.append((test, err)) + result.testsRun -= 1 + result.errors = errors + + print(result) + for test, err in result.errors: + print(test.id(), err) + for test, err in result.failures: + print(err, result.failures) + if result.skipped: + print('%d binman test%s SKIPPED:' % + (len(result.skipped), 's' if len(result.skipped) > 1 else '')) + for skip_info in result.skipped: + print('%s: %s' % (skip_info[0], skip_info[1])) + if result.errors or result.failures: + print('binman tests FAILED') + return 1 + return 0 + + +def RunTestSuites(result, debug, verbosity, test_preserve_dirs, processes, + test_name, toolpath, test_class_list): + """Run a series of test suites and collect the results + + Args: + result: A unittest.TestResult object to add the results to + debug: True to enable debugging, which shows a full stack trace on error + verbosity: Verbosity level to use (0-4) + test_preserve_dirs: True to preserve the input directory used by tests + so that it can be examined afterwards (only useful for debugging + tests). If a single test is selected (in args[0]) it also preserves + the output directory for this test. Both directories are displayed + on the command line. + processes: Number of processes to use to run tests (None=same as #CPUs) + test_name: Name of test to run, or None for all + toolpath: List of paths to use for tools + test_class_list: List of test classes to run + """ + for module in []: + suite = doctest.DocTestSuite(module) + suite.run(result) + + sys.argv = [sys.argv[0]] + if debug: + sys.argv.append('-D') + if verbosity: + sys.argv.append('-v%d' % verbosity) + if toolpath: + for path in toolpath: + sys.argv += ['--toolpath', path] + + suite = unittest.TestSuite() + loader = unittest.TestLoader() + for module in test_class_list: + # Test the test module about our arguments, if it is interested + if hasattr(module, 'setup_test_args'): + setup_test_args = getattr(module, 'setup_test_args') + setup_test_args(preserve_indir=test_preserve_dirs, + preserve_outdirs=test_preserve_dirs and test_name is not None, + toolpath=toolpath, verbosity=verbosity) + if test_name: + try: + suite.addTests(loader.loadTestsFromName(test_name, module)) + except AttributeError: + continue + else: + suite.addTests(loader.loadTestsFromTestCase(module)) + if use_concurrent and processes != 1: + concurrent_suite = ConcurrentTestSuite(suite, + fork_for_tests(processes or multiprocessing.cpu_count())) + concurrent_suite.run(result) + else: + suite.run(result) From 0ede00fdaf1d2162350631294f57645675737d89 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:09:02 -0600 Subject: [PATCH 19/23] buildman: Move to absolute imports At present buildman sets the python path on startup so that it can access the libraries it needs. If we convert to use absolute imports this is not necessary. Move buildman to use absolute imports. Also adjust moveconfig.py too since it uses some buildman modules and cannot work without this. Signed-off-by: Simon Glass --- tools/buildman/builder.py | 4 ++-- tools/buildman/control.py | 12 ++++++------ tools/buildman/func_test.py | 9 +++++---- tools/buildman/main.py | 20 ++++++++++---------- tools/buildman/test.py | 12 ++++++------ tools/buildman/toolchain.py | 2 +- tools/moveconfig.py | 8 ++++---- 7 files changed, 34 insertions(+), 33 deletions(-) diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index 1b61e3a837..b7f2c426e3 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -17,12 +17,12 @@ import sys import threading import time -import builderthread +from buildman import builderthread +from buildman import toolchain import command import gitutil import terminal from terminal import Print -import toolchain """ Theory of Operation diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 7c8d7520fb..e05234c08f 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -5,18 +5,18 @@ import multiprocessing import os import shutil +import subprocess import sys -import board -import bsettings -from builder import Builder +from buildman import board +from buildman import bsettings +from buildman import toolchain +from buildman.builder import Builder +import command import gitutil import patchstream import terminal from terminal import Print -import toolchain -import command -import subprocess def GetPlural(count): """Returns a plural 's' if count is not 1""" diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 29b28f5a9f..9bfdd53698 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -8,11 +8,12 @@ import sys import tempfile import unittest -import board -import bsettings -import cmdline +from buildman import board +from buildman import bsettings +from buildman import cmdline +from buildman import control +from buildman import toolchain import command -import control import gitutil import terminal import toolchain diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 0add628a63..94d495c40b 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -6,6 +6,7 @@ """See README for more information""" +import doctest import multiprocessing import os import re @@ -14,20 +15,19 @@ import unittest # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.insert(1, os.path.join(our_path, '../patman')) +sys.path.insert(1, os.path.join(our_path, '..')) +sys.path.insert(2, os.path.join(our_path, '../patman')) # Our modules -import board -import bsettings -import builder -import checkpatch -import cmdline -import control -import doctest -import gitutil +from buildman import board +from buildman import bsettings +from buildman import builder +from buildman import cmdline +from buildman import control +from buildman import toolchain import patchstream +import gitutil import terminal -import toolchain def RunTests(skip_net_tests): import func_test diff --git a/tools/buildman/test.py b/tools/buildman/test.py index 8b6d138f70..87175eeb63 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -13,15 +13,15 @@ import unittest our_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(our_path, '../patman')) -import board -import bsettings -import builder -import control -import command +from buildman import board +from buildman import bsettings +from buildman import builder +from buildman import control +from buildman import toolchain import commit +import command import terminal import test_util -import toolchain import tools use_network = True diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 4456a805c7..a3540491ec 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -10,7 +10,7 @@ import sys import tempfile import urllib.request, urllib.error, urllib.parse -import bsettings +from buildman import bsettings import command import terminal import tools diff --git a/tools/moveconfig.py b/tools/moveconfig.py index d8bf7fd071..0dd8670403 100755 --- a/tools/moveconfig.py +++ b/tools/moveconfig.py @@ -314,11 +314,11 @@ import tempfile import threading import time -sys.path.append(os.path.join(os.path.dirname(__file__), 'buildman')) +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) sys.path.append(os.path.join(os.path.dirname(__file__), 'patman')) -import bsettings -import kconfiglib -import toolchain +from buildman import bsettings +from buildman import kconfiglib +from buildman import toolchain SHOW_GNU_MAKE = 'scripts/show-gnu-make' SLEEP_TIME=0.03 From 16287933a852bab2ac4985a770e08c9aa69d21b1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:09:03 -0600 Subject: [PATCH 20/23] binman: Move to absolute imports At present binman sets the python path on startup so that it can access the libraries it needs. If we convert to use absolute imports this is not necessary. Move binman to use absolute imports. This enables removable of the path adjusting in Entry also. Signed-off-by: Simon Glass --- tools/binman/cbfs_util.py | 2 +- tools/binman/cbfs_util_test.py | 6 +-- tools/binman/control.py | 12 +++--- tools/binman/elf.py | 2 +- tools/binman/elf_test.py | 2 +- tools/binman/entry.py | 16 +++----- tools/binman/entry_test.py | 10 ++--- tools/binman/etype/__init__.py | 0 tools/binman/etype/_testing.py | 4 +- tools/binman/etype/blob.py | 4 +- tools/binman/etype/blob_dtb.py | 6 +-- tools/binman/etype/blob_named_by_arg.py | 4 +- tools/binman/etype/cbfs.py | 10 ++--- tools/binman/etype/cros_ec_rw.py | 2 +- tools/binman/etype/fdtmap.py | 6 +-- tools/binman/etype/files.py | 6 +-- tools/binman/etype/fill.py | 4 +- tools/binman/etype/fmap.py | 6 +-- tools/binman/etype/gbb.py | 4 +- tools/binman/etype/image_header.py | 4 +- tools/binman/etype/intel_cmc.py | 4 +- tools/binman/etype/intel_descriptor.py | 4 +- tools/binman/etype/intel_fit.py | 2 +- tools/binman/etype/intel_fit_ptr.py | 2 +- tools/binman/etype/intel_fsp.py | 4 +- tools/binman/etype/intel_fsp_m.py | 4 +- tools/binman/etype/intel_fsp_s.py | 4 +- tools/binman/etype/intel_fsp_t.py | 4 +- tools/binman/etype/intel_ifwi.py | 6 +-- tools/binman/etype/intel_me.py | 4 +- tools/binman/etype/intel_mrc.py | 4 +- tools/binman/etype/intel_refcode.py | 4 +- tools/binman/etype/intel_vbt.py | 4 +- tools/binman/etype/intel_vga.py | 4 +- .../etype/powerpc_mpc85xx_bootpg_resetvec.py | 4 +- tools/binman/etype/section.py | 4 +- tools/binman/etype/text.py | 4 +- tools/binman/etype/u_boot.py | 4 +- tools/binman/etype/u_boot_dtb.py | 4 +- tools/binman/etype/u_boot_dtb_with_ucode.py | 8 ++-- tools/binman/etype/u_boot_elf.py | 6 +-- tools/binman/etype/u_boot_img.py | 4 +- tools/binman/etype/u_boot_nodtb.py | 4 +- tools/binman/etype/u_boot_spl.py | 7 ++-- tools/binman/etype/u_boot_spl_bss_pad.py | 6 +-- tools/binman/etype/u_boot_spl_dtb.py | 4 +- tools/binman/etype/u_boot_spl_elf.py | 4 +- tools/binman/etype/u_boot_spl_nodtb.py | 4 +- .../binman/etype/u_boot_spl_with_ucode_ptr.py | 6 +-- tools/binman/etype/u_boot_tpl.py | 7 ++-- tools/binman/etype/u_boot_tpl_dtb.py | 4 +- .../binman/etype/u_boot_tpl_dtb_with_ucode.py | 5 +-- tools/binman/etype/u_boot_tpl_elf.py | 4 +- .../binman/etype/u_boot_tpl_with_ucode_ptr.py | 6 +-- tools/binman/etype/u_boot_ucode.py | 4 +- tools/binman/etype/u_boot_with_ucode_ptr.py | 10 ++--- tools/binman/etype/vblock.py | 4 +- tools/binman/etype/x86_reset16.py | 4 +- tools/binman/etype/x86_reset16_spl.py | 4 +- tools/binman/etype/x86_reset16_tpl.py | 4 +- tools/binman/etype/x86_start16.py | 4 +- tools/binman/etype/x86_start16_spl.py | 4 +- tools/binman/etype/x86_start16_tpl.py | 4 +- tools/binman/fdt_test.py | 6 +-- tools/binman/ftest.py | 39 ++++++++++--------- tools/binman/image.py | 12 +++--- tools/binman/image_test.py | 2 +- tools/binman/main.py | 23 ++++++----- tools/binman/state.py | 6 +-- tools/patman/main.py | 20 +++++----- 70 files changed, 199 insertions(+), 214 deletions(-) delete mode 100644 tools/binman/etype/__init__.py diff --git a/tools/binman/cbfs_util.py b/tools/binman/cbfs_util.py index 34c5116688..f7c3cd0d0e 100644 --- a/tools/binman/cbfs_util.py +++ b/tools/binman/cbfs_util.py @@ -20,8 +20,8 @@ import io import struct import sys +from binman import elf import command -import elf import tools # Set to True to enable printing output while working diff --git a/tools/binman/cbfs_util_test.py b/tools/binman/cbfs_util_test.py index 4aa2494fee..a929612b19 100755 --- a/tools/binman/cbfs_util_test.py +++ b/tools/binman/cbfs_util_test.py @@ -16,9 +16,9 @@ import struct import tempfile import unittest -import cbfs_util -from cbfs_util import CbfsWriter -import elf +from binman import cbfs_util +from binman.cbfs_util import CbfsWriter +from binman import elf import test_util import tools diff --git a/tools/binman/control.py b/tools/binman/control.py index 82bc90d802..d715b601b9 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -10,9 +10,9 @@ import os import sys import tools -import cbfs_util +from binman import cbfs_util +from binman import elf import command -import elf import tout # List of images we plan to create @@ -60,7 +60,7 @@ def WriteEntryDocs(modules, test_missing=None): to show as missing even if it is present. Should be set to None in normal use. """ - from entry import Entry + from binman.entry import Entry Entry.WriteDocs(modules, test_missing) @@ -334,8 +334,8 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt): """ # Import these here in case libfdt.py is not available, in which case # the above help option still works. - import fdt - import fdt_util + from dtoc import fdt + from dtoc import fdt_util global images # Get the device tree ready by compiling it and copying the compiled @@ -473,7 +473,7 @@ def Binman(args): # Put these here so that we can import this module without libfdt from image import Image - import state + from binman import state if args.cmd in ['ls', 'extract', 'replace']: try: diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 29fdac1b8f..335d411303 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -6,7 +6,6 @@ # from collections import namedtuple, OrderedDict -import command import io import os import re @@ -14,6 +13,7 @@ import shutil import struct import tempfile +import command import tools import tout diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index ac26fd51e4..e4497f30fc 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -10,8 +10,8 @@ import sys import tempfile import unittest +from binman import elf import command -import elf import test_util import tools import tout diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 1244d36c20..9f62322bed 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -9,9 +9,9 @@ import importlib import os import sys -import fdt_util +from dtoc import fdt_util import tools -from tools import ToHex, ToHexSize +from patman.tools import ToHex, ToHexSize import tout modules = {} @@ -63,7 +63,7 @@ class Entry(object): def __init__(self, section, etype, node, name_prefix=''): # Put this here to allow entry-docs and help to work without libfdt global state - import state + from binman import state self.section = section self.etype = etype @@ -108,15 +108,11 @@ class Entry(object): # Import the module if we have not already done so. if not module: - old_path = sys.path - sys.path.insert(0, os.path.join(our_path, 'etype')) try: - module = importlib.import_module(module_name) + module = importlib.import_module('binman.etype.' + module_name) except ImportError as e: raise ValueError("Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" % (etype, node_path, module_name, e)) - finally: - sys.path = old_path modules[module_name] = module # Look up the expected class name @@ -590,9 +586,7 @@ features to produce new behaviours. modules.remove('_testing') missing = [] for name in modules: - if name.startswith('__'): - continue - module = Entry.Lookup(name, name) + module = Entry.Lookup('WriteDocs', name) docs = getattr(module, '__doc__') if test_missing == name: docs = None diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py index 277e10b585..ca5bb0fe1b 100644 --- a/tools/binman/entry_test.py +++ b/tools/binman/entry_test.py @@ -9,9 +9,9 @@ import os import sys import unittest -import entry -import fdt -import fdt_util +from binman import entry +from dtoc import fdt +from dtoc import fdt_util import tools class TestEntry(unittest.TestCase): @@ -37,11 +37,11 @@ class TestEntry(unittest.TestCase): else: reload(entry) else: - import entry + from binman import entry def testEntryContents(self): """Test the Entry bass class""" - import entry + from binman import entry base_entry = entry.Entry(None, None, None) self.assertEqual(True, base_entry.ObtainContents()) diff --git a/tools/binman/etype/__init__.py b/tools/binman/etype/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py index 25a6206bf3..4cde8df6f5 100644 --- a/tools/binman/etype/_testing.py +++ b/tools/binman/etype/_testing.py @@ -7,8 +7,8 @@ from collections import OrderedDict -from entry import Entry, EntryArg -import fdt_util +from binman.entry import Entry, EntryArg +from dtoc import fdt_util import tools diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index d34c7b51bf..409beaadcc 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -5,8 +5,8 @@ # Entry-type module for blobs, which are binary objects read from files # -from entry import Entry -import fdt_util +from binman.entry import Entry +from dtoc import fdt_util import tools import tout diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py index b2afa064c1..6c06943763 100644 --- a/tools/binman/etype/blob_dtb.py +++ b/tools/binman/etype/blob_dtb.py @@ -5,8 +5,8 @@ # Entry-type module for U-Boot device tree files # -from entry import Entry -from blob import Entry_blob +from binman.entry import Entry +from binman.etype.blob import Entry_blob class Entry_blob_dtb(Entry_blob): """A blob that holds a device tree @@ -18,7 +18,7 @@ class Entry_blob_dtb(Entry_blob): def __init__(self, section, etype, node): # Put this here to allow entry-docs and help to work without libfdt global state - import state + from binman import state Entry_blob.__init__(self, section, etype, node) diff --git a/tools/binman/etype/blob_named_by_arg.py b/tools/binman/etype/blob_named_by_arg.py index 344112bc42..3b4593f071 100644 --- a/tools/binman/etype/blob_named_by_arg.py +++ b/tools/binman/etype/blob_named_by_arg.py @@ -8,8 +8,8 @@ from collections import OrderedDict -from blob import Entry_blob -from entry import EntryArg +from binman.etype.blob import Entry_blob +from binman.entry import EntryArg class Entry_blob_named_by_arg(Entry_blob): diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 35b78370b2..e9aed8310c 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -7,10 +7,10 @@ from collections import OrderedDict -import cbfs_util -from cbfs_util import CbfsWriter -from entry import Entry -import fdt_util +from binman import cbfs_util +from binman.cbfs_util import CbfsWriter +from binman.entry import Entry +from dtoc import fdt_util class Entry_cbfs(Entry): """Entry containing a Coreboot Filesystem (CBFS) @@ -165,7 +165,7 @@ class Entry_cbfs(Entry): def __init__(self, section, etype, node): # Put this here to allow entry-docs and help to work without libfdt global state - import state + from binman import state Entry.__init__(self, section, etype, node) self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86') diff --git a/tools/binman/etype/cros_ec_rw.py b/tools/binman/etype/cros_ec_rw.py index 261f8657a6..0dbe14b342 100644 --- a/tools/binman/etype/cros_ec_rw.py +++ b/tools/binman/etype/cros_ec_rw.py @@ -5,7 +5,7 @@ # Entry-type module for a Chromium OS EC image (read-write section) # -from blob_named_by_arg import Entry_blob_named_by_arg +from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg class Entry_cros_ec_rw(Entry_blob_named_by_arg): diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py index 5dc08b8289..820f34515a 100644 --- a/tools/binman/etype/fdtmap.py +++ b/tools/binman/etype/fdtmap.py @@ -8,7 +8,7 @@ This handles putting an FDT into the image with just the information about the image. """ -from entry import Entry +from binman.entry import Entry import tools import tout @@ -82,8 +82,8 @@ class Entry_fdtmap(Entry): global Fdt import libfdt - import state - from fdt import Fdt + from binman import state + from dtoc.fdt import Fdt Entry.__init__(self, section, etype, node) diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py index 3473a2b1ef..7b4fc7db91 100644 --- a/tools/binman/etype/files.py +++ b/tools/binman/etype/files.py @@ -9,8 +9,8 @@ import glob import os -from section import Entry_section -import fdt_util +from binman.etype.section import Entry_section +from dtoc import fdt_util import tools @@ -30,7 +30,7 @@ class Entry_files(Entry_section): def __init__(self, section, etype, node): # Put this here to allow entry-docs and help to work without libfdt global state - import state + from binman import state Entry_section.__init__(self, section, etype, node) self._pattern = fdt_util.GetString(self._node, 'pattern') diff --git a/tools/binman/etype/fill.py b/tools/binman/etype/fill.py index 623b7f4e95..1124ef26ea 100644 --- a/tools/binman/etype/fill.py +++ b/tools/binman/etype/fill.py @@ -3,8 +3,8 @@ # Written by Simon Glass # -from entry import Entry -import fdt_util +from binman.entry import Entry +from dtoc import fdt_util import tools class Entry_fill(Entry): diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py index 835ba5012e..a155beb617 100644 --- a/tools/binman/etype/fmap.py +++ b/tools/binman/etype/fmap.py @@ -5,10 +5,10 @@ # Entry-type module for a Flash map, as used by the flashrom SPI flash tool # -from entry import Entry -import fmap_util +from binman.entry import Entry +from binman import fmap_util import tools -from tools import ToHexSize +from patman.tools import ToHexSize import tout diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py index a94c0fca9d..0fc7667908 100644 --- a/tools/binman/etype/gbb.py +++ b/tools/binman/etype/gbb.py @@ -9,9 +9,9 @@ from collections import OrderedDict import command -from entry import Entry, EntryArg +from binman.entry import Entry, EntryArg -import fdt_util +from dtoc import fdt_util import tools # Build GBB flags. diff --git a/tools/binman/etype/image_header.py b/tools/binman/etype/image_header.py index b9327dd799..176bdeb29b 100644 --- a/tools/binman/etype/image_header.py +++ b/tools/binman/etype/image_header.py @@ -11,8 +11,8 @@ image. import struct -from entry import Entry -import fdt_util +from binman.entry import Entry +from dtoc import fdt_util IMAGE_HEADER_MAGIC = b'BinM' IMAGE_HEADER_LEN = 8 diff --git a/tools/binman/etype/intel_cmc.py b/tools/binman/etype/intel_cmc.py index fa6f7793c6..5e6edbe4df 100644 --- a/tools/binman/etype/intel_cmc.py +++ b/tools/binman/etype/intel_cmc.py @@ -5,8 +5,8 @@ # Entry-type module for Intel Chip Microcode binary blob # -from entry import Entry -from blob import Entry_blob +from binman.entry import Entry +from binman.etype.blob import Entry_blob class Entry_intel_cmc(Entry_blob): """Entry containing an Intel Chipset Micro Code (CMC) file diff --git a/tools/binman/etype/intel_descriptor.py b/tools/binman/etype/intel_descriptor.py index b6477931d6..d4d7a26901 100644 --- a/tools/binman/etype/intel_descriptor.py +++ b/tools/binman/etype/intel_descriptor.py @@ -7,8 +7,8 @@ import struct -from entry import Entry -from blob import Entry_blob +from binman.entry import Entry +from binman.etype.blob import Entry_blob FD_SIGNATURE = struct.pack(' Date: Fri, 17 Apr 2020 18:09:04 -0600 Subject: [PATCH 21/23] patman: Move to absolute imports At present patman sets the python path on startup so that it can access the libraries it needs. If we convert to use absolute imports this is not necessary. Move patman to use absolute imports. This requires changes in tools which use the patman libraries (which is most of them). Signed-off-by: Simon Glass --- tools/binman/cbfs_util.py | 4 ++-- tools/binman/cbfs_util_test.py | 4 ++-- tools/binman/control.py | 6 +++--- tools/binman/elf.py | 6 +++--- tools/binman/elf_test.py | 8 ++++---- tools/binman/entry.py | 4 ++-- tools/binman/entry_test.py | 2 +- tools/binman/etype/_testing.py | 2 +- tools/binman/etype/blob.py | 4 ++-- tools/binman/etype/fdtmap.py | 4 ++-- tools/binman/etype/files.py | 2 +- tools/binman/etype/fill.py | 2 +- tools/binman/etype/fmap.py | 4 ++-- tools/binman/etype/gbb.py | 4 ++-- tools/binman/etype/intel_ifwi.py | 2 +- tools/binman/etype/section.py | 4 ++-- tools/binman/etype/text.py | 2 +- tools/binman/etype/u_boot_dtb_with_ucode.py | 2 +- tools/binman/etype/u_boot_elf.py | 2 +- tools/binman/etype/u_boot_spl_bss_pad.py | 4 ++-- .../binman/etype/u_boot_tpl_with_ucode_ptr.py | 4 ++-- tools/binman/etype/u_boot_ucode.py | 2 +- tools/binman/etype/u_boot_with_ucode_ptr.py | 4 ++-- tools/binman/etype/vblock.py | 2 +- tools/binman/fdt_test.py | 2 +- tools/binman/fmap_util.py | 2 +- tools/binman/ftest.py | 8 ++++---- tools/binman/image.py | 4 ++-- tools/binman/main.py | 2 +- tools/binman/state.py | 4 ++-- tools/buildman/builder.py | 8 ++++---- tools/buildman/builderthread.py | 4 ++-- tools/buildman/control.py | 10 +++++----- tools/buildman/func_test.py | 9 ++++----- tools/buildman/main.py | 6 +++--- tools/buildman/test.py | 10 +++++----- tools/buildman/toolchain.py | 6 +++--- tools/dtoc/dtb_platdata.py | 6 +++--- tools/dtoc/fdt.py | 4 ++-- tools/dtoc/fdt_util.py | 4 ++-- tools/dtoc/main.py | 5 +++-- tools/dtoc/test_dtoc.py | 10 +++++----- tools/dtoc/test_fdt.py | 12 ++++++------ tools/patman/checkpatch.py | 8 +++++--- tools/patman/command.py | 5 +++-- tools/patman/func_test.py | 8 ++++---- tools/patman/get_maintainer.py | 5 +++-- tools/patman/gitutil.py | 12 ++++++------ tools/patman/main.py | 18 +++++++++--------- tools/patman/patchstream.py | 8 ++++---- tools/patman/project.py | 2 +- tools/patman/series.py | 10 +++++----- tools/patman/settings.py | 6 +++--- tools/patman/test.py | 10 +++++----- tools/patman/test_util.py | 3 ++- tools/patman/tools.py | 4 ++-- tools/patman/tout.py | 2 +- tools/rmboard.py | 2 +- 58 files changed, 154 insertions(+), 149 deletions(-) diff --git a/tools/binman/cbfs_util.py b/tools/binman/cbfs_util.py index f7c3cd0d0e..39973371b9 100644 --- a/tools/binman/cbfs_util.py +++ b/tools/binman/cbfs_util.py @@ -21,8 +21,8 @@ import struct import sys from binman import elf -import command -import tools +from patman import command +from patman import tools # Set to True to enable printing output while working DEBUG = False diff --git a/tools/binman/cbfs_util_test.py b/tools/binman/cbfs_util_test.py index a929612b19..2c62c8a0f8 100755 --- a/tools/binman/cbfs_util_test.py +++ b/tools/binman/cbfs_util_test.py @@ -19,8 +19,8 @@ import unittest from binman import cbfs_util from binman.cbfs_util import CbfsWriter from binman import elf -import test_util -import tools +from patman import test_util +from patman import tools U_BOOT_DATA = b'1234' U_BOOT_DTB_DATA = b'udtb' diff --git a/tools/binman/control.py b/tools/binman/control.py index d715b601b9..dc1dd2a7dc 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -8,12 +8,12 @@ from collections import OrderedDict import os import sys -import tools +from patman import tools from binman import cbfs_util from binman import elf -import command -import tout +from patman import command +from patman import tout # List of images we plan to create # Make this global so that it can be referenced from tests diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 335d411303..f88031c2bf 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -13,9 +13,9 @@ import shutil import struct import tempfile -import command -import tools -import tout +from patman import command +from patman import tools +from patman import tout ELF_TOOLS = True try: diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index e4497f30fc..37e1b423cf 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -11,10 +11,10 @@ import tempfile import unittest from binman import elf -import command -import test_util -import tools -import tout +from patman import command +from patman import test_util +from patman import tools +from patman import tout binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 9f62322bed..90ffd27617 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -10,9 +10,9 @@ import os import sys from dtoc import fdt_util -import tools +from patman import tools from patman.tools import ToHex, ToHexSize -import tout +from patman import tout modules = {} diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py index ca5bb0fe1b..80802f33de 100644 --- a/tools/binman/entry_test.py +++ b/tools/binman/entry_test.py @@ -12,7 +12,7 @@ import unittest from binman import entry from dtoc import fdt from dtoc import fdt_util -import tools +from patman import tools class TestEntry(unittest.TestCase): def setUp(self): diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py index 4cde8df6f5..ed718eed14 100644 --- a/tools/binman/etype/_testing.py +++ b/tools/binman/etype/_testing.py @@ -9,7 +9,7 @@ from collections import OrderedDict from binman.entry import Entry, EntryArg from dtoc import fdt_util -import tools +from patman import tools class Entry__testing(Entry): diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index 409beaadcc..ede7a7a68c 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -7,8 +7,8 @@ from binman.entry import Entry from dtoc import fdt_util -import tools -import tout +from patman import tools +from patman import tout class Entry_blob(Entry): """Entry containing an arbitrary binary blob diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py index 820f34515a..aa8807990b 100644 --- a/tools/binman/etype/fdtmap.py +++ b/tools/binman/etype/fdtmap.py @@ -9,8 +9,8 @@ image. """ from binman.entry import Entry -import tools -import tout +from patman import tools +from patman import tout FDTMAP_MAGIC = b'_FDTMAP_' FDTMAP_HDR_LEN = 16 diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py index 7b4fc7db91..10ab585f0e 100644 --- a/tools/binman/etype/files.py +++ b/tools/binman/etype/files.py @@ -11,7 +11,7 @@ import os from binman.etype.section import Entry_section from dtoc import fdt_util -import tools +from patman import tools class Entry_files(Entry_section): diff --git a/tools/binman/etype/fill.py b/tools/binman/etype/fill.py index 1124ef26ea..860410ed6e 100644 --- a/tools/binman/etype/fill.py +++ b/tools/binman/etype/fill.py @@ -5,7 +5,7 @@ from binman.entry import Entry from dtoc import fdt_util -import tools +from patman import tools class Entry_fill(Entry): """An entry which is filled to a particular byte value diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py index a155beb617..a43fac38de 100644 --- a/tools/binman/etype/fmap.py +++ b/tools/binman/etype/fmap.py @@ -7,9 +7,9 @@ from binman.entry import Entry from binman import fmap_util -import tools +from patman import tools from patman.tools import ToHexSize -import tout +from patman import tout class Entry_fmap(Entry): diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py index 0fc7667908..dd10599717 100644 --- a/tools/binman/etype/gbb.py +++ b/tools/binman/etype/gbb.py @@ -8,11 +8,11 @@ from collections import OrderedDict -import command +from patman import command from binman.entry import Entry, EntryArg from dtoc import fdt_util -import tools +from patman import tools # Build GBB flags. # (src/platform/vboot_reference/firmware/include/gbb_header.h) diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py index 1545476f8f..6a96f6be55 100644 --- a/tools/binman/etype/intel_ifwi.py +++ b/tools/binman/etype/intel_ifwi.py @@ -10,7 +10,7 @@ from collections import OrderedDict from binman.entry import Entry from binman.etype.blob import Entry_blob from dtoc import fdt_util -import tools +from patman import tools class Entry_intel_ifwi(Entry_blob): """Entry containing an Intel Integrated Firmware Image (IFWI) file diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 5893249e11..91b8e0c110 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -14,8 +14,8 @@ import sys from binman.entry import Entry from dtoc import fdt_util -import tools -import tout +from patman import tools +from patman import tout class Entry_section(Entry): diff --git a/tools/binman/etype/text.py b/tools/binman/etype/text.py index cde816aec5..3577135adb 100644 --- a/tools/binman/etype/text.py +++ b/tools/binman/etype/text.py @@ -7,7 +7,7 @@ from collections import OrderedDict from binman.entry import Entry, EntryArg from dtoc import fdt_util -import tools +from patman import tools class Entry_text(Entry): diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py index c802f477b4..aec145533e 100644 --- a/tools/binman/etype/u_boot_dtb_with_ucode.py +++ b/tools/binman/etype/u_boot_dtb_with_ucode.py @@ -7,7 +7,7 @@ from binman.entry import Entry from binman.etype.blob_dtb import Entry_blob_dtb -import tools +from patman import tools class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): """A U-Boot device tree file, with the microcode removed diff --git a/tools/binman/etype/u_boot_elf.py b/tools/binman/etype/u_boot_elf.py index 5123b9dc1e..5f906e520c 100644 --- a/tools/binman/etype/u_boot_elf.py +++ b/tools/binman/etype/u_boot_elf.py @@ -9,7 +9,7 @@ from binman.entry import Entry from binman.etype.blob import Entry_blob from dtoc import fdt_util -import tools +from patman import tools class Entry_u_boot_elf(Entry_blob): """U-Boot ELF image diff --git a/tools/binman/etype/u_boot_spl_bss_pad.py b/tools/binman/etype/u_boot_spl_bss_pad.py index cfcca6b7c5..a6a177a128 100644 --- a/tools/binman/etype/u_boot_spl_bss_pad.py +++ b/tools/binman/etype/u_boot_spl_bss_pad.py @@ -9,9 +9,9 @@ from binman import elf from binman.entry import Entry -import command +from patman import command from binman.etype.blob import Entry_blob -import tools +from patman import tools class Entry_u_boot_spl_bss_pad(Entry_blob): """U-Boot SPL binary padded with a BSS region diff --git a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py index ca1f436c61..7f7fab7105 100644 --- a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py @@ -7,11 +7,11 @@ import struct -import command +from patman import command from binman.entry import Entry from binman.etype.blob import Entry_blob from binman.etype.u_boot_with_ucode_ptr import Entry_u_boot_with_ucode_ptr -import tools +from patman import tools class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): """U-Boot TPL with embedded microcode pointer diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py index 692ccceb71..d9e1a605ef 100644 --- a/tools/binman/etype/u_boot_ucode.py +++ b/tools/binman/etype/u_boot_ucode.py @@ -7,7 +7,7 @@ from binman.entry import Entry from binman.etype.blob import Entry_blob -import tools +from patman import tools class Entry_u_boot_ucode(Entry_blob): """U-Boot microcode block diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py index 47ee33caba..06047b654d 100644 --- a/tools/binman/etype/u_boot_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_with_ucode_ptr.py @@ -11,8 +11,8 @@ from binman import elf from binman.entry import Entry from binman.etype.blob import Entry_blob from dtoc import fdt_util -import tools -import command +from patman import tools +from patman import command class Entry_u_boot_with_ucode_ptr(Entry_blob): """U-Boot with embedded microcode pointer diff --git a/tools/binman/etype/vblock.py b/tools/binman/etype/vblock.py index c13ceda796..5753de7ec7 100644 --- a/tools/binman/etype/vblock.py +++ b/tools/binman/etype/vblock.py @@ -12,7 +12,7 @@ import os from binman.entry import Entry, EntryArg from dtoc import fdt_util -import tools +from patman import tools class Entry_vblock(Entry): """An entry which contains a Chromium OS verified boot block diff --git a/tools/binman/fdt_test.py b/tools/binman/fdt_test.py index a9ab04e80d..c491d40e9e 100644 --- a/tools/binman/fdt_test.py +++ b/tools/binman/fdt_test.py @@ -12,7 +12,7 @@ import unittest from dtoc import fdt from dtoc import fdt_util from dtoc.fdt import FdtScan -import tools +from patman import tools class TestFdt(unittest.TestCase): @classmethod diff --git a/tools/binman/fmap_util.py b/tools/binman/fmap_util.py index d0f956b622..25fe60a9cc 100644 --- a/tools/binman/fmap_util.py +++ b/tools/binman/fmap_util.py @@ -10,7 +10,7 @@ import collections import struct import sys -import tools +from patman import tools # constants imported from lib/fmap.h FMAP_SIGNATURE = b'__FMAP__' diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index a11675d9aa..5e24920088 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -29,10 +29,10 @@ from dtoc import fdt_util from binman.etype import fdtmap from binman.etype import image_header from image import Image -import command -import test_util -import tools -import tout +from patman import command +from patman import test_util +from patman import tools +from patman import tout # Contents of test files, corresponding to different entry types U_BOOT_DATA = b'1234' diff --git a/tools/binman/image.py b/tools/binman/image.py index 50bd57cdcb..523b274c31 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -18,8 +18,8 @@ from binman.etype import image_header from binman.etype import section from dtoc import fdt from dtoc import fdt_util -import tools -import tout +from patman import tools +from patman import tout class Image(section.Entry_section): """A Image, representing an output from binman diff --git a/tools/binman/main.py b/tools/binman/main.py index 8736938d11..97a8a02034 100755 --- a/tools/binman/main.py +++ b/tools/binman/main.py @@ -36,7 +36,7 @@ sys.path.append(get_python_lib()) from binman import cmdline from binman import control -import test_util +from patman import test_util def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath): """Run the functional tests and any embedded doctests diff --git a/tools/binman/state.py b/tools/binman/state.py index 7f85ab1f98..36bc513535 100644 --- a/tools/binman/state.py +++ b/tools/binman/state.py @@ -10,8 +10,8 @@ import re from dtoc import fdt import os -import tools -import tout +from patman import tools +from patman import tout # Records the device-tree files known to binman, keyed by entry type (e.g. # 'u-boot-spl-dtb'). These are the output FDT files, which can be updated by diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index b7f2c426e3..f8e71de427 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -19,10 +19,10 @@ import time from buildman import builderthread from buildman import toolchain -import command -import gitutil -import terminal -from terminal import Print +from patman import command +from patman import gitutil +from patman import terminal +from patman.terminal import Print """ Theory of Operation diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index f673f386e4..48fcd6cf7e 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -9,8 +9,8 @@ import shutil import sys import threading -import command -import gitutil +from patman import command +from patman import gitutil RETURN_CODE_RETRY = -1 diff --git a/tools/buildman/control.py b/tools/buildman/control.py index e05234c08f..071c2613ec 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -12,11 +12,11 @@ from buildman import board from buildman import bsettings from buildman import toolchain from buildman.builder import Builder -import command -import gitutil -import patchstream -import terminal -from terminal import Print +from patman import command +from patman import gitutil +from patman import patchstream +from patman import terminal +from patman.terminal import Print def GetPlural(count): """Returns a plural 's' if count is not 1""" diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 9bfdd53698..418677f9cc 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -13,11 +13,10 @@ from buildman import bsettings from buildman import cmdline from buildman import control from buildman import toolchain -import command -import gitutil -import terminal -import toolchain -import tools +from patman import command +from patman import gitutil +from patman import terminal +from patman import tools settings_data = ''' # Buildman settings file diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 94d495c40b..52a83fce7d 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -25,9 +25,9 @@ from buildman import builder from buildman import cmdline from buildman import control from buildman import toolchain -import patchstream -import gitutil -import terminal +from patman import patchstream +from patman import gitutil +from patman import terminal def RunTests(skip_net_tests): import func_test diff --git a/tools/buildman/test.py b/tools/buildman/test.py index 87175eeb63..b37c37b2fa 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -18,11 +18,11 @@ from buildman import bsettings from buildman import builder from buildman import control from buildman import toolchain -import commit -import command -import terminal -import test_util -import tools +from patman import commit +from patman import command +from patman import terminal +from patman import test_util +from patman import tools use_network = True diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index a3540491ec..acb5a29c8f 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -11,9 +11,9 @@ import tempfile import urllib.request, urllib.error, urllib.parse from buildman import bsettings -import command -import terminal -import tools +from patman import command +from patman import terminal +from patman import tools (PRIORITY_FULL_PREFIX, PRIORITY_PREFIX_GCC, PRIORITY_PREFIX_GCC_PATH, PRIORITY_CALC) = list(range(4)) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 90a9e1a626..ecfe0624d1 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -15,9 +15,9 @@ import collections import copy import sys -import fdt -import fdt_util -import tools +from dtoc import fdt +from dtoc import fdt_util +from patman import tools # When we see these properties we ignore them - i.e. do not create a structure member PROP_IGNORE_LIST = [ diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 1b7b730359..188490b728 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -8,10 +8,10 @@ import struct import sys -import fdt_util +from dtoc import fdt_util import libfdt from libfdt import QUIET_NOTFOUND -import tools +from patman import tools # This deals with a device tree, presenting it as an assortment of Node and # Prop objects, representing nodes and properties, respectively. This file diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index b105faec74..b040793772 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -13,8 +13,8 @@ import struct import sys import tempfile -import command -import tools +from patman import command +from patman import tools def fdt32_to_cpu(val): """Convert a device tree cell to an integer diff --git a/tools/dtoc/main.py b/tools/dtoc/main.py index b1eee21f17..6c63d637a7 100755 --- a/tools/dtoc/main.py +++ b/tools/dtoc/main.py @@ -33,14 +33,15 @@ import unittest # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(our_path, '../patman')) +sys.path.append(os.path.join(our_path, '..')) # Bring in the libfdt module sys.path.insert(0, 'scripts/dtc/pylibfdt') sys.path.insert(0, os.path.join(our_path, '../../build-sandbox_spl/scripts/dtc/pylibfdt')) -import dtb_platdata -import test_util +from dtoc import dtb_platdata +from patman import test_util def run_tests(args): """Run all the test we have for dtoc diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index 9db97489d4..8498e8303c 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -14,15 +14,15 @@ import os import struct import unittest -import dtb_platdata +from dtoc import dtb_platdata from dtb_platdata import conv_name_to_c from dtb_platdata import get_compat_name from dtb_platdata import get_value from dtb_platdata import tab_to -import fdt -import fdt_util -import test_util -import tools +from dtoc import fdt +from dtoc import fdt_util +from patman import test_util +from patman import tools our_path = os.path.dirname(os.path.realpath(__file__)) diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 4f39a5589f..d68230713e 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -17,14 +17,14 @@ our_path = os.path.dirname(os.path.realpath(__file__)) for dirname in ['../patman', '..']: sys.path.insert(0, os.path.join(our_path, dirname)) -import command -import fdt +from dtoc import fdt +from dtoc import fdt_util +from dtoc.fdt_util import fdt32_to_cpu from fdt import TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, BytesToValue -import fdt_util -from fdt_util import fdt32_to_cpu import libfdt -import test_util -import tools +from patman import command +from patman import test_util +from patman import tools def _GetPropertyValue(dtb, node, prop_name): """Low-level function to get the property value based on its offset diff --git a/tools/patman/checkpatch.py b/tools/patman/checkpatch.py index d47ea438b7..795b519314 100644 --- a/tools/patman/checkpatch.py +++ b/tools/patman/checkpatch.py @@ -3,12 +3,14 @@ # import collections -import command -import gitutil import os import re import sys -import terminal + +from patman import command +from patman import gitutil +from patman import terminal +from patman import tools def FindCheckPatch(): top_level = gitutil.GetTopLevel() diff --git a/tools/patman/command.py b/tools/patman/command.py index 5fbd2c4a3e..e67ac159e5 100644 --- a/tools/patman/command.py +++ b/tools/patman/command.py @@ -3,8 +3,9 @@ # import os -import cros_subprocess -import tools + +from patman import cros_subprocess +from patman import tools """Shell command ease-ups for Python.""" diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index 748e225446..b7e2825de8 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -14,10 +14,10 @@ import unittest from io import StringIO -import gitutil -import patchstream -import settings -import tools +from patman import gitutil +from patman import patchstream +from patman import settings +from patman import tools @contextlib.contextmanager diff --git a/tools/patman/get_maintainer.py b/tools/patman/get_maintainer.py index 0ffb55a821..473f0feebf 100644 --- a/tools/patman/get_maintainer.py +++ b/tools/patman/get_maintainer.py @@ -2,10 +2,11 @@ # Copyright (c) 2012 The Chromium OS Authors. # -import command -import gitutil import os +from patman import command +from patman import gitutil + def FindGetMaintainer(): """Look for the get_maintainer.pl script. diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index a2a225c6b9..770a051014 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -2,17 +2,17 @@ # Copyright (c) 2011 The Chromium OS Authors. # -import command import re import os -import series import subprocess import sys -import terminal -import checkpatch -import settings -import tools +from patman import checkpatch +from patman import command +from patman import series +from patman import settings +from patman import terminal +from patman import tools # True to use --no-decorate - we check this in Setup() use_no_decorate = True diff --git a/tools/patman/main.py b/tools/patman/main.py index b642c2ed03..f59367fafb 100755 --- a/tools/patman/main.py +++ b/tools/patman/main.py @@ -18,14 +18,14 @@ if __name__ == "__main__": sys.path.append(os.path.join(our_path, '..')) # Our modules -import checkpatch -import command -import gitutil -import patchstream -import project -import settings -import terminal -import test +from patman import checkpatch +from patman import command +from patman import gitutil +from patman import patchstream +from patman import project +from patman import settings +from patman import terminal +from patman import test parser = OptionParser() @@ -86,7 +86,7 @@ if __name__ != "__main__": # Run our meagre tests elif options.test: import doctest - import func_test + from patman import func_test sys.argv = [sys.argv[0]] result = unittest.TestResult() diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index df3eb7483b..405297505c 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -9,10 +9,10 @@ import re import shutil import tempfile -import command -import commit -import gitutil -from series import Series +from patman import command +from patman import commit +from patman import gitutil +from patman.series import Series # Tags that we detect and remove re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Review URL:' diff --git a/tools/patman/project.py b/tools/patman/project.py index 1d9cfc0625..2dfc303729 100644 --- a/tools/patman/project.py +++ b/tools/patman/project.py @@ -4,7 +4,7 @@ import os.path -import gitutil +from patman import gitutil def DetectProject(): """Autodetect the name of the current project. diff --git a/tools/patman/series.py b/tools/patman/series.py index 3869696abc..e5e28cebdf 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -5,11 +5,11 @@ import itertools import os -import get_maintainer -import gitutil -import settings -import terminal -import tools +from patman import get_maintainer +from patman import gitutil +from patman import settings +from patman import terminal +from patman import tools # Series-xxx tags that we understand valid_series = ['to', 'cc', 'version', 'changes', 'prefix', 'notes', 'name', diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 21e8fc41a9..ca74fc611f 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -10,9 +10,9 @@ except: import os import re -import command -import gitutil -import tools +from patman import command +from patman import gitutil +from patman import tools """Default settings per-project. diff --git a/tools/patman/test.py b/tools/patman/test.py index 889e186606..e7f709e34c 100644 --- a/tools/patman/test.py +++ b/tools/patman/test.py @@ -8,11 +8,11 @@ import os import tempfile import unittest -import checkpatch -import gitutil -import patchstream -import series -import commit +from patman import checkpatch +from patman import gitutil +from patman import patchstream +from patman import series +from patman import commit class TestPatch(unittest.TestCase): diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index bb5a298e39..4d28d9fc92 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -10,7 +10,8 @@ import os import sys import unittest -import command +from patman import command +from patman import test_util from io import StringIO diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 7b21a128f3..b50370dfe8 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -3,7 +3,6 @@ # Copyright (c) 2016 Google, Inc # -import command import glob import os import shutil @@ -11,7 +10,8 @@ import struct import sys import tempfile -import tout +from patman import command +from patman import tout # Output directly (generally this is temporary) outdir = None diff --git a/tools/patman/tout.py b/tools/patman/tout.py index ee3c519c80..c7e3272096 100644 --- a/tools/patman/tout.py +++ b/tools/patman/tout.py @@ -6,7 +6,7 @@ import sys -import terminal +from patman import terminal # Output verbosity levels that we support ERROR, WARNING, NOTICE, INFO, DETAIL, DEBUG = range(6) diff --git a/tools/rmboard.py b/tools/rmboard.py index 446e5d6ee2..1ed2527d0e 100755 --- a/tools/rmboard.py +++ b/tools/rmboard.py @@ -32,7 +32,7 @@ import sys our_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(our_path, '../tools/patman')) -import command +from patman import command def rm_kconfig_include(path): """Remove a path from Kconfig files From b4fa94959db039c7eca4531a5b9a41baffa8b4c8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 17 Apr 2020 18:09:05 -0600 Subject: [PATCH 22/23] patman: Tidy up sys.path changes Now that we are using absolute paths we can remove some of the sys.path mangling that appears in the tools. We only need to add the path to 'tools/' so that everything can find modules relative to that directory. The special paths for finding pylibfdt remain. Signed-off-by: Simon Glass --- tools/binman/main.py | 5 +++-- tools/buildman/main.py | 3 +-- tools/buildman/test.py | 1 - tools/dtoc/main.py | 1 - tools/dtoc/test_fdt.py | 3 +-- tools/genboardscfg.py | 3 +-- tools/moveconfig.py | 2 -- tools/patman/main.py | 2 +- tools/rmboard.py | 1 - 9 files changed, 7 insertions(+), 14 deletions(-) diff --git a/tools/binman/main.py b/tools/binman/main.py index 97a8a02034..efa7fa8386 100755 --- a/tools/binman/main.py +++ b/tools/binman/main.py @@ -20,8 +20,9 @@ import unittest # Bring in the patman and dtoc libraries (but don't override the first path # in PYTHONPATH) our_path = os.path.dirname(os.path.realpath(__file__)) -for dirname in ['../patman', '../dtoc', '../concurrencytest', '..']: - sys.path.insert(2, os.path.realpath(os.path.join(our_path, dirname))) +sys.path.insert(2, os.path.join(our_path, '..')) + +from patman import test_util # Bring in the libfdt module sys.path.insert(2, 'scripts/dtc/pylibfdt') diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 52a83fce7d..2b714739a2 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -16,7 +16,6 @@ import unittest # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(1, os.path.join(our_path, '..')) -sys.path.insert(2, os.path.join(our_path, '../patman')) # Our modules from buildman import board @@ -35,7 +34,7 @@ def RunTests(skip_net_tests): import doctest result = unittest.TestResult() - for module in ['toolchain', 'gitutil']: + for module in ['buildman.toolchain', 'patman.gitutil']: suite = doctest.DocTestSuite(module) suite.run(result) diff --git a/tools/buildman/test.py b/tools/buildman/test.py index b37c37b2fa..40811ba9f9 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -11,7 +11,6 @@ import unittest # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(our_path, '../patman')) from buildman import board from buildman import bsettings diff --git a/tools/dtoc/main.py b/tools/dtoc/main.py index 6c63d637a7..b94d9c301f 100755 --- a/tools/dtoc/main.py +++ b/tools/dtoc/main.py @@ -32,7 +32,6 @@ import unittest # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(our_path, '../patman')) sys.path.append(os.path.join(our_path, '..')) # Bring in the libfdt module diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index d68230713e..375e906424 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -14,8 +14,7 @@ import unittest # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) -for dirname in ['../patman', '..']: - sys.path.insert(0, os.path.join(our_path, dirname)) +sys.path.insert(1, os.path.join(our_path, '..')) from dtoc import fdt from dtoc import fdt_util diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py index 4f6382bc7c..4ee7aa1f89 100755 --- a/tools/genboardscfg.py +++ b/tools/genboardscfg.py @@ -22,8 +22,7 @@ import sys import tempfile import time -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'buildman')) -import kconfiglib +from buildman import kconfiglib ### constant variables ### OUTPUT_FILE = 'boards.cfg' diff --git a/tools/moveconfig.py b/tools/moveconfig.py index 0dd8670403..36361f9ed1 100755 --- a/tools/moveconfig.py +++ b/tools/moveconfig.py @@ -314,8 +314,6 @@ import tempfile import threading import time -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -sys.path.append(os.path.join(os.path.dirname(__file__), 'patman')) from buildman import bsettings from buildman import kconfiglib from buildman import toolchain diff --git a/tools/patman/main.py b/tools/patman/main.py index f59367fafb..f3d9c0c434 100755 --- a/tools/patman/main.py +++ b/tools/patman/main.py @@ -13,7 +13,7 @@ import sys import unittest if __name__ == "__main__": - # Allow 'import xxx to work' + # Allow 'from patman import xxx to work' our_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(our_path, '..')) diff --git a/tools/rmboard.py b/tools/rmboard.py index 1ed2527d0e..06c3562ad8 100755 --- a/tools/rmboard.py +++ b/tools/rmboard.py @@ -30,7 +30,6 @@ import sys # Bring in the patman libraries our_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(our_path, '../tools/patman')) from patman import command From c1f39edc62adc81775e750957aa557bcf994e607 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 19 Apr 2020 10:48:36 +0200 Subject: [PATCH 23/23] log: remove useless cast There is no need to cast from (void *) before assigning to a pointer. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- common/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/log.c b/common/log.c index ffb3cd6933..c5b9b489ca 100644 --- a/common/log.c +++ b/common/log.c @@ -233,7 +233,7 @@ int log_add_filter(const char *drv_name, enum log_category_t cat_list[], ldev = log_device_find_by_name(drv_name); if (!ldev) return -ENOENT; - filt = (struct log_filter *)calloc(1, sizeof(*filt)); + filt = calloc(1, sizeof(*filt)); if (!filt) return -ENOMEM;