Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions Runner/plans/video_pre-merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,48 @@ run:
RPATH="$REPO_ROOT/suites/Multimedia/Video/Video_V4L2_Runner/run.sh"
RESFILE="$REPO_ROOT/suites/Multimedia/Video/Video_V4L2_Runner/Video_V4L2_Runner.res"

# Custom media bundle (local) paths
# Custom media bundle (local) path
CLIPS_TAR="/data/vendor/iris_test_app/video_clips_iris.tar.gz"
CLIPS_DEST="/data/vendor/iris_test_app/clips"

# Custom downstream module location (directory containing iris_vpu.ko)
KO_DIR="/data/vendor/iris_test_app"

# Optional: downstream firmware needed on Kodiak overlay
DS_FW="/data/vendor/iris_test_app/vpu20_p1_gen2.mbn"
DS_FW="/data/vendor/iris_test_app/vpu20_1v.mbn"

# Prefer explicit TARGET; otherwise derive from LAVA device-type
if [ -n "${TARGET:-}" ]; then
TL="$(printf '%s' "$TARGET" | tr '[:upper:]' '[:lower:]')"
else
DEVTYPE_RAW="${DEVICE_TYPE:-${LAVA_DEVICE_TYPE:-${LAVA_DEVICE_TYPE_NAME:-${DEVICE_TYPE_NAME:-}}}}"
DEVTYPE="$(printf '%s' "$DEVTYPE_RAW" | tr '[:upper:]' '[:lower:]')"
case "$DEVTYPE" in
# monaco
qcs8300-ride|qcs8300-ride-sx|iq-8275-evk) TL="monaco" ;;
# lemans
qcs9100-ride-r3|sa8775p-ride|iq-9075-evk|qcs9075-rb8|qcs9100-ride-sx) TL="lemans" ;;
# kodiak
qcs6490-rb3gen2|rb3gen2|qcs6490-rb3gen2-core-kit) TL="kodiak" ;;
# fallback to autodetect in run.sh
*) TL="" ;;
esac
fi

# Normalize/derive platform flag
TL="$(printf '%s' "${TARGET:-}" | tr '[:upper:]' '[:lower:]')"
case "$TL" in
kodiak|lemans|monaco) PLAT="--platform $TL" ;;
*) PLAT="" ;; # autodetect
esac

# Common args (clips local, no Wi-Fi or TAR_URL needed)
ARGS_COMMON="--clips-tar $CLIPS_TAR --clips-dest $CLIPS_DEST --app /data/vendor/iris_test_app/iris_v4l2_test $PLAT --retry-on-fail 2 --loglevel 15"
echo "DEBUG: TARGET='${TARGET:-}' DEVTYPE='${DEVTYPE:-}' -> TL='$TL' PLAT='$PLAT'"

# Common args (local clips; no Wi-Fi/TAR_URL needed)
ARGS_COMMON="--clips-tar $CLIPS_TAR --app /data/vendor/iris_test_app/iris_v4l2_test $PLAT --retry-on-fail 2 --loglevel 15"

# --- BASE (upstream): NO ko args here ---
ARGS_BASE="--stack base $ARGS_COMMON"

# --- OVERLAY (downstream): add ko args; on kodiak also add downstream FW ---
ARGS_OVERLAY="--stack overlay $ARGS_COMMON --ko-dir $KO_DIR --ko-prefer-custom"
# --- OVERLAY (downstream): add ko args; only add FW on kodiak ---
ARGS_OVERLAY="--stack overlay $ARGS_COMMON"
if [ "$TL" = "kodiak" ]; then
ARGS_OVERLAY="$ARGS_OVERLAY --downstream-fw $DS_FW"
fi
Expand Down
65 changes: 56 additions & 9 deletions Runner/suites/Multimedia/Video/Video_V4L2_Runner/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ export INTER_TEST_SLEEP
# --- EARLY dependency check (bail out fast) ---

# Ensure the app is executable if a path was provided but lacks +x
if [ -n "$VIDEO_APP" ] && [ -f "$VIDEO_APP" ] && [ ! -x "$VIDEO_APP" ]; then
chmod +x "$VIDEO_APP" 2>/dev/null || true
if [ ! -x "$VIDEO_APP" ]; then
log_warn "App $VIDEO_APP is not executable and chmod failed; attempting to run anyway."
fi
fi

