Files
SDK_SG200x_V2/build/scripts/gen_release_bin.py
carbon 0545e9dc6d init version 2024-05-07
commit d1edce71135cc6d98c0a4b5729774542b676e769
Author: sophgo-forum-service <forum_service@sophgo.com>
Date:   Fri Mar 15 16:07:33 2024 +0800

    [fix] recommend using ssh method to clone repo.
    [fix] fix sensor driver repo branch name.
2024-05-07 19:36:36 +08:00

434 lines
11 KiB
Python
Executable File

#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK
import logging
import os
import re
import argparse
import itertools
import collections
import json
import os.path
import subprocess
import glob
from datetime import datetime
import build_helper
import sign_fip
try:
import argcomplete
except ImportError:
argcomplete = None
build_helper.check_python_min_version()
Board = collections.namedtuple("Board", "chip, board, ddr_cfg, info")
Target = collections.namedtuple("Target", "chip_arch chip is_multi_fip atf_key")
GEN_REL_BIN_EXCLUDE_CHIPS = [
"cv181x",
"cv180x",
]
GEN_REL_BIN_EXCLUDE = [
"cv1835_fpga",
"cv1835_palladium",
"cv1822_fpga",
"cv1822_palladium",
"cv181x_fpga",
"cv181x_fpga_c906",
"cv181x_riscv-fpga",
"cv181x_palladium",
"cv1826_wevb_0005a_alios_spinand",
]
ATF_REPO_BRANCH = {}
ATF_REPO_PATH = "arm-trusted-firmware"
BLD_REPO_PATH = "bm_bld"
REL_BIN_ATF = "rel_bin/release_bin_atf"
REL_BIN_BLDS = {
"bld": "rel_bin/release_bin_bld",
"bldp": "rel_bin/release_bin_bldp",
"blp": "rel_bin/release_bin_blp",
}
KEYSERVER = "10.18.98.102"
KEYSERVER_SSHKEY_PATH = os.path.join(
ATF_REPO_PATH, "tools/build_script/service_sign@cvi_keyserver.pem"
)
def parse_args():
parser = argparse.ArgumentParser(
description="Scan boards to generate env and configs"
)
parser.add_argument(
"-v",
"--verbose",
default="INFO",
choices=["CRITICAL", "DEBUG", "ERROR", "INFO", "NOTSET", "WARNING"],
)
parser.add_argument("--logfile", type=str)
parser.add_argument("--gen-atf", action="store_true")
parser.add_argument("--gen-bld", action="store_true")
parser.add_argument("--push", action="store_true")
parser.add_argument("--exclude", action="append")
if argcomplete:
argcomplete.autocomplete(parser)
return parser.parse_args()
def board_dir_to_name(board_dir):
chips = build_helper.get_chip_list()
chip_list = list(itertools.chain(*chips.values()))
m = re.search(
r"^([0-9a-z]+)_(.+)$", os.path.basename(board_dir), flags=re.IGNORECASE
)
chip, br_name = m.groups()
if chip not in chip_list:
raise Exception(
"%r of %r is unknown (missing in chip_list.json?)" % (chip, board_dir)
)
for chip_arch, xlist in chips.items():
if chip in xlist:
break
else:
raise Exception("Can't find CHIP_ARCH for %r" % chip)
return chip_arch, chip, br_name
def get_current_branch(git_path):
ret = subprocess.run(
["git", "rev-parse", "--abbrev-ref", "HEAD"],
cwd=git_path,
check=True,
stdout=subprocess.PIPE,
)
return ret.stdout.decode().strip()
def get_atf_branch(chip_arch, is_multi_fip):
if is_multi_fip:
return "cv1835_multibin_boot"
try:
atf_branch = [b for b, a in ATF_REPO_BRANCH.items() if chip_arch in a][0]
except IndexError:
atf_branch = "master"
return atf_branch
def checkout_atf_branch(atf_branch):
current = get_current_branch(ATF_REPO_PATH)
if current == atf_branch:
return
logging.info("checkout_atf_branch: %s", atf_branch)
if atf_branch != "master":
git_cmd = [
"git",
"fetch",
"--depth",
"1",
"origin",
"%s:%s" % (atf_branch, atf_branch),
]
subprocess.run(git_cmd, cwd=ATF_REPO_PATH, check=True)
subprocess.run(["git", "checkout", atf_branch], cwd=ATF_REPO_PATH, check=True)
subprocess.run(["git", "clean", "-fd"], cwd=ATF_REPO_PATH, check=True)
def list_board_dirs():
for board_conf in sorted(glob.glob(build_helper.BOARD_KCONFIG_SAVED_GLOB)):
board_dir = os.path.dirname(board_conf)
if "/default/" in board_dir:
continue
if not os.path.isdir(board_dir):
continue
yield board_dir
def gen_bld_for_board(chip_arch, board, atf_key):
logging.info("gen_bld_rel_bin_for_board=%s (%s)", board, atf_key)
for i in [ATF_REPO_PATH, BLD_REPO_PATH]:
if not os.path.exists(i):
raise Exception("%s doesn't exist" % i)
chip_arch, chip, br_name = board_dir_to_name(board)
logging.info("%r", [chip_arch, chip, br_name])
atf_branch = get_atf_branch(chip_arch, "rtos" in br_name)
checkout_atf_branch(atf_branch)
cj_path = os.path.join(
"build", build_helper.BOARD_DIR, chip_arch, board, "config.json"
)
with open(cj_path, "r", encoding="utf-8") as fp:
cj = json.load(fp)
ddr_cfg_list = cj["ddr_cfg_list"]
ddr_cfg_list = [i for i in ddr_cfg_list if i]
if not ddr_cfg_list:
ddr_cfg_list = ["none"]
# Build for all DDR_CFG
if atf_key != "":
atf_key = "setconfig ATF_KEY_SEL_%s=y" % atf_key
for d in ddr_cfg_list:
logging.info("ddr_cfg=%s", d)
script = """
set -eo pipefail
source build/envsetup_soc.sh f
defconfig %(board)s
setconfig DDR_CFG_%(ddr_cfg)s=y
%(atf_key)s
clean_bld
clean_atf
build_atf
""" % {
"board": board,
"ddr_cfg": d,
"atf_key": atf_key,
}
subprocess.run(["bash"], input=script.encode(), shell=True, check=True)
def gen_bld(push):
boards = [board_dir_to_name(e) for e in list_board_dirs()]
boards = [
(get_atf_branch(chip_arch, False), chip_arch, chip, br)
for chip_arch, chip, br in boards
]
boards.sort()
for n, (_, chip_arch, chip, br) in enumerate(boards):
if chip in GEN_REL_BIN_EXCLUDE_CHIPS:
continue
fullname = chip + "_" + br
if fullname in GEN_REL_BIN_EXCLUDE:
continue
gen_bld_for_board(chip_arch, fullname, "")
if chip_arch == "cv183x" and "rtos" not in fullname:
gen_bld_for_board(chip_arch, fullname, "clear")
checkout_atf_branch("master")
for i in sorted(glob.glob(os.path.join(REL_BIN_BLDS["bld"], "*_key0.tar"))):
if "_single" in i:
continue
if "_rtos" in i:
continue
b = re.findall(r'^bld_(.*?)_(.*)_key0.tar', os.path.basename(i))[0][1]
chip_arch, chip, _ = board_dir_to_name(b)
sign_fip.sign_bld(i, chip_arch, chip)
git_cmd = ["git", "log", r"--pretty=format:%h %aI%n%s%n%b", "-n", "1"]
ret = subprocess.run(git_cmd, cwd=BLD_REPO_PATH, check=True, stdout=subprocess.PIPE)
message = ret.stdout.decode()
message = "\n".join([">>> " + i for i in message.split("\n")])
logging.info("message=%r", message)
for path in REL_BIN_BLDS.values():
subprocess.run(["git", "add", "."], cwd=path, check=True)
ret = subprocess.run(
["git", "status", "--porcelain"],
cwd=path,
check=True,
stdout=subprocess.PIPE,
)
if not ret.stdout.decode().strip():
logging.info("%s: nothing to commit", path)
continue
subprocess.run(
["git", "commit", "-F", "-"],
cwd=path,
input=message.encode(),
check=True,
)
if push:
subprocess.run(
["git", "push", "origin", "HEAD:master"], cwd=path, check=True
)
def gen_atf_for_chip(target):
logging.info("gen_atf_for_chip=%r", target)
for i in [ATF_REPO_PATH, BLD_REPO_PATH]:
if not os.path.exists(i):
raise Exception("%s doesn't exist" % i)
boards = [board_dir_to_name(e) for e in list_board_dirs()]
for _, chip, br in boards:
if "fpga" in br or "palladium" in br:
continue
if target.chip in chip:
break
else:
logging.warning("No board for %s", target.chip)
return
board = chip + "_" + br
atf_branch = get_atf_branch(target.chip_arch, target.is_multi_fip)
logging.info("atf_branch=%s board=%s", atf_branch, board)
checkout_atf_branch(atf_branch)
git_cmd = ["git", "log", r"--pretty=format:%h %aI%n%s%n%b", "-n", "1"]
ret = subprocess.run(git_cmd, cwd=ATF_REPO_PATH, check=True, stdout=subprocess.PIPE)
message = ret.stdout.decode()
# Build fip.bin
atf_key = ""
if target.atf_key:
atf_key = "setconfig ATF_KEY_SEL_%s=y" % target.atf_key
script = """
set -eo pipefail
source build/envsetup_soc.sh f
defconfig %(board)s
%(multibin)s
%(atf_key)s
clean_bld
clean_atf
build_atf
""" % {
"board": board,
"multibin": "setconfig MULTI_FIP=y" if target.is_multi_fip else "",
"atf_key": atf_key,
}
subprocess.run(["bash"], input=script.encode(), shell=True, check=True)
# Check status
ret = subprocess.run(
["git", "status", "--porcelain", "-z"],
cwd=REL_BIN_ATF,
check=True,
stdout=subprocess.PIPE,
)
out = ret.stdout.strip(b"\0").split(b"\0")
out = [i.decode() for i in out]
fip = []
txt = []
for i in out:
if re.search(r"^( [MA]|\?\?) .+\.bin", i):
fip.append(i)
elif re.search(r"^( [MA]|\?\?) .+\.txt", i):
txt.append(i)
if len(fip) != 1:
raise ValueError("Only one fip.bin should be generated (%r)", fip)
if len(txt) > 1:
raise ValueError("Only one fip.txt should be generated (%r)", txt)
# Add fip.bin
logging.info("add fip %s", fip[0])
subprocess.run(["git", "add", fip[0][3:]], cwd=REL_BIN_ATF, check=True)
if txt:
logging.info("add txt %s", txt[0])
subprocess.run(["git", "add", txt[0][3:]], cwd=REL_BIN_ATF, check=True)
if fip[0][3:].endswith("_key0.bin"):
sign_fip.sign_atf(os.path.join(REL_BIN_ATF, fip[0][3:]))
subprocess.run(
["git", "add", fip[0][3:].replace("_key0", "_key1")],
cwd=REL_BIN_ATF,
check=True,
)
return message
def gen_atf(push):
chip_list = build_helper.get_chip_list()
xlist = [
(get_atf_branch(chip_arch, False), chip_arch, chips, False)
for chip_arch, chips in chip_list.items()
]
xlist.sort(reverse=True)
targets = [Target("cv183x", "cv1835", None, "clear")]
for _, chip_arch, chips, is_multi_fip in xlist:
if not chips:
continue
t = Target(chip_arch, chips[0], is_multi_fip, None)
targets.append(t)
message = set()
for t in targets:
m = gen_atf_for_chip(t)
if not m:
continue
message.add(m.strip())
message = "\n\n".join(message)
message = "\n".join([">>> " + i for i in message.split("\n")])
logging.info("message=%r", message)
subprocess.run(
["git", "commit", "-F", "-"],
cwd=REL_BIN_ATF,
input=message.encode(),
check=True,
)
if push:
subprocess.run(
["git", "push", "origin", "HEAD:master"], cwd=REL_BIN_ATF, check=True
)
def main():
args = parse_args()
build_helper.init_logging(args.logfile, stdout_level=args.verbose)
logging.debug("[%s] start", datetime.now().isoformat())
# The location of the top Kconfig
os.environ["srctree"] = build_helper.BUILD_REPO_DIR
os.environ["KEYSERVER"] = KEYSERVER
os.environ["KEYSERVER_SSHKEY_PATH"] = KEYSERVER_SSHKEY_PATH
os.environ["RELEASE_BIN_ATF_DIR"] = REL_BIN_ATF
if args.exclude:
GEN_REL_BIN_EXCLUDE.extend(args.exclude)
if args.gen_bld:
gen_bld(args.push)
if args.gen_atf:
gen_atf(args.push)
logging.debug("[%s] finished", datetime.now().isoformat())
if __name__ == "__main__":
main()