xref: /openbmc/openpower-pnor-code-mgmt/mmc/obmc-flash-bios (revision b9d864914c78667e83dc5e27ac7f8ee94c54be8b)
1e8606daaSAdriana Kobylak#!/bin/sh
2e8606daaSAdriana Kobylak
3514a094eSIsaac Kurthbios_reset_if_needed() {
4514a094eSIsaac Kurth    resetval=$(fw_printenv -n rwreset 2>/dev/nell)
5514a094eSIsaac Kurth    if [ "$resetval" = "0" ] || [ "$resetval" = "1" ]; then
6514a094eSIsaac Kurth        varstore="/media/hostfw/reset-gpio-val"
7514a094eSIsaac Kurth        if [ -f "$varstore" ]; then
8514a094eSIsaac Kurth            if [ "$resetval" != "$(cat $varstore)" ]; then
9514a094eSIsaac Kurth                if busctl call org.open_power.Software.Host.Updater /xyz/openbmc_project/software xyz.openbmc_project.Common.FactoryReset Reset; then
10514a094eSIsaac Kurth                    echo "$resetval" > "$varstore"
11514a094eSIsaac Kurth                fi
12514a094eSIsaac Kurth            fi
13514a094eSIsaac Kurth        else
14514a094eSIsaac Kurth            echo "$resetval" > "$varstore"
15514a094eSIsaac Kurth        fi
16514a094eSIsaac Kurth    fi
17514a094eSIsaac Kurth}
18514a094eSIsaac Kurth
19*b9d86491SBryon Catlinmmc_get_primary_label() {
20*b9d86491SBryon Catlin    # Get root device /dev/mmcblkpX
21*b9d86491SBryon Catlin    rootmatch=" on / "
22*b9d86491SBryon Catlin    root="$(mount | grep "${rootmatch}")"
23*b9d86491SBryon Catlin    # shellcheck disable=SC2295
24*b9d86491SBryon Catlin    root="${root%${rootmatch}*}"
25*b9d86491SBryon Catlin
26*b9d86491SBryon Catlin    # Find the device label
27*b9d86491SBryon Catlin    if [ "$(readlink -f /dev/disk/by-partlabel/rofs-a)" = "${root}" ]; then
28*b9d86491SBryon Catlin        echo "a"
29*b9d86491SBryon Catlin    elif [ "$(readlink -f /dev/disk/by-partlabel/rofs-b)" = "${root}" ]; then
30*b9d86491SBryon Catlin        echo "b"
31*b9d86491SBryon Catlin    else
32*b9d86491SBryon Catlin        echo ""
33*b9d86491SBryon Catlin    fi
34*b9d86491SBryon Catlin}
35*b9d86491SBryon Catlin
36e8606daaSAdriana Kobylakmmc_init() {
37e8606daaSAdriana Kobylak    base_dir="/media/hostfw"
3898f22326SAdriana Kobylak    ro_dir="${base_dir}/running-ro"
39e8606daaSAdriana Kobylak    running_dir="${base_dir}/running"
40e8606daaSAdriana Kobylak    prsv_dir="${base_dir}/prsv"
4187372ae1SAdriana Kobylak    staging_dir="${base_dir}/staging"
428652eb9bSAdriana Kobylak    nvram_dir="${base_dir}/nvram"
43e8606daaSAdriana Kobylak
4498f22326SAdriana Kobylak    if [ ! -d "${ro_dir}" ]; then
4598f22326SAdriana Kobylak        mkdir -p "${ro_dir}"
4698f22326SAdriana Kobylak    fi
47e8606daaSAdriana Kobylak    if [ ! -d "${running_dir}" ]; then
48e8606daaSAdriana Kobylak        mkdir -p ${running_dir}
49e8606daaSAdriana Kobylak    fi
50e8606daaSAdriana Kobylak    if [ ! -d "${prsv_dir}" ]; then
51e8606daaSAdriana Kobylak        mkdir -p "${prsv_dir}"
52e8606daaSAdriana Kobylak    fi
5387372ae1SAdriana Kobylak    if [ ! -d "${staging_dir}" ]; then
5487372ae1SAdriana Kobylak        mkdir -p "${staging_dir}"
5587372ae1SAdriana Kobylak    fi
568652eb9bSAdriana Kobylak    if [ ! -d "${nvram_dir}" ]; then
578652eb9bSAdriana Kobylak        mkdir -p "${nvram_dir}"
588652eb9bSAdriana Kobylak    fi
59e8606daaSAdriana Kobylak
6098f22326SAdriana Kobylak    # Mount the image that corresponds to the boot label as read-only to be used
6198f22326SAdriana Kobylak    # to populate the running directory.
62*b9d86491SBryon Catlin    boot_label="$(mmc_get_primary_label)"
630ddd4fadSIsaac Kurth    if ! grep -q "${ro_dir}" /proc/mounts; then
64f6d4d76bSAdriana Kobylak        mount ${base_dir}/hostfw-"${boot_label}" ${ro_dir} -o ro
650ddd4fadSIsaac Kurth    fi
6698f22326SAdriana Kobylak
6798f22326SAdriana Kobylak    # Determine if the running dir contains the running version
68e8606daaSAdriana Kobylak    running_label=""
69e8606daaSAdriana Kobylak    running_label_file="${running_dir}/partlabel"
70e8606daaSAdriana Kobylak    if [ -f "${running_label_file}" ]; then
71e8606daaSAdriana Kobylak        running_label=$(cat ${running_label_file})
72e8606daaSAdriana Kobylak    fi
73e8606daaSAdriana Kobylak    if [ "${running_label}" != "${boot_label}" ]; then
74e8606daaSAdriana Kobylak        # Copy off the preserved partitions
754e82bc84SAdriana Kobylak        # A line in the pnor.toc (81e00994.lid) looks like this:
76e8606daaSAdriana Kobylak        # partition05=SECBOOT,0x00381000,0x003a5000,00,ECC,PRESERVED
77e8606daaSAdriana Kobylak        rm -f ${prsv_dir}/*
784e82bc84SAdriana Kobylak        if [ -f "${ro_dir}/81e00994.lid" ]; then
794e82bc84SAdriana Kobylak            prsvs=$(grep PRESERVED "${ro_dir}/81e00994.lid")
80e8606daaSAdriana Kobylak            for prsv in ${prsvs}; do
81e8606daaSAdriana Kobylak                prsv=${prsv##partition*=}
82f6d4d76bSAdriana Kobylak                prsv=$(echo "${prsv}" | cut -d "," -f 1)
83ff675db0SAdriana Kobylak                if [ -L "${running_dir}/${prsv}" ]; then
84ff675db0SAdriana Kobylak                    # Preserve the symlink target file
85ff675db0SAdriana Kobylak                    prsv="$(readlink "${running_dir}/${prsv}")"
86d38d3649Szamiseck                    if [ -f "${running_dir}/${prsv}" ] && [ -f "${ro_dir}/${prsv}" ]; then
871e01078eSzamiseck                        runsize="$(stat -c '%s' "${running_dir}/${prsv}")"
881e01078eSzamiseck                        rosize="$(stat -c '%s' "${ro_dir}/${prsv}")"
891e01078eSzamiseck                        if [ "$runsize" != "$rosize" ]; then
901e01078eSzamiseck                            # Partition size may have changed or became corrupted
911e01078eSzamiseck                            # So it will not be copied to the preserved directory
921e01078eSzamiseck                            # Log PEL to indicate such
931e01078eSzamiseck                            busctl call xyz.openbmc_project.Logging \
941e01078eSzamiseck                                /xyz/openbmc_project/logging \
951e01078eSzamiseck                                xyz.openbmc_project.Logging.Create Create "ssa{ss}" \
961e01078eSzamiseck                                xyz.openbmc_project.Software.Version.Error.HostFile \
971e01078eSzamiseck                                xyz.openbmc_project.Logging.Entry.Level.Error 3 "FILE_NAME" \
981e01078eSzamiseck                                "${prsv}" "CURRENT_FILE_SIZE" "${runsize}" "EXPECTED_FILE_SIZE" \
991e01078eSzamiseck                                "${rosize}"
1001e01078eSzamiseck                            # Initiate dump
1011e01078eSzamiseck                            busctl call xyz.openbmc_project.Dump.Manager \
1021e01078eSzamiseck                                /xyz/openbmc_project/dump/bmc xyz.openbmc_project.Dump.Create \
1031e01078eSzamiseck                                CreateDump "a{sv}" 0
1041e01078eSzamiseck                        else
105f6d4d76bSAdriana Kobylak                            cp -p ${running_dir}/"${prsv}" ${prsv_dir}
106ff675db0SAdriana Kobylak                        fi
1071e01078eSzamiseck                    fi
108d38d3649Szamiseck                fi
109e8606daaSAdriana Kobylak            done
110e8606daaSAdriana Kobylak        fi
111e8606daaSAdriana Kobylak
112ff675db0SAdriana Kobylak        # Copy lid contents of running image to running dir
113e8606daaSAdriana Kobylak        rm -f ${running_dir}/*
114ff675db0SAdriana Kobylak        cp -p ${ro_dir}/*.lid ${running_dir}/
115e8606daaSAdriana Kobylak
11698f22326SAdriana Kobylak        # Restore the preserved partitions. Ignore error, there may be none.
11798f22326SAdriana Kobylak        cp -p ${prsv_dir}/* ${running_dir}/ 2>/dev/null || true
118f6d4d76bSAdriana Kobylak        rm -f "${prsv_dir:?}/"*
119e8606daaSAdriana Kobylak
12087372ae1SAdriana Kobylak        # Clean up the staging dir in case of a failed update
121f6d4d76bSAdriana Kobylak        rm -rf "${staging_dir:?}/"*
12287372ae1SAdriana Kobylak
123e8606daaSAdriana Kobylak        # Save the label
124e8606daaSAdriana Kobylak        echo "${boot_label}" > "${running_label_file}"
125e8606daaSAdriana Kobylak
126e8606daaSAdriana Kobylak    fi
127e8606daaSAdriana Kobylak
128e8606daaSAdriana Kobylak    # Mount alternate dir
129e8606daaSAdriana Kobylak    if [ "${boot_label}" = "a" ]; then
130e8606daaSAdriana Kobylak        alternate_label="b"
131e8606daaSAdriana Kobylak    else
132e8606daaSAdriana Kobylak        alternate_label="a"
133e8606daaSAdriana Kobylak    fi
134e8606daaSAdriana Kobylak    alternate_dir="${base_dir}/alternate"
135e8606daaSAdriana Kobylak    if [ ! -d "${alternate_dir}" ]; then
136e8606daaSAdriana Kobylak        mkdir -p ${alternate_dir}
137e8606daaSAdriana Kobylak    fi
1380ddd4fadSIsaac Kurth    if ! grep -q "${alternate_dir}" /proc/mounts; then
139e8606daaSAdriana Kobylak        mount ${base_dir}/hostfw-${alternate_label} ${alternate_dir} -o ro
1400ddd4fadSIsaac Kurth    fi
141e8606daaSAdriana Kobylak}
142e8606daaSAdriana Kobylak
143e8606daaSAdriana Kobylakmmc_patch() {
144e8606daaSAdriana Kobylak    # Patching is disabled if field mode is set
145f6d4d76bSAdriana Kobylak    if [ "$(fw_printenv fieldmode 2>/dev/null)" = "fieldmode=true" ]; then
146e8606daaSAdriana Kobylak        return 0
147e8606daaSAdriana Kobylak    fi
148e8606daaSAdriana Kobylak
149*b9d86491SBryon Catlin    boot_label="$(mmc_get_primary_label)"
150f6608a82SAdriana Kobylak    if [ "${boot_label}" = "a" ]; then
151f6608a82SAdriana Kobylak        alternate_label="b"
152f6608a82SAdriana Kobylak    else
153f6608a82SAdriana Kobylak        alternate_label="a"
154e8606daaSAdriana Kobylak    fi
155e8606daaSAdriana Kobylak
156f6608a82SAdriana Kobylak    # Create patch directories
157f6608a82SAdriana Kobylak    patch_dir="/media/hostfw/patch-"
158f6608a82SAdriana Kobylak    running_patch_dir="${patch_dir}${boot_label}"
159f6608a82SAdriana Kobylak    if [ ! -d "${running_patch_dir}" ]; then
160f6608a82SAdriana Kobylak        mkdir -p "${running_patch_dir}"
161f6608a82SAdriana Kobylak    fi
162f6608a82SAdriana Kobylak    alternate_patch_dir="${patch_dir}${alternate_label}"
163f6608a82SAdriana Kobylak    if [ ! -d "${alternate_patch_dir}" ]; then
164f6608a82SAdriana Kobylak        mkdir -p "${alternate_patch_dir}"
165e8606daaSAdriana Kobylak    fi
166e8606daaSAdriana Kobylak
167f6608a82SAdriana Kobylak    # Create patch symlinks
168f6608a82SAdriana Kobylak    symlink_base="/usr/local/share"
169f6608a82SAdriana Kobylak    if [ ! -d "${symlink_base}" ]; then
170f6608a82SAdriana Kobylak        mkdir -p "${symlink_base}"
171f6608a82SAdriana Kobylak    fi
172f6608a82SAdriana Kobylak    hostfw_symlink_base="${symlink_base}/hostfw"
173f6608a82SAdriana Kobylak    if [ ! -d "${hostfw_symlink_base}" ]; then
174f6608a82SAdriana Kobylak        mkdir -p "${hostfw_symlink_base}"
175f6608a82SAdriana Kobylak    fi
176f6608a82SAdriana Kobylak
1770ddd4fadSIsaac Kurth    if [ "$(readlink -f "${symlink_base}/pnor")" != "${running_patch_dir}" ]; then
178f6608a82SAdriana Kobylak        ln -s "${running_patch_dir}" "${symlink_base}/pnor"
1790ddd4fadSIsaac Kurth    fi
1800ddd4fadSIsaac Kurth    if [ "$(readlink -f "${hostfw_symlink_base}/running")" != "${running_patch_dir}" ]; then
181f6608a82SAdriana Kobylak        ln -s "${running_patch_dir}" "${hostfw_symlink_base}/running"
1820ddd4fadSIsaac Kurth    fi
1830ddd4fadSIsaac Kurth    if [ "$(readlink -f "${hostfw_symlink_base}/alternate")" != "${alternate_patch_dir}" ]; then
184f6608a82SAdriana Kobylak        ln -s "${alternate_patch_dir}" "${hostfw_symlink_base}/alternate"
1850ddd4fadSIsaac Kurth    fi
186e8606daaSAdriana Kobylak}
187e8606daaSAdriana Kobylak
188e8606daaSAdriana Kobylakcase "$1" in
189514a094eSIsaac Kurth    bios-reset-if-needed)
190514a094eSIsaac Kurth        bios_reset_if_needed
191514a094eSIsaac Kurth        ;;
192e8606daaSAdriana Kobylak    mmc-init)
193e8606daaSAdriana Kobylak        mmc_init
194e8606daaSAdriana Kobylak        ;;
195e8606daaSAdriana Kobylak    mmc-patch)
196e8606daaSAdriana Kobylak        mmc_patch
197e8606daaSAdriana Kobylak        ;;
198e8606daaSAdriana Kobylak    *)
199514a094eSIsaac Kurth        echo "Invalid argument: $1" >&2
200e8606daaSAdriana Kobylak        exit 1
201e8606daaSAdriana Kobylak        ;;
202e8606daaSAdriana Kobylakesac
203