From 9741eb316e4093f404fba9bea779fdd4228f6da2 Mon Sep 17 00:00:00 2001 From: wangzc Date: Tue, 25 Jun 2024 11:47:12 +0800 Subject: [PATCH 1/5] loadsvf: Add a tool to update SVF files using jtag Signed-off-by: wangzc Change-Id: I4d00fee32fa9939e3ce85024abc5c2e115ea1a58 --- ...cation-to-match-the-current-jtag-dri.patch | 292 ++++++++++++++++++ .../recipes-phytium/loadsvf/loadsvf_git.bb | 15 + 2 files changed, 307 insertions(+) create mode 100644 meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf/0001-Modify-the-application-to-match-the-current-jtag-dri.patch create mode 100644 meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf_git.bb diff --git a/meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf/0001-Modify-the-application-to-match-the-current-jtag-dri.patch b/meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf/0001-Modify-the-application-to-match-the-current-jtag-dri.patch new file mode 100644 index 0000000000..90d3a7caff --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf/0001-Modify-the-application-to-match-the-current-jtag-dri.patch @@ -0,0 +1,292 @@ +From ad8bb819cf8e33925aa8147def616f495fec90f8 Mon Sep 17 00:00:00 2001 +From: wangzc +Date: Tue, 16 Jan 2024 15:11:58 +0800 +Subject: [PATCH] Modify the application to match the current jtag driver + +1) Do not support JTAG_run_state operation, implement +using usleep instead +2) The shitf operation does not support JTAG_READ_WRITE_XFER, +modify to READ or WRITE +3) Consistency between data structure and driver +4) Modify the update progress display format + +Signed-off-by: wangzc +Change-Id: Ic2d0e2491c69744338526622fd91ff10b5023631 +--- + src/jtag.c | 24 +++++++++++------------- + src/jtag.h | 4 +--- + src/main.c | 26 +++++++++++++++++++++++--- + src/svf.c | 19 +++++++++++++++---- + 4 files changed, 50 insertions(+), 23 deletions(-) + +diff --git a/src/jtag.c b/src/jtag.c +index 847acb9..b45aaca 100644 +--- a/src/jtag.c ++++ b/src/jtag.c +@@ -2,9 +2,12 @@ + #include + #include + #include ++#include + + #include "jtag.h" + ++unsigned int time = 0; ++ + extern void DBG_log(int level, const char *format, ...); + + static const struct name_mapping { +@@ -60,11 +63,11 @@ STATUS JTAG_set_clock_frequency(int handle, unsigned int frequency) + { + unsigned long req = JTAG_SIOCFREQ; + +- printf("Set freq: %u\n", frequency); + if (ioctl(handle, req, &frequency) < 0) { + DBG_log(LEV_ERROR, "ioctl JTAG_SIOCFREQ failed"); + return ST_ERR; + } ++ time = 40000000 / frequency; //us + return ST_OK; + } + +@@ -86,7 +89,6 @@ STATUS JTAG_run_state(JTAG_Handler* state, JtagStates tap_state, unsigned int nu + + tapstate.reset = 0; + tapstate.tck = number_of_cycles; +- tapstate.from = JTAG_STATE_CURRENT; + tapstate.endstate = tap_state; + if (ioctl(state->JTAG_driver_handle, JTAG_SIOCSTATE, &tapstate) < 0) { + perror("run state"); +@@ -101,10 +103,7 @@ STATUS JTAG_wait_cycles(JTAG_Handler* state, unsigned int number_of_cycles) + if (state == NULL) + return ST_ERR; + +- if (ioctl(state->JTAG_driver_handle, JTAG_RUNTEST, number_of_cycles) < 0) { +- return JTAG_run_state(state, JTAG_STATE_CURRENT, number_of_cycles); +- } +- ++ usleep(number_of_cycles * time / 40); + return ST_OK; + } + +@@ -121,7 +120,6 @@ STATUS JTAG_set_tap_state(JTAG_Handler* state, JtagStates tap_state) + + tapstate.reset = 0; + tapstate.tck = 0; +- tapstate.from = JTAG_STATE_CURRENT; + tapstate.endstate = tap_state; + + if (ioctl(state->JTAG_driver_handle, req, &tapstate) < 0) { +@@ -131,7 +129,7 @@ STATUS JTAG_set_tap_state(JTAG_Handler* state, JtagStates tap_state) + } + + // move the [soft] state to the requested tap state. +- state->tap_state = tap_state; ++// state->tap_state = tap_state; + #if 0 + if ((tap_state == JtagRTI) || (tap_state == JtagPauDR)) + if (JTAG_wait_cycles(state, 5) != ST_OK) +@@ -141,7 +139,8 @@ STATUS JTAG_set_tap_state(JTAG_Handler* state, JtagStates tap_state) + return ST_OK; + } + +-STATUS JTAG_shift(JTAG_Handler* state, struct scan_xfer *scan_xfer, unsigned int type) ++STATUS JTAG_shift(JTAG_Handler* state, struct scan_xfer *scan_xfer, ++ unsigned int type, unsigned int dir) + { + struct jtag_xfer xfer; + unsigned char tdio[TDI_DATA_SIZE]; +@@ -151,11 +150,10 @@ STATUS JTAG_shift(JTAG_Handler* state, struct scan_xfer *scan_xfer, unsigned int + __u64 ptr = (__u64)tdio; + #endif + memset(&xfer, 0, sizeof(xfer)); +- xfer.from = JTAG_STATE_CURRENT; + xfer.endstate = scan_xfer->end_tap_state; + xfer.length = scan_xfer->length; + xfer.type = type; +- xfer.direction = JTAG_READ_WRITE_XFER; ++ xfer.direction = dir; + xfer.tdio = ptr; + memcpy(tdio, scan_xfer->tdi, scan_xfer->tdi_bytes); + if (ioctl(state->JTAG_driver_handle, JTAG_IOCXFER, &xfer) < 0) { +@@ -189,7 +187,7 @@ int JTAG_dr_scan(JTAG_Handler* handler, int num_bits, const uint8_t *out_bits, u + scan_xfer.end_tap_state = JtagShfDR; + else + scan_xfer.end_tap_state = state; +- if (JTAG_shift(handler, &scan_xfer, JTAG_SDR_XFER) != ST_OK) { ++ if (JTAG_shift(handler, &scan_xfer, JTAG_SDR_XFER,JTAG_READ_XFER) != ST_OK) { + DBG_log(LEV_ERROR, "ShftDR error"); + return -1; + } +@@ -216,7 +214,7 @@ int JTAG_ir_scan(JTAG_Handler* handler, int num_bits, const uint8_t *out_bits, u + memcpy(scan_xfer.tdi, out_bits, scan_xfer.tdi_bytes); + scan_xfer.tdo_bytes = scan_xfer.tdi_bytes; + scan_xfer.end_tap_state = state; +- if (JTAG_shift(handler, &scan_xfer, JTAG_SIR_XFER) != ST_OK) { ++ if (JTAG_shift(handler, &scan_xfer, JTAG_SIR_XFER,JTAG_WRITE_XFER) != ST_OK) { + DBG_log(LEV_ERROR, "ShftIR error"); + return -1; + } +diff --git a/src/jtag.h b/src/jtag.h +index 071936b..7f87afd 100644 +--- a/src/jtag.h ++++ b/src/jtag.h +@@ -85,16 +85,14 @@ struct scan_xfer { + struct jtag_xfer { + __u8 type; + __u8 direction; +- __u8 from; + __u8 endstate; +- __u32 padding; ++ __u8 padding; + __u32 length; + __u64 tdio; + }; + + struct jtag_tap_state { + __u8 reset; +- __u8 from; + __u8 endstate; + __u8 tck; + }; +diff --git a/src/main.c b/src/main.c +index fb295f9..474dad1 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -18,6 +18,7 @@ + int loglevel = LOG_LEVEL; + unsigned int frequency = 0; + int step = 0; ++int verbose = 0; + unsigned long total_runtest_time = 0; + + static int mode = JTAG_MODE_SPI; /* default transfer mode */ +@@ -38,6 +39,19 @@ void DBG_log(int level, const char *format, ...) + va_end(args); + } + ++void log_verbose (const char *fmt, ...) ++{ ++ va_list ap; ++ ++ if (!verbose) ++ return; ++ ++ va_start (ap,fmt); ++ vfprintf (stdout,fmt,ap); ++ va_end (ap); ++ fflush (stdout); ++} ++ + void showUsage(char **argv) + { + fprintf(stderr, "Usage: %s [option(s)]\n", argv[0]); +@@ -50,13 +64,14 @@ void showUsage(char **argv) + fprintf(stderr, " for PSPI mode\n"); + fprintf(stderr, " -s load svf file\n"); + fprintf(stderr, " -g run svf command line by line\n\n"); ++ fprintf(stderr, " -v Show progress reports\n\n"); + } + + void process_command_line(int argc, char **argv) + { + int c = 0; + int v; +- while ((c = getopt(argc, argv, "m:f:l:s:d:g")) != -1) { ++ while ((c = getopt(argc, argv, "m:f:l:s:d:g:v")) != -1) { + switch (c) { + case 'l': { + loglevel = atoi(optarg); +@@ -93,6 +108,10 @@ void process_command_line(int argc, char **argv) + strcpy(svf_path, optarg); + break; + } ++ case 'v' : { ++ verbose = 1; ++ break; ++ } + default: // h, ?, and other + showUsage(argv); + exit(EXIT_SUCCESS); +@@ -164,11 +183,12 @@ int main(int argc, char **argv) + } + + gettimeofday(&start,NULL); +- handle_svf_command(jtag_handler, svf_path); ++ if(handle_svf_command(jtag_handler, svf_path) != 0) ++ fprintf(stderr, "\nFailed to handle svf command\n"); + gettimeofday(&end,NULL); + diff = 1000 * (end.tv_sec-start.tv_sec)+ (end.tv_usec-start.tv_usec) / 1000; + printf("loading time is %ld ms\n",diff); +- //printf("total runtest time is %ld ms\n", total_runtest_time / 1000); ++ printf("total runtest time is %ld ms\n", total_runtest_time / 1000); + + err: + free(svf_path); +diff --git a/src/svf.c b/src/svf.c +index 222763f..d923298 100644 +--- a/src/svf.c ++++ b/src/svf.c +@@ -52,6 +52,7 @@ extern unsigned int frequency; + extern void DBG_log(int level, const char *format, ...); + static JTAG_Handler* jtag_handler = NULL; + extern unsigned long total_runtest_time; ++extern void log_verbose (const char *fmt, ...); + + /* SVF command */ + enum svf_command { +@@ -503,6 +504,7 @@ int handle_svf_command(JTAG_Handler* state, char *filename) + long svf_file_size; + long pos; + int progress, tmp; ++ bool bad_file = true; + + jtag_handler = state; + /* parse command line */ +@@ -545,7 +547,7 @@ int handle_svf_command(JTAG_Handler* state, char *filename) + } + + memcpy(&svf_para, &svf_para_init, sizeof(svf_para)); +- ++ log_verbose("Update progress: 0kb/%dkb (0%%)", svf_file_size/1024); + while (ERROR_OK == svf_read_command_from_file(svf_fd)) { + int c; + /* Run Command */ +@@ -562,9 +564,11 @@ int handle_svf_command(JTAG_Handler* state, char *filename) + if (ERROR_OK != svf_run_command(svf_command_buffer)) { + LOG_ERROR("fail to run command at line %d", svf_line_number); + ret = ERROR_FAIL; ++ bad_file = true; + break; + } + command_num++; ++ + if (svf_file_size > 0) { + pos = ftell(svf_fd); + if (pos > svf_cur_pos) +@@ -573,12 +577,19 @@ int handle_svf_command(JTAG_Handler* state, char *filename) + tmp = 100 * svf_cur_pos / svf_file_size; + if (tmp > progress) { + progress = tmp; +- printf("Progress: %d%%\r", progress); +- fflush(stdout); ++ log_verbose("\rUpdate progress: %dkb/%dkb (%d%%)", ++ svf_cur_pos/1024,svf_file_size/1024, progress); + } + } ++ bad_file = false; + } +- ++ if (bad_file) ++ { ++ ret = ERROR_FAIL; ++ goto free_all; ++ } ++ log_verbose("\rUpdate progress: %dkb/%dkb (100%%)\n", svf_cur_pos/1024, ++ svf_file_size/1024); + svf_check_tdo(false); + printf("\nDone!\n"); + free_all: +-- +2.23.0 + diff --git a/meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf_git.bb b/meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf_git.bb new file mode 100644 index 0000000000..111a841cd1 --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phytium/loadsvf/loadsvf_git.bb @@ -0,0 +1,15 @@ +DESCRIPTION = "CPLD/FPGA Programmer" +PR = "r1" + +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" + +SRC_URI = "git://github.com/Nuvoton-Israel/loadsvf.git;branch=master;protocol=https \ + file://0001-Modify-the-application-to-match-the-current-jtag-dri.patch \ + " +SRCREV = "535bfe23c3372fce6cfd40df42d1dc281f826c75" +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +DEPENDS += "autoconf-archive-native" -- Gitee From 526a1b0c2365bc88b31fef8dbd725552b4b86cf1 Mon Sep 17 00:00:00 2001 From: wangzc Date: Tue, 25 Jun 2024 18:26:35 +0800 Subject: [PATCH 2/5] phosphor-dbus-interfaces: Add cpld version interface Signed-off-by: hujun Signed-off-by: wangzc Change-Id: I629535de506dd783b0328f98cd0757f15039c4a3 --- ...e-Version-add-cpld-version-interface.patch | 23 +++++++++++++++++++ .../dbus/phosphor-dbus-interfaces_%.bbappend | 3 +++ 2 files changed, 26 insertions(+) create mode 100644 meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Software-Version-add-cpld-version-interface.patch create mode 100644 meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Software-Version-add-cpld-version-interface.patch b/meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Software-Version-add-cpld-version-interface.patch new file mode 100644 index 0000000000..2dedeec933 --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Software-Version-add-cpld-version-interface.patch @@ -0,0 +1,23 @@ +From 5f298ed6ee20bbfc630963f0da043ae13dad629f Mon Sep 17 00:00:00 2001 +From: hujun +Date: Wed, 9 Aug 2023 17:26:58 +0800 +Subject: [PATCH] Software-Version:add cpld version interface + +Signed-off-by: hujun +--- + yaml/xyz/openbmc_project/Software/Version.interface.yaml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/yaml/xyz/openbmc_project/Software/Version.interface.yaml b/yaml/xyz/openbmc_project/Software/Version.interface.yaml +index 345e5b51..253c862d 100644 +--- a/yaml/xyz/openbmc_project/Software/Version.interface.yaml ++++ b/yaml/xyz/openbmc_project/Software/Version.interface.yaml +@@ -38,3 +38,6 @@ enumerations: + - name: PSU + description: > + The version is a version for a PSU. ++ - name: Cpld ++ description: > ++ The version is a version for a CPLD +-- +2.25.1 diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend new file mode 100644 index 0000000000..67d17a18c5 --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend @@ -0,0 +1,3 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" + +SRC_URI += "file://0001-Software-Version-add-cpld-version-interface.patch" -- Gitee From de1d3fe397360de14891dcfaaa4cacf58d67c206 Mon Sep 17 00:00:00 2001 From: wangzc Date: Thu, 27 Jun 2024 09:53:38 +0800 Subject: [PATCH 3/5] phosphor-software-manager: Add cpld firmware support Signed-off-by: wangzc Change-Id: Ied4b827102752850ff83853a572bd73001d8fa32 --- ...-cpld-update-Add-cpld-update-support.patch | 417 ++++++++++++++++++ .../obmc-update-cpld@.service | 8 + .../phosphor-software-manager/update-cpld.sh | 180 ++++++++ .../phosphor-software-manager_%.bbappend | 19 + 4 files changed, 624 insertions(+) create mode 100644 meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/0001-cpld-update-Add-cpld-update-support.patch create mode 100644 meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/obmc-update-cpld@.service create mode 100755 meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/update-cpld.sh create mode 100644 meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/0001-cpld-update-Add-cpld-update-support.patch b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/0001-cpld-update-Add-cpld-update-support.patch new file mode 100644 index 0000000000..f92f59f33c --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/0001-cpld-update-Add-cpld-update-support.patch @@ -0,0 +1,417 @@ +From 3c557bf33bbea03d773168696487595925fe0d58 Mon Sep 17 00:00:00 2001 +From: hujun +Date: Wed, 23 Aug 2023 14:20:01 +0800 +Subject: [PATCH] cpld-update: Add cpld update support + +Signed-off-by: hujun +Signed-off-by: wangzc +Change-Id: I24c74685f93194c3f632936aa5e7d6e92e251da3 +--- + activation.cpp | 98 ++++++++++++++++++++++++++++++++++++ + activation.hpp | 8 +++ + gen-bios-tar | 34 +++++++++++-- + item_updater.cpp | 36 +++++++++++++ + item_updater.hpp | 20 ++++++++ + meson.build | 9 ++++ + meson_options.txt | 9 ++++ + obmc-update-cpld@.service.in | 7 +++ + 8 files changed, 216 insertions(+), 5 deletions(-) + create mode 100644 obmc-update-cpld@.service.in + +diff --git a/activation.cpp b/activation.cpp +index c90b537..e75b10e 100644 +--- a/activation.cpp ++++ b/activation.cpp +@@ -127,6 +127,29 @@ auto Activation::activation(Activations value) -> Activations + } + #endif + ++#ifdef HOST_CPLD_UPGRADE ++ auto cpldPurpose = parent.versions.find(versionId)->second->purpose(); ++ if (cpldPurpose == VersionPurpose::Cpld) ++ { ++ if (!activationProgress) ++ { ++ activationProgress = ++ std::make_unique(bus, path); ++ } ++ ++ // Enable systemd signals ++ subscribeToSystemdSignals(); ++ ++ // Set initial progress ++ activationProgress->progress(0); ++ ++ // update cpld ++ cpldUpdate(); ++ ++ return softwareServer::Activation::activation(value); ++ } ++#endif ++ + auto versionStr = parent.versions.find(versionId)->second->version(); + + if (!minimum_ship_level::verify(versionStr)) +@@ -302,6 +325,15 @@ void Activation::unitStateChange(sdbusplus::message::message& msg) + } + #endif + ++#ifdef HOST_CPLD_UPGRADE ++ auto cpldPurpose = parent.versions.find(versionId)->second->purpose(); ++ if (cpldPurpose == VersionPurpose::Cpld) ++ { ++ onStateChangesCPLD(msg); ++ return; ++ } ++#endif ++ + onStateChanges(msg); + + return; +@@ -447,6 +479,72 @@ void Activation::onStateChangesBios(sdbusplus::message::message& msg) + + #endif + ++#ifdef HOST_CPLD_UPGRADE ++void Activation::cpldUpdate() ++{ ++ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, ++ SYSTEMD_INTERFACE, "StartUnit"); ++ auto cpldServiceFile = "obmc-update-cpld@" + versionId + ".service"; ++ method.append(cpldServiceFile, "replace"); ++ try ++ { ++ auto reply = bus.call(method); ++ } ++ catch (const sdbusplus::exception::exception& e) ++ { ++ error("Error in trying to upgrade CPLD: {ERROR}", "ERROR", e); ++ report(); ++ } ++} ++ ++void Activation::onStateChangesCPLD(sdbusplus::message::message& msg) ++{ ++ uint32_t newStateID{}; ++ sdbusplus::message::object_path newStateObjPath; ++ std::string newStateUnit{}; ++ std::string newStateResult{}; ++ ++ // Read the msg and populate each variable ++ msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); ++ ++ auto cpldServiceFile = "obmc-update-cpld@" + versionId + ".service"; ++ ++ if (newStateUnit == cpldServiceFile) ++ { ++ // unsubscribe to systemd signals ++ unsubscribeFromSystemdSignals(); ++ ++ if (newStateResult == "done") ++ { ++ // Set activation progress to 100 ++ activationProgress->progress(100); ++ ++ // Set Activation value to active ++ activation(softwareServer::Activation::Activations::Active); ++ ++ info("CPLD upgrade completed successfully."); ++ parent.cpldVersion->version( ++ parent.versions.find(versionId)->second->version()); ++ ++ // Delete the uploaded activation ++ boost::asio::post(getIOContext(), [this]() { ++ this->parent.erase(this->versionId); ++ }); ++ } ++ else if (newStateResult == "failed") ++ { ++ // Set Activation value to Failed ++ activation(softwareServer::Activation::Activations::Failed); ++ ++ error("CPLD upgrade failed."); ++ } ++ } ++ ++ return; ++} ++ ++#endif ++ + void Activation::rebootBmc() + { + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, +diff --git a/activation.hpp b/activation.hpp +index 90b32b7..7abc407 100644 +--- a/activation.hpp ++++ b/activation.hpp +@@ -247,6 +247,14 @@ class Activation : public ActivationInherit, public Flash + void onStateChangesBios(sdbusplus::message::message&); + #endif + ++#ifdef HOST_CPLD_UPGRADE ++ /* @brief write to cpld function */ ++ void cpldUpdate(); ++ ++ /** @brief Function that acts on CPLD upgrade service file state changes */ ++ void onStateChangesCPLD(sdbusplus::message::message&); ++#endif ++ + /** @brief Overloaded function that acts on service file state changes */ + void onStateChanges(sdbusplus::message::message&) override; + +diff --git a/gen-bios-tar b/gen-bios-tar +index d0ddd8e..ca8fb30 100755 +--- a/gen-bios-tar ++++ b/gen-bios-tar +@@ -19,6 +19,7 @@ Options: + -m, --machine Optionally specify the target machine name of this + image. + -v, --version Specify the version of bios image file ++ -t, --type maybe bios or cpld + -h, --help Display this help text and exit. + ' + +@@ -52,6 +53,7 @@ private_key_path="${PRIVATE_KEY_PATH}" + outfile="" + machine="" + version="" ++purpose="" + + while [[ $# -gt 0 ]]; do + key="$1" +@@ -77,6 +79,10 @@ while [[ $# -gt 0 ]]; do + version="$2" + shift 2 + ;; ++ -t|--type) ++ purpose="$2" ++ shift 2 ++ ;; + -h|--help) + echo "$help" + exit +@@ -94,7 +100,7 @@ while [[ $# -gt 0 ]]; do + done + + if [ ! -f "${file}" ]; then +- echo "${file} not found, Please enter a valid Bios image file" ++ echo "${file} not found, Please enter a valid image file" + echo "$help" + exit 1 + fi +@@ -105,13 +111,31 @@ if [[ -z $version ]]; then + fi + + if [[ -z $outfile ]]; then +- outfile=`pwd`/obmc-bios.tar.gz ++ if [[ $purpose = "bios" ]]; then ++ outfile=`pwd`/obmc-bios.tar.gz ++ fi ++ if [[ $purpose = "cpld" ]]; then ++ outfile=`pwd`/obmc-cpld.tar.gz ++ fi ++ + else + if [[ $outfile != /* ]]; then + outfile=`pwd`/$outfile + fi + fi + ++if [[ $purpose = "bios" ]]; then ++ purpose="xyz.openbmc_project.Software.Version.VersionPurpose.Host" ++ des_file="bios.bin" ++elif [[ $purpose = "cpld" ]]; then ++ purpose="xyz.openbmc_project.Software.Version.VersionPurpose.Cpld" ++ des_file="jtag.svf" ++else ++ purpose="" ++ des_file=${file} ++ exit 1 ++fi ++ + scratch_dir=`mktemp -d` + # Remove the temp directory on exit. + # The files in the temp directory may contain read-only files, so add +@@ -141,12 +165,12 @@ manifest_location="MANIFEST" + files_to_sign="$manifest_location $public_key_file" + + # Go to scratch_dir +-cp ${file} ${scratch_dir} ++cp ${file} ${scratch_dir}/${des_file} + cd "${scratch_dir}" +-files_to_sign+=" $(basename ${file})" ++files_to_sign+=" $(basename ${des_file})" + + echo "Creating MANIFEST for the image" +-echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.Host\n\ ++echo -e "purpose=${purpose}\n\ + version=$version" > $manifest_location + + if [[ ! -z "${machine}" ]]; then +diff --git a/item_updater.cpp b/item_updater.cpp +index fe9c808..1953927 100644 +--- a/item_updater.cpp ++++ b/item_updater.cpp +@@ -68,6 +68,9 @@ void ItemUpdater::createActivation(sdbusplus::message::message& msg) + if (value == VersionPurpose::BMC || + #ifdef HOST_BIOS_UPGRADE + value == VersionPurpose::Host || ++#endif ++#ifdef HOST_CPLD_UPGRADE ++ value == VersionPurpose::Cpld || + #endif + value == VersionPurpose::System) + { +@@ -781,6 +784,39 @@ void ItemUpdater::createBIOSObject() + } + #endif + ++#ifdef HOST_CPLD_UPGRADE ++void ItemUpdater::createCPLDObject() ++{ ++ std::string path = CPLD_OBJPATH; ++ // Get version id from last item in the path ++ auto pos = path.rfind("/"); ++ if (pos == std::string::npos) ++ { ++ error("No version id found in object path {PATH}", "PATH", path); ++ return; ++ } ++ ++ createActiveAssociation(path); ++ createFunctionalAssociation(path); ++ ++ auto versionId = path.substr(pos + 1); ++ auto version = "null"; ++ AssociationList assocs = {}; ++ cpldActivation = std::make_unique( ++ bus, path, *this, versionId, server::Activation::Activations::Active, ++ assocs); ++ auto dummyErase = [](std::string /*entryId*/) { ++ // Do nothing; ++ }; ++ cpldVersion = std::make_unique( ++ bus, path, version, VersionPurpose::Cpld, "", "", ++ std::bind(dummyErase, std::placeholders::_1)); ++ cpldVersion->deleteObject = ++ std::make_unique(bus, path, ++ *cpldVersion); ++} ++#endif ++ + } // namespace updater + } // namespace software + } // namespace phosphor +diff --git a/item_updater.hpp b/item_updater.hpp +index b18e4bd..e2c9649 100644 +--- a/item_updater.hpp ++++ b/item_updater.hpp +@@ -64,6 +64,9 @@ class ItemUpdater : public ItemUpdaterInherit + restoreFieldModeStatus(); + #ifdef HOST_BIOS_UPGRADE + createBIOSObject(); ++#endif ++#ifdef HOST_CPLD_UPGRADE ++ createCPLDObject(); + #endif + emit_object_added(); + }; +@@ -273,6 +276,23 @@ class ItemUpdater : public ItemUpdaterInherit + /** @brief Persistent Version D-Bus object for BIOS */ + std::unique_ptr biosVersion; + #endif ++ ++#ifdef HOST_CPLD_UPGRADE ++ /** @brief Create the CPLD object without knowing the version. ++ * ++ * The object is created only to provide the DBus access so that an ++ * external service could set the correct CPLD version. ++ * On CPLD code update, the version is updated accordingly. ++ */ ++ void createCPLDObject(); ++ ++ /** @brief Persistent Activation D-Bus object for CPLD */ ++ std::unique_ptr cpldActivation; ++ ++ public: ++ /** @brief Persistent Version D-Bus object for CPLD */ ++ std::unique_ptr cpldVersion; ++#endif + }; + + } // namespace updater +diff --git a/meson.build b/meson.build +index e182f46..1660c7b 100644 +--- a/meson.build ++++ b/meson.build +@@ -68,6 +68,7 @@ conf.set('MMC_LAYOUT', get_option('bmc-layout').contains('mmc')) + + # Configurable features + conf.set('HOST_BIOS_UPGRADE', get_option('host-bios-upgrade').enabled()) ++conf.set('HOST_CPLD_UPGRADE', get_option('host-cpld-upgrade').enabled()) + conf.set('WANT_SIGNATURE_VERIFY', \ + get_option('verify-signature').enabled() or \ + get_option('verify-full-signature').enabled()) +@@ -97,6 +98,10 @@ if get_option('host-bios-upgrade').enabled() + conf.set_quoted('BIOS_OBJPATH', get_option('bios-object-path')) + endif + ++if get_option('host-cpld-upgrade').enabled() ++ conf.set_quoted('CPLD_OBJPATH', get_option('cpld-object-path')) ++endif ++ + configure_file(output: 'config.h', configuration: conf) + + sdbusplus_dep = dependency('sdbusplus', required: false) +@@ -217,6 +222,10 @@ if get_option('host-bios-upgrade').enabled() + unit_files += 'obmc-flash-host-bios@.service.in' + endif + ++if get_option('host-cpld-upgrade').enabled() ++ unit_files += 'obmc-update-cpld@.service.in' ++endif ++ + if get_option('sync-bmc-files').enabled() + executable( + 'phosphor-sync-software-manager', +diff --git a/meson_options.txt b/meson_options.txt +index de3540c..43b5a21 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -12,6 +12,9 @@ option('bmc-layout', type: 'combo', + option('host-bios-upgrade', type: 'feature', value: 'enabled', + description: 'Enable host bios upgrade support.') + ++option('host-cpld-upgrade', type: 'feature', value: 'enabled', ++ description: 'Enable host cpld upgrade support.') ++ + option('sync-bmc-files', type: 'feature', value: 'enabled', + description: 'Enable sync of filesystem files.') + +@@ -109,3 +112,9 @@ option( + value: '/xyz/openbmc_project/software/bios_active', + description: 'The BIOS DBus object path.', + ) ++ ++option( ++ 'cpld-object-path', type: 'string', ++ value: '/xyz/openbmc_project/software/cpld_active', ++ description: 'The CPLD DBus object path.', ++) +diff --git a/obmc-update-cpld@.service.in b/obmc-update-cpld@.service.in +new file mode 100644 +index 0000000..20050db +--- /dev/null ++++ b/obmc-update-cpld@.service.in +@@ -0,0 +1,7 @@ ++[Unit] ++Description=CPLD update %I ++ ++[Service] ++Type=oneshot ++RemainAfterExit=no ++ExecStart=echo Please add custom command for update cpld file /tmp/image/%i +-- +2.23.0 + diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/obmc-update-cpld@.service b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/obmc-update-cpld@.service new file mode 100644 index 0000000000..8529d0af3a --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/obmc-update-cpld@.service @@ -0,0 +1,8 @@ +[Unit] +Description=Update board cpld %I. + +[Service] +Type=oneshot +RemainAfterExit=no +EnvironmentFile={envfiledir}/obmc/update +ExecStart=/usr/local/update-cpld.sh /tmp/images/%i $CPLD_GPIO diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/update-cpld.sh b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/update-cpld.sh new file mode 100755 index 0000000000..8c8d7917b8 --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager/update-cpld.sh @@ -0,0 +1,180 @@ +#!/bin/bash + +### Variable +image_dir=$1 +gpio_name=$2 +cpld_file="${image_dir}/jtag.svf" +jtag="/dev/jtag0" +progress_file="/tmp/cpld_progress" +curr_version="" +update_version="" +firmware_type="CPLD" +soft_id=${image_dir##*/} +soft_dbus="xyz.openbmc_project.Software.BMC.Updater /xyz/openbmc_project/software/" + +### Function Definition +# +# Verify version +verify_version() { + curr_version=$(busctl get-property ${soft_dbus}cpld_active \ + "xyz.openbmc_project.Software.Version" "Version") + curr_version=$(echo $curr_version | awk '{print $2}') + + update_version=$(busctl get-property ${soft_dbus}${soft_id} \ + "xyz.openbmc_project.Software.Version" "Version") + update_version=$(echo $update_version | awk '{print $2}') + if test "$curr_version" = "$update_version"; then + echo "Update version $update_version is currently running on the host" + return 1 + fi +} + +# Check the power status of the host +check_chassis_state() { + chassis_state=$(busctl get-property "xyz.openbmc_project.State.Chassis" "/xyz/openbmc_project/state/chassis0" \ + "xyz.openbmc_project.State.Chassis" "CurrentPowerState") + + if [[ $chassis_state =~ "On" ]]; then + echo "The chassis is in a power on, can not update cpld" + return 1 + fi +} + +# Record failed messages to redfish log +generate_redfish_log() { + openbmc_tag="OpenBMC.0.1.$1" + para="" + shift + while [ $# -ne 0 ]; do + para=$para",$1" + shift + done + logger -p local7.info "${openbmc_tag}${para}" +} + +## Delete firmware with failed updates +delete_software() { + busctl call ${soft_dbus}${soft_id} "xyz.openbmc_project.Object.Delete" "Delete" +} + +## Set software update state interface +## $1 state, it can be Staged Invalid Failed... +set_dbus_acvivate_state() { + activate_state="xyz.openbmc_project.Software.Activation.Activations.$1" + + busctl set-property ${soft_dbus}${soft_id} "xyz.openbmc_project.Software.Activation" \ + "Activation" s $activate_state +} + +##Set software update dbus progress info +## $1 Progress +set_dbus_progress_info() { + local progress=$1 + busctl set-property ${soft_dbus}${soft_id} "xyz.openbmc_project.Software.ActivationProgress" \ + "Progress" y $progress +} + +### When an error occurs, report logs, update status, delete software +handle_err() { + local message=$1 + ### Send error log + generate_redfish_log "FirmwareUpdateFailed" "$firmware_type" "$update_version" "$message" + ### Set sctivate state failed + set_dbus_acvivate_state "Failed" + ### delete failed software + delete_software + exit 1 +} + +### Obtain progress information +find_str_progress() { + local info=$1 + local key=$2 + str=$(echo "$info" | grep -i $key | tail -n 1) + if test ! -z "$str"; then + str=${str##*(} + echo ${str%\%*} + fi +} + +### Check update status +# return +# 0 update +# 1 stop update +check_update_state() { + local info=$1 + state=$(echo "$info" | grep "Done") + if test -n "$state"; then + generate_redfish_log "FirmwareUpdateCompleted" $firmware_type $update_version + return 1 + fi + + state=$(echo "$info" | grep -iE "fail|not") + if test -n "$state"; then + handle_err "loadsvf program running error" + fi + return 0 +} + +### Main Process #### +generate_redfish_log "FirmwareUpdateStarted" $firmware_type $update_version +### Verify version information +verify_version +if test $? -ne 0; then + handle_err "Same version" +fi + +### Check if the chaiss is powered on +check_chassis_state +if test $? -ne 0; then + handle_err "The chassis is in a power on state" +fi + +### Check if the device or file exists +if test ! -e "$jtag"; then + handle_err "jtag device does not exist" +fi + +if test ! -e "$cpld_file"; then + handle_err "jtag.svf does not exist" +fi +gpioutil set $gpio_name 1 + +# Set cpld update progress monitor +{ + set_progress=0 + while true; do + if test ! -e $progress_file; then + continue + fi + ##Get progress data output by loadsvf and remove '\r\n' characters. + data=$(cat $progress_file | sed 's/\r/\n/g') + + # Exit the loop when encountering errors or completion + check_update_state "$data" + if test $? -ne 0; then + break + fi + set_progress=$(find_str_progress "$data" "progress") + + ##Write the progress value to the DBUS interface. + if test $set_progress; then + set_dbus_progress_info $set_progress + fi + sleep 0.5 + done +} & + +# Run cpld update +loadsvf -d /dev/jtag0 -v -s $cpld_file >$progress_file 2>&1 +gpioutil set $gpio_name 0 + +# When the loadsvf program runs incorrectly, we need exit 1 +data=$(cat $progress_file | sed 's/\r/\n/g') + +state=$(echo "$data" | grep -iE "fail|not") +if test -n "$state"; then + sleep 1 + rm $progress_file + exit 1 +fi diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend new file mode 100644 index 0000000000..988167e617 --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/flash/phosphor-software-manager_%.bbappend @@ -0,0 +1,19 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" + +SRC_URI += "\ + file://0001-cpld-update-Add-cpld-update-support.patch \ + file://update-cpld.sh \ + " + +RDEPENDS:${PN}-updater += "bash" +SYSTEMD_ENVIRONMENT_FILE:${PN}-updater:append := " obmc/update" + +PACKAGECONFIG[update-cpld] = "-Dhost-cpld-upgrade=enabled, -Dhost-cpld-upgrade=disabled" +PACKAGECONFIG:append:phytium = " update-cpld" +SYSTEMD_SERVICE:${PN}-updater += "${@bb.utils.contains('PACKAGECONFIG', 'update-cpld', 'obmc-update-cpld@.service', '', d)}" +RDEPENDS:${PN}-updater += "${@bb.utils.contains('PACKAGECONFIG', 'update-cpld', 'loadsvf', '', d)}" + +do_install:append() { + # intsall cpld update script + install -m 0755 ${WORKDIR}/update-cpld.sh ${D}/usr/local/update-cpld.sh +} -- Gitee From ecfad2e397c361b4a8a938dec4de7b47a1ebf4b7 Mon Sep 17 00:00:00 2001 From: wangzc Date: Tue, 2 Jul 2024 08:59:15 +0800 Subject: [PATCH 4/5] meta-tx64: Add gpio config for cpld update Signed-off-by: wangzc Change-Id: I0caa33910d40bbd82c0f5a073b6cf6d7c555e368 --- .../recipes-phosphor/flash/phosphor-software-manager/obmc/update | 1 + .../recipes-phosphor/flash/phosphor-software-manager_%.bbappend | 1 + 2 files changed, 2 insertions(+) create mode 100644 meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager/obmc/update create mode 100644 meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager_%.bbappend diff --git a/meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager/obmc/update b/meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager/obmc/update new file mode 100644 index 0000000000..573c5779ab --- /dev/null +++ b/meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager/obmc/update @@ -0,0 +1 @@ +CPLD_GPIO=CPU_JTAG_SELECT diff --git a/meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager_%.bbappend b/meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager_%.bbappend new file mode 100644 index 0000000000..4fc41d0580 --- /dev/null +++ b/meta-phytium-openbmc/meta-tx64/recipes-phosphor/flash/phosphor-software-manager_%.bbappend @@ -0,0 +1 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" -- Gitee From 285f4bf94a44a376a497f8a5055a43f19180ff6a Mon Sep 17 00:00:00 2001 From: wangzc Date: Fri, 28 Jun 2024 19:37:23 +0800 Subject: [PATCH 5/5] bmcweb:update_service: Add firmware update type identification Signed-off-by: wangzc Change-Id: Ifeef0b3de2b382e74f6662a9d530cf8b18033bd3 --- ...dd-firmware-update-type-identificati.patch | 110 ++++++++++++++++++ .../interfaces/bmcweb_%.bbappend | 1 + 2 files changed, 111 insertions(+) create mode 100644 meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb/0006-update_service-Add-firmware-update-type-identificati.patch diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb/0006-update_service-Add-firmware-update-type-identificati.patch b/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb/0006-update_service-Add-firmware-update-type-identificati.patch new file mode 100644 index 0000000000..d0aab50f6d --- /dev/null +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb/0006-update_service-Add-firmware-update-type-identificati.patch @@ -0,0 +1,110 @@ +From bb3629a9ed0ad3560f06e9dfdbe2958516c04ccc Mon Sep 17 00:00:00 2001 +From: wangzc +Date: Thu, 17 Aug 2023 14:25:22 +0800 +Subject: [PATCH] update_service:Add firmware update type identification + +When updating firmware, we need to know which type of +firmware is being updated. Therefore, when returning +to the task node to the front-end, add Type attribute +information: + +{ + "@odata.id": "/redfish/v1/TaskService/Tasks/1", + "@odata.type": "#Task.v1_4_3.Task", + "Id": "1", + "Oem": { + "Type": "cpld" + }, + "TaskState": "Running", + "TaskStatus": "OK" +} + +The Type maybe "bmc", "bios", "cpld". + +Signed-off-by: wangzc +Change-Id: I29ab1d9bfdc3862ea7e49c7e67882258ccf55309 +--- + redfish-core/include/utils/fw_utils.hpp | 4 +++ + redfish-core/lib/update_service.hpp | 36 +++++++++++++++++++++---- + 2 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/redfish-core/include/utils/fw_utils.hpp b/redfish-core/include/utils/fw_utils.hpp +index c990023..bad5a10 100644 +--- a/redfish-core/include/utils/fw_utils.hpp ++++ b/redfish-core/include/utils/fw_utils.hpp +@@ -18,6 +18,10 @@ constexpr const char* biosPurpose = + constexpr const char* bmcPurpose = + "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"; + ++/* @brief String that indicates a cpld firmware instance */ ++constexpr const char* cpldPurpose = ++ "xyz.openbmc_project.Software.Version.VersionPurpose.Cpld"; ++ + /** + * @brief Populate the running firmware version and image links + * +diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp +index e22b44e..655055a 100644 +--- a/redfish-core/lib/update_service.hpp ++++ b/redfish-core/lib/update_service.hpp +@@ -77,19 +77,43 @@ static void + m.read(objPath, interfacesProperties); + + BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; ++ std::string type; + for (auto& interface : interfacesProperties) + { + BMCWEB_LOG_DEBUG << "interface = " << interface.first; + ++ if (interface.first == "xyz.openbmc_project.Software.Version") ++ { ++ std::string purpose; ++ for (auto& property : interface.second) ++ { ++ if (property.first == "Purpose") ++ { ++ purpose = std::get(property.second); ++ break; ++ } ++ } ++ ++ if (!purpose.empty()) ++ { ++ if (purpose == fw_util::biosPurpose) ++ type = "bios"; ++ else if (purpose == fw_util::cpldPurpose) ++ type = "cpld"; ++ else if (purpose == fw_util::bmcPurpose) ++ type = "bmc"; ++ } ++ } ++ + if (interface.first == "xyz.openbmc_project.Software.Activation") + { + // Retrieve service and activate + crow::connections::systemBus->async_method_call( +- [objPath, asyncResp, payload(std::move(payload))]( +- const boost::system::error_code errorCode, +- const std::vector< +- std::pair>>& +- objInfo) mutable { ++ [objPath, asyncResp, payload(std::move(payload)), ++ type](const boost::system::error_code errorCode, ++ const std::vector< ++ std::pair>>& ++ objInfo) mutable { + if (errorCode) + { + BMCWEB_LOG_DEBUG << "error_code = " << errorCode; +@@ -243,6 +267,8 @@ static void + objPath.str + "'"); + task->startTimer(std::chrono::minutes(5)); + task->populateResp(asyncResp->res); ++ if (!type.empty()) ++ asyncResp->res.jsonValue["Oem"]["Type"] = type; + task->payload.emplace(std::move(payload)); + } + fwUpdateInProgress = false; +-- +2.23.0 + diff --git a/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend index ac8548b5e3..16fc6a196a 100644 --- a/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-phytium-openbmc/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -14,4 +14,5 @@ SRC_URI += "\ file://0003-ethernet-Resolve-the-modification-failure.patch \ file://0004-update_service-Add-a-custom-version-field.patch \ file://0005-log_service-Add-phytium-post-code-support.patch \ + file://0006-update_service-Add-firmware-update-type-identificati.patch \ " -- Gitee