diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile | 7 | ||||
-rw-r--r-- | tools/binman/elf.py | 2 | ||||
-rw-r--r-- | tools/binman/etype/fit.py | 2 | ||||
-rw-r--r-- | tools/binman/etype/section.py | 17 | ||||
-rw-r--r-- | tools/binman/ftest.py | 7 | ||||
-rwxr-xr-x | tools/binman/main.py | 8 | ||||
-rw-r--r-- | tools/binman/requirements.txt | 1 | ||||
-rw-r--r-- | tools/binman/state.py | 3 | ||||
-rw-r--r-- | tools/binman/test/184_compress_section_size.dts | 1 | ||||
-rw-r--r-- | tools/buildman/buildman.rst | 2 | ||||
-rw-r--r-- | tools/buildman/test.py | 2 | ||||
-rw-r--r-- | tools/buildman/toolchain.py | 4 | ||||
-rw-r--r-- | tools/docker/Dockerfile | 39 | ||||
-rw-r--r-- | tools/fit_check_sign.c | 19 | ||||
-rw-r--r-- | tools/mkimage.c | 1 | ||||
-rw-r--r-- | tools/patman/control.py | 3 | ||||
-rw-r--r-- | tools/patman/func_test.py | 49 | ||||
-rw-r--r-- | tools/patman/patchstream.py | 43 | ||||
-rw-r--r-- | tools/patman/series.py | 2 | ||||
-rwxr-xr-x | tools/qconfig.py | 8 | ||||
-rw-r--r-- | tools/rkcommon.c | 2 | ||||
-rw-r--r-- | tools/u_boot_pylib/gitutil.py | 27 | ||||
-rw-r--r-- | tools/u_boot_pylib/test_util.py | 20 |
23 files changed, 197 insertions, 72 deletions
diff --git a/tools/Makefile b/tools/Makefile index 53b87d22a80..97ce1dbb17e 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -63,8 +63,7 @@ HOSTCFLAGS_img2srec.o := -pedantic hostprogs-y += mkenvimage mkenvimage-objs := mkenvimage.o os_support.o generated/lib/crc32.o -hostprogs-y += dumpimage mkimage -hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign +hostprogs-y += dumpimage mkimage fit_info fit_check_sign hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fdt_add_pubkey hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += preload_check_sign @@ -169,6 +168,8 @@ fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o fdt_add_pubkey-objs := $(dumpimage-mkimage-objs) fdt_add_pubkey.o file2include-objs := file2include.o preload_check_sign-objs := $(dumpimage-mkimage-objs) $(PRELOAD_OBJS-y) preload_check_sign.o +HOSTCFLAGS_preload_check_sign.o += \ + $(shell pkg-config --cflags libssl libcrypto 2> /dev/null || echo "") ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_TOOLS_LIBCRYPTO),) # Add CFG_MXS into host CFLAGS, so we can check whether or not register @@ -207,6 +208,8 @@ HOSTLDLIBS_fit_info := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fit_check_sign := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_fdt_add_pubkey := $(HOSTLDLIBS_mkimage) HOSTLDLIBS_preload_check_sign := $(HOSTLDLIBS_mkimage) +HOSTLDLIBS_preload_check_sign += \ + $(shell pkg-config --libs libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto") hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl diff --git a/tools/binman/elf.py b/tools/binman/elf.py index c75f4478813..6ac960e0419 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -28,7 +28,7 @@ except: # pragma: no cover # BSYM in little endian, keep in sync with include/binman_sym.h BINMAN_SYM_MAGIC_VALUE = 0x4d595342 -# Information about an EFL symbol: +# Information about an ELF symbol: # section (str): Name of the section containing this symbol # address (int): Address of the symbol (its value) # size (int): Size of the symbol in bytes diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index 803fb66ea83..ed3cac4ee7e 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -562,8 +562,6 @@ class Entry_fit(Entry_section): for subnode in node.subnodes: if (subnode.name.startswith('signature') or subnode.name.startswith('cipher')): - if subnode.props.get('key-name-hint') is None: - continue hint = subnode.props['key-name-hint'].value name = tools.get_input_filename( f"{hint}.key" if subnode.name.startswith('signature') diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 5e11cf58d28..4c4c8c417f8 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -662,23 +662,6 @@ class Entry_section(Entry): else: raise ValueError("%s: No such property '%s'" % (msg, prop_name)) - def GetRootSkipAtStart(self): - """Get the skip-at-start value for the top-level section - - This is used to find out the starting offset for root section that - contains this section. If this is a top-level section then it returns - the skip-at-start offset for this section. - - This is used to get the absolute position of section within the image. - - Returns: - Integer skip-at-start value for the root section containing this - section - """ - if self.section: - return self.section.GetRootSkipAtStart() - return self._skip_at_start - def GetStartOffset(self): """Get the start offset for this section diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 948fcc02259..92df2a03650 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -4613,6 +4613,8 @@ class TestFunctional(unittest.TestCase): dtb.Scan() props = self._GetPropTree(dtb, ['offset', 'image-pos', 'size', 'uncomp-size']) + data = data[:0x30] + data = data.rstrip(b'\xff') orig = self._decompress(data) self.assertEqual(COMPRESS_DATA + U_BOOT_DATA, orig) expected = { @@ -6218,8 +6220,9 @@ fdt fdtmap Extract the devicetree blob from the fdtmap def testCompUtilPadding(self): """Test padding of compression algorithms""" - # Skip zstd because it doesn't support padding - for bintool in [v for k,v in self.comp_bintools.items() if k != 'zstd']: + # Skip zstd and lz4 because they doesn't support padding + for bintool in [v for k,v in self.comp_bintools.items() + if not k in ['zstd', 'lz4']]: self._CheckBintool(bintool) data = bintool.compress(COMPRESS_DATA) self.assertNotEqual(COMPRESS_DATA, data) diff --git a/tools/binman/main.py b/tools/binman/main.py index 619840e7d55..326f5c93155 100755 --- a/tools/binman/main.py +++ b/tools/binman/main.py @@ -94,10 +94,16 @@ def RunTestCoverage(toolpath, build_dir, args): if toolpath: for path in toolpath: extra_args += ' --toolpath %s' % path + + # Some files unfortunately don't thave the required test coverage. This will + # eventually be fixed, but exclude them for now test_util.run_test_coverage('tools/binman/binman', None, ['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*', 'tools/u_boot_pylib/*'], - build_dir, all_set, extra_args or None, args=args) + build_dir, all_set, extra_args or None, args=args, + allow_failures=['tools/binman/btool/cst.py', + 'tools/binman/etype/nxp_imx8mcst.py', + 'tools/binman/etype/nxp_imx8mimage.py']) def RunBinman(args): """Main entry point to binman once arguments are parsed diff --git a/tools/binman/requirements.txt b/tools/binman/requirements.txt index f068ef75a30..7db72e888e3 100644 --- a/tools/binman/requirements.txt +++ b/tools/binman/requirements.txt @@ -1,3 +1,4 @@ +coverage==7.8.0 importlib_resources==6.5.2 jsonschema==4.23.0 pycryptodomex==3.21.0 diff --git a/tools/binman/state.py b/tools/binman/state.py index 6772d3678fe..f4d885c772a 100644 --- a/tools/binman/state.py +++ b/tools/binman/state.py @@ -411,8 +411,7 @@ def CheckSetHashValue(node, get_data_func): m = hashlib.sha256() m.update(get_data_func()) data = m.digest() - if data is None: - raise ValueError(f"Node '{node.path}': Unknown hash algorithm '{algo}'") + assert data for n in GetUpdateNodes(hash_node): n.SetData('value', data) diff --git a/tools/binman/test/184_compress_section_size.dts b/tools/binman/test/184_compress_section_size.dts index 95ed30add1a..1c1dbd5f580 100644 --- a/tools/binman/test/184_compress_section_size.dts +++ b/tools/binman/test/184_compress_section_size.dts @@ -6,6 +6,7 @@ section { size = <0x30>; compress = "lz4"; + pad-byte = <0xff>; blob { filename = "compress"; }; diff --git a/tools/buildman/buildman.rst b/tools/buildman/buildman.rst index 924564b5700..07ecc5c110c 100644 --- a/tools/buildman/buildman.rst +++ b/tools/buildman/buildman.rst @@ -247,7 +247,7 @@ Setting up section is ignored. If more than one line is provided, only the last one is taken. -#. Make sure you have the require Python pre-requisites +#. Make sure you have the required Python pre-requisites Buildman uses multiprocessing, Queue, shutil, StringIO, ConfigParser and urllib2. These should normally be available, but if you get an error like diff --git a/tools/buildman/test.py b/tools/buildman/test.py index c5feb74a105..e31e6c72e1a 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -987,7 +987,7 @@ class TestBuild(unittest.TestCase): diff = self.call_make_environment(tchn, full_path=True)[0] self.assertEqual({b'LC_ALL': b'C'}, diff) - # Test that virtualenv is handled correctly + # Test that Python sandbox is handled correctly tchn.override_toolchain = False sys.prefix = '/some/venv' env = dict(os.environb) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 5d051e005da..5e5bb4b0aed 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -217,7 +217,7 @@ class Toolchain: elif self.cross: env[b'CROSS_COMPILE'] = tools.to_bytes(wrapper + self.cross) - # Detect a Python virtualenv and avoid defeating it + # Detect a Python sandbox and avoid defeating it if sys.prefix != sys.base_prefix: paths = env[b'PATH'].split(b':') new_paths = [] @@ -531,7 +531,7 @@ class Toolchains: if arch == 'aarch64': arch = 'arm64' base = 'https://www.kernel.org/pub/tools/crosstool/files/bin' - versions = ['13.2.0', '12.2.0'] + versions = ['14.2.0', '13.2.0'] links = [] for version in versions: url = '%s/%s/%s/' % (base, arch, version) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index e14d1640f9c..1d7d2a1877e 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -2,7 +2,7 @@ # This Dockerfile is used to build an image containing basic stuff to be used # to build U-Boot and run our test suites. -FROM ubuntu:jammy-20240911.1 +FROM ubuntu:jammy-20250404 LABEL org.opencontainers.image.authors="Tom Rini <trini@konsulko.com>" LABEL org.opencontainers.image.description=" This image is for building U-Boot inside a container" @@ -23,7 +23,7 @@ ENV ARCHS="aarch64 arc i386 m68k mips microblaze nios2 powerpc riscv64 riscv32 s ENV MIRROR=https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin # Toolchain version -ENV TCVER=13.2.0 +ENV TCVER=14.2.0 RUN echo "Building on $BUILDPLATFORM, for target $TARGETPLATFORM" @@ -32,7 +32,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update && apt-get install -y gnupg2 wget xz-utils RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - -RUN echo deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main | tee /etc/apt/sources.list.d/llvm.list +RUN echo deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main | tee /etc/apt/sources.list.d/llvm.list # Create a list of URLs to process, then pass them into a 'while read' loop RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then HOSTARCH=x86_64; else HOSTARCH=arm64; fi; ( \ @@ -64,8 +64,9 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ binutils-dev \ bison \ build-essential \ + byacc \ cgpt \ - clang-17 \ + clang-18 \ coreutils \ cpio \ curl \ @@ -77,6 +78,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ exfatprogs \ expect \ fakeroot \ + fdisk \ flex \ gawk \ gdisk \ @@ -88,6 +90,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ help2man \ iasl \ imagemagick \ + inetutils-telnet \ iputils-ping \ libconfuse-dev \ libgit2-dev \ @@ -122,7 +125,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ python3-dev \ python3-pip \ python3-sphinx \ - python3-virtualenv \ + python3-venv \ rpm2cpio \ sbsigntool \ socat \ @@ -134,7 +137,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ texinfo \ util-linux \ uuid-dev \ - virtualenv \ vboot-kernel-utils \ vboot-utils \ xilinx-bootgen \ @@ -177,7 +179,7 @@ RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \ search search_fs_file search_fs_uuid search_label serial sleep test \ true && \ make clean && \ - ./configure --target=riscv64 --with-platform=efi \ + grub_cv_cc_mcmodel=no ./configure --target=riscv64 --with-platform=efi \ CC=gcc \ TARGET_CC=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-gcc \ TARGET_OBJCOPY=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-objcopy \ @@ -230,13 +232,24 @@ RUN git clone https://gitlab.com/qemu-project/qemu.git /tmp/qemu && \ # Build fiptool RUN git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git /tmp/tf-a && \ cd /tmp/tf-a/ && \ - git checkout v2.10.0 && \ - cd tools/fiptool && \ - make -j$(nproc) && \ - mkdir -p /usr/local/bin && \ - cp fiptool /usr/local/bin && \ + git checkout v2.12.0 && \ + make CROSS_COMPILE=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux- \ + PLAT=fvp BL33=/dev/null -j$(nproc) all fip && \ + mkdir -p /usr/local/bin /opt/tf-a/vexpress_fvp && \ + cp tools/fiptool/fiptool /usr/local/bin && \ + cp build/fvp/release/fip.bin build/fvp/release/bl1.bin \ + /opt/tf-a/vexpress_fvp/ && \ + rm -rf build/fvp && \ + make CROSS_COMPILE=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux- \ + PLAT=fvp BL33=/dev/null TRANSFER_LIST=1 -j$(nproc) all fip && \ + mkdir -p /opt/tf-a/vexpress_fvp_bloblist && \ + cp build/fvp/release/fip.bin build/fvp/release/bl1.bin \ + /opt/tf-a/vexpress_fvp_bloblist/ && \ rm -rf /tmp/tf-a +# Download the Arm Architecture FVP platform. This file is double compressed. +RUN wget -O - https://developer.arm.com/-/cdn-downloads/permalink/FVPs-Architecture/FM-11.28/FVP_Base_RevC-2xAEMvA_11.28_23_Linux64.tgz | gunzip -dc | tar -C /opt -x + # Build genimage (required by some targets to generate disk images) RUN wget -O - https://github.com/pengutronix/genimage/releases/download/v14/genimage-14.tar.xz | tar -C /tmp -xJ && \ cd /tmp/genimage-14 && \ @@ -308,7 +321,7 @@ RUN wget -O /tmp/binman-requirements.txt https://source.denx.de/u-boot/u-boot/-/ RUN wget -O /tmp/buildman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt RUN wget -O /tmp/patman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/patman/requirements.txt RUN wget -O /tmp/u_boot_pylib-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/u_boot_pylib/requirements.txt -RUN virtualenv -p /usr/bin/python3 /tmp/venv && \ +RUN python3 -m venv /tmp/venv && \ . /tmp/venv/bin/activate && \ pip install -r /tmp/pytest-requirements.txt \ -r /tmp/sphinx-requirements.txt \ diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c index 3d1d33fdab1..32d0fdb8829 100644 --- a/tools/fit_check_sign.c +++ b/tools/fit_check_sign.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) char *config_name = NULL; char cmdname[256]; int ret; - void *key_blob; + void *key_blob = NULL; int c; strncpy(cmdname, *argv, sizeof(cmdname) - 1); @@ -70,18 +70,15 @@ int main(int argc, char **argv) fprintf(stderr, "%s: Missing fdt file\n", *argv); usage(*argv); } - if (!keyfile) { - fprintf(stderr, "%s: Missing key file\n", *argv); - usage(*argv); - } ffd = mmap_fdt(cmdname, fdtfile, 0, &fit_blob, &fsbuf, false, true); if (ffd < 0) return EXIT_FAILURE; - kfd = mmap_fdt(cmdname, keyfile, 0, &key_blob, &ksbuf, false, true); - if (kfd < 0) - return EXIT_FAILURE; - + if (keyfile) { + kfd = mmap_fdt(cmdname, keyfile, 0, &key_blob, &ksbuf, false, true); + if (kfd < 0) + return EXIT_FAILURE; + } image_set_host_blob(key_blob); ret = fit_check_sign(fit_blob, key_blob, config_name); if (!ret) { @@ -93,7 +90,9 @@ int main(int argc, char **argv) } (void) munmap((void *)fit_blob, fsbuf.st_size); - (void) munmap((void *)key_blob, ksbuf.st_size); + + if (key_blob) + (void)munmap((void *)key_blob, ksbuf.st_size); close(ffd); close(kfd); diff --git a/tools/mkimage.c b/tools/mkimage.c index ac62ebbde9b..2954626a283 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -196,6 +196,7 @@ static const struct option longopts[] = { { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { "xip", no_argument, NULL, 'x' }, + { /* sentinel */ }, }; static void process_args(int argc, char **argv) diff --git a/tools/patman/control.py b/tools/patman/control.py index fb5a4246ced..b8a45912058 100644 --- a/tools/patman/control.py +++ b/tools/patman/control.py @@ -63,7 +63,8 @@ def prepare_patches(col, branch, count, start, end, ignore_binary, signoff, branch, start, to_do, ignore_binary, series, signoff) # Fix up the patch files to our liking, and insert the cover letter - patchstream.fix_patches(series, patch_files, keep_change_id) + patchstream.fix_patches(series, patch_files, keep_change_id, + insert_base_commit=not cover_fname) if cover_fname and series.get('cover'): patchstream.insert_cover_letter(cover_fname, series, to_do) return series, cover_fname, patch_files diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index bf333dc557b..720746e21f5 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -216,6 +216,8 @@ class TestFunctional(unittest.TestCase): text = self._get_text('test01.txt') series = patchstream.get_metadata_for_test(text) + series.base_commit = Commit('1a44532') + series.branch = 'mybranch' cover_fname, args = self._create_patches_for_test(series) get_maintainer_script = str(pathlib.Path(__file__).parent.parent.parent / 'get_maintainer.pl') + ' --norolestats' @@ -308,6 +310,8 @@ Simon Glass (2): --\x20 2.7.4 +base-commit: 1a44532 +branch: mybranch ''' lines = open(cover_fname, encoding='utf-8').read().splitlines() self.assertEqual( @@ -353,6 +357,31 @@ Changes in v2: expected = expected.splitlines() self.assertEqual(expected, lines[start:(start+len(expected))]) + def test_base_commit(self): + """Test adding a base commit with no cover letter""" + orig_text = self._get_text('test01.txt') + pos = orig_text.index('commit 5ab48490f03051875ab13d288a4bf32b507d76fd') + text = orig_text[:pos] + series = patchstream.get_metadata_for_test(text) + series.base_commit = Commit('1a44532') + series.branch = 'mybranch' + cover_fname, args = self._create_patches_for_test(series) + self.assertFalse(cover_fname) + with capture_sys_output() as out: + patchstream.fix_patches(series, args, insert_base_commit=True) + self.assertEqual('Cleaned 1 patch\n', out[0].getvalue()) + lines = tools.read_file(args[0], binary=False).splitlines() + pos = lines.index('-- ') + + # We expect these lines at the end: + # -- (with trailing space) + # 2.7.4 + # (empty) + # base-commit: xxx + # branch: xxx + self.assertEqual('base-commit: 1a44532', lines[pos + 3]) + self.assertEqual('branch: mybranch', lines[pos + 4]) + def make_commit_with_file(self, subject, body, fname, text): """Create a file and add it to the git repo with a new commit @@ -511,12 +540,23 @@ complicated as possible''') # Check that it can detect a different branch self.assertEqual(3, gitutil.count_commits_to_branch('second')) with capture_sys_output() as _: - _, cover_fname, patch_files = control.prepare_patches( + series, cover_fname, patch_files = control.prepare_patches( col, branch='second', count=-1, start=0, end=0, ignore_binary=False, signoff=True) self.assertIsNotNone(cover_fname) self.assertEqual(3, len(patch_files)) + cover = tools.read_file(cover_fname, binary=False) + lines = cover.splitlines()[-2:] + base = repo.lookup_reference('refs/heads/base').target + self.assertEqual(f'base-commit: {base}', lines[0]) + self.assertEqual('branch: second', lines[1]) + + # Make sure that the base-commit is not present when it is in the + # cover letter + for fname in patch_files: + self.assertNotIn(b'base-commit:', tools.read_file(fname)) + # Check that it can skip patches at the end with capture_sys_output() as _: _, cover_fname, patch_files = control.prepare_patches( @@ -524,6 +564,13 @@ complicated as possible''') ignore_binary=False, signoff=True) self.assertIsNotNone(cover_fname) self.assertEqual(2, len(patch_files)) + + cover = tools.read_file(cover_fname, binary=False) + lines = cover.splitlines()[-2:] + base2 = repo.lookup_reference('refs/heads/second') + ref = base2.peel(pygit2.GIT_OBJ_COMMIT).parents[0].parents[0].id + self.assertEqual(f'base-commit: {ref}', lines[0]) + self.assertEqual('branch: second', lines[1]) finally: os.chdir(orig_dir) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index 490d382045b..7a695c37c27 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -76,8 +76,13 @@ class PatchStream: are interested in. We can also process a patch file in order to remove unwanted tags or inject additional ones. These correspond to the two phases of processing. + + Args: + keep_change_id (bool): Keep the Change-Id tag + insert_base_commit (bool): True to add the base commit to the end """ - def __init__(self, series, is_log=False, keep_change_id=False): + def __init__(self, series, is_log=False, keep_change_id=False, + insert_base_commit=False): self.skip_blank = False # True to skip a single blank line self.found_test = False # Found a TEST= line self.lines_after_test = 0 # Number of lines found after TEST= @@ -103,6 +108,7 @@ class PatchStream: self.recent_quoted = collections.deque([], 5) self.recent_unquoted = queue.Queue() self.was_quoted = None + self.insert_base_commit = insert_base_commit @staticmethod def process_text(text, is_comment=False): @@ -658,6 +664,13 @@ class PatchStream: outfd.write(line + '\n') self.blank_count = 0 self.finalise() + if self.insert_base_commit: + if self.series.base_commit: + print(f'base-commit: {self.series.base_commit.hash}', + file=outfd) + if self.series.branch: + print(f'branch: {self.series.branch}', file=outfd) + def insert_tags(msg, tags_to_emit): """Add extra tags to a commit message @@ -755,8 +768,12 @@ def get_metadata(branch, start, count): Returns: Series: Object containing information about the commits. """ - return get_metadata_for_list( - '%s~%d' % (branch if branch else 'HEAD', start), None, count) + top = f"{branch if branch else 'HEAD'}~{start}" + series = get_metadata_for_list(top, None, count) + series.base_commit = commit.Commit(gitutil.get_hash(f'{top}~{count}')) + series.branch = branch or gitutil.get_branch() + series.top = top + return series def get_metadata_for_test(text): """Process metadata from a file containing a git log. Used for tests @@ -774,7 +791,8 @@ def get_metadata_for_test(text): pst.finalise() return series -def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False): +def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False, + insert_base_commit=False): """Fix up a patch file, by adding/removing as required. We remove our tags from the patch file, insert changes lists, etc. @@ -788,6 +806,7 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False): series (Series): Series information about this patch set cmt (Commit): Commit object for this patch file keep_change_id (bool): Keep the Change-Id tag. + insert_base_commit (bool): True to add the base commit to the end Return: list: A list of errors, each str, or [] if all ok. @@ -795,7 +814,8 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False): handle, tmpname = tempfile.mkstemp() outfd = os.fdopen(handle, 'w', encoding='utf-8') infd = open(fname, 'r', encoding='utf-8') - pst = PatchStream(series, keep_change_id=keep_change_id) + pst = PatchStream(series, keep_change_id=keep_change_id, + insert_base_commit=insert_base_commit) pst.commit = cmt pst.process_stream(infd, outfd) infd.close() @@ -807,7 +827,7 @@ def fix_patch(backup_dir, fname, series, cmt, keep_change_id=False): shutil.move(tmpname, fname) return cmt.warn -def fix_patches(series, fnames, keep_change_id=False): +def fix_patches(series, fnames, keep_change_id=False, insert_base_commit=False): """Fix up a list of patches identified by filenames The patch files are processed in place, and overwritten. @@ -816,6 +836,7 @@ def fix_patches(series, fnames, keep_change_id=False): series (Series): The Series object fnames (:type: list of str): List of patch files to process keep_change_id (bool): Keep the Change-Id tag. + insert_base_commit (bool): True to add the base commit to the end """ # Current workflow creates patches, so we shouldn't need a backup backup_dir = None #tempfile.mkdtemp('clean-patch') @@ -825,7 +846,8 @@ def fix_patches(series, fnames, keep_change_id=False): cmt.patch = fname cmt.count = count result = fix_patch(backup_dir, fname, series, cmt, - keep_change_id=keep_change_id) + keep_change_id=keep_change_id, + insert_base_commit=insert_base_commit) if result: print('%d warning%s for %s:' % (len(result), 's' if len(result) > 1 else '', fname)) @@ -868,4 +890,11 @@ def insert_cover_letter(fname, series, count): out = series.MakeChangeLog(None) line += '\n' + '\n'.join(out) fil.write(line) + + # Insert the base commit and branch + if series.base_commit: + print(f'base-commit: {series.base_commit.hash}', file=fil) + if series.branch: + print(f'branch: {series.branch}', file=fil) + fil.close() diff --git a/tools/patman/series.py b/tools/patman/series.py index d7f2f010f5d..b73e9c58de4 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -42,6 +42,8 @@ class Series(dict): self.notes = [] self.changes = {} self.allow_overwrite = False + self.base_commit = None + self.branch = None # Written in MakeCcFile() # key: name of patch file diff --git a/tools/qconfig.py b/tools/qconfig.py index c96a305a48f..5b85f9d22c3 100755 --- a/tools/qconfig.py +++ b/tools/qconfig.py @@ -1175,7 +1175,7 @@ def prefix_config(cfg): return oper + cfg -RE_MK_CONFIGS = re.compile(r'CONFIG_(\$\(XPL_\)|\$\(PHASE_\))?([A-Za-z0-9_]*)') +RE_MK_CONFIGS = re.compile(r'CONFIG_(\$\(PHASE_\))?([A-Za-z0-9_]*)') RE_IFDEF = re.compile(r'(ifdef|ifndef)') RE_C_CONFIGS = re.compile(r'CONFIG_([A-Za-z0-9_]*)') RE_CONFIG_IS = re.compile(r'CONFIG_IS_ENABLED\(([A-Za-z0-9_]*)\)') @@ -1220,8 +1220,6 @@ def scan_makefiles(fnames): >>> RE_MK_CONFIGS.search('CONFIG_FRED').groups() (None, 'FRED') - >>> RE_MK_CONFIGS.search('CONFIG_$(XPL_)MARY').groups() - ('$(XPL_)', 'MARY') >>> RE_MK_CONFIGS.search('CONFIG_$(PHASE_)MARY').groups() ('$(PHASE_)', 'MARY') """ @@ -1321,8 +1319,8 @@ def do_scan_source(path, do_update): spl_mode (int): If MODE_SPL, look at source code which implies an xPL_ option, but for which there is none; for MOD_PROPER, look at source code which implies a Proper - option (i.e. use of CONFIG_IS_ENABLED() or $(XPL_) or - $(PHASE_) but for which there none; + option (i.e. use of CONFIG_IS_ENABLED() or $(PHASE_) but for + which there none; if MODE_NORMAL, ignore SPL Returns: diff --git a/tools/rkcommon.c b/tools/rkcommon.c index 3e52236b15a..a0caa029cc0 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -134,7 +134,9 @@ static struct spl_info spl_infos[] = { { "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 }, { "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 }, { "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 }, + { "rk3528", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 }, { "rk3568", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 }, + { "rk3576", "RK35", 0x80000 - 0x1000, false, RK_HEADER_V2 }, { "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 }, }; diff --git a/tools/u_boot_pylib/gitutil.py b/tools/u_boot_pylib/gitutil.py index 5e3e98ac9a6..0376bece3e6 100644 --- a/tools/u_boot_pylib/gitutil.py +++ b/tools/u_boot_pylib/gitutil.py @@ -701,13 +701,38 @@ def setup(): .return_code == 0) +def get_hash(spec): + """Get the hash of a commit + + Args: + spec (str): Git commit to show, e.g. 'my-branch~12' + + Returns: + str: Hash of commit + """ + return command.output_one_line('git', 'show', '-s', '--pretty=format:%H', + spec) + + def get_head(): """Get the hash of the current HEAD Returns: Hash of HEAD """ - return command.output_one_line('git', 'show', '-s', '--pretty=format:%H') + return get_hash('HEAD') + + +def get_branch(): + """Get the branch we are currently on + + Return: + str: branch name, or None if none + """ + out = command.output_one_line('git', 'rev-parse', '--abbrev-ref', 'HEAD') + if out == 'HEAD': + return None + return out if __name__ == "__main__": diff --git a/tools/u_boot_pylib/test_util.py b/tools/u_boot_pylib/test_util.py index dd671965263..637403f8715 100644 --- a/tools/u_boot_pylib/test_util.py +++ b/tools/u_boot_pylib/test_util.py @@ -8,6 +8,7 @@ import doctest import glob import multiprocessing import os +import re import sys import unittest @@ -25,7 +26,7 @@ except: def run_test_coverage(prog, filter_fname, exclude_list, build_dir, required=None, extra_args=None, single_thread='-P1', - args=None): + args=None, allow_failures=None): """Run tests and check that we get 100% coverage Args: @@ -56,14 +57,14 @@ def run_test_coverage(prog, filter_fname, exclude_list, build_dir, else: glob_list = [] glob_list += exclude_list - glob_list += ['*libfdt.py', '*site-packages*', '*dist-packages*'] + glob_list += ['*libfdt.py', '*/site-packages/*', '*/dist-packages/*'] glob_list += ['*concurrencytest*'] test_cmd = 'test' if 'binman' in prog or 'patman' in prog else '-t' prefix = '' if build_dir: prefix = 'PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools ' % build_dir - # Detect a Python virtualenv and use 'coverage' instead + # Detect a Python sandbox and use 'coverage' instead covtool = ('python3-coverage' if sys.prefix == sys.base_prefix else 'coverage') @@ -96,6 +97,19 @@ def run_test_coverage(prog, filter_fname, exclude_list, build_dir, print('Coverage error: %s, but should be 100%%' % coverage) ok = False if not ok: + if allow_failures: + # for line in lines: + # print('.', line, re.match(r'^(tools/.*py) *\d+ *(\d+) *(\d+)%$', line)) + lines = [re.match(r'^(tools/.*py) *\d+ *(\d+) *\d+%$', line) + for line in stdout.splitlines()] + bad = [] + for mat in lines: + if mat and mat.group(2) != '0': + fname = mat.group(1) + if fname not in allow_failures: + bad.append(fname) + if not bad: + return raise ValueError('Test coverage failure') |