xref: /openbmc/openpower-pnor-code-mgmt/vpnor/obmc-vpnor-util (revision 837b09428d86a80fcae589b81c2fc7b00dd36484)
1#!/bin/bash
2
3function clear_volatile() {
4    service=$(mapper get-service /org/open_power/control/volatile)
5    clearVolatileEnabled=$(busctl get-property "$service" /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled)
6    if [[ "$clearVolatileEnabled" != "b true" ]]; then
7        return 0
8    fi
9
10    PNOR_TOC_FILE="pnor.toc"
11    PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro/"
12    PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw/"
13    PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv/"
14
15    # toc partition string format:
16    # partition27=HB_VOLATILE,0x02ba9000,0x02bae000,00,ECC,VOLATILE,READWRITE
17    tocFilePath="${PNOR_RO_ACTIVE_PATH}${PNOR_TOC_FILE}"
18    if [ ! -f "${tocFilePath}" ]; then
19        tocFilePath="${PNOR_RW_ACTIVE_PATH}${PNOR_TOC_FILE}"
20    fi
21    mapfile -t volatiles < <(grep VOLATILE "${tocFilePath}" | grep -Eo '^partition([0-9]+)=([A-Za-z0-9_]+)')
22    for (( index=0; index<${#volatiles[@]}; index++ )); do
23        volatileName="$(echo "${volatiles[${index}]}" | awk -F '=' '{print $2}')"
24
25        rwVolatile="${PNOR_RW_ACTIVE_PATH}${volatileName}"
26
27        if [ ! -f "${PNOR_RO_ACTIVE_PATH}${volatileName}" ]; then
28            echo "Clear ${volatileName} lid 81e0066f.lid"
29            cp -a "${PNOR_RO_ACTIVE_PATH}81e0066f.lid" "${PNOR_PRSV_ACTIVE_PATH}"
30        else
31            if [ -f "${rwVolatile}" ]; then
32                echo "Clear $rwVolatile"
33                rm "${rwVolatile}"
34            fi
35            prsvVolatile="${PNOR_PRSV_ACTIVE_PATH}${volatileName}"
36            if [ -f "${prsvVolatile}" ]; then
37                echo "Clear $prsvVolatile"
38                rm "${prsvVolatile}"
39            fi
40        fi
41    done
42    # Always reset the sensor after clearing
43    busctl set-property "$service" /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled b false
44}
45
46function update_symlinks() {
47    PNOR_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/"
48    HOSTFW_ACTIVE_PATH="/var/lib/phosphor-software-manager/hostfw/"
49    PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro"
50    PNOR_RO_PREFIX="/media/pnor-ro-"
51    PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw"
52    PNOR_RW_PREFIX="/media/pnor-rw-"
53    PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv"
54    PNOR_PRSV="/media/pnor-prsv"
55    PERSISTENCE_PATH="/var/lib/obmc/openpower-pnor-code-mgmt/"
56    PNOR_PATCH_LOCATION="/usr/local/share/pnor/"
57    MMC_BASE_PATH="/media/hostfw"
58    MMC_RO_PATH="${MMC_BASE_PATH}/running-ro"
59    MMC_RUNNING_PATH="${MMC_BASE_PATH}/running"
60    MMC_ALTERNATE_PATH="${MMC_BASE_PATH}/alternate"
61    MMC_STAGING_PATH="${MMC_BASE_PATH}/staging"
62    MMC_NVRAM_PATH="${MMC_BASE_PATH}/nvram"
63    HOSTFW_RUNNING_PATH="${HOSTFW_ACTIVE_PATH}/running"
64    HOSTFW_ALTERNATE_PATH="${HOSTFW_ACTIVE_PATH}/alternate"
65    HOSTFW_STAGING_PATH="${HOSTFW_ACTIVE_PATH}/staging"
66    HOSTFW_NVRAM_PATH="${HOSTFW_ACTIVE_PATH}/nvram"
67
68    # Get a list of all active PNOR versions
69    data="$(ls -d ${PNOR_RO_PREFIX}* 2>/dev/null)"
70    mapfile -t array <<< "${data}"
71
72    currentVersion=""
73    lowestPriority=255
74    for element in "${array[@]}"; do
75        #Remove the PNOR_RO_PREFIX from the path to get version ID.
76        versionId="${element#"${PNOR_RO_PREFIX}"}"
77
78        # Get the priority of active versions from persistence files.
79        if [[ -f "${PERSISTENCE_PATH}${versionId}" ]]; then
80            data="$(grep -r "priority" "${PERSISTENCE_PATH}${versionId}")"
81            priority="${data: -1}"
82            if [[ priority -le lowestPriority ]]; then
83                lowestPriority=${priority}
84                currentVersion=${versionId}
85            fi
86        fi
87    done
88
89    if [ -n "$currentVersion" ]; then
90        # Use active version
91        roTarget="${PNOR_RO_PREFIX}${currentVersion}"
92        rwTarget="${PNOR_RW_PREFIX}${currentVersion}"
93        prsvTarget="${PNOR_PRSV}"
94    elif [ -d "${MMC_BASE_PATH}" ]; then
95        # Use eMMC
96        roTarget="${MMC_RO_PATH}"
97        rwTarget="${MMC_RUNNING_PATH}"
98        prsvTarget="${MMC_RUNNING_PATH}"
99
100        if [ ! -d "${HOSTFW_ACTIVE_PATH}" ]; then
101            mkdir -p "${HOSTFW_ACTIVE_PATH}"
102        fi
103        # Symlinks used by PLDM
104        if [[ $(readlink -f "${HOSTFW_RUNNING_PATH}") != "${MMC_RUNNING_PATH}" ]]; then
105            rm -f ${HOSTFW_RUNNING_PATH}
106            ln -sfv ${MMC_RUNNING_PATH} ${HOSTFW_RUNNING_PATH}
107        fi
108        if [[ $(readlink -f "${HOSTFW_ALTERNATE_PATH}") != "${MMC_ALTERNATE_PATH}" ]]; then
109            rm -f ${HOSTFW_ALTERNATE_PATH}
110            ln -sfv ${MMC_ALTERNATE_PATH} ${HOSTFW_ALTERNATE_PATH}
111        fi
112        if [[ $(readlink -f "${HOSTFW_STAGING_PATH}") != "${MMC_STAGING_PATH}" ]]; then
113            rm -f ${HOSTFW_STAGING_PATH}
114            ln -sfv ${MMC_STAGING_PATH} ${HOSTFW_STAGING_PATH}
115        fi
116        if [[ $(readlink -f "${HOSTFW_NVRAM_PATH}") != "${MMC_NVRAM_PATH}" ]]; then
117            rm -f ${HOSTFW_NVRAM_PATH}
118            ln -sfv ${MMC_NVRAM_PATH} ${HOSTFW_NVRAM_PATH}
119        fi
120    fi
121
122    if [ ! -d "${PNOR_ACTIVE_PATH}" ]; then
123        mkdir -p "${PNOR_ACTIVE_PATH}"
124    fi
125
126    # If the RW or RO active links doesn't point to the version with
127    # lowest priority, then remove the symlink and create new ones.
128    if [[ $(readlink -f "${PNOR_RO_ACTIVE_PATH}") != "${roTarget}" ]]; then
129        rm -f ${PNOR_RO_ACTIVE_PATH}
130        rm -rf ${PNOR_PATCH_LOCATION}*
131        ln -sfv "${roTarget}" ${PNOR_RO_ACTIVE_PATH}
132    fi
133
134    if [[ $(readlink -f "${PNOR_RW_ACTIVE_PATH}") != "${rwTarget}" ]]; then
135        rm -f ${PNOR_RW_ACTIVE_PATH}
136        ln -sfv "${rwTarget}" ${PNOR_RW_ACTIVE_PATH}
137    fi
138
139    if [[ $(readlink -f "${PNOR_PRSV_ACTIVE_PATH}") != "${prsvTarget}" ]]; then
140        rm -f ${PNOR_PRSV_ACTIVE_PATH}
141        ln -sfv "${prsvTarget}" ${PNOR_PRSV_ACTIVE_PATH}
142    fi
143}
144
145case "$1" in
146    clearvolatile)
147        clear_volatile
148        ;;
149    updatesymlinks)
150        update_symlinks
151        ;;
152    *)
153        echo "Invalid argument"
154        exit 1
155        ;;
156esac
157rc=$?
158if [ ${rc} -ne 0 ]; then
159    echo "$0: error ${rc}"
160    exit ${rc}
161fi
162