diff --git a/.ci-farms-disabled/google-freedreno b/.ci-farms-disabled/google-freedreno deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/.gitlab-ci/bare-metal/cros-servo.sh b/.gitlab-ci/bare-metal/cros-servo.sh deleted file mode 100755 index f95886afddb..00000000000 --- a/.gitlab-ci/bare-metal/cros-servo.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC1091 # The relative paths in this file only become valid at runtime. -# shellcheck disable=SC2034 -# shellcheck disable=SC2086 # we want word splitting - -# Boot script for Chrome OS devices attached to a servo debug connector, using -# NFS and TFTP to boot. - -# We're run from the root of the repo, make a helper var for our paths -BM=$CI_PROJECT_DIR/install/bare-metal -CI_COMMON=$CI_PROJECT_DIR/install/common -CI_INSTALL=$CI_PROJECT_DIR/install - -# Runner config checks -if [ -z "$BM_SERIAL" ]; then - echo "Must set BM_SERIAL in your gitlab-runner config.toml [[runners]] environment" - echo "This is the CPU serial device." - exit 1 -fi - -if [ -z "$BM_SERIAL_EC" ]; then - echo "Must set BM_SERIAL in your gitlab-runner config.toml [[runners]] environment" - echo "This is the EC serial device for controlling board power" - exit 1 -fi - -if [ ! -d /nfs ]; then - echo "NFS rootfs directory needs to be mounted at /nfs by the gitlab runner" - exit 1 -fi - -if [ ! -d /tftp ]; then - echo "TFTP directory for this board needs to be mounted at /tftp by the gitlab runner" - exit 1 -fi - -# job config checks -if [ -z "$BM_KERNEL" ]; then - echo "Must set BM_KERNEL to your board's kernel FIT image" - exit 1 -fi - -if [ -z "$BM_ROOTFS" ]; then - echo "Must set BM_ROOTFS to your board's rootfs directory in the job's variables" - exit 1 -fi - -if [ -z "$BM_CMDLINE" ]; then - echo "Must set BM_CMDLINE to your board's kernel command line arguments" - exit 1 -fi - -. "${SCRIPTS_DIR}/setup-test-env.sh" - -section_start prepare_rootfs "Preparing rootfs components" - -set -ex - -# Clear out any previous run's artifacts. -rm -rf results/ -mkdir -p results - -# Create the rootfs in the NFS directory. rm to make sure it's in a pristine -# state, since it's volume-mounted on the host. -rsync -a --delete $BM_ROOTFS/ /nfs/ -mkdir -p /nfs/results -. $BM/rootfs-setup.sh /nfs - -# Put the kernel/dtb image and the boot command line in the tftp directory for -# the board to find. For normal Mesa development, we build the kernel and -# store it in the docker container that this script is running in. -# -# However, container builds are expensive, so when you're hacking on the -# kernel, it's nice to be able to skip the half hour container build and plus -# moving that container to the runner. So, if BM_KERNEL is a URL, fetch it -# instead of looking in the container. Note that the kernel build should be -# the output of: -# -# make Image.lzma -# -# mkimage \ -# -A arm64 \ -# -f auto \ -# -C lzma \ -# -d arch/arm64/boot/Image.lzma \ -# -b arch/arm64/boot/dts/qcom/sdm845-cheza-r3.dtb \ -# cheza-image.img - -rm -rf /tftp/* -if echo "$BM_KERNEL" | grep -q http; then - curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \ - "$BM_KERNEL" -o /tftp/vmlinuz -else - cp /baremetal-files/"$BM_KERNEL" /tftp/vmlinuz -fi -echo "$BM_CMDLINE" > /tftp/cmdline - -set +e -STRUCTURED_LOG_FILE=results/job_detail.json -python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update dut_job_type "${DEVICE_TYPE}" -python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update farm "${FARM}" -python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --create-dut-job dut_name "${CI_RUNNER_DESCRIPTION}" -python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update-dut-time submit "${CI_JOB_STARTED_AT}" -section_end prepare_rootfs - -python3 $BM/cros_servo_run.py \ - --cpu $BM_SERIAL \ - --ec $BM_SERIAL_EC \ - --test-timeout ${TEST_PHASE_TIMEOUT_MINUTES:-20} -ret=$? - -section_start dut_cleanup "Cleaning up after job" -python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --close-dut-job -python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --close -set -e - -# Bring artifacts back from the NFS dir to the build dir where gitlab-runner -# will look for them. -cp -Rp /nfs/results/. results/ -section_end dut_cleanup - -exit $ret diff --git a/.gitlab-ci/bare-metal/cros_servo_run.py b/.gitlab-ci/bare-metal/cros_servo_run.py deleted file mode 100755 index 95fed60c473..00000000000 --- a/.gitlab-ci/bare-metal/cros_servo_run.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright © 2020 Google LLC -# SPDX-License-Identifier: MIT - -import argparse -import datetime -import math -import os -import re -import sys - -from custom_logger import CustomLogger -from serial_buffer import SerialBuffer - -ANSI_ESCAPE="\x1b[0K" -ANSI_COLOUR="\x1b[0;36m" -ANSI_RESET="\x1b[0m" -SECTION_START="start" -SECTION_END="end" - -class CrosServoRun: - def __init__(self, cpu, ec, test_timeout, logger): - self.cpu_ser = SerialBuffer( - cpu, "results/serial.txt", ": ") - # Merge the EC serial into the cpu_ser's line stream so that we can - # effectively poll on both at the same time and not have to worry about - self.ec_ser = SerialBuffer( - ec, "results/serial-ec.txt", " EC: ", line_queue=self.cpu_ser.line_queue) - self.test_timeout = test_timeout - self.logger = logger - - def close(self): - self.ec_ser.close() - self.cpu_ser.close() - - def ec_write(self, s): - print("EC> %s" % s) - self.ec_ser.serial.write(s.encode()) - - def cpu_write(self, s): - print("> %s" % s) - self.cpu_ser.serial.write(s.encode()) - - def print_error(self, message): - RED = '\033[0;31m' - NO_COLOR = '\033[0m' - print(RED + message + NO_COLOR) - self.logger.update_status_fail(message) - - def get_rel_timestamp(self): - now = datetime.datetime.now(tz=datetime.UTC) - then_env = os.getenv("CI_JOB_STARTED_AT") - if not then_env: - return "" - delta = now - datetime.datetime.fromisoformat(then_env) - return f"[{math.floor(delta.seconds / 60):02}:{(delta.seconds % 60):02}]" - - def get_cur_timestamp(self): - return str(int(datetime.datetime.timestamp(datetime.datetime.now()))) - - def print_gitlab_section(self, action, name, description, collapse=True): - assert action in [SECTION_START, SECTION_END] - out = ANSI_ESCAPE + "section_" + action + ":" - out += self.get_cur_timestamp() + ":" - out += name - if action == "start" and collapse: - out += "[collapsed=true]" - out += "\r" + ANSI_ESCAPE + ANSI_COLOUR - out += self.get_rel_timestamp() + " " + description + ANSI_RESET - print(out) - - def boot_section(self, action): - self.print_gitlab_section(action, "dut_boot", "Booting hardware device", True) - - def run(self): - # Flush any partial commands in the EC's prompt, then ask for a reboot. - self.ec_write("\n") - self.ec_write("reboot\n") - - bootloader_done = False - self.logger.create_job_phase("boot") - self.boot_section(SECTION_START) - tftp_failures = 0 - # This is emitted right when the bootloader pauses to check for input. - # Emit a ^N character to request network boot, because we don't have a - # direct-to-netboot firmware on cheza. - for line in self.cpu_ser.lines(timeout=120, phase="bootloader"): - if re.search("load_archive: loading locale_en.bin", line): - self.cpu_write("\016") - bootloader_done = True - break - - # The Cheza firmware seems to occasionally get stuck looping in - # this error state during TFTP booting, possibly based on amount of - # network traffic around it, but it'll usually recover after a - # reboot. Currently mostly visible on google-freedreno-cheza-14. - if re.search("R8152: Bulk read error 0xffffffbf", line): - tftp_failures += 1 - if tftp_failures >= 10: - self.print_error( - "Detected intermittent tftp failure, restarting run.") - return 1 - - # If the board has a netboot firmware and we made it to booting the - # kernel, proceed to processing of the test run. - if re.search("Booting Linux", line): - bootloader_done = True - break - - # The Cheza boards have issues with failing to bring up power to - # the system sometimes, possibly dependent on ambient temperature - # in the farm. - if re.search("POWER_GOOD not seen in time", line): - self.print_error( - "Detected intermittent poweron failure, abandoning run.") - return 1 - - if not bootloader_done: - self.print_error("Failed to make it through bootloader, abandoning run.") - return 1 - - self.logger.create_job_phase("test") - for line in self.cpu_ser.lines(timeout=self.test_timeout, phase="test"): - if re.search("---. end Kernel panic", line): - return 1 - - # There are very infrequent bus errors during power management transitions - # on cheza, which we don't expect to be the case on future boards. - if re.search("Kernel panic - not syncing: Asynchronous SError Interrupt", line): - self.print_error( - "Detected cheza power management bus error, abandoning run.") - return 1 - - # If the network device dies, it's probably not graphics's fault, just try again. - if re.search("NETDEV WATCHDOG", line): - self.print_error( - "Detected network device failure, abandoning run.") - return 1 - - # These HFI response errors started appearing with the introduction - # of piglit runs. CosmicPenguin says: - # - # "message ID 106 isn't a thing, so likely what happened is that we - # got confused when parsing the HFI queue. If it happened on only - # one run, then memory corruption could be a possible clue" - # - # Given that it seems to trigger randomly near a GPU fault and then - # break many tests after that, just restart the whole run. - if re.search("a6xx_hfi_send_msg.*Unexpected message id .* on the response queue", line): - self.print_error( - "Detected cheza power management bus error, abandoning run.") - return 1 - - if re.search("coreboot.*bootblock starting", line): - self.print_error( - "Detected spontaneous reboot, abandoning run.") - return 1 - - if re.search("arm-smmu 5040000.iommu: TLB sync timed out -- SMMU may be deadlocked", line): - self.print_error("Detected cheza MMU fail, abandoning run.") - return 1 - - result = re.search(r"hwci: mesa: (\S*), exit_code: (\d+)", line) - if result: - status = result.group(1) - exit_code = int(result.group(2)) - - if status == "pass": - self.logger.update_dut_job("status", "pass") - else: - self.logger.update_status_fail("test fail") - - self.logger.update_dut_job("exit_code", exit_code) - return exit_code - - self.print_error( - "Reached the end of the CPU serial log without finding a result") - return 1 - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--cpu', type=str, - help='CPU Serial device', required=True) - parser.add_argument( - '--ec', type=str, help='EC Serial device', required=True) - parser.add_argument( - '--test-timeout', type=int, help='Test phase timeout (minutes)', required=True) - args = parser.parse_args() - - logger = CustomLogger("results/job_detail.json") - logger.update_dut_time("start", None) - servo = CrosServoRun(args.cpu, args.ec, args.test_timeout * 60, logger) - retval = servo.run() - - # power down the CPU on the device - servo.ec_write("power off\n") - logger.update_dut_time("end", None) - servo.close() - - sys.exit(retval) - - -if __name__ == '__main__': - main() diff --git a/.gitlab-ci/bare-metal/eth008-power-down.sh b/.gitlab-ci/bare-metal/eth008-power-down.sh deleted file mode 100755 index d61156de192..00000000000 --- a/.gitlab-ci/bare-metal/eth008-power-down.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -relay=$1 - -if [ -z "$relay" ]; then - echo "Must supply a relay arg" - exit 1 -fi - -"$CI_PROJECT_DIR"/install/bare-metal/eth008-power-relay.py "$ETH_HOST" "$ETH_PORT" off "$relay" diff --git a/.gitlab-ci/bare-metal/eth008-power-relay.py b/.gitlab-ci/bare-metal/eth008-power-relay.py deleted file mode 100755 index 589ea5dd6f4..00000000000 --- a/.gitlab-ci/bare-metal/eth008-power-relay.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python3 - -import sys -import socket - -host = sys.argv[1] -port = sys.argv[2] -mode = sys.argv[3] -relay = sys.argv[4] -msg = None - -if mode == "on": - msg = b'\x20' -else: - msg = b'\x21' - -msg += int(relay).to_bytes(1, 'big') -msg += b'\x00' - -c = socket.create_connection((host, int(port))) -c.sendall(msg) - -data = c.recv(1) -c.close() - -if data[0] == b'\x01': - print('Command failed') - sys.exit(1) diff --git a/.gitlab-ci/bare-metal/eth008-power-up.sh b/.gitlab-ci/bare-metal/eth008-power-up.sh deleted file mode 100755 index 4c978ac9d53..00000000000 --- a/.gitlab-ci/bare-metal/eth008-power-up.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -relay=$1 - -if [ -z "$relay" ]; then - echo "Must supply a relay arg" - exit 1 -fi - -"$CI_PROJECT_DIR"/install/bare-metal/eth008-power-relay.py "$ETH_HOST" "$ETH_PORT" off "$relay" -sleep 5 -"$CI_PROJECT_DIR"/install/bare-metal/eth008-power-relay.py "$ETH_HOST" "$ETH_PORT" on "$relay" diff --git a/.gitlab-ci/bare-metal/expect-output.sh b/.gitlab-ci/bare-metal/expect-output.sh deleted file mode 100755 index 425814d8794..00000000000 --- a/.gitlab-ci/bare-metal/expect-output.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -set -e - -STRINGS=$(mktemp) -ERRORS=$(mktemp) - -trap 'rm $STRINGS; rm $ERRORS;' EXIT - -FILE=$1 -shift 1 - -while getopts "f:e:" opt; do - case $opt in - f) echo "$OPTARG" >> "$STRINGS";; - e) echo "$OPTARG" >> "$STRINGS" ; echo "$OPTARG" >> "$ERRORS";; - *) exit - esac -done -shift $((OPTIND -1)) - -echo "Waiting for $FILE to say one of following strings" -cat "$STRINGS" - -while ! grep -E -wf "$STRINGS" "$FILE"; do - sleep 2 -done - -if grep -E -wf "$ERRORS" "$FILE"; then - exit 1 -fi diff --git a/.gitlab-ci/bare-metal/fastboot.sh b/.gitlab-ci/bare-metal/fastboot.sh deleted file mode 100755 index 7142f72fd24..00000000000 --- a/.gitlab-ci/bare-metal/fastboot.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC1091 # The relative paths in this file only become valid at runtime. -# shellcheck disable=SC2034 -# shellcheck disable=SC2086 # we want word splitting - -. "$SCRIPTS_DIR"/setup-test-env.sh - -BM=$CI_PROJECT_DIR/install/bare-metal -CI_COMMON=$CI_PROJECT_DIR/install/common - -if [ -z "$BM_SERIAL" ] && [ -z "$BM_SERIAL_SCRIPT" ]; then - echo "Must set BM_SERIAL OR BM_SERIAL_SCRIPT in your gitlab-runner config.toml [[runners]] environment" - echo "BM_SERIAL:" - echo " This is the serial device to talk to for waiting for fastboot to be ready and logging from the kernel." - echo "BM_SERIAL_SCRIPT:" - echo " This is a shell script to talk to for waiting for fastboot to be ready and logging from the kernel." - exit 1 -fi - -if [ -z "$BM_POWERUP" ]; then - echo "Must set BM_POWERUP in your gitlab-runner config.toml [[runners]] environment" - echo "This is a shell script that should reset the device and begin its boot sequence" - echo "such that it pauses at fastboot." - exit 1 -fi - -if [ -z "$BM_POWERDOWN" ]; then - echo "Must set BM_POWERDOWN in your gitlab-runner config.toml [[runners]] environment" - echo "This is a shell script that should power off the device." - exit 1 -fi - -if [ -z "$BM_FASTBOOT_SERIAL" ]; then - echo "Must set BM_FASTBOOT_SERIAL in your gitlab-runner config.toml [[runners]] environment" - echo "This must be the a stable-across-resets fastboot serial number." - exit 1 -fi - -if [ -z "$BM_KERNEL" ]; then - echo "Must set BM_KERNEL to your board's kernel vmlinuz or Image.gz in the job's variables:" - exit 1 -fi - -if [ -z "$BM_DTB" ]; then - echo "Must set BM_DTB to your board's DTB file in the job's variables:" - exit 1 -fi - -if [ -z "$BM_ROOTFS" ]; then - echo "Must set BM_ROOTFS to your board's rootfs directory in the job's variables:" - exit 1 -fi - -if echo $BM_CMDLINE | grep -q "root=/dev/nfs"; then - BM_FASTBOOT_NFSROOT=1 -fi - -section_start prepare_rootfs "Preparing rootfs components" - -set -ex - -# Clear out any previous run's artifacts. -rm -rf results/ -mkdir -p results/ - -if [ -n "$BM_FASTBOOT_NFSROOT" ]; then - # Create the rootfs in the NFS directory. rm to make sure it's in a pristine - # state, since it's volume-mounted on the host. - rsync -a --delete $BM_ROOTFS/ /nfs/ - mkdir -p /nfs/results - . $BM/rootfs-setup.sh /nfs - - # Root on NFS, no need for an inintramfs. - rm -f rootfs.cpio.gz - touch rootfs.cpio - gzip rootfs.cpio -else - # Create the rootfs in a temp dir - rsync -a --delete $BM_ROOTFS/ rootfs/ - . $BM/rootfs-setup.sh rootfs - - # Finally, pack it up into a cpio rootfs. Skip the vulkan CTS since none of - # these devices use it and it would take up space in the initrd. - - EXCLUDE_FILTER="deqp|arb_gpu_shader5|arb_gpu_shader_fp64|arb_gpu_shader_int64|glsl-4.[0123456]0|arb_tessellation_shader" - - pushd rootfs - find -H . | \ - grep -E -v "external/(openglcts|vulkancts|amber|glslang|spirv-tools)" | - grep -E -v "traces-db|apitrace|renderdoc" | \ - grep -E -v $EXCLUDE_FILTER | \ - cpio -H newc -o | \ - xz --check=crc32 -T4 - > $CI_PROJECT_DIR/rootfs.cpio.gz - popd -fi - -if echo "$BM_KERNEL $BM_DTB" | grep -q http; then - curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \ - "$BM_KERNEL" -o kernel - # FIXME: modules should be supplied too - curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \ - "$BM_DTB" -o dtb - - cat kernel dtb > Image.gz-dtb -else - cat /baremetal-files/"$BM_KERNEL" /baremetal-files/"$BM_DTB".dtb > Image.gz-dtb - cp /baremetal-files/"$BM_DTB".dtb dtb -fi - -export PATH=$BM:$PATH - -mkdir -p artifacts -mkbootimg.py \ - --kernel Image.gz-dtb \ - --ramdisk rootfs.cpio.gz \ - --dtb dtb \ - --cmdline "$BM_CMDLINE" \ - $BM_MKBOOT_PARAMS \ - --header_version 2 \ - -o artifacts/fastboot.img - -rm Image.gz-dtb dtb - -# Start background command for talking to serial if we have one. -if [ -n "$BM_SERIAL_SCRIPT" ]; then - $BM_SERIAL_SCRIPT > results/serial-output.txt & - - while [ ! -e results/serial-output.txt ]; do - sleep 1 - done -fi - -section_end prepare_rootfs - -set +e -$BM/fastboot_run.py \ - --dev="$BM_SERIAL" \ - --test-timeout ${TEST_PHASE_TIMEOUT_MINUTES:-20} \ - --fbserial="$BM_FASTBOOT_SERIAL" \ - --powerup="$BM_POWERUP" \ - --powerdown="$BM_POWERDOWN" -ret=$? -set -e - -if [ -n "$BM_FASTBOOT_NFSROOT" ]; then - # Bring artifacts back from the NFS dir to the build dir where gitlab-runner - # will look for them. - cp -Rp /nfs/results/. results/ -fi - -exit $ret diff --git a/.gitlab-ci/bare-metal/fastboot_run.py b/.gitlab-ci/bare-metal/fastboot_run.py deleted file mode 100755 index f0637040023..00000000000 --- a/.gitlab-ci/bare-metal/fastboot_run.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright © 2020 Google LLC -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -import argparse -import subprocess -import re -from serial_buffer import SerialBuffer -import sys -import threading - - -class FastbootRun: - def __init__(self, args, test_timeout): - self.powerup = args.powerup - self.ser = SerialBuffer( - args.dev, "results/serial-output.txt", "R SERIAL> ") - self.fastboot = "fastboot boot -s {ser} artifacts/fastboot.img".format( - ser=args.fbserial) - self.test_timeout = test_timeout - - def close(self): - self.ser.close() - - def print_error(self, message): - RED = '\033[0;31m' - NO_COLOR = '\033[0m' - print(RED + message + NO_COLOR) - - def logged_system(self, cmd, timeout=60): - print("Running '{}'".format(cmd)) - try: - return subprocess.call(cmd, shell=True, timeout=timeout) - except subprocess.TimeoutExpired: - self.print_error("timeout, abandoning run.") - return 1 - - def run(self): - if ret := self.logged_system(self.powerup): - return ret - - fastboot_ready = False - for line in self.ser.lines(timeout=2 * 60, phase="bootloader"): - if re.search("[Ff]astboot: [Pp]rocessing commands", line) or \ - re.search("Listening for fastboot command on", line): - fastboot_ready = True - break - - if re.search("data abort", line): - self.print_error( - "Detected crash during boot, abandoning run.") - return 1 - - if not fastboot_ready: - self.print_error( - "Failed to get to fastboot prompt, abandoning run.") - return 1 - - if ret := self.logged_system(self.fastboot): - return ret - - print_more_lines = -1 - for line in self.ser.lines(timeout=self.test_timeout, phase="test"): - if print_more_lines == 0: - return 1 - if print_more_lines > 0: - print_more_lines -= 1 - - if re.search("---. end Kernel panic", line): - return 1 - - # The db820c boards intermittently reboot. Just restart the run - # when if we see a reboot after we got past fastboot. - if re.search("PON REASON", line): - self.print_error( - "Detected spontaneous reboot, abandoning run.") - return 1 - - # db820c sometimes wedges around iommu fault recovery - if re.search("watchdog: BUG: soft lockup - CPU.* stuck", line): - self.print_error( - "Detected kernel soft lockup, abandoning run.") - return 1 - - # If the network device dies, it's probably not graphics's fault, just try again. - if re.search("NETDEV WATCHDOG", line): - self.print_error( - "Detected network device failure, abandoning run.") - return 1 - - # A3xx recovery doesn't quite work. Sometimes the GPU will get - # wedged and recovery will fail (because power can't be reset?) - # This assumes that the jobs are sufficiently well-tested that GPU - # hangs aren't always triggered, so just try again. But print some - # more lines first so that we get better information on the cause - # of the hang. Once a hang happens, it's pretty chatty. - if "[drm:adreno_recover] *ERROR* gpu hw init failed: -22" in line: - self.print_error( - "Detected GPU hang, abandoning run.") - if print_more_lines == -1: - print_more_lines = 30 - - result = re.search(r"hwci: mesa: (\S*), exit_code: (\d+)", line) - if result: - status = result.group(1) - exit_code = int(result.group(2)) - - return exit_code - - self.print_error( - "Reached the end of the CPU serial log without finding a result, abandoning run.") - return 1 - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - '--dev', type=str, help='Serial device (otherwise reading from serial-output.txt)') - parser.add_argument('--powerup', type=str, - help='shell command for rebooting', required=True) - parser.add_argument('--powerdown', type=str, - help='shell command for powering off', required=True) - parser.add_argument('--fbserial', type=str, - help='fastboot serial number of the board', required=True) - parser.add_argument('--test-timeout', type=int, - help='Test phase timeout (minutes)', required=True) - args = parser.parse_args() - - fastboot = FastbootRun(args, args.test_timeout * 60) - - retval = fastboot.run() - fastboot.close() - - fastboot.logged_system(args.powerdown) - - sys.exit(retval) - - -if __name__ == '__main__': - main() diff --git a/.gitlab-ci/bare-metal/google-power-down.sh b/.gitlab-ci/bare-metal/google-power-down.sh deleted file mode 100755 index 0404619cd92..00000000000 --- a/.gitlab-ci/bare-metal/google-power-down.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -relay=$1 - -if [ -z "$relay" ]; then - echo "Must supply a relay arg" - exit 1 -fi - -"$CI_PROJECT_DIR"/install/bare-metal/google-power-relay.py off "$relay" diff --git a/.gitlab-ci/bare-metal/google-power-relay.py b/.gitlab-ci/bare-metal/google-power-relay.py deleted file mode 100755 index 52ed6f5e48f..00000000000 --- a/.gitlab-ci/bare-metal/google-power-relay.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/python3 - -import sys -import serial - -mode = sys.argv[1] -relay = sys.argv[2] - -# our relays are "off" means "board is powered". -mode_swap = { - "on": "off", - "off": "on", -} -mode = mode_swap[mode] - -ser = serial.Serial('/dev/ttyACM0', 115200, timeout=2) -command = "relay {} {}\n\r".format(mode, relay) -ser.write(command.encode()) -ser.close() diff --git a/.gitlab-ci/bare-metal/google-power-up.sh b/.gitlab-ci/bare-metal/google-power-up.sh deleted file mode 100755 index d5c3cf77e41..00000000000 --- a/.gitlab-ci/bare-metal/google-power-up.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -relay=$1 - -if [ -z "$relay" ]; then - echo "Must supply a relay arg" - exit 1 -fi - -"$CI_PROJECT_DIR"/install/bare-metal/google-power-relay.py off "$relay" -sleep 5 -"$CI_PROJECT_DIR"/install/bare-metal/google-power-relay.py on "$relay" diff --git a/.gitlab-ci/bare-metal/mkbootimg.py b/.gitlab-ci/bare-metal/mkbootimg.py deleted file mode 100755 index 5f000dbcf9b..00000000000 --- a/.gitlab-ci/bare-metal/mkbootimg.py +++ /dev/null @@ -1,569 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2015, The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Creates the boot image.""" -from argparse import (ArgumentParser, ArgumentTypeError, - FileType, RawDescriptionHelpFormatter) -from hashlib import sha1 -from os import fstat -from struct import pack -import array -import collections -import os -import re -import subprocess -import tempfile -# Constant and structure definition is in -# system/tools/mkbootimg/include/bootimg/bootimg.h -BOOT_MAGIC = 'ANDROID!' -BOOT_MAGIC_SIZE = 8 -BOOT_NAME_SIZE = 16 -BOOT_ARGS_SIZE = 512 -BOOT_EXTRA_ARGS_SIZE = 1024 -BOOT_IMAGE_HEADER_V1_SIZE = 1648 -BOOT_IMAGE_HEADER_V2_SIZE = 1660 -BOOT_IMAGE_HEADER_V3_SIZE = 1580 -BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096 -BOOT_IMAGE_HEADER_V4_SIZE = 1584 -BOOT_IMAGE_V4_SIGNATURE_SIZE = 4096 -VENDOR_BOOT_MAGIC = 'VNDRBOOT' -VENDOR_BOOT_MAGIC_SIZE = 8 -VENDOR_BOOT_NAME_SIZE = BOOT_NAME_SIZE -VENDOR_BOOT_ARGS_SIZE = 2048 -VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112 -VENDOR_BOOT_IMAGE_HEADER_V4_SIZE = 2128 -VENDOR_RAMDISK_TYPE_NONE = 0 -VENDOR_RAMDISK_TYPE_PLATFORM = 1 -VENDOR_RAMDISK_TYPE_RECOVERY = 2 -VENDOR_RAMDISK_TYPE_DLKM = 3 -VENDOR_RAMDISK_NAME_SIZE = 32 -VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE = 16 -VENDOR_RAMDISK_TABLE_ENTRY_V4_SIZE = 108 -# Names with special meaning, mustn't be specified in --ramdisk_name. -VENDOR_RAMDISK_NAME_BLOCKLIST = {b'default'} -PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT = '--vendor_ramdisk_fragment' -def filesize(f): - if f is None: - return 0 - try: - return fstat(f.fileno()).st_size - except OSError: - return 0 -def update_sha(sha, f): - if f: - sha.update(f.read()) - f.seek(0) - sha.update(pack('I', filesize(f))) - else: - sha.update(pack('I', 0)) -def pad_file(f, padding): - pad = (padding - (f.tell() & (padding - 1))) & (padding - 1) - f.write(pack(str(pad) + 'x')) -def get_number_of_pages(image_size, page_size): - """calculates the number of pages required for the image""" - return (image_size + page_size - 1) // page_size -def get_recovery_dtbo_offset(args): - """calculates the offset of recovery_dtbo image in the boot image""" - num_header_pages = 1 # header occupies a page - num_kernel_pages = get_number_of_pages(filesize(args.kernel), args.pagesize) - num_ramdisk_pages = get_number_of_pages(filesize(args.ramdisk), - args.pagesize) - num_second_pages = get_number_of_pages(filesize(args.second), args.pagesize) - dtbo_offset = args.pagesize * (num_header_pages + num_kernel_pages + - num_ramdisk_pages + num_second_pages) - return dtbo_offset -def write_header_v3_and_above(args): - if args.header_version > 3: - boot_header_size = BOOT_IMAGE_HEADER_V4_SIZE - else: - boot_header_size = BOOT_IMAGE_HEADER_V3_SIZE - args.output.write(pack(f'{BOOT_MAGIC_SIZE}s', BOOT_MAGIC.encode())) - # kernel size in bytes - args.output.write(pack('I', filesize(args.kernel))) - # ramdisk size in bytes - args.output.write(pack('I', filesize(args.ramdisk))) - # os version and patch level - args.output.write(pack('I', (args.os_version << 11) | args.os_patch_level)) - args.output.write(pack('I', boot_header_size)) - # reserved - args.output.write(pack('4I', 0, 0, 0, 0)) - # version of boot image header - args.output.write(pack('I', args.header_version)) - args.output.write(pack(f'{BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE}s', - args.cmdline)) - if args.header_version >= 4: - # The signature used to verify boot image v4. - args.output.write(pack('I', BOOT_IMAGE_V4_SIGNATURE_SIZE)) - pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE) -def write_vendor_boot_header(args): - if filesize(args.dtb) == 0: - raise ValueError('DTB image must not be empty.') - if args.header_version > 3: - vendor_ramdisk_size = args.vendor_ramdisk_total_size - vendor_boot_header_size = VENDOR_BOOT_IMAGE_HEADER_V4_SIZE - else: - vendor_ramdisk_size = filesize(args.vendor_ramdisk) - vendor_boot_header_size = VENDOR_BOOT_IMAGE_HEADER_V3_SIZE - args.vendor_boot.write(pack(f'{VENDOR_BOOT_MAGIC_SIZE}s', - VENDOR_BOOT_MAGIC.encode())) - # version of boot image header - args.vendor_boot.write(pack('I', args.header_version)) - # flash page size - args.vendor_boot.write(pack('I', args.pagesize)) - # kernel physical load address - args.vendor_boot.write(pack('I', args.base + args.kernel_offset)) - # ramdisk physical load address - args.vendor_boot.write(pack('I', args.base + args.ramdisk_offset)) - # ramdisk size in bytes - args.vendor_boot.write(pack('I', vendor_ramdisk_size)) - args.vendor_boot.write(pack(f'{VENDOR_BOOT_ARGS_SIZE}s', - args.vendor_cmdline)) - # kernel tags physical load address - args.vendor_boot.write(pack('I', args.base + args.tags_offset)) - # asciiz product name - args.vendor_boot.write(pack(f'{VENDOR_BOOT_NAME_SIZE}s', args.board)) - # header size in bytes - args.vendor_boot.write(pack('I', vendor_boot_header_size)) - # dtb size in bytes - args.vendor_boot.write(pack('I', filesize(args.dtb))) - # dtb physical load address - args.vendor_boot.write(pack('Q', args.base + args.dtb_offset)) - if args.header_version > 3: - vendor_ramdisk_table_size = (args.vendor_ramdisk_table_entry_num * - VENDOR_RAMDISK_TABLE_ENTRY_V4_SIZE) - # vendor ramdisk table size in bytes - args.vendor_boot.write(pack('I', vendor_ramdisk_table_size)) - # number of vendor ramdisk table entries - args.vendor_boot.write(pack('I', args.vendor_ramdisk_table_entry_num)) - # vendor ramdisk table entry size in bytes - args.vendor_boot.write(pack('I', VENDOR_RAMDISK_TABLE_ENTRY_V4_SIZE)) - # bootconfig section size in bytes - args.vendor_boot.write(pack('I', filesize(args.vendor_bootconfig))) - pad_file(args.vendor_boot, args.pagesize) -def write_header(args): - if args.header_version > 4: - raise ValueError( - f'Boot header version {args.header_version} not supported') - if args.header_version in {3, 4}: - return write_header_v3_and_above(args) - ramdisk_load_address = ((args.base + args.ramdisk_offset) - if filesize(args.ramdisk) > 0 else 0) - second_load_address = ((args.base + args.second_offset) - if filesize(args.second) > 0 else 0) - args.output.write(pack(f'{BOOT_MAGIC_SIZE}s', BOOT_MAGIC.encode())) - # kernel size in bytes - args.output.write(pack('I', filesize(args.kernel))) - # kernel physical load address - args.output.write(pack('I', args.base + args.kernel_offset)) - # ramdisk size in bytes - args.output.write(pack('I', filesize(args.ramdisk))) - # ramdisk physical load address - args.output.write(pack('I', ramdisk_load_address)) - # second bootloader size in bytes - args.output.write(pack('I', filesize(args.second))) - # second bootloader physical load address - args.output.write(pack('I', second_load_address)) - # kernel tags physical load address - args.output.write(pack('I', args.base + args.tags_offset)) - # flash page size - args.output.write(pack('I', args.pagesize)) - # version of boot image header - args.output.write(pack('I', args.header_version)) - # os version and patch level - args.output.write(pack('I', (args.os_version << 11) | args.os_patch_level)) - # asciiz product name - args.output.write(pack(f'{BOOT_NAME_SIZE}s', args.board)) - args.output.write(pack(f'{BOOT_ARGS_SIZE}s', args.cmdline)) - sha = sha1() - update_sha(sha, args.kernel) - update_sha(sha, args.ramdisk) - update_sha(sha, args.second) - if args.header_version > 0: - update_sha(sha, args.recovery_dtbo) - if args.header_version > 1: - update_sha(sha, args.dtb) - img_id = pack('32s', sha.digest()) - args.output.write(img_id) - args.output.write(pack(f'{BOOT_EXTRA_ARGS_SIZE}s', args.extra_cmdline)) - if args.header_version > 0: - if args.recovery_dtbo: - # recovery dtbo size in bytes - args.output.write(pack('I', filesize(args.recovery_dtbo))) - # recovert dtbo offset in the boot image - args.output.write(pack('Q', get_recovery_dtbo_offset(args))) - else: - # Set to zero if no recovery dtbo - args.output.write(pack('I', 0)) - args.output.write(pack('Q', 0)) - # Populate boot image header size for header versions 1 and 2. - if args.header_version == 1: - args.output.write(pack('I', BOOT_IMAGE_HEADER_V1_SIZE)) - elif args.header_version == 2: - args.output.write(pack('I', BOOT_IMAGE_HEADER_V2_SIZE)) - if args.header_version > 1: - if filesize(args.dtb) == 0: - raise ValueError('DTB image must not be empty.') - # dtb size in bytes - args.output.write(pack('I', filesize(args.dtb))) - # dtb physical load address - args.output.write(pack('Q', args.base + args.dtb_offset)) - pad_file(args.output, args.pagesize) - return img_id -class AsciizBytes: - """Parses a string and encodes it as an asciiz bytes object. - >>> AsciizBytes(bufsize=4)('foo') - b'foo\\x00' - >>> AsciizBytes(bufsize=4)('foob') - Traceback (most recent call last): - ... - argparse.ArgumentTypeError: Encoded asciiz length exceeded: max 4, got 5 - """ - def __init__(self, bufsize): - self.bufsize = bufsize - def __call__(self, arg): - arg_bytes = arg.encode() + b'\x00' - if len(arg_bytes) > self.bufsize: - raise ArgumentTypeError( - 'Encoded asciiz length exceeded: ' - f'max {self.bufsize}, got {len(arg_bytes)}') - return arg_bytes -class VendorRamdiskTableBuilder: - """Vendor ramdisk table builder. - Attributes: - entries: A list of VendorRamdiskTableEntry namedtuple. - ramdisk_total_size: Total size in bytes of all ramdisks in the table. - """ - VendorRamdiskTableEntry = collections.namedtuple( # pylint: disable=invalid-name - 'VendorRamdiskTableEntry', - ['ramdisk_path', 'ramdisk_size', 'ramdisk_offset', 'ramdisk_type', - 'ramdisk_name', 'board_id']) - def __init__(self): - self.entries = [] - self.ramdisk_total_size = 0 - self.ramdisk_names = set() - def add_entry(self, ramdisk_path, ramdisk_type, ramdisk_name, board_id): - # Strip any trailing null for simple comparison. - stripped_ramdisk_name = ramdisk_name.rstrip(b'\x00') - if stripped_ramdisk_name in VENDOR_RAMDISK_NAME_BLOCKLIST: - raise ValueError( - f'Banned vendor ramdisk name: {stripped_ramdisk_name}') - if stripped_ramdisk_name in self.ramdisk_names: - raise ValueError( - f'Duplicated vendor ramdisk name: {stripped_ramdisk_name}') - self.ramdisk_names.add(stripped_ramdisk_name) - if board_id is None: - board_id = array.array( - 'I', [0] * VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE) - else: - board_id = array.array('I', board_id) - if len(board_id) != VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE: - raise ValueError('board_id size must be ' - f'{VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE}') - with open(ramdisk_path, 'rb') as f: - ramdisk_size = filesize(f) - self.entries.append(self.VendorRamdiskTableEntry( - ramdisk_path, ramdisk_size, self.ramdisk_total_size, ramdisk_type, - ramdisk_name, board_id)) - self.ramdisk_total_size += ramdisk_size - def write_ramdisks_padded(self, fout, alignment): - for entry in self.entries: - with open(entry.ramdisk_path, 'rb') as f: - fout.write(f.read()) - pad_file(fout, alignment) - def write_entries_padded(self, fout, alignment): - for entry in self.entries: - fout.write(pack('I', entry.ramdisk_size)) - fout.write(pack('I', entry.ramdisk_offset)) - fout.write(pack('I', entry.ramdisk_type)) - fout.write(pack(f'{VENDOR_RAMDISK_NAME_SIZE}s', - entry.ramdisk_name)) - fout.write(entry.board_id) - pad_file(fout, alignment) -def write_padded_file(f_out, f_in, padding): - if f_in is None: - return - f_out.write(f_in.read()) - pad_file(f_out, padding) -def parse_int(x): - return int(x, 0) -def parse_os_version(x): - match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x) - if match: - a = int(match.group(1)) - b = c = 0 - if match.lastindex >= 2: - b = int(match.group(2)) - if match.lastindex == 3: - c = int(match.group(3)) - # 7 bits allocated for each field - assert a < 128 - assert b < 128 - assert c < 128 - return (a << 14) | (b << 7) | c - return 0 -def parse_os_patch_level(x): - match = re.search(r'^(\d{4})-(\d{2})(?:-(\d{2}))?', x) - if match: - y = int(match.group(1)) - 2000 - m = int(match.group(2)) - # 7 bits allocated for the year, 4 bits for the month - assert 0 <= y < 128 - assert 0 < m <= 12 - return (y << 4) | m - return 0 -def parse_vendor_ramdisk_type(x): - type_dict = { - 'none': VENDOR_RAMDISK_TYPE_NONE, - 'platform': VENDOR_RAMDISK_TYPE_PLATFORM, - 'recovery': VENDOR_RAMDISK_TYPE_RECOVERY, - 'dlkm': VENDOR_RAMDISK_TYPE_DLKM, - } - if x.lower() in type_dict: - return type_dict[x.lower()] - return parse_int(x) -def get_vendor_boot_v4_usage(): - return """vendor boot version 4 arguments: - --ramdisk_type {none,platform,recovery,dlkm} - specify the type of the ramdisk - --ramdisk_name NAME - specify the name of the ramdisk - --board_id{0..15} NUMBER - specify the value of the board_id vector, defaults to 0 - --vendor_ramdisk_fragment VENDOR_RAMDISK_FILE - path to the vendor ramdisk file - These options can be specified multiple times, where each vendor ramdisk - option group ends with a --vendor_ramdisk_fragment option. - Each option group appends an additional ramdisk to the vendor boot image. -""" -def parse_vendor_ramdisk_args(args, args_list): - """Parses vendor ramdisk specific arguments. - Args: - args: An argparse.Namespace object. Parsed results are stored into this - object. - args_list: A list of argument strings to be parsed. - Returns: - A list argument strings that are not parsed by this method. - """ - parser = ArgumentParser(add_help=False) - parser.add_argument('--ramdisk_type', type=parse_vendor_ramdisk_type, - default=VENDOR_RAMDISK_TYPE_NONE) - parser.add_argument('--ramdisk_name', - type=AsciizBytes(bufsize=VENDOR_RAMDISK_NAME_SIZE), - required=True) - for i in range(VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE): - parser.add_argument(f'--board_id{i}', type=parse_int, default=0) - parser.add_argument(PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT, required=True) - unknown_args = [] - vendor_ramdisk_table_builder = VendorRamdiskTableBuilder() - if args.vendor_ramdisk is not None: - vendor_ramdisk_table_builder.add_entry( - args.vendor_ramdisk.name, VENDOR_RAMDISK_TYPE_PLATFORM, b'', None) - while PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT in args_list: - idx = args_list.index(PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT) + 2 - vendor_ramdisk_args = args_list[:idx] - args_list = args_list[idx:] - ramdisk_args, extra_args = parser.parse_known_args(vendor_ramdisk_args) - ramdisk_args_dict = vars(ramdisk_args) - unknown_args.extend(extra_args) - ramdisk_path = ramdisk_args.vendor_ramdisk_fragment - ramdisk_type = ramdisk_args.ramdisk_type - ramdisk_name = ramdisk_args.ramdisk_name - board_id = [ramdisk_args_dict[f'board_id{i}'] - for i in range(VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE)] - vendor_ramdisk_table_builder.add_entry(ramdisk_path, ramdisk_type, - ramdisk_name, board_id) - if len(args_list) > 0: - unknown_args.extend(args_list) - args.vendor_ramdisk_total_size = (vendor_ramdisk_table_builder - .ramdisk_total_size) - args.vendor_ramdisk_table_entry_num = len(vendor_ramdisk_table_builder - .entries) - args.vendor_ramdisk_table_builder = vendor_ramdisk_table_builder - return unknown_args -def parse_cmdline(): - version_parser = ArgumentParser(add_help=False) - version_parser.add_argument('--header_version', type=parse_int, default=0) - if version_parser.parse_known_args()[0].header_version < 3: - # For boot header v0 to v2, the kernel commandline field is split into - # two fields, cmdline and extra_cmdline. Both fields are asciiz strings, - # so we minus one here to ensure the encoded string plus the - # null-terminator can fit in the buffer size. - cmdline_size = BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 1 - else: - cmdline_size = BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, - epilog=get_vendor_boot_v4_usage()) - parser.add_argument('--kernel', type=FileType('rb'), - help='path to the kernel') - parser.add_argument('--ramdisk', type=FileType('rb'), - help='path to the ramdisk') - parser.add_argument('--second', type=FileType('rb'), - help='path to the second bootloader') - parser.add_argument('--dtb', type=FileType('rb'), help='path to the dtb') - dtbo_group = parser.add_mutually_exclusive_group() - dtbo_group.add_argument('--recovery_dtbo', type=FileType('rb'), - help='path to the recovery DTBO') - dtbo_group.add_argument('--recovery_acpio', type=FileType('rb'), - metavar='RECOVERY_ACPIO', dest='recovery_dtbo', - help='path to the recovery ACPIO') - parser.add_argument('--cmdline', type=AsciizBytes(bufsize=cmdline_size), - default='', help='kernel command line arguments') - parser.add_argument('--vendor_cmdline', - type=AsciizBytes(bufsize=VENDOR_BOOT_ARGS_SIZE), - default='', - help='vendor boot kernel command line arguments') - parser.add_argument('--base', type=parse_int, default=0x10000000, - help='base address') - parser.add_argument('--kernel_offset', type=parse_int, default=0x00008000, - help='kernel offset') - parser.add_argument('--ramdisk_offset', type=parse_int, default=0x01000000, - help='ramdisk offset') - parser.add_argument('--second_offset', type=parse_int, default=0x00f00000, - help='second bootloader offset') - parser.add_argument('--dtb_offset', type=parse_int, default=0x01f00000, - help='dtb offset') - parser.add_argument('--os_version', type=parse_os_version, default=0, - help='operating system version') - parser.add_argument('--os_patch_level', type=parse_os_patch_level, - default=0, help='operating system patch level') - parser.add_argument('--tags_offset', type=parse_int, default=0x00000100, - help='tags offset') - parser.add_argument('--board', type=AsciizBytes(bufsize=BOOT_NAME_SIZE), - default='', help='board name') - parser.add_argument('--pagesize', type=parse_int, - choices=[2**i for i in range(11, 15)], default=2048, - help='page size') - parser.add_argument('--id', action='store_true', - help='print the image ID on standard output') - parser.add_argument('--header_version', type=parse_int, default=0, - help='boot image header version') - parser.add_argument('-o', '--output', type=FileType('wb'), - help='output file name') - parser.add_argument('--gki_signing_algorithm', - help='GKI signing algorithm to use') - parser.add_argument('--gki_signing_key', - help='path to RSA private key file') - parser.add_argument('--gki_signing_signature_args', - help='other hash arguments passed to avbtool') - parser.add_argument('--gki_signing_avbtool_path', - help='path to avbtool for boot signature generation') - parser.add_argument('--vendor_boot', type=FileType('wb'), - help='vendor boot output file name') - parser.add_argument('--vendor_ramdisk', type=FileType('rb'), - help='path to the vendor ramdisk') - parser.add_argument('--vendor_bootconfig', type=FileType('rb'), - help='path to the vendor bootconfig file') - args, extra_args = parser.parse_known_args() - if args.vendor_boot is not None and args.header_version > 3: - extra_args = parse_vendor_ramdisk_args(args, extra_args) - if len(extra_args) > 0: - raise ValueError(f'Unrecognized arguments: {extra_args}') - if args.header_version < 3: - args.extra_cmdline = args.cmdline[BOOT_ARGS_SIZE-1:] - args.cmdline = args.cmdline[:BOOT_ARGS_SIZE-1] + b'\x00' - assert len(args.cmdline) <= BOOT_ARGS_SIZE - assert len(args.extra_cmdline) <= BOOT_EXTRA_ARGS_SIZE - return args -def add_boot_image_signature(args, pagesize): - """Adds the boot image signature. - Note that the signature will only be verified in VTS to ensure a - generic boot.img is used. It will not be used by the device - bootloader at boot time. The bootloader should only verify - the boot vbmeta at the end of the boot partition (or in the top-level - vbmeta partition) via the Android Verified Boot process, when the - device boots. - """ - args.output.flush() # Flush the buffer for signature calculation. - # Appends zeros if the signing key is not specified. - if not args.gki_signing_key or not args.gki_signing_algorithm: - zeros = b'\x00' * BOOT_IMAGE_V4_SIGNATURE_SIZE - args.output.write(zeros) - pad_file(args.output, pagesize) - return - avbtool = 'avbtool' # Used from otatools.zip or Android build env. - # We need to specify the path of avbtool in build/core/Makefile. - # Because avbtool is not guaranteed to be in $PATH there. - if args.gki_signing_avbtool_path: - avbtool = args.gki_signing_avbtool_path - # Need to specify a value of --partition_size for avbtool to work. - # We use 64 MB below, but avbtool will not resize the boot image to - # this size because --do_not_append_vbmeta_image is also specified. - avbtool_cmd = [ - avbtool, 'add_hash_footer', - '--partition_name', 'boot', - '--partition_size', str(64 * 1024 * 1024), - '--image', args.output.name, - '--algorithm', args.gki_signing_algorithm, - '--key', args.gki_signing_key, - '--salt', 'd00df00d'] # TODO: use a hash of kernel/ramdisk as the salt. - # Additional arguments passed to avbtool. - if args.gki_signing_signature_args: - avbtool_cmd += args.gki_signing_signature_args.split() - # Outputs the signed vbmeta to a separate file, then append to boot.img - # as the boot signature. - with tempfile.TemporaryDirectory() as temp_out_dir: - boot_signature_output = os.path.join(temp_out_dir, 'boot_signature') - avbtool_cmd += ['--do_not_append_vbmeta_image', - '--output_vbmeta_image', boot_signature_output] - subprocess.check_call(avbtool_cmd) - with open(boot_signature_output, 'rb') as boot_signature: - if filesize(boot_signature) > BOOT_IMAGE_V4_SIGNATURE_SIZE: - raise ValueError( - f'boot sigature size is > {BOOT_IMAGE_V4_SIGNATURE_SIZE}') - write_padded_file(args.output, boot_signature, pagesize) -def write_data(args, pagesize): - write_padded_file(args.output, args.kernel, pagesize) - write_padded_file(args.output, args.ramdisk, pagesize) - write_padded_file(args.output, args.second, pagesize) - if args.header_version > 0 and args.header_version < 3: - write_padded_file(args.output, args.recovery_dtbo, pagesize) - if args.header_version == 2: - write_padded_file(args.output, args.dtb, pagesize) - if args.header_version >= 4: - add_boot_image_signature(args, pagesize) -def write_vendor_boot_data(args): - if args.header_version > 3: - builder = args.vendor_ramdisk_table_builder - builder.write_ramdisks_padded(args.vendor_boot, args.pagesize) - write_padded_file(args.vendor_boot, args.dtb, args.pagesize) - builder.write_entries_padded(args.vendor_boot, args.pagesize) - write_padded_file(args.vendor_boot, args.vendor_bootconfig, - args.pagesize) - else: - write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize) - write_padded_file(args.vendor_boot, args.dtb, args.pagesize) -def main(): - args = parse_cmdline() - if args.vendor_boot is not None: - if args.header_version not in {3, 4}: - raise ValueError( - '--vendor_boot not compatible with given header version') - if args.header_version == 3 and args.vendor_ramdisk is None: - raise ValueError('--vendor_ramdisk missing or invalid') - write_vendor_boot_header(args) - write_vendor_boot_data(args) - if args.output is not None: - if args.second is not None and args.header_version > 2: - raise ValueError( - '--second not compatible with given header version') - img_id = write_header(args) - if args.header_version > 2: - write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE) - else: - write_data(args, args.pagesize) - if args.id and img_id is not None: - print('0x' + ''.join(f'{octet:02x}' for octet in img_id)) -if __name__ == '__main__': - main() diff --git a/.gitlab-ci/container/baremetal_build.sh b/.gitlab-ci/container/baremetal_build.sh index 6f85af7dcfd..6e368086118 100644 --- a/.gitlab-ci/container/baremetal_build.sh +++ b/.gitlab-ci/container/baremetal_build.sh @@ -29,39 +29,5 @@ if [[ $arch == "arm64" ]]; then -O "${KERNEL_IMAGE_BASE}"/arm64/Image curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \ -O "${KERNEL_IMAGE_BASE}"/arm64/Image.gz - curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \ - -O "${KERNEL_IMAGE_BASE}"/arm64/cheza-kernel - - DEVICE_TREES="" - DEVICE_TREES="$DEVICE_TREES apq8016-sbc-usb-host.dtb" - DEVICE_TREES="$DEVICE_TREES apq8096-db820c.dtb" - - for DTB in $DEVICE_TREES; do - curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \ - -O "${KERNEL_IMAGE_BASE}/arm64/$DTB" - done - popd - - # Download and extract the firmware for the Qualcomm DUTs - curl --location --fail --retry-connrefused --retry 3 --retry-delay 10 \ - -O http://ftp.de.debian.org/debian/pool/non-free-firmware/f/firmware-nonfree/firmware-qcom-soc_20230210-5_all.deb - - mkdir firmware/ - dpkg-deb -x firmware-qcom-soc_20230210-5_all.deb firmware/ - - # Copy only the firmware files for the devices in CI - install -Dm644 firmware/lib/firmware/qcom/a300_pfp.fw /rootfs-arm64/lib/firmware/qcom/a300_pfp.fw - install -Dm644 firmware/lib/firmware/qcom/a300_pm4.fw /rootfs-arm64/lib/firmware/qcom/a300_pm4.fw - install -Dm644 firmware/lib/firmware/qcom/a530_pfp.fw /rootfs-arm64/lib/firmware/qcom/a530_pfp.fw - install -Dm644 firmware/lib/firmware/qcom/a530_pm4.fw /rootfs-arm64/lib/firmware/qcom/a530_pm4.fw - install -Dm644 firmware/lib/firmware/qcom/a530_zap.mdt /rootfs-arm64/lib/firmware/qcom/a530_zap.mdt - install -Dm644 firmware/lib/firmware/qcom/a530v3_gpmu.fw2 /rootfs-arm64/lib/firmware/qcom/a530v3_gpmu.fw2 - install -Dm644 firmware/lib/firmware/qcom/apq8096/a530_zap.mbn /rootfs-arm64/lib/firmware/qcom/apq8096/a530_zap.mbn - install -Dm644 firmware/lib/firmware/qcom/a630_gmu.bin /rootfs-arm64/lib/firmware/qcom/a630_gmu.bin - install -Dm644 firmware/lib/firmware/qcom/a630_sqe.fw /rootfs-arm64/lib/firmware/qcom/a630_sqe.fw - install -Dm644 firmware/lib/firmware/qcom/sdm845/a630_zap.mbn /rootfs-arm64/lib/firmware/qcom/sdm845/a630_zap.mbn - - rm firmware-qcom-soc_20230210-5_all.deb - rm -rf firmware/ fi diff --git a/.gitlab-ci/container/debian/baremetal_arm_test.sh b/.gitlab-ci/container/debian/baremetal_arm_test.sh index 70d9fd8aea7..1aaa5908812 100644 --- a/.gitlab-ci/container/debian/baremetal_arm_test.sh +++ b/.gitlab-ci/container/debian/baremetal_arm_test.sh @@ -14,7 +14,6 @@ set -o xtrace DEPS=( cpio curl - fastboot netcat-openbsd openssh-server procps diff --git a/.gitlab-ci/farm-rules.yml b/.gitlab-ci/farm-rules.yml index 4d05a60312b..2241198c82d 100644 --- a/.gitlab-ci/farm-rules.yml +++ b/.gitlab-ci/farm-rules.yml @@ -34,7 +34,7 @@ # anholt | baremetal/poe-powered | @anholt # austriancoder | ci-tron | @austriancoder # collabora | lava | @daniels, @sergi -# google-freedreno | baremetal/{fastboot,cros-servo} | @robclark +# google-freedreno | none (moving to LAVA) | @daniels, @sergi # igalia | baremetal/poe-powered | @jasuarez, @chema # lima | lava | @enunes # microsoft | custom | @jenatali, @alatiera @@ -211,7 +211,6 @@ when: never - !reference [.valve-farm-rules, rules] - .austriancoder-farm-rules: rules: - exists: [ .ci-farms-disabled/austriancoder ] @@ -232,27 +231,6 @@ when: never - !reference [.austriancoder-farm-rules, rules] - -.google-freedreno-farm-rules: - rules: - - exists: [ .ci-farms-disabled/google-freedreno ] - when: never - - changes: [ .ci-farms-disabled/google-freedreno ] - if: '$CI_PIPELINE_SOURCE != "schedule"' - when: on_success - - changes: [ .ci-farms-disabled/* ] - if: '$CI_PIPELINE_SOURCE != "schedule"' - when: never - -.google-freedreno-farm-manual-rules: - rules: - - exists: [ .ci-farms-disabled/google-freedreno ] - when: never - - changes: [ .ci-farms-disabled/google-freedreno ] - if: '$CI_PIPELINE_SOURCE != "schedule"' - when: never - - !reference [.google-freedreno-farm-rules, rules] - .vmware-farm-rules: rules: - exists: [ .ci-farms-disabled/vmware ] @@ -315,6 +293,15 @@ - !reference [.pengutronix-farm-rules, rules] +# Temporary placeholder as the devices move across to LAVA. +.google-freedreno-farm-rules: + rules: + - when: never + +.google-freedreno-farm-manual-rules: + rules: + - when: never + # Skip container & build jobs when disabling any farm, and run them if any # farm gets re-enabled. # Only apply these rules in MR context, because otherwise we get a false @@ -359,10 +346,6 @@ changes: [ .ci-farms-disabled/austriancoder ] exists: [ .ci-farms-disabled/austriancoder ] when: never - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - changes: [ .ci-farms-disabled/google-freedreno ] - exists: [ .ci-farms-disabled/google-freedreno ] - when: never - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' changes: [ .ci-farms-disabled/ondracka ] exists: [ .ci-farms-disabled/ondracka ] diff --git a/.gitlab-ci/image-tags.yml b/.gitlab-ci/image-tags.yml index 4c1cca0ba1b..1241fe14674 100644 --- a/.gitlab-ci/image-tags.yml +++ b/.gitlab-ci/image-tags.yml @@ -19,7 +19,7 @@ include: - .gitlab-ci/conditional-build-image-tags.yml variables: - DEBIAN_BASE_TAG: "20250515-firmware" + DEBIAN_BASE_TAG: "20250526-barermetal" DEBIAN_BUILD_TAG: "20250515-aarch64"