xref: /openbmc/openpower-pnor-code-mgmt/mmc/obmc-flash-bios (revision 4e82bc847fcda9cd09ce3e0e31256fdeca8239d8)
1#!/bin/sh
2
3mmc_init() {
4  base_dir="/media/hostfw"
5  ro_dir="${base_dir}/running-ro"
6  running_dir="${base_dir}/running"
7  prsv_dir="${base_dir}/prsv"
8  staging_dir="${base_dir}/staging"
9
10  if [ ! -d "${ro_dir}" ]; then
11    mkdir -p "${ro_dir}"
12  fi
13  if [ ! -d "${running_dir}" ]; then
14    mkdir -p ${running_dir}
15  fi
16  if [ ! -d "${prsv_dir}" ]; then
17    mkdir -p "${prsv_dir}"
18  fi
19  if [ ! -d "${staging_dir}" ]; then
20    mkdir -p "${staging_dir}"
21  fi
22
23  # Mount the image that corresponds to the boot label as read-only to be used
24  # to populate the running directory.
25  boot_label="$(fw_printenv -n bootside)"
26  if ! grep -q "${ro_dir}" /proc/mounts; then
27    mount ${base_dir}/hostfw-"${boot_label}" ${ro_dir} -o ro
28  fi
29
30  # Determine if the running dir contains the running version
31  running_label=""
32  running_label_file="${running_dir}/partlabel"
33  if [ -f "${running_label_file}" ]; then
34    running_label=$(cat ${running_label_file})
35  fi
36  if [ "${running_label}" != "${boot_label}" ]; then
37    # Copy off the preserved partitions
38    # A line in the pnor.toc (81e00994.lid) looks like this:
39    # partition05=SECBOOT,0x00381000,0x003a5000,00,ECC,PRESERVED
40    rm -f ${prsv_dir}/*
41    if [ -f "${ro_dir}/81e00994.lid" ]; then
42      prsvs=$(grep PRESERVED "${ro_dir}/81e00994.lid")
43      for prsv in ${prsvs}; do
44        prsv=${prsv##partition*=}
45        prsv=$(echo "${prsv}" | cut -d "," -f 1)
46        if [ -L "${running_dir}/${prsv}" ]; then
47          # Preserve the symlink target file
48          prsv="$(readlink "${running_dir}/${prsv}")"
49          cp -p ${running_dir}/"${prsv}" ${prsv_dir}
50        fi
51      done
52    fi
53
54    # Copy lid contents of running image to running dir
55    rm -f ${running_dir}/*
56    cp -p ${ro_dir}/*.lid ${running_dir}/
57
58    # Restore the preserved partitions. Ignore error, there may be none.
59    cp -p ${prsv_dir}/* ${running_dir}/ 2>/dev/null || true
60    rm -f "${prsv_dir:?}/"*
61
62    # Clean up the staging dir in case of a failed update
63    rm -rf "${staging_dir:?}/"*
64
65    # Save the label
66    echo "${boot_label}" > "${running_label_file}"
67
68  fi
69
70  # Mount alternate dir
71  if [ "${boot_label}" = "a" ]; then
72    alternate_label="b"
73  else
74    alternate_label="a"
75  fi
76  alternate_dir="${base_dir}/alternate"
77  if [ ! -d "${alternate_dir}" ]; then
78    mkdir -p ${alternate_dir}
79  fi
80  if ! grep -q "${alternate_dir}" /proc/mounts; then
81    mount ${base_dir}/hostfw-${alternate_label} ${alternate_dir} -o ro
82  fi
83}
84
85mmc_patch() {
86  # Patching is disabled if field mode is set
87  if [ "$(fw_printenv fieldmode 2>/dev/null)" = "fieldmode=true" ]; then
88    return 0
89  fi
90
91  boot_label="$(fw_printenv -n bootside)"
92  if [ "${boot_label}" = "a" ]; then
93    alternate_label="b"
94  else
95    alternate_label="a"
96  fi
97
98  # Create patch directories
99  patch_dir="/media/hostfw/patch-"
100  running_patch_dir="${patch_dir}${boot_label}"
101  if [ ! -d "${running_patch_dir}" ]; then
102    mkdir -p "${running_patch_dir}"
103  fi
104  alternate_patch_dir="${patch_dir}${alternate_label}"
105  if [ ! -d "${alternate_patch_dir}" ]; then
106    mkdir -p "${alternate_patch_dir}"
107  fi
108
109  # Create patch symlinks
110  symlink_base="/usr/local/share"
111  if [ ! -d "${symlink_base}" ]; then
112    mkdir -p "${symlink_base}"
113  fi
114  hostfw_symlink_base="${symlink_base}/hostfw"
115  if [ ! -d "${hostfw_symlink_base}" ]; then
116    mkdir -p "${hostfw_symlink_base}"
117  fi
118
119  if [ "$(readlink -f "${symlink_base}/pnor")" != "${running_patch_dir}" ]; then
120    ln -s "${running_patch_dir}" "${symlink_base}/pnor"
121  fi
122  if [ "$(readlink -f "${hostfw_symlink_base}/running")" != "${running_patch_dir}" ]; then
123    ln -s "${running_patch_dir}" "${hostfw_symlink_base}/running"
124  fi
125  if [ "$(readlink -f "${hostfw_symlink_base}/alternate")" != "${alternate_patch_dir}" ]; then
126    ln -s "${alternate_patch_dir}" "${hostfw_symlink_base}/alternate"
127  fi
128}
129
130case "$1" in
131  mmc-init)
132    mmc_init
133    ;;
134  mmc-patch)
135    mmc_patch
136    ;;
137  *)
138    echo "Invalid argument"
139    exit 1
140    ;;
141esac
142