# --- Optional: unpack a custom module tarball **once** (no env exports) ---
KVER="$(uname -r 2>/dev/null || printf '%s' unknown)"
Expand All @@ -308,16 +314,13 @@ if [ -n "$KO_TARBALL" ] && [ -f "$KO_TARBALL" ]; then
fi
;;
*)
# not a tar? treat as a directory if user passed one by mistake
:
;;
esac
fi
# decide whether the tar contained a full tree or loose .ko’s
if [ -d "$DEST/lib/modules/$KVER" ]; then
KO_TREE="$DEST"
else
# find first dir that has at least one .ko (bounded depth)
first_ko_dir="$(find "$DEST" -type f -name '*.ko*' -maxdepth 3 2>/dev/null | head -n1 | xargs -r dirname)"
if [ -n "$first_ko_dir" ]; then
if [ -n "$KO_DIRS" ]; then
Expand All @@ -327,7 +330,6 @@ if [ -n "$KO_TARBALL" ] && [ -f "$KO_TARBALL" ]; then
fi
fi
fi
# quiet summary (only if user opted-in)
log_info "Custom module source prepared (tree='${KO_TREE:-none}', dirs='${KO_DIRS:-none}', prefer_custom=$KO_PREFER_CUSTOM)"
fi

Expand Down Expand Up @@ -689,7 +691,7 @@ if [ "${VIDEO_STACK}" = "both" ]; then
overlay_reason="missing --downstream-fw"
fi

if [ "$rc_base" -eq 0 ] && [ "$rc_overlay" -eq 0 ]; then
if [ "$rc_base" -eq 0 ] && [ "$rc_overlay" -eq 0 ] ; then
if [ "$base_status" = "PASS" ] && [ "$overlay_status" = "SKIP" ]; then
if [ -n "$overlay_reason" ]; then
log_info "[both] upstream/base executed and PASS; downstream/overlay SKIP ($overlay_reason). Overall PASS."
Expand Down Expand Up @@ -720,7 +722,6 @@ if [ -n "$VIDEO_FW_DS" ]; then
log_info "Downstream FW override: $VIDEO_FW_DS"
fi
if [ -n "$KO_TREE$KO_DIRS$KO_TARBALL" ]; then
# print only when user actually provided custom sources
if [ -n "$KO_TREE" ]; then
log_info "Custom module tree (modprobe -d): $KO_TREE"
fi
Expand Down Expand Up @@ -776,6 +777,33 @@ fi
# --- Optional cleanup: robust capture + normalization of post-stack value ---
video_dump_stack_state "pre"

# --- Custom .ko staging (only if user provided --ko-dir) ---
if [ -n "${KO_DIRS:-}" ]; then
case "$(video_normalize_stack "$VIDEO_STACK")" in
downstream|overlay|down)
KVER="$(uname -r 2>/dev/null || printf '%s' unknown)"

if command -v video_find_module_file >/dev/null 2>&1; then
modpath="$(video_find_module_file iris_vpu "$KO_DIRS" 2>/dev/null | tail -n1 | tr -d '\r')"
else
modpath=""
fi

if [ -n "$modpath" ] && [ -f "$modpath" ]; then
log_info "Using custom iris_vpu candidate: $modpath"
if command -v video_ensure_moddir_install >/dev/null 2>&1; then
video_ensure_moddir_install "$modpath" "$KVER" >/dev/null 2>&1 || true
fi
if command -v depmod >/dev/null 2>&1; then
depmod -a "$KVER" >/dev/null 2>&1 || true
fi
else
log_warn "KO_DIRS set, but iris_vpu.ko not found under: $KO_DIRS"
fi
;;
esac
fi

video_step "" "Apply desired stack = $VIDEO_STACK"

stack_tmp="$LOG_DIR/.ensure_stack.$$.out"
Expand Down Expand Up @@ -804,6 +832,28 @@ log_info "Video stack (post): $post_stack"

video_dump_stack_state "post"

# --- Custom .ko load assist (only if user provided --ko-dir) ---
if [ -n "${KO_DIRS:-}" ]; then
case "$(video_normalize_stack "$VIDEO_STACK")" in
downstream|overlay|down)
if ! video_has_module_loaded iris_vpu 2>/dev/null; then
if command -v video_find_module_file >/dev/null 2>&1; then
modpath2="$(video_find_module_file iris_vpu "$KO_DIRS" 2>/dev/null | tail -n1 | tr -d '\r')"
else
modpath2=""
fi

