Skip to content
1 change: 1 addition & 0 deletions scripts/cmake/version.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ string(JSON SOF_MICRO ERROR_VARIABLE micro_error
if(NOT "${micro_error}" STREQUAL "NOTFOUND")
message(STATUS "versions.json: ${micro_error}, defaulting to 0")
# TODO: default this to .99 on the main, never released branch like zephyr does
# Keep this default SOF_MICRO the same as the one in xtensa-build-zephyr.py
set(SOF_MICRO 0)
endif()

Expand Down
116 changes: 71 additions & 45 deletions scripts/xtensa-build-zephyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import warnings
import fnmatch
import hashlib
import json
import gzip
import dataclasses
import concurrent.futures as concurrent
Expand Down Expand Up @@ -276,9 +277,9 @@ def execute_command(*run_args, **run_kwargs):
env_arg = run_kwargs.get('env')
env_change = set(env_arg.items()) - set(os.environ.items()) if env_arg else None
if env_change and (run_kwargs.get('sof_log_env') or args.verbose >= 1):
output += "\n... with extra/modified environment:"
output += "\n... with extra/modified environment:\n"
for k_v in env_change:
output += f"\n{k_v[0]}={k_v[1]}"
output += f"{k_v[0]}={k_v[1]}\n"
print(output, flush=True)

run_kwargs = {k: run_kwargs[k] for k in run_kwargs if not k.startswith("sof_")}
Expand Down Expand Up @@ -443,27 +444,25 @@ def west_update():
execute_command(["west", "update"], check=True, timeout=3000, cwd=west_top)


def get_sof_version(abs_build_dir):
def get_sof_version():
"""[summary] Get version string major.minor.micro of SOF
firmware file. When building multiple platforms from the same SOF
commit, all platforms share the same version. So for the 1st platform,
generate the version string from sof_version.h and later platforms will
extract the version information from sof/versions.json and later platforms will
reuse it.
"""
global sof_fw_version
if sof_fw_version:
return sof_fw_version

versions = {}
with open(pathlib.Path(abs_build_dir,
"zephyr/include/generated/sof_versions.h"), encoding="utf8") as hfile:
for hline in hfile:
words = hline.split()
if words[0] == '#define':
versions[words[1]] = words[2]
sof_fw_version = versions['SOF_MAJOR'] + '.' + versions['SOF_MINOR'] + '.' + \
versions['SOF_MICRO']

with open(SOF_TOP / "versions.json") as versions_file:
versions = json.load(versions_file)
# Keep this default value the same as the default SOF_MICRO in version.cmake
sof_micro = versions['SOF'].get('MICRO', "0")
sof_fw_version = (
f"{versions['SOF']['MAJOR']}.{versions['SOF']['MINOR']}.{sof_micro}"
)
return sof_fw_version

def rmtree_if_exists(directory):
Expand Down Expand Up @@ -521,6 +520,60 @@ def build_rimage():
execute_command(rimage_build_cmd, cwd=west_top)


def rimage_configuration(platform_dict):

sign_cmd = []

rimage_executable = shutil.which("rimage", path=RIMAGE_BUILD_DIR)

sign_cmd += ["--tool-path", rimage_executable, "--"]

# Flatten the list of [ ( "-o", "value" ), ...] tuples
for t in rimage_options(platform_dict):
sign_cmd += t

return sign_cmd


def rimage_options(platform_dict):
"""Return a list of default rimage options as a list of tuples,
example: [ (-f, 2.5.0), (-b, 1), (-k, key.pem),... ]

"""
opts = []

signing_key = ""
if args.key:
signing_key = args.key
elif "RIMAGE_KEY" in platform_dict:
signing_key = platform_dict["RIMAGE_KEY"]
else:
signing_key = default_rimage_key

opts.append(("-k", str(signing_key)))

sof_fw_vers = get_sof_version()

opts.append(("-f", sof_fw_vers))

# Default value is 0 in rimage but for Zephyr the "build counter" has always
# been hardcoded to 1 in CMake and there is even a (broken) test that fails
# when it's not hardcoded to 1.
# FIXME: drop this line once the following test is fixed
# tests/avs/fw_00_basic/test_01_load_fw_extended.py::TestLoadFwExtended::()::
# test_00_01_load_fw_and_check_version
opts.append(("-b", "1"))

if args.ipc == "IPC4":
rimage_desc = platform_dict["IPC4_RIMAGE_DESC"]
else:
rimage_desc = platform_dict["name"] + ".toml"

opts.append(("-c", str(RIMAGE_SOURCE_DIR / "config" / rimage_desc)))

return opts


STAGING_DIR = None
def build_platforms():
global west_top, SOF_TOP
Expand Down Expand Up @@ -634,6 +687,11 @@ def build_platforms():
see https://docs.zephyrproject.org/latest/guides/west/build-flash-debug.html#one-time-cmake-arguments
Try "west config build.cmake-args -- ..." instead.""")

sign_cmd = ["west"]
sign_cmd += ["-v"] * args.verbose
sign_cmd += ["sign", "--build-dir", platform_build_dir_name, "--tool", "rimage"]
sign_cmd += rimage_configuration(platform_dict)

# Make sure the build logs don't leave anything hidden
execute_command(['west', 'config', '-l'], cwd=west_top)

Expand All @@ -655,38 +713,6 @@ def build_platforms():
execute_command([str(smex_executable), "-l", str(fw_ldc_file), str(input_elf_file)])

# Sign firmware
rimage_executable = shutil.which("rimage", path=RIMAGE_BUILD_DIR)
rimage_config = RIMAGE_SOURCE_DIR / "config"
sign_cmd = ["west"]
sign_cmd += ["-v"] * args.verbose
sign_cmd += ["sign", "--build-dir", platform_build_dir_name, "--tool", "rimage"]
sign_cmd += ["--tool-path", rimage_executable]
signing_key = ""
if args.key:
signing_key = args.key
elif "RIMAGE_KEY" in platform_dict:
signing_key = platform_dict["RIMAGE_KEY"]
else:
signing_key = default_rimage_key

sign_cmd += ["--tool-data", str(rimage_config), "--", "-k", str(signing_key)]

sof_fw_vers = get_sof_version(abs_build_dir)

sign_cmd += ["-f", sof_fw_vers]

# Default value is 0 in rimage but for Zephyr the "build counter" has always
# been hardcoded to 1 in CMake and there is even a (broken) test that fails
# when it's not hardcoded to 1.
# FIXME: drop this line once the following test is fixed
# tests/avs/fw_00_basic/test_01_load_fw_extended.py::TestLoadFwExtended::()::
# test_00_01_load_fw_and_check_version
sign_cmd += ["-b", "1"]

if args.ipc == "IPC4":
rimage_desc = pathlib.Path(SOF_TOP, "rimage", "config", platform_dict["IPC4_RIMAGE_DESC"])
sign_cmd += ["-c", str(rimage_desc)]

execute_command(sign_cmd, cwd=west_top)

if platform not in RI_INFO_UNSUPPORTED:
Expand Down