xref: /openbmc/openpower-pnor-code-mgmt/mmc/obmc-flash-bios (revision 1e01078ee7d37aa01db48687433704e73c34b68c)
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*1e01078eSzamiseck          runsize="$(stat -c '%s' "${running_dir}/${prsv}")"
70*1e01078eSzamiseck          rosize="$(stat -c '%s' "${ro_dir}/${prsv}")"
71*1e01078eSzamiseck          if [ "$runsize" != "$rosize" ]; then
72*1e01078eSzamiseck              # Partition size may have changed or became corrupted
73*1e01078eSzamiseck              # So it will not be copied to the preserved directory
74*1e01078eSzamiseck              # Log PEL to indicate such
75*1e01078eSzamiseck              busctl call xyz.openbmc_project.Logging \
76*1e01078eSzamiseck              /xyz/openbmc_project/logging \
77*1e01078eSzamiseck              xyz.openbmc_project.Logging.Create Create "ssa{ss}" \
78*1e01078eSzamiseck              xyz.openbmc_project.Software.Version.Error.HostFile \
79*1e01078eSzamiseck              xyz.openbmc_project.Logging.Entry.Level.Error 3 "FILE_NAME" \
80*1e01078eSzamiseck              "${prsv}" "CURRENT_FILE_SIZE" "${runsize}" "EXPECTED_FILE_SIZE" \
81*1e01078eSzamiseck              "${rosize}"
82*1e01078eSzamiseck              # Initiate dump
83*1e01078eSzamiseck              busctl call xyz.openbmc_project.Dump.Manager \
84*1e01078eSzamiseck              /xyz/openbmc_project/dump/bmc xyz.openbmc_project.Dump.Create \
85*1e01078eSzamiseck              CreateDump "a{sv}" 0
86*1e01078eSzamiseck          else
87f6d4d76bSAdriana Kobylak              cp -p ${running_dir}/"${prsv}" ${prsv_dir}
88ff675db0SAdriana Kobylak          fi
89*1e01078eSzamiseck        fi
90e8606daaSAdriana Kobylak      done
91e8606daaSAdriana Kobylak    fi
92e8606daaSAdriana Kobylak
93ff675db0SAdriana Kobylak    # Copy lid contents of running image to running dir
94e8606daaSAdriana Kobylak    rm -f ${running_dir}/*
95ff675db0SAdriana Kobylak    cp -p ${ro_dir}/*.lid ${running_dir}/
96e8606daaSAdriana Kobylak
9798f22326SAdriana Kobylak    # Restore the preserved partitions. Ignore error, there may be none.
9898f22326SAdriana Kobylak    cp -p ${prsv_dir}/* ${running_dir}/ 2>/dev/null || true
99f6d4d76bSAdriana Kobylak    rm -f "${prsv_dir:?}/"*
100e8606daaSAdriana Kobylak
10187372ae1SAdriana Kobylak    # Clean up the staging dir in case of a failed update
102f6d4d76bSAdriana Kobylak    rm -rf "${staging_dir:?}/"*
10387372ae1SAdriana Kobylak
104e8606daaSAdriana Kobylak    # Save the label
105e8606daaSAdriana Kobylak    echo "${boot_label}" > "${running_label_file}"
106e8606daaSAdriana Kobylak
107e8606daaSAdriana Kobylak  fi
108e8606daaSAdriana Kobylak
109e8606daaSAdriana Kobylak  # Mount alternate dir
110e8606daaSAdriana Kobylak  if [ "${boot_label}" = "a" ]; then
111e8606daaSAdriana Kobylak    alternate_label="b"
112e8606daaSAdriana Kobylak  else
113e8606daaSAdriana Kobylak    alternate_label="a"
114e8606daaSAdriana Kobylak  fi
115e8606daaSAdriana Kobylak  alternate_dir="${base_dir}/alternate"
116e8606daaSAdriana Kobylak  if [ ! -d "${alternate_dir}" ]; then
117e8606daaSAdriana Kobylak    mkdir -p ${alternate_dir}
118e8606daaSAdriana Kobylak  fi
1190ddd4fadSIsaac Kurth  if ! grep -q "${alternate_dir}" /proc/mounts; then
120e8606daaSAdriana Kobylak    mount ${base_dir}/hostfw-${alternate_label} ${alternate_dir} -o ro
1210ddd4fadSIsaac Kurth  fi
122e8606daaSAdriana Kobylak}
123e8606daaSAdriana Kobylak
124e8606daaSAdriana Kobylakmmc_patch() {
125e8606daaSAdriana Kobylak  # Patching is disabled if field mode is set
126f6d4d76bSAdriana Kobylak  if [ "$(fw_printenv fieldmode 2>/dev/null)" = "fieldmode=true" ]; then
127e8606daaSAdriana Kobylak    return 0
128e8606daaSAdriana Kobylak  fi
129e8606daaSAdriana Kobylak
130f6608a82SAdriana Kobylak  boot_label="$(fw_printenv -n bootside)"
131f6608a82SAdriana Kobylak  if [ "${boot_label}" = "a" ]; then
132f6608a82SAdriana Kobylak    alternate_label="b"
133f6608a82SAdriana Kobylak  else
134f6608a82SAdriana Kobylak    alternate_label="a"
135e8606daaSAdriana Kobylak  fi
136e8606daaSAdriana Kobylak
137f6608a82SAdriana Kobylak  # Create patch directories
138f6608a82SAdriana Kobylak  patch_dir="/media/hostfw/patch-"
139f6608a82SAdriana Kobylak  running_patch_dir="${patch_dir}${boot_label}"
140f6608a82SAdriana Kobylak  if [ ! -d "${running_patch_dir}" ]; then
141f6608a82SAdriana Kobylak    mkdir -p "${running_patch_dir}"
142f6608a82SAdriana Kobylak  fi
143f6608a82SAdriana Kobylak  alternate_patch_dir="${patch_dir}${alternate_label}"
144f6608a82SAdriana Kobylak  if [ ! -d "${alternate_patch_dir}" ]; then
145f6608a82SAdriana Kobylak    mkdir -p "${alternate_patch_dir}"
146e8606daaSAdriana Kobylak  fi
147e8606daaSAdriana Kobylak
148f6608a82SAdriana Kobylak  # Create patch symlinks
149f6608a82SAdriana Kobylak  symlink_base="/usr/local/share"
150f6608a82SAdriana Kobylak  if [ ! -d "${symlink_base}" ]; then
151f6608a82SAdriana Kobylak    mkdir -p "${symlink_base}"
152f6608a82SAdriana Kobylak  fi
153f6608a82SAdriana Kobylak  hostfw_symlink_base="${symlink_base}/hostfw"
154f6608a82SAdriana Kobylak  if [ ! -d "${hostfw_symlink_base}" ]; then
155f6608a82SAdriana Kobylak    mkdir -p "${hostfw_symlink_base}"
156f6608a82SAdriana Kobylak  fi
157f6608a82SAdriana Kobylak
1580ddd4fadSIsaac Kurth  if [ "$(readlink -f "${symlink_base}/pnor")" != "${running_patch_dir}" ]; then
159f6608a82SAdriana Kobylak    ln -s "${running_patch_dir}" "${symlink_base}/pnor"
1600ddd4fadSIsaac Kurth  fi
1610ddd4fadSIsaac Kurth  if [ "$(readlink -f "${hostfw_symlink_base}/running")" != "${running_patch_dir}" ]; then
162f6608a82SAdriana Kobylak    ln -s "${running_patch_dir}" "${hostfw_symlink_base}/running"
1630ddd4fadSIsaac Kurth  fi
1640ddd4fadSIsaac Kurth  if [ "$(readlink -f "${hostfw_symlink_base}/alternate")" != "${alternate_patch_dir}" ]; then
165f6608a82SAdriana Kobylak    ln -s "${alternate_patch_dir}" "${hostfw_symlink_base}/alternate"
1660ddd4fadSIsaac Kurth  fi
167e8606daaSAdriana Kobylak}
168e8606daaSAdriana Kobylak
169e8606daaSAdriana Kobylakcase "$1" in
170514a094eSIsaac Kurth  bios-reset-if-needed)
171514a094eSIsaac Kurth    bios_reset_if_needed
172514a094eSIsaac Kurth    ;;
173e8606daaSAdriana Kobylak  mmc-init)
174e8606daaSAdriana Kobylak    mmc_init
175e8606daaSAdriana Kobylak    ;;
176e8606daaSAdriana Kobylak  mmc-patch)
177e8606daaSAdriana Kobylak    mmc_patch
178e8606daaSAdriana Kobylak    ;;
179e8606daaSAdriana Kobylak  *)
180514a094eSIsaac Kurth    echo "Invalid argument: $1" >&2
181e8606daaSAdriana Kobylak    exit 1
182e8606daaSAdriana Kobylak    ;;
183e8606daaSAdriana Kobylakesac
184