diff --git a/coreboot-t440p/main.sh b/coreboot-t440p/main.sh index 2eb265d..36d8154 100755 --- a/coreboot-t440p/main.sh +++ b/coreboot-t440p/main.sh @@ -53,16 +53,9 @@ run_step() { return 0 fi - # Step failed - ask what to do + # Step failed — prompt retry-or-quit. + # handle_failure exits the whole script on "quit"; otherwise loop retries. handle_failure "$_step_name" - _decision=$? - - if [ $_decision -eq 0 ]; then - # Skip - warn "Skipping: $_step_name" - return 0 - fi - # Otherwise retry (loop continues) done } diff --git a/coreboot-t440p/steps/extract_bios.sh b/coreboot-t440p/steps/extract_bios.sh index 032571c..a287f67 100755 --- a/coreboot-t440p/steps/extract_bios.sh +++ b/coreboot-t440p/steps/extract_bios.sh @@ -17,66 +17,84 @@ _resolve_chip() { fi _log=$(mktemp) - printf " ${DIM}\$ sudo flashrom --programmer ch341a_spi${NC}\n" - sudo flashrom --programmer ch341a_spi >"$_log" 2>&1 - _st=$? - # Unambiguous success: one "Found ... chip \"NAME\"" line, exit 0. - if [ $_st -eq 0 ]; then - _chip=$(sed -nE 's/.*Found .* flash chip "([^"]+)".*/\1/p' "$_log" | head -1) - if [ -n "$_chip" ]; then - eval "$_var=\"\$_chip\"" - info "Detected chip: $_chip" + while true; do + printf " ${DIM}\$ sudo flashrom --programmer ch341a_spi${NC}\n" + sudo flashrom --programmer ch341a_spi >"$_log" 2>&1 + _st=$? + + # Unambiguous success: one "Found ... chip \"NAME\"" line, exit 0. + if [ $_st -eq 0 ]; then + _chip=$(sed -nE 's/.*Found .* flash chip "([^"]+)".*/\1/p' "$_log" | head -1) + if [ -n "$_chip" ]; then + eval "$_var=\"\$_chip\"" + info "Detected chip: $_chip" + rm -f "$_log" + return 0 + fi + fi + + # Ambiguous match: flashrom lists candidates but refuses to pick. + if grep -q "Multiple flash chip definitions match" "$_log"; then + _candidates=$(sed -nE 's/.*Found .* flash chip "([^"]+)".*/\1/p' "$_log") + _count=$(printf '%s\n' "$_candidates" | wc -l | tr -d ' ') + echo "" + warn "Flashrom read the chip but multiple variants match the same silicon ID." + info "This is normal for Winbond W25Q* parts. Pick one (the newest is safe):" + echo "" + _i=1 + for _c in $_candidates; do + if [ "$_i" = "$_count" ]; then + echo " $_i) $_c (default — newest)" + else + echo " $_i) $_c" + fi + _i=$((_i+1)) + done + echo "" + + _picked="" + while [ -z "$_picked" ]; do + printf "${CYAN}Choice [1-%s] (Enter = %s):${NC} " "$_count" "$_count" + read -r _sel + [ -z "$_sel" ] && _sel="$_count" + case "$_sel" in + ''|*[!0-9]*) echo "Enter a number."; continue ;; + esac + if [ "$_sel" -lt 1 ] || [ "$_sel" -gt "$_count" ]; then + echo "Out of range." + continue + fi + _picked=$(printf '%s\n' "$_candidates" | sed -n "${_sel}p") + done + eval "$_var=\"\$_picked\"" + info "Using chip definition: $_picked" rm -f "$_log" return 0 fi - fi - # Ambiguous match: flashrom lists candidates but refuses to pick. - if grep -q "Multiple flash chip definitions match" "$_log"; then - _candidates=$(sed -nE 's/.*Found .* flash chip "([^"]+)".*/\1/p' "$_log") - _count=$(printf '%s\n' "$_candidates" | wc -l | tr -d ' ') + # Hard failure — no chip detected. Show output and offer re-seat retry. echo "" - warn "Flashrom read the chip but multiple variants match the same silicon ID." - info "This is normal for Winbond W25Q* parts. Pick one (the newest is safe):" + error "Chip probe failed. flashrom output:" + sed 's/^/ /' "$_log" echo "" - _i=1 - for _c in $_candidates; do - if [ "$_i" = "$_count" ]; then - echo " $_i) $_c ${DIM}(default — newest)${NC}" - else - echo " $_i) $_c" - fi - _i=$((_i+1)) - done + warn "Most common causes:" + echo " - Clip not seated flush on chip (press down gently, wiggle)" + echo " - Pin 1 misaligned (red ribbon wire ↔ chip dot/notch)" + echo " - Clipped onto the wrong chip (try the other one, then switch back)" + echo " - Residual laptop power (remove main battery + CMOS coin cell)" + echo " - Cheap SOIC-8 clips can make intermittent contact" echo "" - - _picked="" - while [ -z "$_picked" ]; do - printf "${CYAN}Choice [1-%s] (Enter = %s):${NC} " "$_count" "$_count" - read -r _sel - [ -z "$_sel" ] && _sel="$_count" - case "$_sel" in - ''|*[!0-9]*) echo "Enter a number."; continue ;; - esac - if [ "$_sel" -lt 1 ] || [ "$_sel" -gt "$_count" ]; then - echo "Out of range." - continue - fi - _picked=$(printf '%s\n' "$_candidates" | sed -n "${_sel}p") - done - eval "$_var=\"\$_picked\"" - info "Using chip definition: $_picked" - rm -f "$_log" - return 0 - fi - - # Real failure (no chip, clip bad, etc.) — show the log and fail. - echo "" - error "Chip probe failed. flashrom output:" - sed 's/^/ /' "$_log" - rm -f "$_log" - return 1 + echo " 1) Re-seat clip and retry" + echo " 2) Abort" + echo "" + printf "${CYAN}Choice [1-2]:${NC} " + read -r _choice + case "$_choice" in + 1) continue ;; + *) rm -f "$_log"; return 1 ;; + esac + done } # Read a chip with inline retry on failure. diff --git a/coreboot-t440p/utils.sh b/coreboot-t440p/utils.sh index 142c221..590fa03 100755 --- a/coreboot-t440p/utils.sh +++ b/coreboot-t440p/utils.sh @@ -12,11 +12,11 @@ BOLD='\033[1m' DIM='\033[2m' NC='\033[0m' -# Logging -info() { printf "${BLUE}[*]${NC} %s\n" "$1"; } -warn() { printf "${YELLOW}[!]${NC} %s\n" "$1"; } -error() { printf "${RED}[x]${NC} %s\n" "$1"; } -success() { printf "${GREEN}[+]${NC} %s\n" "$1"; } +# Logging — %b interprets backslash escapes so inline ${BOLD}, ${DIM} etc. work. +info() { printf "${BLUE}[*]${NC} %b\n" "$1"; } +warn() { printf "${YELLOW}[!]${NC} %b\n" "$1"; } +error() { printf "${RED}[x]${NC} %b\n" "$1"; } +success() { printf "${GREEN}[+]${NC} %b\n" "$1"; } # Print a section header section() { @@ -188,20 +188,20 @@ show_image() { [ -n "$_caption" ] && info "$_caption" } -# Handle step failure - ask user how to proceed +# Handle step failure — retry or quit only. +# Skipping is deliberately not offered: most steps (extract/flash/revert) +# are irreversible or a skip will brick the board downstream. handle_failure() { echo "" error "Step failed: $1" echo "" echo " 1) Retry this step" - echo " 2) Skip and continue" - echo " 3) Quit" + echo " 2) Quit" echo "" - printf "${CYAN}Choice [1-3]:${NC} " + printf "${CYAN}Choice [1-2]:${NC} " read -r _choice case "$_choice" in - 1) return 1 ;; # Signal retry - 2) return 0 ;; # Signal skip + 1) return 1 ;; # Signal retry *) exit 1 ;; esac }