if [ "$KO_PREFER_CUSTOM" = "1" ] && [ -n "$modpath2" ] && [ -f "$modpath2" ]; then
if command -v video_insmod_with_deps >/dev/null 2>&1; then
log_info "Prefer custom: insmod with deps: $modpath2"
video_insmod_with_deps "$modpath2" >/dev/null 2>&1 || true
fi
fi
fi
;;
esac
fi

# Always refresh/prune device nodes (even if no switch occurred)
video_step "" "Refresh V4L device nodes (udev trigger + prune stale)"
video_clean_and_refresh_v4l || true
Expand Down Expand Up @@ -1193,7 +1243,6 @@ while IFS= read -r cfg; do
r=1
log_info "[$id] RETRY_ON_FAIL: up to $RETRY_ON_FAIL additional attempt(s)"
while [ "$r" -le "$RETRY_ON_FAIL" ]; do
# optional delay between retries, reuse REPEAT_DELAY for consistency
if [ "$REPEAT_DELAY" -gt 0 ] 2>/dev/null; then
sleep "$REPEAT_DELAY"
fi
Expand All @@ -1205,7 +1254,6 @@ while IFS= read -r cfg; do
log_pass "[$id] RETRY succeeded — marking PASS"
break
else
# capture latest rc marker for visibility
rc_val="$(awk -F'=' '/^END-RUN rc=/{print $2}' "$logf" 2>/dev/null | tail -n1 | tr -d ' ')"
if [ -n "$rc_val" ]; then
case "$rc_val" in
Expand Down Expand Up @@ -1253,7 +1301,6 @@ while IFS= read -r cfg; do
fi
fi

# (6) Post-test settle sleep
case "$POST_TEST_SLEEP" in
''|*[!0-9]* )
:
Expand Down
123 changes: 105 additions & 18 deletions Runner/utils/lib_video.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,58 +105,144 @@ video_log_fw_hint() {
fi
}

# -----------------------------------------------------------------------------
# Shared module introspection helpers (kept; used by dump)
# -----------------------------------------------------------------------------
# Install a module file into /lib/modules/$(uname -r)/updates and run depmod.
# Usage: video_ensure_moddir_install <module_path> <logical_name>
video_ensure_moddir_install() {
mp="$1" # source path to .ko
mname="$2" # logical module name for logging
kr="$(uname -r 2>/dev/null)"
[ -z "$kr" ] && kr="$(find /lib/modules -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | head -n 1)"

if [ -z "$mp" ] || [ ! -f "$mp" ]; then
log_warn "install-ko: invalid module path: $mp"
return 1
fi

updates="/lib/modules/$kr/updates"
if [ ! -d "$updates" ]; then
if ! mkdir -p "$updates" 2>/dev/null; then
log_warn "install-ko: cannot create $updates (read-only FS?)"
return 1
fi
fi

base="$(basename "$mp")"
dst="$updates/$base"

do_copy=1
if [ -f "$dst" ]; then
if command -v md5sum >/dev/null 2>&1; then
src_md5="$(md5sum "$mp" 2>/dev/null | awk '{print $1}')"
dst_md5="$(md5sum "$dst" 2>/dev/null | awk '{print $1}')"
[ -n "$src_md5" ] && [ "$src_md5" = "$dst_md5" ] && do_copy=0
else
if cmp -s "$mp" "$dst" 2>/dev/null; then
do_copy=0
fi
fi
fi

if [ "$do_copy" -eq 1 ]; then
if ! cp -f "$mp" "$dst" 2>/dev/null; then
log_warn "install-ko: failed to copy $mp -> $dst"
return 1
fi
chmod 0644 "$dst" 2>/dev/null || true
sync 2>/dev/null || true
log_info "install-ko: copied $(basename "$mp") to $dst"
else
log_info "install-ko: up-to-date at $dst"
fi

if command -v depmod >/dev/null 2>&1; then
if depmod -a "$kr" >/dev/null 2>&1; then
log_info "install-ko: depmod -a $kr done"
else
log_warn "install-ko: depmod -a $kr failed (continuing)"
fi
else
log_warn "install-ko: depmod not found; modprobe may fail to resolve deps"
fi

[ -n "$mname" ] && video_log_resolve "$mname" updates-tree "$dst"
printf '%s\n' "$dst"
return 0
}

