tan-cli 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tan/__init__.py +0 -0
- tan/__main__.py +120 -0
- tan/cli.py +939 -0
- tan/command_table.py +265 -0
- tan/commands/__init__.py +8 -0
- tan/commands/bootstrap_cmd.py +4856 -0
- tan/commands/bootstrap_patches.py +164 -0
- tan/commands/bootstrap_toolchain_fetch.py +155 -0
- tan/commands/bootstrap_toolchain_pin.py +36 -0
- tan/commands/build/__init__.py +1 -0
- tan/commands/build/configure_inputs.py +277 -0
- tan/commands/build/execute.py +1852 -0
- tan/commands/build/host_python.py +59 -0
- tan/commands/build/link_stale.py +78 -0
- tan/commands/build/manifest.py +428 -0
- tan/commands/build/materialise.py +81 -0
- tan/commands/build/token_substitution.py +381 -0
- tan/commands/build/toolchain.py +482 -0
- tan/commands/build/user_defines_wipe.py +115 -0
- tan/commands/build/workspace_patches.py +65 -0
- tan/commands/build_cmd.py +2236 -0
- tan/commands/build_output.py +331 -0
- tan/commands/clean_cmd.py +1183 -0
- tan/commands/completion_cmd.py +786 -0
- tan/commands/debug_config_cmd.py +2425 -0
- tan/commands/diff_cmd.py +940 -0
- tan/commands/doctor_cmd.py +4767 -0
- tan/commands/examples_cmd.py +644 -0
- tan/commands/explain_cmd.py +1319 -0
- tan/commands/faultdecode_cmd.py +931 -0
- tan/commands/flash_atoc_guard.py +240 -0
- tan/commands/flash_cmd.py +5731 -0
- tan/commands/flash_mram_guard.py +150 -0
- tan/commands/flash_ram.py +578 -0
- tan/commands/flash_raw.py +583 -0
- tan/commands/generate_cmd.py +1456 -0
- tan/commands/image_cmd.py +753 -0
- tan/commands/init_cmd.py +1740 -0
- tan/commands/inspect_cmd.py +377 -0
- tan/commands/kconfig_cmd.py +734 -0
- tan/commands/model_cmd.py +1514 -0
- tan/commands/model_device_cmd.py +351 -0
- tan/commands/model_device_live.py +234 -0
- tan/commands/model_host_cmd.py +430 -0
- tan/commands/model_zoo_cmd.py +363 -0
- tan/commands/monitor_actions.py +125 -0
- tan/commands/monitor_cmd.py +626 -0
- tan/commands/monitor_session.py +505 -0
- tan/commands/new_som_cmd.py +1522 -0
- tan/commands/pinmux_cmd.py +568 -0
- tan/commands/presets_cmd.py +1123 -0
- tan/commands/probe_cmd.py +421 -0
- tan/commands/reset_cmd.py +354 -0
- tan/commands/reset_confirm.py +168 -0
- tan/commands/run_cmd.py +637 -0
- tan/commands/scaffold_cmd.py +490 -0
- tan/commands/sdk_cmd.py +1723 -0
- tan/commands/size_cmd.py +1020 -0
- tan/commands/support_bundle_cmd.py +1073 -0
- tan/commands/trace_cmd.py +341 -0
- tan/commands/validate_cmd.py +2009 -0
- tan/commands/west_forward_cmd.py +736 -0
- tan/commands/workspace_patch_check.py +296 -0
- tan/core/__init__.py +1 -0
- tan/core/alp_conf_pregen.py +100 -0
- tan/core/artifact_provenance.py +240 -0
- tan/core/atoc_guard.py +276 -0
- tan/core/atoc_guard_messages.py +232 -0
- tan/core/atoc_replacement.py +118 -0
- tan/core/atomic_write.py +178 -0
- tan/core/board_context.py +351 -0
- tan/core/board_diagnostic.py +111 -0
- tan/core/board_files.py +221 -0
- tan/core/board_validator.py +542 -0
- tan/core/board_validator_compat.py +196 -0
- tan/core/board_validator_run.py +129 -0
- tan/core/board_validator_schema.py +186 -0
- tan/core/board_validator_skew.py +46 -0
- tan/core/board_yaml_edit.py +295 -0
- tan/core/board_yaml_pos.py +118 -0
- tan/core/bootstrap.py +2572 -0
- tan/core/build_plan.py +625 -0
- tan/core/consent.py +104 -0
- tan/core/console_filter.py +245 -0
- tan/core/debug_launch.py +1803 -0
- tan/core/devicetree_lint.py +168 -0
- tan/core/dir_removal.py +229 -0
- tan/core/doctor_git.py +172 -0
- tan/core/doctor_libraries.py +253 -0
- tan/core/doctor_render.py +185 -0
- tan/core/doctor_scope.py +66 -0
- tan/core/doctor_setools.py +237 -0
- tan/core/doctor_stale.py +180 -0
- tan/core/document_guards.py +723 -0
- tan/core/dp_id.py +97 -0
- tan/core/elf_load.py +63 -0
- tan/core/error_catalog.py +171 -0
- tan/core/example_catalog.py +499 -0
- tan/core/example_facets.py +151 -0
- tan/core/faultdecode.py +521 -0
- tan/core/flash_plan.py +2501 -0
- tan/core/flow_d_report.py +381 -0
- tan/core/flow_d_uptime.py +164 -0
- tan/core/fs_confine.py +130 -0
- tan/core/global_flags.py +230 -0
- tan/core/host_python.py +210 -0
- tan/core/image_bundle.py +247 -0
- tan/core/inert.py +147 -0
- tan/core/jlink_binary.py +128 -0
- tan/core/jlink_probe.py +481 -0
- tan/core/jsonc_splice.py +404 -0
- tan/core/launch_provenance.py +257 -0
- tan/core/link_refusal.py +76 -0
- tan/core/metadata_schema.py +376 -0
- tan/core/model_check.py +227 -0
- tan/core/model_device.py +449 -0
- tan/core/model_doctor.py +198 -0
- tan/core/model_host.py +48 -0
- tan/core/model_list.py +112 -0
- tan/core/model_zoo.py +353 -0
- tan/core/module_template.py +340 -0
- tan/core/mram_link.py +87 -0
- tan/core/new_som_ospi.py +94 -0
- tan/core/os_class.py +159 -0
- tan/core/patch_paths.py +87 -0
- tan/core/pending.py +40 -0
- tan/core/plain_zephyr_plan.py +138 -0
- tan/core/plan_exec.py +373 -0
- tan/core/plan_tokens.py +600 -0
- tan/core/probe.py +155 -0
- tan/core/probe_plan.py +237 -0
- tan/core/proxy.py +168 -0
- tan/core/publish.py +31 -0
- tan/core/python_floor.py +178 -0
- tan/core/ram_run.py +694 -0
- tan/core/ram_watch.py +231 -0
- tan/core/raw_write.py +160 -0
- tan/core/reset_plan.py +56 -0
- tan/core/run.py +161 -0
- tan/core/scaffold.py +2203 -0
- tan/core/scaffold_selftest_identity.py +225 -0
- tan/core/sdk_default_registry.py +565 -0
- tan/core/sdk_discovery.py +996 -0
- tan/core/sdk_removal.py +465 -0
- tan/core/serial_actions.py +175 -0
- tan/core/serial_capture.py +185 -0
- tan/core/serial_url.py +45 -0
- tan/core/setools.py +608 -0
- tan/core/setools_scratch.py +243 -0
- tan/core/shapes.py +194 -0
- tan/core/size.py +610 -0
- tan/core/som_buildability.py +204 -0
- tan/core/som_schema_version.py +62 -0
- tan/core/subprocess_env.py +201 -0
- tan/core/sysbuild_image.py +94 -0
- tan/core/system_manifest.py +827 -0
- tan/core/text_layout.py +73 -0
- tan/core/timestamp.py +182 -0
- tan/core/tool_lookup.py +383 -0
- tan/core/toolchain_pin.py +117 -0
- tan/core/toolchain_provision.py +1224 -0
- tan/core/trusted_path.py +134 -0
- tan/core/uboot_breakin.py +154 -0
- tan/core/uri_reference.py +415 -0
- tan/core/user_defines.py +152 -0
- tan/core/venv.py +332 -0
- tan/core/west_patches.py +143 -0
- tan/core/west_workspace_refusal.py +159 -0
- tan/core/zephyr_env.py +124 -0
- tan/env.py +185 -0
- tan/envelope.py +647 -0
- tan/exit_codes.py +12 -0
- tan/lazy_typer.py +185 -0
- tan/model/__init__.py +2 -0
- tan/model/_gen_fixture.py +132 -0
- tan/model/adapters/__init__.py +116 -0
- tan/model/adapters/cpu.py +26 -0
- tan/model/adapters/deepx.py +94 -0
- tan/model/adapters/drpai.py +242 -0
- tan/model/adapters/ethos_u.py +951 -0
- tan/model/adapters/executorch.py +55 -0
- tan/model/analyze.py +694 -0
- tan/model/build.py +304 -0
- tan/model/check.py +682 -0
- tan/model/manifest.py +625 -0
- tan/model/measure.py +216 -0
- tan/model/npu_ops_validate.py +130 -0
- tan/model/package.py +125 -0
- tan/model/perf.py +635 -0
- tan/model/perf_apply.py +721 -0
- tan/model/prep.py +193 -0
- tan/model/sram_fit.py +502 -0
- tan/model/targets.py +374 -0
- tan/model/tensorio.py +287 -0
- tan/net.py +73 -0
- tan/output_format.py +213 -0
- tan/planner/__init__.py +219 -0
- tan/planner/aperture.py +202 -0
- tan/planner/buildplan.py +1092 -0
- tan/planner/camera_owner.py +192 -0
- tan/planner/cameras.py +132 -0
- tan/planner/carveout.py +755 -0
- tan/planner/cli.py +274 -0
- tan/planner/headers.py +315 -0
- tan/planner/kconfig.py +2435 -0
- tan/planner/kconfig_symbols.py +473 -0
- tan/planner/libraries.py +677 -0
- tan/planner/link_target.py +237 -0
- tan/planner/linux_ownership.py +216 -0
- tan/planner/loader.py +1525 -0
- tan/planner/manifest.py +116 -0
- tan/planner/memory.py +161 -0
- tan/planner/memregion.py +56 -0
- tan/planner/models.py +533 -0
- tan/planner/orchestrator.py +874 -0
- tan/planner/ownership.py +203 -0
- tan/planner/partition.py +1160 -0
- tan/planner/paths.py +32 -0
- tan/planner/plain_slice.py +139 -0
- tan/planner/project_emit/__init__.py +60 -0
- tan/planner/project_emit/bom_netlist.py +375 -0
- tan/planner/project_emit/dts.py +580 -0
- tan/planner/project_emit/hw_info.py +221 -0
- tan/planner/project_emit/native_sim.py +136 -0
- tan/planner/project_emit/west_libs.py +213 -0
- tan/planner/project_loader.py +264 -0
- tan/planner/sdk_capability.py +203 -0
- tan/planner/sdk_compat.py +395 -0
- tan/planner/secure.py +350 -0
- tan/planner/slugs.py +394 -0
- tan/planner/som_metadata.py +325 -0
- tan/planner/strict_loaders.py +131 -0
- tan/planner/template.py +1037 -0
- tan/planner/template_pins.py +535 -0
- tan/planner/template_rewrite.py +714 -0
- tan/planner/topology.py +208 -0
- tan/planner/validate.py +365 -0
- tan/planner/whole_device_alias.py +67 -0
- tan/planner/zephyr_board.py +3510 -0
- tan/planner_cli.py +97 -0
- tan/planner_emit.py +617 -0
- tan/planner_root.py +119 -0
- tan/soc_ref.py +58 -0
- tan/templates/__init__.py +34 -0
- tan/templates/vendored/MANIFEST.md +1862 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
- tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
- tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
- tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
- tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
- tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
- tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
- tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
- tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
- tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
- tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
- tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
- tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
- tan/version.py +102 -0
- tan_cli-0.7.0.dist-info/METADATA +125 -0
- tan_cli-0.7.0.dist-info/RECORD +330 -0
- tan_cli-0.7.0.dist-info/WHEEL +5 -0
- tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
- tan_cli-0.7.0.dist-info/top_level.txt +1 -0
tan/planner/secure.py
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
"""Secure-boot config emitters -- sysbuild.conf + the TF-M child-image overlay.
|
|
4
|
+
|
|
5
|
+
`emit_sysbuild_conf` renders the sysbuild.conf overlay from board.yaml's `boot:`
|
|
6
|
+
block (the MCUboot wiring); `emit_tfm_sysbuild_conf` renders the TF-M sysbuild
|
|
7
|
+
child-image overlay from `security.psa:`. Pure string templating off the parsed
|
|
8
|
+
BoardProject -- the leaf-most emit seam (#285), a sink the build-plan emitter
|
|
9
|
+
imports later.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
from .models import BoardProject, OrchestratorError
|
|
18
|
+
from .paths import REPO
|
|
19
|
+
|
|
20
|
+
# SoM-preset `family:` (metadata/e1m_modules/*.yaml, e.g.
|
|
21
|
+
# "alif-ensemble") -> the short slug the curated
|
|
22
|
+
# zephyr/sysbuild/<slug>/sysbuild.conf directory uses. Mirrors the
|
|
23
|
+
# alif-ensemble / renesas-rzv2n family-token `startswith` match already
|
|
24
|
+
# duplicated in kconfig.py / validate.py. Only families that actually
|
|
25
|
+
# ship a curated file are listed -- renesas-rzv2n boots via
|
|
26
|
+
# U-Boot/Yocto, not sysbuild, so it has none today; adding one is a
|
|
27
|
+
# metadata-only change (drop the file under zephyr/sysbuild/<slug>/),
|
|
28
|
+
# no code change needed here.
|
|
29
|
+
_FAMILY_SYSBUILD_DIRS: dict[str, str] = {
|
|
30
|
+
"alif-ensemble": "aen",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# The per-family `boot.method:` default `board.schema.json` documents but
|
|
34
|
+
# nothing implemented (#562): "the SoM family supplies the default
|
|
35
|
+
# (AEN -> mcuboot, V2N/V2N-M1 -> none on the Zephyr slice since
|
|
36
|
+
# U-Boot owns boot on Linux)". `emit_sysbuild_conf` used to hard-default
|
|
37
|
+
# every family to `mcuboot`, so a Renesas project that omitted `method:`
|
|
38
|
+
# was pushed down the MCUboot path -- and, with `rsa3072` (a value
|
|
39
|
+
# `validate.py` PERMITS for renesas-rzv2n precisely because its boot
|
|
40
|
+
# chain is the U-Boot/FIT stack, not sysbuild), hard-raised and took the
|
|
41
|
+
# whole build-plan emit with it. Same `family:`-token `startswith` match
|
|
42
|
+
# as `_FAMILY_SYSBUILD_DIRS` above and `validate._boot_signing_supported_
|
|
43
|
+
# for_family`. `boot.method:` has no other consumer anywhere in the
|
|
44
|
+
# tree, so this emitter is the only site the default has to exist at.
|
|
45
|
+
_FAMILY_BOOT_METHOD_DEFAULTS: dict[str, str] = {
|
|
46
|
+
"alif-ensemble": "mcuboot",
|
|
47
|
+
"renesas-rzv2n": "none",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# What an UNRECOGNISED `family:` token defaults to. Deliberately the
|
|
51
|
+
# historical value, so an in-development preset whose family string is
|
|
52
|
+
# not in the table above emits exactly what it emitted before #562 --
|
|
53
|
+
# the fix is "recognised families get their documented default", not
|
|
54
|
+
# "the default silently flips for everyone".
|
|
55
|
+
_BOOT_METHOD_FALLBACK = "mcuboot"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _default_boot_method(project: BoardProject) -> str:
|
|
59
|
+
"""The `boot.method:` this project's SoM family implies."""
|
|
60
|
+
family = (project.som_preset.get("family") or "").lower()
|
|
61
|
+
return next((v for k, v in _FAMILY_BOOT_METHOD_DEFAULTS.items()
|
|
62
|
+
if family.startswith(k)), _BOOT_METHOD_FALLBACK)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _boot_target_is_single_slot(project: BoardProject) -> bool:
|
|
66
|
+
"""Whether this project resolves to a disjoint-slot0 boot shape on
|
|
67
|
+
ANY of its Zephyr M55 cores -- i.e. any MCUboot swap mode (scratch,
|
|
68
|
+
move, overwrite) has no slot1/scratch partition to swap into.
|
|
69
|
+
|
|
70
|
+
Reuses `zephyr_board._aen_role_slot0_map` -- the SAME resolver the
|
|
71
|
+
board-DT generator and `loader._resolve_slot0_load_address` already
|
|
72
|
+
call to answer this exact question -- instead of re-deriving the
|
|
73
|
+
answer from `memory_map:` region NAMES. The two disagree in general:
|
|
74
|
+
`som-preset-v2.schema.json` documents `memory_map:` as a build-policy
|
|
75
|
+
override "ONLY for non-stock partitioning", not something only a
|
|
76
|
+
disjoint-slot0 SoM sets. A `memory_map:` present for an unrelated
|
|
77
|
+
reason (an rpmsg carve-out, say) that declares no `<role>_slot0`
|
|
78
|
+
region makes the partition emitter fall through to the STOCK two-slot
|
|
79
|
+
layout -- a REAL `image-1` + `image-scratch` -- regardless of what its
|
|
80
|
+
own region names happen to be, so a check that scans those names for
|
|
81
|
+
"slot1"/"scratch" can answer True (single-slot) on a target that
|
|
82
|
+
generates both. `_aen_role_slot0_map` asks the real question: does
|
|
83
|
+
THIS role have its own `<role>_slot0` region (the only shape that
|
|
84
|
+
drops slot1/scratch, alp-sdk#1069 -- every AEN preset sets one: each
|
|
85
|
+
SoM's M55 cores share one physical App MRAM, so slot0 is split into
|
|
86
|
+
per-core windows and the secondary/scratch slot was dropped rather
|
|
87
|
+
than forced to fit)?
|
|
88
|
+
|
|
89
|
+
Only `m55_he`/`m55_hp` roles are AEN slot0-XIP cores (same convention
|
|
90
|
+
as `loader._resolve_slot0_load_address`); a project with neither in
|
|
91
|
+
`cores:` -- any non-AEN family, or an AEN project with no Zephyr M55
|
|
92
|
+
slice -- is never single-slot by this check.
|
|
93
|
+
|
|
94
|
+
Lazy import for the same circularity reason
|
|
95
|
+
`loader._resolve_slot0_load_address` documents: `zephyr_board.py`
|
|
96
|
+
imports from `loader.py` at module scope.
|
|
97
|
+
"""
|
|
98
|
+
memory_map = project.som_preset.get("memory_map")
|
|
99
|
+
if not memory_map:
|
|
100
|
+
return False
|
|
101
|
+
from .zephyr_board import ( # noqa: PLC0415
|
|
102
|
+
ZephyrBoardEmitError,
|
|
103
|
+
_aen_role_slot0_map,
|
|
104
|
+
)
|
|
105
|
+
for core_id in project.cores:
|
|
106
|
+
if not core_id.startswith("m55_"):
|
|
107
|
+
continue
|
|
108
|
+
role = core_id[len("m55_"):]
|
|
109
|
+
if role not in ("he", "hp"):
|
|
110
|
+
continue
|
|
111
|
+
try:
|
|
112
|
+
if _aen_role_slot0_map(memory_map, role) is not None:
|
|
113
|
+
return True
|
|
114
|
+
except ZephyrBoardEmitError as exc:
|
|
115
|
+
raise OrchestratorError(
|
|
116
|
+
f"cannot resolve boot.swap_algorithm default for "
|
|
117
|
+
f"{project.sku}: {exc}") from exc
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _has_zephyr_slice(project: BoardProject) -> bool:
|
|
122
|
+
"""Whether any core in this project builds under Zephyr.
|
|
123
|
+
|
|
124
|
+
sysbuild is a Zephyr-build concept: `build/alp_sysbuild.conf` is
|
|
125
|
+
consumed only as `west build --sysbuild -- -DSB_CONF_FILE=<path>`.
|
|
126
|
+
A project with no Zephyr slice has no sysbuild configure for the
|
|
127
|
+
overlay to reach, so emitting one is dead output at best -- and at
|
|
128
|
+
worst (#562) a hard refusal of a project that never runs sysbuild.
|
|
129
|
+
"""
|
|
130
|
+
return any(s.os == "zephyr" for s in project.cores.values())
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def sysbuild_family_base_conf(project: BoardProject) -> Optional[Path]:
|
|
134
|
+
"""Path to the curated `zephyr/sysbuild/<family>/sysbuild.conf` for
|
|
135
|
+
this project's SoM family, or None when the family has no curated
|
|
136
|
+
profile on disk.
|
|
137
|
+
|
|
138
|
+
This is the LAYERING base (issue #807): a customer `boot:` overlay
|
|
139
|
+
from `emit_sysbuild_conf` builds ON TOP of this file via a
|
|
140
|
+
semicolon-separated `SB_CONF_FILE` list rather than replacing it,
|
|
141
|
+
so a `boot:` block no longer forks family boot policy into two
|
|
142
|
+
divergent places. Verified against the pinned Zephyr 4.4.0's
|
|
143
|
+
`share/sysbuild/cmake/modules/sysbuild_kconfig.cmake`: `SB_CONF_FILE`
|
|
144
|
+
accepts a CMake list (`foreach(conf_file ${conf_file_expanded})`
|
|
145
|
+
splits on the list separator) and every listed file lands in the
|
|
146
|
+
merged sysbuild `.config`, later files winning on a repeated
|
|
147
|
+
symbol -- confirmed empirically via a `native_sim` sysbuild
|
|
148
|
+
configure with two `;`-joined conf files, both symbols present in
|
|
149
|
+
the merged `.config`.
|
|
150
|
+
"""
|
|
151
|
+
family = (project.som_preset.get("family") or "").lower()
|
|
152
|
+
slug = next((v for k, v in _FAMILY_SYSBUILD_DIRS.items()
|
|
153
|
+
if family.startswith(k)), None)
|
|
154
|
+
if slug is None:
|
|
155
|
+
return None
|
|
156
|
+
base = REPO / "zephyr" / "sysbuild" / slug / "sysbuild.conf"
|
|
157
|
+
return base if base.is_file() else None
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def emit_sysbuild_conf(project: BoardProject) -> str:
|
|
161
|
+
"""Emit the sysbuild.conf overlay for the project's `boot:` block.
|
|
162
|
+
|
|
163
|
+
Returns a SB_CONFIG_*-style snippet the build wires into
|
|
164
|
+
`build/alp_sysbuild.conf` (consumed via `west build --sysbuild
|
|
165
|
+
-- -DSB_CONF_FILE=<abs path>`). Returns an empty string when the project
|
|
166
|
+
does not declare a `boot:` block (the SDK's stock per-family
|
|
167
|
+
defaults at zephyr/sysbuild/<family>/sysbuild.conf apply), and when
|
|
168
|
+
the project has NO Zephyr slice at all (#562) -- sysbuild exists
|
|
169
|
+
only inside a Zephyr build, so a Yocto-only project has nothing to
|
|
170
|
+
apply the overlay to. On such a project the `boot:` block governs
|
|
171
|
+
the U-Boot/FIT chain instead, which this emitter has never rendered;
|
|
172
|
+
the previous behaviour was to render it as MCUboot anyway and, on
|
|
173
|
+
`rsa3072`, to raise below and fail the project's entire build-plan
|
|
174
|
+
emit with sysbuild advice for a platform that never runs sysbuild.
|
|
175
|
+
|
|
176
|
+
`boot.method:` is optional and the SoM family supplies its default
|
|
177
|
+
(`_FAMILY_BOOT_METHOD_DEFAULTS` -- the value board.schema.json has
|
|
178
|
+
always documented). It is NOT an unconditional `mcuboot`.
|
|
179
|
+
|
|
180
|
+
Every `SB_CONFIG_*` symbol emitted here MUST exist in the pinned
|
|
181
|
+
Zephyr's `share/sysbuild/**/Kconfig*` -- sysbuild treats an
|
|
182
|
+
undefined-symbol warning as FATAL, so one invented name aborts the
|
|
183
|
+
whole `boot:` configure (issue #807). Slot/scratch partition
|
|
184
|
+
*sizes* have no sysbuild expression at all: MCUboot takes slot
|
|
185
|
+
geometry from the board DT partitions, per the Zephyr 4.4 Kconfig
|
|
186
|
+
help text on every `MCUBOOT_MODE_*` choice -- that's also why
|
|
187
|
+
`boot.slots` / `boot.scratch_size_kib` were dropped from the
|
|
188
|
+
schema rather than fixed (see board.schema.json for the full
|
|
189
|
+
rationale).
|
|
190
|
+
"""
|
|
191
|
+
boot = project.boot or {}
|
|
192
|
+
if not boot:
|
|
193
|
+
return ""
|
|
194
|
+
if not _has_zephyr_slice(project):
|
|
195
|
+
return ""
|
|
196
|
+
method = (boot.get("method") or _default_boot_method(project)).lower()
|
|
197
|
+
if method == "none":
|
|
198
|
+
return ("# Auto-generated from board.yaml `boot:` block.\n"
|
|
199
|
+
"SB_CONFIG_BOOTLOADER_MCUBOOT=n\n")
|
|
200
|
+
if method != "mcuboot":
|
|
201
|
+
return ""
|
|
202
|
+
|
|
203
|
+
lines: list[str] = [
|
|
204
|
+
"# Auto-generated by scripts/alp_orchestrate.py from "
|
|
205
|
+
"board.yaml `boot:`.",
|
|
206
|
+
"# Drives the sysbuild MCUboot child image. Customers who",
|
|
207
|
+
"# omit `boot:` get the SDK's stock per-family defaults.",
|
|
208
|
+
"",
|
|
209
|
+
"SB_CONFIG_BOOTLOADER_MCUBOOT=y",
|
|
210
|
+
]
|
|
211
|
+
sign = boot.get("signing") or {}
|
|
212
|
+
algo = (sign.get("algorithm") or "").lower()
|
|
213
|
+
if algo == "rsa3072":
|
|
214
|
+
# sysbuild's BOOT_SIGNATURE_TYPE_RSA choice has no key-length
|
|
215
|
+
# knob -- length is an mcuboot-image CONFIG_BOOT_SIGNATURE_
|
|
216
|
+
# TYPE_RSA_LEN symbol (bootloader/mcuboot/boot/zephyr/Kconfig),
|
|
217
|
+
# a different Kconfig namespace sysbuild never forwards into.
|
|
218
|
+
# Until a per-image `sysbuild/mcuboot.conf` overlay seam exists
|
|
219
|
+
# (see docs/secure-boot.md), rsa3072 has no honest emit -- fail
|
|
220
|
+
# loud rather than silently ship rsa2048's default length.
|
|
221
|
+
raise OrchestratorError(
|
|
222
|
+
"boot.signing.algorithm: rsa3072 has no sysbuild "
|
|
223
|
+
"expression yet -- SB_CONFIG_BOOT_SIGNATURE_TYPE_RSA has "
|
|
224
|
+
"no key-length knob (that's an mcuboot-image CONFIG_BOOT_"
|
|
225
|
+
"SIGNATURE_TYPE_RSA_LEN symbol, a different Kconfig "
|
|
226
|
+
"namespace sysbuild doesn't forward). Use rsa2048 (mcuboot's "
|
|
227
|
+
"RSA default length) or ecdsa_p256/ed25519 until a per-image "
|
|
228
|
+
"sysbuild/mcuboot.conf overlay seam ships.")
|
|
229
|
+
algo_kc = {
|
|
230
|
+
"ecdsa_p256": "SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y",
|
|
231
|
+
"rsa2048": "SB_CONFIG_BOOT_SIGNATURE_TYPE_RSA=y",
|
|
232
|
+
"ed25519": "SB_CONFIG_BOOT_SIGNATURE_TYPE_ED25519=y",
|
|
233
|
+
}.get(algo)
|
|
234
|
+
if algo_kc:
|
|
235
|
+
lines.append(algo_kc)
|
|
236
|
+
if sign.get("key_file"):
|
|
237
|
+
lines.append(f'SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="{sign["key_file"]}"')
|
|
238
|
+
swap_explicit = boot.get("swap_algorithm")
|
|
239
|
+
swap = (swap_explicit or "").lower()
|
|
240
|
+
single_slot = _boot_target_is_single_slot(project)
|
|
241
|
+
if swap_explicit and swap in ("scratch", "move", "overwrite") and single_slot:
|
|
242
|
+
# alp-sdk#1413: this SKU's `memory_map:` has no slot1/scratch
|
|
243
|
+
# region (see `_boot_target_is_single_slot`) -- every two-slot
|
|
244
|
+
# MCUboot swap mode needs one. An explicit request for one here
|
|
245
|
+
# is not a default that quietly drifted, it is a `boot:` block
|
|
246
|
+
# asking for a partition that does not exist on this target's DT,
|
|
247
|
+
# so fail loud rather than emit a config that cannot boot.
|
|
248
|
+
raise OrchestratorError(
|
|
249
|
+
f"boot.swap_algorithm: {swap} needs a slot1/scratch "
|
|
250
|
+
f"partition that {project.sku}'s disjoint-slot0 "
|
|
251
|
+
"`memory_map:` (metadata/e1m_modules/"
|
|
252
|
+
f"{project.sku}.yaml, alp-sdk#1069) doesn't declare -- this "
|
|
253
|
+
"single-slot target only supports the stock "
|
|
254
|
+
"single-app boot. Drop `boot.swap_algorithm:` (it now "
|
|
255
|
+
"defaults correctly on single-slot targets) rather than "
|
|
256
|
+
"setting it explicitly.")
|
|
257
|
+
if not swap_explicit:
|
|
258
|
+
# Historically defaulted unconditionally to "scratch"
|
|
259
|
+
# (alp-sdk#1413): wrong on a single-slot target, whose DT has no
|
|
260
|
+
# scratch partition to swap into. Single-slot targets default to
|
|
261
|
+
# the single-app boot their curated `zephyr/sysbuild/aen/
|
|
262
|
+
# sysbuild.conf` base already ships; every other target keeps the
|
|
263
|
+
# historical "scratch" default.
|
|
264
|
+
swap = "none" if single_slot else "scratch"
|
|
265
|
+
swap_kc = {
|
|
266
|
+
"scratch": "SB_CONFIG_MCUBOOT_MODE_SWAP_SCRATCH=y",
|
|
267
|
+
"move": "SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE=y",
|
|
268
|
+
"overwrite": "SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y",
|
|
269
|
+
"none": "SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=y",
|
|
270
|
+
}.get(swap)
|
|
271
|
+
if swap_kc:
|
|
272
|
+
lines.append(swap_kc)
|
|
273
|
+
return "\n".join(lines) + "\n"
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def emit_tfm_sysbuild_conf(project: BoardProject) -> str:
|
|
277
|
+
"""Emit the TF-M sysbuild child-image overlay for `security.psa:`.
|
|
278
|
+
|
|
279
|
+
Returns a `SB_CONFIG_*` + `CONFIG_PSA_CRYPTO_*` snippet the build
|
|
280
|
+
wires into `build/sysbuild/tfm/tfm.conf` (picked up by sysbuild
|
|
281
|
+
convention from its `sysbuild/tfm/` path). Returns an empty
|
|
282
|
+
string when the project omits `security.psa:` or sets
|
|
283
|
+
`tfm: false` -- PSA Crypto then runs entirely non-secure
|
|
284
|
+
(mbedTLS-only) and no child image is built.
|
|
285
|
+
|
|
286
|
+
The TF-M boundary lives on the same M55-HP core as the non-secure
|
|
287
|
+
app via Armv8-M TrustZone-M; see ADR 0013.
|
|
288
|
+
"""
|
|
289
|
+
security = project.security or {}
|
|
290
|
+
psa = security.get("psa") or {}
|
|
291
|
+
if not psa or not psa.get("tfm"):
|
|
292
|
+
return ""
|
|
293
|
+
|
|
294
|
+
# TF-M build type follows the project's MCUboot build_type when
|
|
295
|
+
# set so the secure + bootloader artefacts ship the same flavour.
|
|
296
|
+
# Default is Release; debug builds use MinSizeRel for parity with
|
|
297
|
+
# the upstream sysbuild template.
|
|
298
|
+
boot = project.boot or {}
|
|
299
|
+
build_type = (boot.get("build_type") or "Release")
|
|
300
|
+
if build_type.lower() == "debug":
|
|
301
|
+
tfm_build_type = "Debug"
|
|
302
|
+
elif build_type.lower() in ("minsizerel", "min_size_rel"):
|
|
303
|
+
tfm_build_type = "MinSizeRel"
|
|
304
|
+
elif build_type.lower() == "release":
|
|
305
|
+
tfm_build_type = "Release"
|
|
306
|
+
else:
|
|
307
|
+
# Pass through verbatim if the customer set an exact CMake
|
|
308
|
+
# build-type string we don't pre-canonicalise.
|
|
309
|
+
tfm_build_type = build_type
|
|
310
|
+
|
|
311
|
+
lines: list[str] = [
|
|
312
|
+
"# Auto-generated by scripts/alp_orchestrate.py from "
|
|
313
|
+
"board.yaml `security.psa:`.",
|
|
314
|
+
"# Drives the sysbuild TF-M child image on the M55-HP core via "
|
|
315
|
+
"Armv8-M TrustZone-M.",
|
|
316
|
+
"# See docs/adr/0013-tfm-boundary-m55-hp-trustzone.md and "
|
|
317
|
+
"docs/security-audit-plan.md.",
|
|
318
|
+
"",
|
|
319
|
+
"SB_CONFIG_TFM=y",
|
|
320
|
+
f"SB_CONFIG_TFM_BUILD_TYPE={tfm_build_type}",
|
|
321
|
+
]
|
|
322
|
+
|
|
323
|
+
persistent_slots = psa.get("persistent_slots")
|
|
324
|
+
if persistent_slots is None:
|
|
325
|
+
# Schema default mirrors v0.6: 16 slots.
|
|
326
|
+
persistent_slots = 16
|
|
327
|
+
lines.append(
|
|
328
|
+
f"CONFIG_PSA_CRYPTO_PERSISTENT_SLOT_COUNT={int(persistent_slots)}"
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
its = psa.get("its_storage")
|
|
332
|
+
if its:
|
|
333
|
+
lines.append(f'CONFIG_PSA_CRYPTO_ITS_BACKING_STORE="{its}"')
|
|
334
|
+
ps = psa.get("ps_storage")
|
|
335
|
+
if ps:
|
|
336
|
+
lines.append(f'CONFIG_PSA_CRYPTO_PS_BACKING_STORE="{ps}"')
|
|
337
|
+
|
|
338
|
+
att_root = (psa.get("attestation_root") or "none").lower()
|
|
339
|
+
if att_root == "optiga_trust_m":
|
|
340
|
+
lines.append(
|
|
341
|
+
"# Attestation root anchored in OPTIGA Trust M (on-module "
|
|
342
|
+
"secure element).")
|
|
343
|
+
lines.append(
|
|
344
|
+
"# See src/security/optiga_trust_m_bridge.c for the "
|
|
345
|
+
"PSA <-> OPTIGA bridge driver.")
|
|
346
|
+
lines.append("CONFIG_ALP_SDK_PSA_ATTESTATION_OPTIGA=y")
|
|
347
|
+
elif att_root == "tfm_internal":
|
|
348
|
+
lines.append("CONFIG_ALP_SDK_PSA_ATTESTATION_TFM_INTERNAL=y")
|
|
349
|
+
|
|
350
|
+
return "\n".join(lines) + "\n"
|