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
19e8606daaSAdriana Kobylakmmc_init() {
20e8606daaSAdriana Kobylak    base_dir="/media/hostfw"
2198f22326SAdriana Kobylak    ro_dir="${base_dir}/running-ro"
22e8606daaSAdriana Kobylak    running_dir="${base_dir}/running"
23e8606daaSAdriana Kobylak    prsv_dir="${base_dir}/prsv"
2487372ae1SAdriana Kobylak    staging_dir="${base_dir}/staging"
258652eb9bSAdriana Kobylak    nvram_dir="${base_dir}/nvram"
26e8606daaSAdriana Kobylak
2798f22326SAdriana Kobylak    if [ ! -d "${ro_dir}" ]; then
2898f22326SAdriana Kobylak        mkdir -p "${ro_dir}"
2998f22326SAdriana Kobylak    fi
30e8606daaSAdriana Kobylak    if [ ! -d "${running_dir}" ]; then
31e8606daaSAdriana Kobylak        mkdir -p ${running_dir}
32e8606daaSAdriana Kobylak    fi
33e8606daaSAdriana Kobylak    if [ ! -d "${prsv_dir}" ]; then
34e8606daaSAdriana Kobylak        mkdir -p "${prsv_dir}"
35e8606daaSAdriana Kobylak    fi
3687372ae1SAdriana Kobylak    if [ ! -d "${staging_dir}" ]; then
3787372ae1SAdriana Kobylak        mkdir -p "${staging_dir}"
3887372ae1SAdriana Kobylak    fi
398652eb9bSAdriana Kobylak    if [ ! -d "${nvram_dir}" ]; then
408652eb9bSAdriana Kobylak        mkdir -p "${nvram_dir}"
418652eb9bSAdriana Kobylak    fi
42e8606daaSAdriana Kobylak
4398f22326SAdriana Kobylak    # Mount the image that corresponds to the boot label as read-only to be used
4498f22326SAdriana Kobylak    # to populate the running directory.
45e8606daaSAdriana Kobylak    boot_label="$(fw_printenv -n bootside)"
460ddd4fadSIsaac Kurth    if ! grep -q "${ro_dir}" /proc/mounts; then
47f6d4d76bSAdriana Kobylak        mount ${base_dir}/hostfw-"${boot_label}" ${ro_dir} -o ro
480ddd4fadSIsaac Kurth    fi
4998f22326SAdriana Kobylak
5098f22326SAdriana Kobylak    # Determine if the running dir contains the running version
51e8606daaSAdriana Kobylak    running_label=""
52e8606daaSAdriana Kobylak    running_label_file="${running_dir}/partlabel"
53e8606daaSAdriana Kobylak    if [ -f "${running_label_file}" ]; then
54e8606daaSAdriana Kobylak        running_label=$(cat ${running_label_file})
55e8606daaSAdriana Kobylak    fi
56e8606daaSAdriana Kobylak    if [ "${running_label}" != "${boot_label}" ]; then
57e8606daaSAdriana Kobylak        # Copy off the preserved partitions
584e82bc84SAdriana Kobylak        # A line in the pnor.toc (81e00994.lid) looks like this:
59e8606daaSAdriana Kobylak        # partition05=SECBOOT,0x00381000,0x003a5000,00,ECC,PRESERVED
60e8606daaSAdriana Kobylak        rm -f ${prsv_dir}/*
614e82bc84SAdriana Kobylak        if [ -f "${ro_dir}/81e00994.lid" ]; then
624e82bc84SAdriana Kobylak            prsvs=$(grep PRESERVED "${ro_dir}/81e00994.lid")
63e8606daaSAdriana Kobylak            for prsv in ${prsvs}; do
64e8606daaSAdriana Kobylak                prsv=${prsv##partition*=}
65f6d4d76bSAdriana Kobylak                prsv=$(echo "${prsv}" | cut -d "," -f 1)
66ff675db0SAdriana Kobylak                if [ -L "${running_dir}/${prsv}" ]; then
67ff675db0SAdriana Kobylak                    # Preserve the symlink target file
68ff675db0SAdriana Kobylak                    prsv="$(readlink "${running_dir}/${prsv}")"
69*d38d3649Szamiseck                    if [ -f "${running_dir}/${prsv}" ] && [ -f "${ro_dir}/${prsv}" ]; then
701e01078eSzamiseck                        runsize="$(stat -c '%s' "${running_dir}/${prsv}")"
711e01078eSzamiseck                        rosize="$(stat -c '%s' "${ro_dir}/${prsv}")"
721e01078eSzamiseck                        if [ "$runsize" != "$rosize" ]; then
731e01078eSzamiseck                            # Partition size may have changed or became corrupted
741e01078eSzamiseck                            # So it will not be copied to the preserved directory
751e01078eSzamiseck                            # Log PEL to indicate such
761e01078eSzamiseck                            busctl call xyz.openbmc_project.Logging \
771e01078eSzamiseck                                /xyz/openbmc_project/logging \
781e01078eSzamiseck                                xyz.openbmc_project.Logging.Create Create "ssa{ss}" \
791e01078eSzamiseck                                xyz.openbmc_project.Software.Version.Error.HostFile \
801e01078eSzamiseck                                xyz.openbmc_project.Logging.Entry.Level.Error 3 "FILE_NAME" \
811e01078eSzamiseck                                "${prsv}" "CURRENT_FILE_SIZE" "${runsize}" "EXPECTED_FILE_SIZE" \
821e01078eSzamiseck                                "${rosize}"
831e01078eSzamiseck                            # Initiate dump
841e01078eSzamiseck                            busctl call xyz.openbmc_project.Dump.Manager \
851e01078eSzamiseck                                /xyz/openbmc_project/dump/bmc xyz.openbmc_project.Dump.Create \
861e01078eSzamiseck                                CreateDump "a{sv}" 0
871e01078eSzamiseck                        else
88f6d4d76bSAdriana Kobylak                            cp -p ${running_dir}/"${prsv}" ${prsv_dir}
89ff675db0SAdriana Kobylak                        fi
901e01078eSzamiseck                    fi
91*d38d3649Szamiseck                fi
92e8606daaSAdriana Kobylak            done
93e8606daaSAdriana Kobylak        fi
94e8606daaSAdriana Kobylak
95ff675db0SAdriana Kobylak        # Copy lid contents of running image to running dir
96e8606daaSAdriana Kobylak        rm -f ${running_dir}/*
97ff675db0SAdriana Kobylak        cp -p ${ro_dir}/*.lid ${running_dir}/
98e8606daaSAdriana Kobylak
9998f22326SAdriana Kobylak        # Restore the preserved partitions. Ignore error, there may be none.
10098f22326SAdriana Kobylak        cp -p ${prsv_dir}/* ${running_dir}/ 2>/dev/null || true
101f6d4d76bSAdriana Kobylak        rm -f "${prsv_dir:?}/"*
102e8606daaSAdriana Kobylak
10387372ae1SAdriana Kobylak        # Clean up the staging dir in case of a failed update
104f6d4d76bSAdriana Kobylak        rm -rf "${staging_dir:?}/"*
10587372ae1SAdriana Kobylak
106e8606daaSAdriana Kobylak        # Save the label
107e8606daaSAdriana Kobylak        echo "${boot_label}" > "${running_label_file}"
108e8606daaSAdriana Kobylak
109e8606daaSAdriana Kobylak    fi
110e8606daaSAdriana Kobylak
111e8606daaSAdriana Kobylak    # Mount alternate dir
112e8606daaSAdriana Kobylak    if [ "${boot_label}" = "a" ]; then
113e8606daaSAdriana Kobylak        alternate_label="b"
114e8606daaSAdriana Kobylak    else
115e8606daaSAdriana Kobylak        alternate_label="a"
116e8606daaSAdriana Kobylak    fi
117e8606daaSAdriana Kobylak    alternate_dir="${base_dir}/alternate"
118e8606daaSAdriana Kobylak    if [ ! -d "${alternate_dir}" ]; then
119e8606daaSAdriana Kobylak        mkdir -p ${alternate_dir}
120e8606daaSAdriana Kobylak    fi
1210ddd4fadSIsaac Kurth    if ! grep -q "${alternate_dir}" /proc/mounts; then
122e8606daaSAdriana Kobylak        mount ${base_dir}/hostfw-${alternate_label} ${alternate_dir} -o ro
1230ddd4fadSIsaac Kurth    fi
124e8606daaSAdriana Kobylak}
125e8606daaSAdriana Kobylak
126e8606daaSAdriana Kobylakmmc_patch() {
127e8606daaSAdriana Kobylak    # Patching is disabled if field mode is set
128f6d4d76bSAdriana Kobylak    if [ "$(fw_printenv fieldmode 2>/dev/null)" = "fieldmode=true" ]; then
129e8606daaSAdriana Kobylak        return 0
130e8606daaSAdriana Kobylak    fi
131e8606daaSAdriana Kobylak
132f6608a82SAdriana Kobylak    boot_label="$(fw_printenv -n bootside)"
133f6608a82SAdriana Kobylak    if [ "${boot_label}" = "a" ]; then
134f6608a82SAdriana Kobylak        alternate_label="b"
135f6608a82SAdriana Kobylak    else
136f6608a82SAdriana Kobylak        alternate_label="a"
137e8606daaSAdriana Kobylak    fi
138e8606daaSAdriana Kobylak
139f6608a82SAdriana Kobylak    # Create patch directories
140f6608a82SAdriana Kobylak    patch_dir="/media/hostfw/patch-"
141f6608a82SAdriana Kobylak    running_patch_dir="${patch_dir}${boot_label}"
142f6608a82SAdriana Kobylak    if [ ! -d "${running_patch_dir}" ]; then
143f6608a82SAdriana Kobylak        mkdir -p "${running_patch_dir}"
144f6608a82SAdriana Kobylak    fi
145f6608a82SAdriana Kobylak    alternate_patch_dir="${patch_dir}${alternate_label}"
146f6608a82SAdriana Kobylak    if [ ! -d "${alternate_patch_dir}" ]; then
147f6608a82SAdriana Kobylak        mkdir -p "${alternate_patch_dir}"
148e8606daaSAdriana Kobylak    fi
149e8606daaSAdriana Kobylak
150f6608a82SAdriana Kobylak    # Create patch symlinks
151f6608a82SAdriana Kobylak    symlink_base="/usr/local/share"
152f6608a82SAdriana Kobylak    if [ ! -d "${symlink_base}" ]; then
153f6608a82SAdriana Kobylak        mkdir -p "${symlink_base}"
154f6608a82SAdriana Kobylak    fi
155f6608a82SAdriana Kobylak    hostfw_symlink_base="${symlink_base}/hostfw"
156f6608a82SAdriana Kobylak    if [ ! -d "${hostfw_symlink_base}" ]; then
157f6608a82SAdriana Kobylak        mkdir -p "${hostfw_symlink_base}"
158f6608a82SAdriana Kobylak    fi
159f6608a82SAdriana Kobylak
1600ddd4fadSIsaac Kurth    if [ "$(readlink -f "${symlink_base}/pnor")" != "${running_patch_dir}" ]; then
161f6608a82SAdriana Kobylak        ln -s "${running_patch_dir}" "${symlink_base}/pnor"
1620ddd4fadSIsaac Kurth    fi
1630ddd4fadSIsaac Kurth    if [ "$(readlink -f "${hostfw_symlink_base}/running")" != "${running_patch_dir}" ]; then
164f6608a82SAdriana Kobylak        ln -s "${running_patch_dir}" "${hostfw_symlink_base}/running"
1650ddd4fadSIsaac Kurth    fi
1660ddd4fadSIsaac Kurth    if [ "$(readlink -f "${hostfw_symlink_base}/alternate")" != "${alternate_patch_dir}" ]; then
167f6608a82SAdriana Kobylak        ln -s "${alternate_patch_dir}" "${hostfw_symlink_base}/alternate"
1680ddd4fadSIsaac Kurth    fi
169e8606daaSAdriana Kobylak}
170e8606daaSAdriana Kobylak
171e8606daaSAdriana Kobylakcase "$1" in
172514a094eSIsaac Kurth    bios-reset-if-needed)
173514a094eSIsaac Kurth        bios_reset_if_needed
174514a094eSIsaac Kurth        ;;
175e8606daaSAdriana Kobylak    mmc-init)
176e8606daaSAdriana Kobylak        mmc_init
177e8606daaSAdriana Kobylak        ;;
178e8606daaSAdriana Kobylak    mmc-patch)
179e8606daaSAdriana Kobylak        mmc_patch
180e8606daaSAdriana Kobylak        ;;
181e8606daaSAdriana Kobylak    *)
182514a094eSIsaac Kurth        echo "Invalid argument: $1" >&2
183e8606daaSAdriana Kobylak        exit 1
184e8606daaSAdriana Kobylak        ;;
185e8606daaSAdriana Kobylakesac
186