# Takes a logical module name (e.g. iris_vpu), resolves/copies into updates/, depmods, then loads deps+module.
video_insmod_with_deps() {
# Takes a logical module name (e.g. qcom_iris), resolves the path, then insmods deps+module
m="$1"
[ -z "$m" ] && { log_warn "insmod-with-deps: empty module name"; return 1; }

[ -z "$MODPROBE" ] && MODPROBE="modprobe"

if video_has_module_loaded "$m"; then
log_info "module already loaded (insmod path skipped): $m"
log_info "module already loaded (skip): $m"
return 0
fi

path="$(video_find_module_file "$m")" || path=""
if [ -z "$path" ] || [ ! -f "$path" ]; then
mp="$(video_find_module_file "$m")" || mp=""
if [ -z "$mp" ] || [ ! -f "$mp" ]; then
log_warn "insmod fallback: could not locate module file for $m"
return 1
fi
log_info "resolve: $m -> $mp"

case "$mp" in
/lib/modules/*) staged="$mp" ;;
*)
staged="$(video_ensure_moddir_install "$mp" "$m")" || staged=""
if [ -z "$staged" ]; then
log_warn "insmod-with-deps: staging into updates/ failed for $m"
return 1
fi
;;
esac

if "$MODPROBE" -q "$m" 2>/dev/null; then
video_log_load_success "$m" modprobe "$staged"
return 0
fi
log_warn "modprobe failed: $m (attempting direct insmod)"

deps=""
if video_exist_cmd modinfo; then
deps="$(modinfo -F depends "$path" 2>/dev/null | tr ',' ' ' | tr -s ' ')"
deps="$(modinfo -F depends "$staged" 2>/dev/null | tr ',' ' ' | tr -s ' ')"
fi

for d in $deps; do
if [ -z "$d" ]; then
continue
fi
[ -z "$d" ] && continue
if video_has_module_loaded "$d"; then
continue
fi
if ! "$MODPROBE" -q "$d" 2>/dev/null; then
dpath="$(video_find_module_file "$d")" || dpath=""
if [ -z "$dpath" ] || [ ! -f "$dpath" ]; then
kr="$(uname -r 2>/dev/null)"
[ -z "$kr" ] && kr="$(find /lib/modules -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | head -n 1)"
cand="/lib/modules/$kr/updates/${d}.ko"
[ -f "$cand" ] && dpath="$cand"
fi
if [ -n "$dpath" ] && [ -f "$dpath" ]; then
if insmod "$dpath" 2>/dev/null; then
video_log_load_success "$d" dep-insmod "$dpath"
else
log_warn "dep insmod failed for $dpath"
log_warn "dep insmod failed: $d ($dpath)"
fi
else
log_warn "dep resolve failed for $d"
log_warn "dep resolve failed: $d"
fi
else
video_log_load_success "$d" dep-modprobe
fi
done

if insmod "$path" 2>/dev/null; then
video_log_load_success "$m" insmod "$path"
if insmod "$staged" 2>/dev/null; then
video_log_load_success "$m" insmod "$staged"
return 0
fi

log_warn "insmod failed for $path"
log_warn "insmod failed for $staged"
return 1
}

Expand Down Expand Up @@ -256,12 +342,12 @@ video_log_load_success() {

video_find_module_file() {
# Resolve a module file path for a logical mod name (handles _ vs -).
# Prefers: modinfo -n, then .../updates/, then general search.
# Prefers: modinfo -n, then .../updates/, then general search (and KO_DIRS/KO_TREE if provided).
m="$1"
kr="$(uname -r 2>/dev/null)"

if [ -z "$kr" ]; then
kr="$(find /lib/modules -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | head -n1)"
kr="$(find /lib/modules -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | head -n 1)"
fi

if video_exist_cmd modinfo; then
Expand All @@ -287,6 +373,7 @@ video_find_module_file() {
IFS=':'
for d in $KO_DIRS; do
IFS="$OLD_IFS"
# SC2015 fix: avoid `[ -n "$d" ] && [ -d "$d" ] || continue`
if [ -z "$d" ] || [ ! -d "$d" ]; then
continue
fi
Expand Down
Loading