From 1c4c2ae2386e47afa1cbf2ca713bf0883a95c493 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Fri, 25 Sep 2026 15:20:36 +0530 Subject: [PATCH] camera: prepare CAMX overlay runtime for NHX validation Signed-off-by: Srikanth Muppandam --- .../Camera/Camera_NHX/README_Camera_NHX.md | 40 ++-- .../Multimedia/Camera/Camera_NHX/run.sh | 187 +++++++++++------- Runner/utils/camera/lib_camera.sh | 57 ++++-- 3 files changed, 181 insertions(+), 103 deletions(-) diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md b/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md index eb3359e2a..117c5a240 100644 --- a/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/README_Camera_NHX.md @@ -75,16 +75,18 @@ Snapshot JSON files are currently expected only for targets where the files are - `qcom,cam-tpg1031` - `qcom,camera` - `fdtdump` scan for camera-related nodes through `lib_camera.sh` - - Camera kernel module detection and loaded-state validation + - Camera kernel module detection and loaded-state validation, including `camera_x1e80100` on Glymur - ICP firmware presence check (`CAMERA_ICP`) - `dmesg` scan for camera warnings/errors - - CAMX package presence check + - CAMX package presence check through the available `opkg`, Debian, or RPM package database + - With `--overlay`, an unavailable package inventory is warn-only after the package set was verified successfully - Sensor presence check is warn-only because NHX may still work depending on target/test config 4. **Runs NHX** + - Resolves `nhx.sh` from `PATH`, then falls back to the packaged CAMX location `/usr/libexec/camx/nhx.sh`. - Default mode runs `nhx.sh` with no argument, preserving the existing SoC-specific default behavior. - Optional mode accepts one selected JSON via `--json` and optionally `--target`. - - The selected JSON is staged to the location expected by `/usr/bin/nhx.sh`. + - The selected JSON is staged to the location expected by the selected `nhx.sh` launcher. 5. **Dump validation** - Collects dump file list from NHX output and/or dump directory based on a marker timestamp. @@ -116,8 +118,8 @@ installs the `camera-nhx` package set: camx-dkms camx-glymur libcamx-glymur1 camx-firmware-glymur camx-nhx ``` -To select a FIT DTB, pass its compatibility name with `--fit-dtb`. For CAMX, -the compatibility name is `camx`: +`--overlay` requires the CAMX FIT DTB and uses the compatibility name `camx`. +The same requirement can be stated explicitly with `--fit-dtb camx`: ```sh ./run.sh --overlay --fit-dtb camx @@ -125,8 +127,9 @@ the compatibility name is `camx`: The test discovers the platform's `VendorDtbOverlays` EFI variable with `efivar -l`. The EFI variable GUID is never supplied by the user or hardcoded -in the test. It writes the requested FIT DTB name without a trailing newline, -verifies the value through `efivar -p`, and synchronizes storage. +in the test. It verifies that the payload is `camx` through `efivar -p`. If it +is not selected, the test writes `camx` without a trailing newline, reads the +variable back, and synchronizes storage. When a new DTB selection is written, the test records `Camera_NHX SKIP` with a reboot-required message instead of rebooting within the LAVA test shell. Reboot @@ -138,9 +141,11 @@ reboot ./run.sh --overlay --fit-dtb camx ``` -If the requested FIT DTB is already selected, the test continues directly to -the normal NHX checks. `--overlay` without `--fit-dtb` only performs the -optional package preparation and does not change the boot DTB. +If the CAMX FIT DTB is already selected, the test continues with runtime DT and +camera-module checks. A loaded board-specific camera module is used as runtime +evidence that the current boot has activated the CAMX camera stack. If EFI is +set to `camx` but the module is not loaded, the test records SKIP and asks the +operator to reboot manually. The test never issues a reboot itself. --- @@ -233,7 +238,7 @@ In that case, pass `--target`: ## How JSON staging works -`/usr/bin/nhx.sh` does not accept an arbitrary absolute JSON path. It expects a JSON name and internally checks: +The `nhx.sh` launcher does not accept an arbitrary absolute JSON path. It expects a JSON name and internally checks: ```sh /etc/camera/test/NHX/${JSON_FILE}.json @@ -278,11 +283,11 @@ Options: ```text --overlay Install the optional Camera NHX CAMX package set on Debian, - Ubuntu, or CentOS. + Ubuntu, or CentOS and ensure the CAMX FIT DTB is selected. --fit-dtb NAME Select NAME as the FIT DTB compatibility name for the next boot. Requires --overlay on a supported desktop distro. - Use camx to select the CAMX DTB overlay. + Camera_NHX accepts camx, which is the --overlay default. --json JSON_FILE NHX JSON file to pass to nhx.sh. Can be absolute, relative to Camera_NHX/, or relative @@ -301,7 +306,7 @@ Examples: ``` ```sh -./run.sh --overlay --fit-dtb camx +./run.sh --overlay ``` ```sh @@ -453,9 +458,10 @@ run: ### SKIP -- Missing CAMX prerequisites, such as DT patterns, camera module artifact/loaded state, ICP firmware, CAMX packages, or `nhx.sh` -- The requested FIT DTB selection was written and a reboot is required before validation -- `VendorDtbOverlays` is unavailable when `--overlay --fit-dtb` was requested +- Missing CAMX prerequisites, such as DT patterns, camera module artifact/loaded state, ICP firmware, CAMX packages, or an executable `nhx.sh` in `PATH` or `/usr/libexec/camx` +- The CAMX FIT DTB selection was written and a manual reboot is required before validation +- EFI selects `camx`, but the board-specific camera module is not loaded, so a manual reboot is required +- `VendorDtbOverlays` is unavailable when `--overlay` was requested - `fdtdump` is not available or camera node evidence is inconclusive - Requested `--json` file is not found - Requested JSON filename is ambiguous and `--target` was not supplied diff --git a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh index 05d2dcbdf..401a1b59f 100755 --- a/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh +++ b/Runner/suites/Multimedia/Camera/Camera_NHX/run.sh @@ -79,10 +79,14 @@ CAM_SERVER_STOPPED_FOR_TEST=0 NHX_JSON="${NHX_JSON:-}" NHX_TARGET="${NHX_TARGET:-}" +NHX_RUNNER="" +NHX_RUNNER_SOURCE="" NHX_JSON_RESOLVED="" NHX_JSON_ARG="" OVERLAY_REQUESTED=0 FIT_DTB_NAME="" +FIT_DTB_SOURCE="" +CAMX_FIT_DTB_SELECTED=0 # shellcheck disable=SC2317 cleanup() { @@ -107,11 +111,11 @@ Usage: $0 [--overlay] [--fit-dtb NAME] [--json JSON_FILE] [--target TARGET] [--h Options: --overlay Install the Camera NHX CAMX package set on supported - Debian, Ubuntu, or CentOS images. + Debian, Ubuntu, or CentOS images and ensure the CAMX FIT + DTB is selected for boot. --fit-dtb NAME Select this FIT DTB compatibility name for the next boot. - For example, pass camx to select the CAMX DTB overlay. - This option is applied only with --overlay on supported - desktop distributions. + Camera_NHX supports camx, which is the --overlay default. + This option requires --overlay. --json JSON_FILE NHX JSON file to pass to nhx.sh. Can be absolute, relative to Camera_NHX/, or relative to target folder when --target is provided. @@ -142,10 +146,12 @@ while [ "$#" -gt 0 ]; do exit 0 fi FIT_DTB_NAME="$2" + FIT_DTB_SOURCE="cli" shift 2 ;; --fit-dtb=*) FIT_DTB_NAME="${1#--fit-dtb=}" + FIT_DTB_SOURCE="cli" shift ;; --json) @@ -188,6 +194,25 @@ while [ "$#" -gt 0 ]; do esac done +if [ "$OVERLAY_REQUESTED" -eq 1 ]; then + if [ -z "$FIT_DTB_NAME" ]; then + FIT_DTB_NAME="camx" + FIT_DTB_SOURCE="overlay-default" + fi + + if [ "$FIT_DTB_NAME" != "camx" ]; then + log_fail "$TESTNAME FAIL - Camera_NHX requires the camx FIT DTB compatibility name" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 0 + fi + + log_info "CAMX FIT DTB policy, name=$FIT_DTB_NAME source=$FIT_DTB_SOURCE" +elif [ -n "$FIT_DTB_NAME" ]; then + log_fail "$TESTNAME FAIL - --fit-dtb requires --overlay" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 0 +fi + if [ "$OVERLAY_REQUESTED" -eq 1 ]; then for required_helper in \ pkg_provider_init \ @@ -217,66 +242,57 @@ if [ "$OVERLAY_REQUESTED" -eq 1 ]; then CAMX_OVERLAY_OS_ID="$(pkg_detect_os_id 2>/dev/null || true)" case "$CAMX_OVERLAY_OS_ID" in debian|ubuntu|centos) - if [ -z "$FIT_DTB_NAME" ]; then - log_info "No FIT DTB compatibility name was requested, skipping EFI overlay selection" - else - - case "$FIT_DTB_NAME" in - *[!A-Za-z0-9._-]* ) - log_fail "$TESTNAME FAIL - invalid FIT DTB compatibility name: $FIT_DTB_NAME" - echo "$TESTNAME FAIL" >"$RES_FILE" - exit 0 - ;; - esac - - for required_helper in \ - efi_find_variable_by_name \ - efi_text_variable_matches \ - efi_write_text_variable \ - efi_restore_efivarfs_ro; do - if ! command -v "$required_helper" >/dev/null 2>&1; then - log_fail "$TESTNAME FAIL - required EFI helper is unavailable: $required_helper" - echo "$TESTNAME FAIL" >"$RES_FILE" - exit 0 - fi - done - - if ! CHECK_DEPS_NO_EXIT=1 check_dependencies efivar mount mktemp od tr sed grep sync awk; then - log_skip "$TESTNAME SKIP - CAMX overlay selection requires efivar and EFI runtime tools" - echo "$TESTNAME SKIP" >"$RES_FILE" + for required_helper in \ + efi_find_variable_by_name \ + efi_text_variable_matches \ + efi_write_text_variable \ + efi_restore_efivarfs_ro; do + if ! command -v "$required_helper" >/dev/null 2>&1; then + log_fail "$TESTNAME FAIL - required EFI helper is unavailable: $required_helper" + echo "$TESTNAME FAIL" >"$RES_FILE" exit 0 fi + done - CAMX_DTB_OVERLAY_VARIABLE="$(efi_find_variable_by_name \ - VendorDtbOverlays \ - "$CAMX_EFI_LIST_LOG" 2>>"$CAMX_EFI_LOG")" - if [ -z "$CAMX_DTB_OVERLAY_VARIABLE" ]; then - log_skip "$TESTNAME SKIP - VendorDtbOverlays EFI variable was not found" - echo "$TESTNAME SKIP" >"$RES_FILE" - exit 0 - fi + if ! CHECK_DEPS_NO_EXIT=1 check_dependencies efivar mount mktemp od tr sed grep sync awk; then + log_skip "$TESTNAME SKIP - CAMX FIT DTB verification requires efivar and EFI runtime tools" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi + + CAMX_DTB_OVERLAY_VARIABLE="$(efi_find_variable_by_name \ + VendorDtbOverlays \ + "$CAMX_EFI_LIST_LOG" 2>>"$CAMX_EFI_LOG")" + if [ -z "$CAMX_DTB_OVERLAY_VARIABLE" ]; then + log_skip "$TESTNAME SKIP - VendorDtbOverlays EFI variable was not found" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 + fi + + log_info "CAMX FIT DTB EFI variable selected: $CAMX_DTB_OVERLAY_VARIABLE" + + if efi_text_variable_matches \ + "$CAMX_DTB_OVERLAY_VARIABLE" \ + "$FIT_DTB_NAME" \ + "$CAMX_EFI_LOG"; then + CAMX_FIT_DTB_SELECTED=1 + log_pass "CAMX FIT DTB is selected in EFI, value=$FIT_DTB_NAME" + log_info "Continuing with runtime DT and camera module validation" + else + log_info "Selecting CAMX FIT DTB for the next boot, value=$FIT_DTB_NAME" - if efi_text_variable_matches \ + if ! efi_write_text_variable \ "$CAMX_DTB_OVERLAY_VARIABLE" \ "$FIT_DTB_NAME" \ "$CAMX_EFI_LOG"; then - log_info "FIT DTB compatibility name is already selected: $FIT_DTB_NAME" - else - log_info "Selecting FIT DTB compatibility name for the next boot: $FIT_DTB_NAME" - - if ! efi_write_text_variable \ - "$CAMX_DTB_OVERLAY_VARIABLE" \ - "$FIT_DTB_NAME" \ - "$CAMX_EFI_LOG"; then - log_fail "$TESTNAME FAIL - could not select FIT DTB compatibility name: $FIT_DTB_NAME" - echo "$TESTNAME FAIL" >"$RES_FILE" - exit 0 - fi - - log_skip "$TESTNAME SKIP - FIT DTB compatibility name selected, reboot required before NHX validation" - echo "$TESTNAME SKIP" >"$RES_FILE" + log_fail "$TESTNAME FAIL - could not select CAMX FIT DTB in EFI" + echo "$TESTNAME FAIL" >"$RES_FILE" exit 0 fi + + log_skip "$TESTNAME SKIP - CAMX FIT DTB selected for the next boot, reboot the target manually and rerun Camera_NHX" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 fi ;; *) @@ -297,12 +313,20 @@ if ! check_dependencies "$deps_list"; then exit 0 fi -if ! command -v nhx.sh >/dev/null 2>&1; then - log_skip "$TESTNAME SKIP nhx.sh not found in PATH" +NHX_RUNNER="$(command -v nhx.sh 2>/dev/null || true)" +if [ -n "$NHX_RUNNER" ] && [ -f "$NHX_RUNNER" ] && [ -x "$NHX_RUNNER" ]; then + NHX_RUNNER_SOURCE="PATH" +elif [ -f "/usr/libexec/camx/nhx.sh" ] && [ -x "/usr/libexec/camx/nhx.sh" ]; then + NHX_RUNNER="/usr/libexec/camx/nhx.sh" + NHX_RUNNER_SOURCE="packaged-libexec" +else + log_skip "$TESTNAME SKIP nhx.sh not found in PATH or /usr/libexec/camx" echo "$TESTNAME SKIP" >"$RES_FILE" exit 0 fi +log_info "NHX runner selected, path=$NHX_RUNNER source=$NHX_RUNNER_SOURCE" + # ----------------------------------------------------------------------------- # CAMX prechecks # ----------------------------------------------------------------------------- @@ -363,7 +387,7 @@ if command -v camx_pick_camera_module >/dev/null 2>&1; then fi if [ -z "$CAM_MOD" ] && command -v lsmod >/dev/null 2>&1; then - CAM_MOD="$(lsmod 2>/dev/null | awk '{print $1}' | grep -E '^(camera_qc|camera_qcm|camera_qcs)' | head -n 1 || true)" + CAM_MOD="$(lsmod 2>/dev/null | awk '{print $1}' | grep -E '^(camera_qc|camera_qcm|camera_qcs|camera_x1e80100)' | head -n 1 || true)" fi if [ -z "$CAM_MOD" ]; then @@ -382,13 +406,22 @@ if [ -z "$CAM_KO" ] || [ ! -f "$CAM_KO" ]; then fi log_info "Camera module artifact found $CAM_KO" -if ! check_driver_loaded "$CAM_MOD" 2>/dev/null; then - log_skip "$TESTNAME SKIP camera module not loaded $CAM_MOD" +if ! is_module_loaded "$CAM_MOD" 2>/dev/null; then + if [ "$CAMX_FIT_DTB_SELECTED" -eq 1 ]; then + log_skip "$TESTNAME SKIP - CAMX FIT DTB is selected in EFI but $CAM_MOD is not loaded, reboot the target manually and rerun Camera_NHX" + else + log_skip "$TESTNAME SKIP camera module not loaded $CAM_MOD" + fi echo "$TESTNAME SKIP" >"$RES_FILE" exit 0 fi +log_pass "Driver/module '$CAM_MOD' is loaded" log_info "Camera module is loaded $CAM_MOD" +if [ "$CAMX_FIT_DTB_SELECTED" -eq 1 ]; then + log_pass "CAMX FIT DTB runtime evidence confirmed by loaded module $CAM_MOD" +fi + ICP_FW="$(camx_find_icp_firmware 2>/dev/null || true)" if [ -z "$ICP_FW" ] || [ ! -f "$ICP_FW" ]; then log_skip "$TESTNAME SKIP CAMERA_ICP firmware not found" @@ -450,17 +483,21 @@ log_info "packages present" CAMX_PKGS="$(camx_opkg_list_camx 2>/dev/null || true)" if [ -z "$CAMX_PKGS" ]; then - log_skip "$TESTNAME SKIP CAMX packages not installed" - echo "$TESTNAME SKIP" >"$RES_FILE" - exit 0 -fi - -log_info "CAMX packages detected" -printf '%s\n' "$CAMX_PKGS" | while IFS= read -r l; do - if [ -n "$l" ]; then - log_info " $l" + if [ "$OVERLAY_REQUESTED" -eq 1 ]; then + log_warn "CAMX package inventory is unavailable after package-set verification, continuing" + else + log_skip "$TESTNAME SKIP CAMX packages not installed" + echo "$TESTNAME SKIP" >"$RES_FILE" + exit 0 fi -done +else + log_info "CAMX packages detected" + printf '%s\n' "$CAMX_PKGS" | while IFS= read -r l; do + if [ -n "$l" ]; then + log_info " $l" + fi + done +fi log_info "sensor presence warn-only NHX may still work without cam sensors" @@ -593,7 +630,7 @@ if [ -n "$NHX_JSON" ]; then log_info "Launching nhx.sh with JSON argument: $NHX_JSON_ARG" if command -v run_cmd_live_to_log >/dev/null 2>&1; then - run_cmd_live_to_log "$RUN_LOG" nhx.sh "$NHX_JSON_ARG" + run_cmd_live_to_log "$RUN_LOG" "$NHX_RUNNER" "$NHX_JSON_ARG" NHX_RC=$? else FIFO="/tmp/${TESTNAME}.fifo.$$" @@ -608,7 +645,7 @@ if [ -n "$NHX_JSON" ]; then ( tee "$RUN_LOG" <"$FIFO"; rm -f "$FIFO" 2>/dev/null || true ) & TEEPID=$! - nhx.sh "$NHX_JSON_ARG" >"$FIFO" 2>&1 + "$NHX_RUNNER" "$NHX_JSON_ARG" >"$FIFO" 2>&1 NHX_RC=$? wait "$TEEPID" 2>/dev/null || true @@ -617,7 +654,7 @@ else log_info "Launching nhx.sh with default SoC-specific JSON" if command -v run_cmd_live_to_log >/dev/null 2>&1; then - run_cmd_live_to_log "$RUN_LOG" nhx.sh + run_cmd_live_to_log "$RUN_LOG" "$NHX_RUNNER" NHX_RC=$? else FIFO="/tmp/${TESTNAME}.fifo.$$" @@ -632,7 +669,7 @@ else ( tee "$RUN_LOG" <"$FIFO"; rm -f "$FIFO" 2>/dev/null || true ) & TEEPID=$! - nhx.sh >"$FIFO" 2>&1 + "$NHX_RUNNER" >"$FIFO" 2>&1 NHX_RC=$? wait "$TEEPID" 2>/dev/null || true @@ -717,6 +754,8 @@ TOTAL_BYTES=0 echo "$TESTNAME Summary" echo "Timestamp: $TS" echo "nhx.sh exit code: $NHX_RC" + echo "NHX runner: $NHX_RUNNER" + echo "NHX runner source: $NHX_RUNNER_SOURCE" echo "NHX JSON requested: ${NHX_JSON:-}" echo "NHX target requested: ${NHX_TARGET:-}" echo "NHX JSON resolved: ${NHX_JSON_RESOLVED:-}" diff --git a/Runner/utils/camera/lib_camera.sh b/Runner/utils/camera/lib_camera.sh index 0c2862000..55cb1d038 100755 --- a/Runner/utils/camera/lib_camera.sh +++ b/Runner/utils/camera/lib_camera.sh @@ -504,28 +504,54 @@ camx_find_icp_firmware() { # ----------------------------------------------------------------------------- # Package helpers (Yocto/QLI proprietary builds) # ----------------------------------------------------------------------------- +# List installed CAMX packages using the image package database. +# Arguments: none. +# Stdout: installed CAMX package names and versions. +# Returns: 0 when at least one CAMX package is installed, 1 otherwise. +# Side effects: queries the available package manager without modifying state. camx_opkg_list_camx() { out="" if command -v opkg >/dev/null 2>&1; then out="$(opkg list-installed 2>/dev/null | grep -i '^camx' || true)" - [ -n "$out" ] || return 1 - printf '%s\n' "$out" - return 0 + if [ -n "$out" ]; then + printf '%s\n' "$out" + return 0 + fi + fi + + if command -v dpkg-query >/dev/null 2>&1; then + out="$( + dpkg-query -W \ + -f='${binary:Package}\t${Status}\t${Version}\n' \ + 2>/dev/null \ + | awk ' + $2 == "install" && $3 == "ok" && $4 == "installed" && + tolower($1) ~ /^camx/ { + print $1, $5 + } + ' + )" + if [ -n "$out" ]; then + printf '%s\n' "$out" + return 0 + fi fi if command -v dnf >/dev/null 2>&1; then out="$(dnf list installed 2>/dev/null | grep -i '^camx' || true)" - [ -n "$out" ] || return 1 - printf '%s\n' "$out" - return 0 + if [ -n "$out" ]; then + printf '%s\n' "$out" + return 0 + fi fi if command -v rpm >/dev/null 2>&1; then out="$(rpm -qa 2>/dev/null | grep -i '^camx' || true)" - [ -n "$out" ] || return 1 - printf '%s\n' "$out" - return 0 + if [ -n "$out" ]; then + printf '%s\n' "$out" + return 0 + fi fi return 1 @@ -634,7 +660,7 @@ nhx_resolve_json_file() { return 1 } -# Stage resolved NHX JSON into the path expected by /usr/bin/nhx.sh. +# Stage resolved NHX JSON into the path expected by the NHX launcher. # nhx.sh expects an argument without ".json" and internally looks under: # /etc/camera/test/NHX/${JSON_FILE}.json # @@ -851,8 +877,11 @@ run_cmd_live_to_log() { } # ----------------------------------------------------------------------------- -# Pick board-specific camera module from DT compatible/model -# ----------------------------------------------------------------------------- +# Select the board-specific camera module from root DT compatible and model data. +# Arguments: none. +# Stdout: selected module name on success, otherwise no output. +# Returns: 0 when a supported board is identified, 1 otherwise. +# Side effects: reads the runtime device tree. camx_pick_camera_module() { compat_list="" model_str="" @@ -879,6 +908,10 @@ $model_str" in printf '%s\n' "camera_qcs615" return 0 ;; + *glymur*|*x1e80100*) + printf '%s\n' "camera_x1e80100" + return 0 + ;; esac return 1