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
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""The IO half of Flow D's link-address guard (tan-cli#1371).
|
|
3
|
+
|
|
4
|
+
`tan.core.mram_link` decides; this finds the artefact's ELF and parses
|
|
5
|
+
`slot0_load_address`, the floor the image's load addresses are held to.
|
|
6
|
+
|
|
7
|
+
**Scope, deliberately narrow.** The guard runs only for the Flow D shapes tan itself
|
|
8
|
+
controls: the mramxip `loadbin` at `slot0_load_address` and the SETOOLS auto-sign
|
|
9
|
+
(`mramAddress`). It does NOT run for an operator-supplied ATOC with no
|
|
10
|
+
`slot0_load_address` (that ATOC may carry a legitimate ITCM load entry), and it does
|
|
11
|
+
NOT run for Flow A (`zephyr_west_flash` on the `alif_flash` runner): alp-sdk's
|
|
12
|
+
`alif_flash.py` already refuses an unrecognised reset vector and supports images linked
|
|
13
|
+
at the ITCM global alias (0x58xxxxxx / 0x50xxxxxx) with an ATOC `loadAddress`, so an ELF
|
|
14
|
+
below `soc_flash_base` is not generally unbootable there. `west flash` generally and
|
|
15
|
+
`baremetal_cmake_flash` are likewise unchecked."""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import os
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from tan.core.flash_plan import FLOW_D_METHOD, FlashPlanError, fa_str_checked, resolve_slot0_binary
|
|
22
|
+
from tan.core.mram_link import mram_link_refusal
|
|
23
|
+
|
|
24
|
+
#: Ceiling on the bytes read: a Zephyr ELF with debug info is tens of MiB, never this.
|
|
25
|
+
MAX_ELF_BYTES = 512 * 1024 * 1024
|
|
26
|
+
_ELF_MAGIC = b"\x7fELF"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
#: How much older than the `.bin` its same-stem `.elf` may be before it is distrusted. A
|
|
30
|
+
#: normal build links the ELF and then `objcopy`s the `.bin` from it, seconds apart; an ELF
|
|
31
|
+
#: from an earlier build beside a swapped-in `.bin` is minutes or more older.
|
|
32
|
+
STALE_ELF_SECONDS = 60.0
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
#: Filesystem timestamp slack (FAT keeps 2 s) when asking whether the `.bin` that will be
|
|
36
|
+
#: written is OLDER than its ELF. `objcopy` runs after the link, so a genuine pair never
|
|
37
|
+
#: has the `.bin` older; a leftover from an earlier build is minutes or more.
|
|
38
|
+
BIN_OLDER_SLACK_SECONDS = 2.0
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def written_bin_older_than_elf(artefact_path: str) -> tuple[str, str] | None:
|
|
42
|
+
"""`(bin, elf)` when the `.bin` Flow D will `loadbin` to slot0 is older than the ELF it
|
|
43
|
+
must have been made from, else `None` (also when there is no same-stem pair to compare).
|
|
44
|
+
|
|
45
|
+
The written `.bin` is `resolve_slot0_binary`'s answer -- the artefact itself, or the
|
|
46
|
+
sibling `.bin` of an ELF artefact -- so this holds whichever of the two the manifest
|
|
47
|
+
names. The ELF's link address (checked separately) only vouches for a `.bin` made from
|
|
48
|
+
THAT link; an ITCM-linked `.bin` left beside a fresh MRAM-linked ELF has an older
|
|
49
|
+
mtime, which is the only evidence of the mismatch on disk (tan-cli#1485)."""
|
|
50
|
+
written = resolve_slot0_binary(artefact_path, os.path.isfile)
|
|
51
|
+
if written is None:
|
|
52
|
+
return None
|
|
53
|
+
elf = artefact_path if written != artefact_path else os.path.splitext(artefact_path)[0] + ".elf"
|
|
54
|
+
try:
|
|
55
|
+
gap = os.path.getmtime(elf) - os.path.getmtime(written)
|
|
56
|
+
except OSError:
|
|
57
|
+
return None
|
|
58
|
+
return (written, elf) if gap > BIN_OLDER_SLACK_SECONDS else None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def written_bin_much_newer_than_elf(artefact_path: str) -> tuple[str, str] | None:
|
|
62
|
+
"""`(bin, elf)` when the ELF artefact's sibling `.bin` (what Flow D `loadbin`s) is more
|
|
63
|
+
than [`STALE_ELF_SECONDS`] newer than the ELF, else `None`. The `.bin`-artefact case is
|
|
64
|
+
`find_elf`'s `stale`; this closes the same gap when the manifest names the ELF, which
|
|
65
|
+
the stale refusal itself recommends (tan-cli#1514): the ELF's link address cannot vouch
|
|
66
|
+
for a `.bin` swapped in long after it."""
|
|
67
|
+
written = resolve_slot0_binary(artefact_path, os.path.isfile)
|
|
68
|
+
if written is None or written == artefact_path:
|
|
69
|
+
return None
|
|
70
|
+
try:
|
|
71
|
+
gap = os.path.getmtime(written) - os.path.getmtime(artefact_path)
|
|
72
|
+
except OSError:
|
|
73
|
+
return None
|
|
74
|
+
return (written, artefact_path) if gap > STALE_ELF_SECONDS else None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def find_elf(artefact_path: str) -> tuple[bytes, bool] | None:
|
|
78
|
+
"""`(bytes, stale)` of the ELF behind a Flow D artefact: the artefact itself when it
|
|
79
|
+
carries ELF magic, else the same-stem `.elf` beside a raw `.bin`. Read once.
|
|
80
|
+
|
|
81
|
+
`stale` is True only for the sibling case, when the `.elf` is more than
|
|
82
|
+
[`STALE_ELF_SECONDS`] older than the `.bin`: its link address cannot vouch for a
|
|
83
|
+
newer binary. Limitation: the pairing is by file stem only. A `.bin` whose `.elf`
|
|
84
|
+
sits elsewhere, or is named differently, is not found -- and a `.bin` with no ELF
|
|
85
|
+
carries no link address, so it is not checked. `None` also for an unreadable or
|
|
86
|
+
oversized file."""
|
|
87
|
+
candidates = [artefact_path]
|
|
88
|
+
stem, ext = os.path.splitext(artefact_path)
|
|
89
|
+
if ext.lower() == ".bin":
|
|
90
|
+
candidates.append(stem + ".elf")
|
|
91
|
+
for path in candidates:
|
|
92
|
+
try:
|
|
93
|
+
if os.path.getsize(path) > MAX_ELF_BYTES:
|
|
94
|
+
continue
|
|
95
|
+
with open(path, "rb") as handle:
|
|
96
|
+
data = handle.read()
|
|
97
|
+
stale = path != artefact_path and (
|
|
98
|
+
os.path.getmtime(artefact_path) - os.path.getmtime(path) > STALE_ELF_SECONDS
|
|
99
|
+
)
|
|
100
|
+
except OSError:
|
|
101
|
+
continue
|
|
102
|
+
if data[:4] == _ELF_MAGIC:
|
|
103
|
+
return data, stale
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def slot0_address(flash_args: Any) -> int | None:
|
|
108
|
+
"""`flash_args.slot0_load_address` as an int, or `None` when absent or malformed (a
|
|
109
|
+
malformed value is refused later by `validate_flow_d_shape` with its own message)."""
|
|
110
|
+
try:
|
|
111
|
+
text = fa_str_checked(flash_args, "slot0_load_address", True)
|
|
112
|
+
return None if text is None else int(text, 16)
|
|
113
|
+
except (FlashPlanError, ValueError):
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def mram_link_guard(artefact_path: str, entry_id: str, *, slot0: int) -> str | None:
|
|
118
|
+
"""The refusal for a Flow D entry whose ELF is loaded below `slot0`
|
|
119
|
+
(`slot0_load_address`), or whose same-stem ELF is much older than its `.bin`, or whose `.bin`
|
|
120
|
+
is older than its ELF, or whose sibling `.bin` (what `loadbin` writes) is much newer than an
|
|
121
|
+
ELF artefact, else `None`.
|
|
122
|
+
The caller invokes this only for the shapes tan controls (see the module docstring)."""
|
|
123
|
+
prefix = f"{FLOW_D_METHOD}[{entry_id}]: refusing -- "
|
|
124
|
+
older = written_bin_older_than_elf(artefact_path)
|
|
125
|
+
if older is not None:
|
|
126
|
+
return (
|
|
127
|
+
f"{prefix}the .bin that would be written to slot0 ({os.path.basename(older[0])}) is "
|
|
128
|
+
f"older than its ELF ({os.path.basename(older[1])}), so it was not produced from that "
|
|
129
|
+
"link and its load address is unknown. Rebuild so the .bin is regenerated from the ELF."
|
|
130
|
+
)
|
|
131
|
+
newer = written_bin_much_newer_than_elf(artefact_path)
|
|
132
|
+
if newer is not None:
|
|
133
|
+
return (
|
|
134
|
+
f"{prefix}the .bin that would be written to slot0 ({os.path.basename(newer[0])}) is "
|
|
135
|
+
f"much newer than its ELF ({os.path.basename(newer[1])}), so it was not produced from "
|
|
136
|
+
"that link and the ELF's link address cannot vouch for it. Rebuild so the .bin is "
|
|
137
|
+
"regenerated from the ELF."
|
|
138
|
+
)
|
|
139
|
+
found = find_elf(artefact_path)
|
|
140
|
+
if found is None:
|
|
141
|
+
return None
|
|
142
|
+
data, stale = found
|
|
143
|
+
if stale:
|
|
144
|
+
return (
|
|
145
|
+
f"{prefix}the ELF beside the .bin ({os.path.basename(os.path.splitext(artefact_path)[0])}"
|
|
146
|
+
".elf) is older than the .bin, so its link address cannot vouch for it. Rebuild, "
|
|
147
|
+
"or pass the ELF itself as the artefact."
|
|
148
|
+
)
|
|
149
|
+
message = mram_link_refusal(data, slot0, "slot0_load_address")
|
|
150
|
+
return None if message is None else prefix + message
|