Initial commit
This commit is contained in:
+295
@@ -0,0 +1,295 @@
|
||||
From 21929dbc4fae5aa78be51ee389523f6cdb638759 Mon Sep 17 00:00:00 2001
|
||||
From: "hliangs90" <hliangs90@gmail.com>
|
||||
Date: Thu, 15 Aug 2024 13:11:23 +0800
|
||||
Subject: [PATCH] Add CPLD Update for SoftWare Manager.
|
||||
|
||||
Signed-off-by: hliangs90 <hliangs90@gmail.com>
|
||||
---
|
||||
activation.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
activation.hpp | 8 +++++
|
||||
item_updater.cpp | 37 +++++++++++++++++++
|
||||
item_updater.hpp | 19 ++++++++++
|
||||
meson.build | 5 +++
|
||||
meson_options.txt | 8 +++++
|
||||
6 files changed, 169 insertions(+)
|
||||
|
||||
diff --git a/activation.cpp b/activation.cpp
|
||||
index d9ee2d0..f866461 100644
|
||||
--- a/activation.cpp
|
||||
+++ b/activation.cpp
|
||||
@@ -143,6 +143,23 @@ auto Activation::activation(Activations value) -> Activations
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef CPLD_UPGRADE
|
||||
+ auto purposeTemp = parent.versions.find(versionId)->second->purpose();
|
||||
+ if (purposeTemp == VersionPurpose::CPLD)
|
||||
+ {
|
||||
+ // Enable systemd signals
|
||||
+ subscribeToSystemdSignals();
|
||||
+
|
||||
+ // Set initial progress
|
||||
+ activationProgress->progress(20);
|
||||
+
|
||||
+ // Initiate image writing to flash
|
||||
+ flashWriteCPLD();
|
||||
+
|
||||
+ return softwareServer::Activation::activation(value);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
activationProgress->progress(10);
|
||||
|
||||
parent.freeSpace(*this);
|
||||
@@ -318,6 +335,15 @@ void Activation::unitStateChange(sdbusplus::message_t& msg)
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef CPLD_UPGRADE
|
||||
+ auto purposeTemp = parent.versions.find(versionId)->second->purpose();
|
||||
+ if (purposeTemp == VersionPurpose::CPLD)
|
||||
+ {
|
||||
+ onStateChangesCPLD(msg);
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
onStateChanges(msg);
|
||||
|
||||
return;
|
||||
@@ -456,6 +482,72 @@ void Activation::onStateChangesBios(sdbusplus::message_t& msg)
|
||||
|
||||
#endif
|
||||
|
||||
+#ifdef CPLD_UPGRADE
|
||||
+void Activation::flashWriteCPLD()
|
||||
+{
|
||||
+ auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
|
||||
+ SYSTEMD_INTERFACE, "StartUnit");
|
||||
+ auto cpldServiceFile = "obmc-flash-cpld@" + versionId + ".service";
|
||||
+ method.append(cpldServiceFile, "replace");
|
||||
+ try
|
||||
+ {
|
||||
+ auto reply = bus.call(method);
|
||||
+ }
|
||||
+ catch (const sdbusplus::exception_t& e)
|
||||
+ {
|
||||
+ error("Error in trying to upgrade CPLD: {ERROR}", "ERROR", e);
|
||||
+ report<InternalFailure>();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Activation::onStateChangesCPLD(sdbusplus::message_t& 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-flash-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 94cc1bb..7d10472 100644
|
||||
--- a/activation.hpp
|
||||
+++ b/activation.hpp
|
||||
@@ -247,6 +247,14 @@ class Activation : public ActivationInherit, public Flash
|
||||
void onStateChangesBios(sdbusplus::message_t&);
|
||||
#endif
|
||||
|
||||
+#ifdef CPLD_UPGRADE
|
||||
+ /* @brief write to CPLD flash function */
|
||||
+ void flashWriteCPLD();
|
||||
+
|
||||
+ /** @brief Function that acts on CPLD upgrade service file state changes */
|
||||
+ void onStateChangesCPLD(sdbusplus::message_t&);
|
||||
+#endif
|
||||
+
|
||||
/** @brief Overloaded function that acts on service file state changes */
|
||||
void onStateChanges(sdbusplus::message_t&) override;
|
||||
|
||||
diff --git a/item_updater.cpp b/item_updater.cpp
|
||||
index 5613a49..76f72d4 100644
|
||||
--- a/item_updater.cpp
|
||||
+++ b/item_updater.cpp
|
||||
@@ -71,6 +71,9 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg)
|
||||
if (value == VersionPurpose::BMC ||
|
||||
#ifdef HOST_BIOS_UPGRADE
|
||||
value == VersionPurpose::Host ||
|
||||
+#endif
|
||||
+#ifdef CPLD_UPGRADE
|
||||
+ value == VersionPurpose::CPLD ||
|
||||
#endif
|
||||
value == VersionPurpose::System)
|
||||
{
|
||||
@@ -879,6 +882,40 @@ void ItemUpdater::createBIOSObject()
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef 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<Activation>(
|
||||
+ bus, path, *this, versionId, server::Activation::Activations::Active,
|
||||
+ assocs);
|
||||
+ auto dummyErase = [](std::string /*entryId*/) {
|
||||
+ // Do nothing;
|
||||
+ };
|
||||
+ cpldVersion = std::make_unique<VersionClass>(
|
||||
+ bus, path, version, VersionPurpose::CPLD, "", "",
|
||||
+ std::vector<std::string>(),
|
||||
+ std::bind(dummyErase, std::placeholders::_1), "");
|
||||
+ cpldVersion->deleteObject =
|
||||
+ std::make_unique<phosphor::software::manager::Delete>(bus, path,
|
||||
+ *cpldVersion);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
void ItemUpdater::getRunningSlot()
|
||||
{
|
||||
// Check /run/media/slot to get the slot number
|
||||
diff --git a/item_updater.hpp b/item_updater.hpp
|
||||
index c50d9de..26b657d 100644
|
||||
--- a/item_updater.hpp
|
||||
+++ b/item_updater.hpp
|
||||
@@ -67,6 +67,9 @@ class ItemUpdater : public ItemUpdaterInherit
|
||||
restoreFieldModeStatus();
|
||||
#ifdef HOST_BIOS_UPGRADE
|
||||
createBIOSObject();
|
||||
+#endif
|
||||
+#ifdef CPLD_UPGRADE
|
||||
+ createCPLDObject();
|
||||
#endif
|
||||
emit_object_added();
|
||||
};
|
||||
@@ -280,6 +283,22 @@ class ItemUpdater : public ItemUpdaterInherit
|
||||
std::unique_ptr<VersionClass> biosVersion;
|
||||
#endif
|
||||
|
||||
+#ifdef 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<Activation> cpldActivation;
|
||||
+
|
||||
+ public:
|
||||
+ /** @brief Persistent Version D-Bus object for CPLD */
|
||||
+ std::unique_ptr<VersionClass> cpldVersion;
|
||||
+#endif
|
||||
/** @brief Get the slot number of running image */
|
||||
void getRunningSlot();
|
||||
};
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 41adfde..509d9f7 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -67,6 +67,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('CPLD_UPGRADE', get_option('cpld-upgrade').enabled())
|
||||
conf.set('WANT_SIGNATURE_VERIFY', \
|
||||
get_option('verify-signature').enabled() or \
|
||||
get_option('verify-full-signature').enabled())
|
||||
@@ -96,6 +97,10 @@ if get_option('host-bios-upgrade').enabled()
|
||||
conf.set_quoted('BIOS_OBJPATH', get_option('bios-object-path'))
|
||||
endif
|
||||
|
||||
+if get_option('cpld-upgrade').enabled()
|
||||
+ conf.set_quoted('CPLD_OBJPATH', get_option('cpld-object-path'))
|
||||
+endif
|
||||
+
|
||||
if get_option('bmc-static-dual-image').enabled()
|
||||
conf.set('BMC_STATIC_DUAL_IMAGE', get_option('bmc-static-dual-image').enabled())
|
||||
conf.set_quoted('ALT_ROFS_DIR', get_option('alt-rofs-dir'))
|
||||
diff --git a/meson_options.txt b/meson_options.txt
|
||||
index d14ed3b..d638c93 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -11,6 +11,8 @@ option('bmc-layout', type: 'combo',
|
||||
# Features
|
||||
option('host-bios-upgrade', type: 'feature', value: 'enabled',
|
||||
description: 'Enable host bios upgrade support.')
|
||||
+option('cpld-upgrade', type: 'feature', value: 'enabled',
|
||||
+ description: 'Enable cpld upgrade support.')
|
||||
|
||||
option('sync-bmc-files', type: 'feature', value: 'enabled',
|
||||
description: 'Enable sync of filesystem files.')
|
||||
@@ -121,6 +123,12 @@ option(
|
||||
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.',
|
||||
+)
|
||||
+
|
||||
option('bmc-static-dual-image', type: 'feature', value: 'enabled',
|
||||
description: 'Enable the dual image support for static layout.')
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
From 88d810c49f7101a8bb46b2a1af17626bd61a5d07 Mon Sep 17 00:00:00 2001
|
||||
From: roly <Rolyli.Li@luxshare-ict.com>
|
||||
Date: Wed, 18 Dec 2024 13:55:03 +0800
|
||||
Subject: [PATCH] Detect boot image source
|
||||
|
||||
---
|
||||
detect-slot-aspeed | 21 +++++++++++++++++----
|
||||
reset-cs0-aspeed | 12 +++++++++++-
|
||||
2 files changed, 28 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/detect-slot-aspeed b/detect-slot-aspeed
|
||||
index 231eb33..6631722 100644
|
||||
--- a/detect-slot-aspeed
|
||||
+++ b/detect-slot-aspeed
|
||||
@@ -1,16 +1,29 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
-# Check the /sys/class/watchdog/watchdog1/access_cs0 and tell if it's running on the primary or the secondary flash.
|
||||
-
|
||||
-ACCESS_CS0="/sys/class/watchdog/watchdog1/access_cs0"
|
||||
SLOT_FILE="/run/media/slot"
|
||||
|
||||
+if [ -f ${SLOT_FILE} ]; then
|
||||
+ # Slot info already detected
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+# Check the sysfs attribute and tell if it's running on the primary or the secondary flash.
|
||||
+SOC_FAMILY=$(cat /sys/bus/soc/devices/soc0/family)
|
||||
+if [ "${SOC_FAMILY}" = "AST2500" ]; then
|
||||
+ ACCESS_PRIMARY="/sys/class/watchdog/watchdog1/access_cs0"
|
||||
+elif [ "${SOC_FAMILY}" = "AST2600" ]; then
|
||||
+ ACCESS_PRIMARY="/sys/devices/platform/ahb/1e620000.spi/access_primary"
|
||||
+else
|
||||
+ echo "SOC Family is neither AST2500 nor AST2600"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
# Create directory if not exist
|
||||
mkdir -p "$(dirname "${SLOT_FILE}")"
|
||||
|
||||
# Write slot info
|
||||
-if [ -f ${ACCESS_CS0} ]; then
|
||||
+if [ -f ${ACCESS_PRIMARY} ]; then
|
||||
echo "1" > ${SLOT_FILE}
|
||||
else
|
||||
echo "0" > ${SLOT_FILE}
|
||||
diff --git a/reset-cs0-aspeed b/reset-cs0-aspeed
|
||||
index e2cf1e0..e761e77 100644
|
||||
--- a/reset-cs0-aspeed
|
||||
+++ b/reset-cs0-aspeed
|
||||
@@ -11,11 +11,21 @@ SHUTDOWN_EXTRA_SCRIPT="/run/initramfs/shutdown_task_after_umount"
|
||||
|
||||
cat <<'EOF' >"${SHUTDOWN_EXTRA_SCRIPT}"
|
||||
#!/bin/sh
|
||||
-ACCESS_CS0="/sys/class/watchdog/watchdog1/access_cs0"
|
||||
+
|
||||
+ACCESS_CS0=""
|
||||
+
|
||||
+SOC_FAMILY=$(cat /sys/bus/soc/devices/soc0/family)
|
||||
+if [ "${SOC_FAMILY}" = "AST2500" ]; then
|
||||
+ ACCESS_CS0="/sys/class/watchdog/watchdog1/access_cs0"
|
||||
+elif [ "${SOC_FAMILY}" = "AST2600" ]; then
|
||||
+ ACCESS_CS0="/sys/devices/platform/ahb/1e620000.spi/access_primary"
|
||||
+fi
|
||||
+
|
||||
if [ -f "${ACCESS_CS0}" ]; then
|
||||
echo "Reset aspeed chip select"
|
||||
echo 1 > "${ACCESS_CS0}"
|
||||
fi
|
||||
+
|
||||
EOF
|
||||
chmod +x "${SHUTDOWN_EXTRA_SCRIPT}"
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
From f96d61f5a96db2deaf34f5ca38b77b3d18704ae6 Mon Sep 17 00:00:00 2001
|
||||
From: "alex-hl.huang" <alex-hl.huang@luxshare-ict.com>
|
||||
Date: Thu, 17 Feb 2022 13:52:46 +0800
|
||||
Subject: [PATCH] add shell script for generate cpld image tar
|
||||
|
||||
---
|
||||
gen-cpld-tar | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 176 insertions(+)
|
||||
create mode 100755 gen-cpld-tar
|
||||
|
||||
diff --git a/gen-cpld-tar b/gen-cpld-tar
|
||||
new file mode 100755
|
||||
index 0000000..d0d59c6
|
||||
--- /dev/null
|
||||
+++ b/gen-cpld-tar
|
||||
@@ -0,0 +1,176 @@
|
||||
+#!/bin/bash
|
||||
+set -eo pipefail
|
||||
+
|
||||
+help=$'Generate Tarball with Cpld image and MANIFEST Script
|
||||
+
|
||||
+Generates a Cpld image tarball from given file as input.
|
||||
+Creates a MANIFEST for image verification and recreation
|
||||
+Packages the image and MANIFEST together in a tarball
|
||||
+
|
||||
+usage: gen-Cpld-tar [OPTION] <Cpld FILE>...
|
||||
+
|
||||
+Options:
|
||||
+-o, --out <file> Specify destination file. Defaults to
|
||||
+`pwd`/obmc-cpld.tar.gz if unspecified.
|
||||
+-s, --sign <path> Sign the image. The optional path argument specifies
|
||||
+the private key file. Defaults to the bash variable
|
||||
+PRIVATE_KEY_PATH if available, or else uses the
|
||||
+open-source private key in this script.
|
||||
+-m, --machine <name> Optionally specify the target machine name of this
|
||||
+image.
|
||||
+-v, --version <name> Specify the version of Cpld image file
|
||||
+-h, --help Display this help text and exit.
|
||||
+'
|
||||
+
|
||||
+#################################################################
|
||||
+# It's the OpenBMC "public" private key (currently under
|
||||
+# meta-phosphor/recipes-phosphor/flash/files/OpenBMC.priv):
|
||||
+# https://gerrit.openbmc-project.xyz/c/openbmc/openbmc/+/8949/15/
|
||||
+# meta-phosphor/common/recipes-phosphor/flash/files/OpenBMC.priv
|
||||
+#
|
||||
+#################################################################
|
||||
+private_key=$'-----BEGIN PRIVATE KEY-----
|
||||
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvSDLu6slkP1gri
|
||||
+PaeQXL9ysD69J/HjbBCIQ0RPfeWBb75US1tRTjPP0Ub8CtH8ExVf8iF1ulsZA78B
|
||||
+zIjBYZVp9pyD6LbpZ/hjV7rIH6dTNhoVpdA+F8LzmQ7cyhHG8l2JMvdunwF2uX5k
|
||||
+D4WDcZt/ITKZNQNavPtmIyD5HprdAgMBAAECgYEAuQkTSi5ZNpAoWz76xtGRFSwU
|
||||
+zUT4wQi3Mz6tDtjKTYXasiQGa0dHC1M9F8fDu6BZ9W7W4Dc9hArRcdzEighuxoI/
|
||||
+nZI/0uL89iUEywnDEIHuS6D5JlZaj86/nx9YvQnO8F/seM+MX0EAWVrd5wC7aAF1
|
||||
+h6Fu7ykZB4ggUjQAWwECQQD+AUiDOEO+8btLJ135dQfSGc5VFcZiequnKWVm6uXt
|
||||
+rX771hEYjYMjLqWGFg9G4gE3GuABM5chMINuQQUivy8tAkEA/cxfy19XkjtqcMgE
|
||||
+x/UDt6Nr+Ky/tk+4Y65WxPRDas0uxFOPk/vEjgVmz1k/TAy9G4giisluTvtmltr5
|
||||
+DCLocQJBAJnRHx9PiD7uVhRJz6/L/iNuOzPtTsi+Loq5F83+O6T15qsM1CeBMsOw
|
||||
+cM5FN5UeMcwz+yjfHAsePMkcmMaU7jUCQHlg9+N8upXuIo7Dqj2zOU7nMmkgvSNE
|
||||
+5yuNImRZabC3ZolwaTdd7nf5r1y1Eyec5Ag5yENV6JKPe1Xkbb1XKJECQDngA0h4
|
||||
+6ATvfP1Vrx4CbP11eKXbCsZ9OGPHSgyvVjn68oY5ZP3uPsIattoN7dE2BRfuJm7m
|
||||
+F0nIdUAhR0yTfKM=
|
||||
+-----END PRIVATE KEY-----
|
||||
+'
|
||||
+
|
||||
+do_sign=false
|
||||
+PRIVATE_KEY_PATH=${PRIVATE_KEY_PATH:-}
|
||||
+private_key_path="${PRIVATE_KEY_PATH}"
|
||||
+outfile=""
|
||||
+machine=""
|
||||
+version=""
|
||||
+default_cpld_name="cpld.svf"
|
||||
+while [[ $# -gt 0 ]]; do
|
||||
+ key="$1"
|
||||
+ case $key in
|
||||
+ -o|--out)
|
||||
+ outfile="$2"
|
||||
+ shift 2
|
||||
+ ;;
|
||||
+ -s|--sign)
|
||||
+ do_sign=true
|
||||
+ if [[ -n "${2}" && "${2}" != -* ]]; then
|
||||
+ private_key_path="$2"
|
||||
+ shift 2
|
||||
+ else
|
||||
+ shift 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ -m|--machine)
|
||||
+ machine="$2"
|
||||
+ shift 2
|
||||
+ ;;
|
||||
+ -v|--version)
|
||||
+ version="$2"
|
||||
+ shift 2
|
||||
+ ;;
|
||||
+ -h|--help)
|
||||
+ echo "$help"
|
||||
+ exit
|
||||
+ ;;
|
||||
+ -*)
|
||||
+ echo "Unrecognised option $1"
|
||||
+ echo "$help"
|
||||
+ exit
|
||||
+ ;;
|
||||
+ *)
|
||||
+ file="$1"
|
||||
+ shift 1
|
||||
+ ;;
|
||||
+ esac
|
||||
+done
|
||||
+
|
||||
+if [ ! -f "${file}" ]; then
|
||||
+ echo "${file} not found, Please enter a valid Cpld image file"
|
||||
+ echo "$help"
|
||||
+ exit 1
|
||||
+else
|
||||
+ cp "$file" $default_cpld_name
|
||||
+ echo "$file"
|
||||
+fi
|
||||
+
|
||||
+if [[ -z $version ]]; then
|
||||
+ echo "Please provide version of image with -v option"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+if [[ -z $outfile ]]; then
|
||||
+ outfile=$(pwd)/obmc-cpld.tar.gz
|
||||
+else
|
||||
+ if [[ $outfile != /* ]]; then
|
||||
+ outfile=$(pwd)/$outfile
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+scratch_dir=$(mktemp -d)
|
||||
+# Remove the temp directory on exit.
|
||||
+# The files in the temp directory may contain read-only files, so add
|
||||
+# --interactive=never to skip the prompt.
|
||||
+trap '{ rm -r --interactive=never ${scratch_dir}; }' EXIT
|
||||
+
|
||||
+if [[ "${do_sign}" == true ]]; then
|
||||
+ if [[ -z "${private_key_path}" ]]; then
|
||||
+ private_key_path=${scratch_dir}/OpenBMC.priv
|
||||
+ echo "${private_key}" > "${private_key_path}"
|
||||
+ echo "Image is NOT secure!! Signing with the open private key!"
|
||||
+ else
|
||||
+ if [[ ! -f "${private_key_path}" ]]; then
|
||||
+ echo "Couldn't find private key ${private_key_path}."
|
||||
+ exit 1
|
||||
+ fi
|
||||
+
|
||||
+ echo "Signing with ${private_key_path}."
|
||||
+ fi
|
||||
+
|
||||
+ public_key_file=publickey
|
||||
+ public_key_path=${scratch_dir}/$public_key_file
|
||||
+ openssl pkey -in "${private_key_path}" -pubout -out "${public_key_path}"
|
||||
+fi
|
||||
+
|
||||
+manifest_location="MANIFEST"
|
||||
+files_to_sign="$manifest_location $public_key_file"
|
||||
+
|
||||
+# Go to scratch_dir
|
||||
+cp "${file}" "${scratch_dir}"
|
||||
+cd "${scratch_dir}"
|
||||
+mv "${file}" ${default_cpld_name}
|
||||
+file=${default_cpld_name}
|
||||
+files_to_sign+=" $(basename ${file})"
|
||||
+
|
||||
+echo "Creating MANIFEST for the image"
|
||||
+echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.CPLD\n\
|
||||
+version=$version" > $manifest_location
|
||||
+
|
||||
+if [[ -n "${machine}" ]]; then
|
||||
+ echo -e "MachineName=${machine}" >> $manifest_location
|
||||
+fi
|
||||
+
|
||||
+if [[ "${do_sign}" == true ]]; then
|
||||
+ private_key_name=$(basename "${private_key_path}")
|
||||
+ key_type="${private_key_name%.*}"
|
||||
+ echo KeyType="${key_type}" >> $manifest_location
|
||||
+ echo HashType="RSA-SHA256" >> $manifest_location
|
||||
+
|
||||
+ for file in $files_to_sign; do
|
||||
+ openssl dgst -sha256 -sign "${private_key_path}" -out "${file}.sig" "$file"
|
||||
+ done
|
||||
+
|
||||
+ additional_files="*.sig"
|
||||
+fi
|
||||
+# shellcheck disable=SC2086
|
||||
+tar -czvf $outfile $files_to_sign $additional_files
|
||||
+echo "Cpld image tarball is at $outfile"
|
||||
@@ -0,0 +1,128 @@
|
||||
#!/bin/bash
|
||||
|
||||
bios_image=$(ls $1/*.bin)
|
||||
|
||||
bios_mtd="/dev/mtd/bios"
|
||||
bios_id=$(basename "$1")
|
||||
bios_slot=""
|
||||
|
||||
power_obj="xyz.openbmc_project.State.Chassis"
|
||||
power_path="/xyz/openbmc_project/state/chassis0"
|
||||
power_intf="xyz.openbmc_project.State.Chassis"
|
||||
power_prop="CurrentPowerState"
|
||||
|
||||
update_obj="xyz.openbmc_project.Software.BMC.Updater"
|
||||
update_path="/xyz/openbmc_project/software/"
|
||||
target_intf="xyz.openbmc_project.Software.UpdateTarget"
|
||||
target_prop="UpdateTargetSlot"
|
||||
|
||||
check_env() {
|
||||
echo "[Info]: Check Environment."
|
||||
#check power status. if On, set to Off.
|
||||
#power_status=$(busctl get-property $power_obj $power_path $power_intf $power_prop)
|
||||
#if [[ $power_status == *On* ]]; then
|
||||
# busctl set-property $power_obj $power_path $power_intf RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.Off
|
||||
#fi
|
||||
sleep 10
|
||||
|
||||
#add other action to prepare flash bios.
|
||||
bios_slot=$(busctl get-property $update_obj $update_path$bios_id $target_intf $target_prop)
|
||||
bios_slot=$(echo "$bios_slot" |cut -d "\"" -f2)
|
||||
if [ "$bios_slot" = "xyz.openbmc_project.Software.UpdateTarget.TargetSlot.Primary" ]; then
|
||||
bios_slot="Primary"
|
||||
elif [ "$bios_slot" = "xyz.openbmc_project.Software.UpdateTarget.TargetSlot.Secondary" ]; then
|
||||
bios_slot="Backup"
|
||||
elif [ "$bios_slot" = "xyz.openbmc_project.Software.UpdateTarget.TargetSlot.Both" ]; then
|
||||
bios_slot="Both"
|
||||
fi
|
||||
}
|
||||
|
||||
switch_primary_flash_to_bmc() {
|
||||
echo "[Info]: Switch Main BIOS Flash To BMC."
|
||||
if [ -d /sys/bus/platform/drivers/spi-aspeed-smc/1e630000.spi ]; then
|
||||
echo -n "1e630000.spi" > /sys/bus/platform/drivers/spi-aspeed-smc/unbind
|
||||
fi
|
||||
|
||||
#Set Mux to bmc.
|
||||
i2ctransfer -y -a 0 w3@0x0d 0xa0 0x03 0x80
|
||||
|
||||
#Switch to primary BIOS flash
|
||||
i2ctransfer -y -a 0 w3@0x0d 0xa1 0x03 0x80
|
||||
|
||||
#mount bios flash to BMC
|
||||
echo -n "1e630000.spi" > /sys/bus/platform/drivers/spi-aspeed-smc/bind
|
||||
sleep 5
|
||||
cat /proc/mtd
|
||||
}
|
||||
|
||||
switch_secondary_flash_to_bmc() {
|
||||
echo "[Info]: Switch Backup BIOS Flash To BMC."
|
||||
if [ -d /sys/bus/platform/drivers/spi-aspeed-smc/1e630000.spi ]; then
|
||||
echo -n "1e630000.spi" > /sys/bus/platform/drivers/spi-aspeed-smc/unbind
|
||||
fi
|
||||
|
||||
#Set Mux to bmc.
|
||||
i2ctransfer -y -a 0 w3@0x0d 0xa0 0x03 0x80
|
||||
|
||||
#Switch to backup BIOS flash
|
||||
i2ctransfer -y -a 0 w3@0x0d 0xa1 0x03 0x40
|
||||
|
||||
#mount bios flash to BMC
|
||||
echo -n "1e630000.spi" > /sys/bus/platform/drivers/spi-aspeed-smc/bind
|
||||
sleep 5
|
||||
cat /proc/mtd
|
||||
}
|
||||
|
||||
flash_bios() {
|
||||
echo "[Info]: Flash BIOS."
|
||||
#Which flash need to be update, e.g. get for Manifest or Settings.
|
||||
# bios_update_select=
|
||||
#Check MTD Exist
|
||||
|
||||
if [[ ! -e $bios_mtd ]]; then
|
||||
echo "[Error]: bios flash not found in $bios_mtd"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
echo "[Info]: bios_image=$bios_image"
|
||||
echo "[Info]: bios_mtd=$bios_mtd"
|
||||
echo "/usr/sbin/flashcp $bios_image $bios_mtd"
|
||||
/usr/sbin/flashcp $bios_image $bios_mtd
|
||||
}
|
||||
|
||||
switch_flash_to_cpu() {
|
||||
echo "[Info]: Switch Main BIOS Flash To CPU."
|
||||
echo -n "1e630000.spi" > /sys/bus/platform/drivers/spi-aspeed-smc/unbind
|
||||
|
||||
sleep 5
|
||||
#Set Mux to CPU.
|
||||
i2ctransfer -y -a 0 w3@0x0d 0xa0 0x03 0x00
|
||||
}
|
||||
|
||||
power_on_system() {
|
||||
echo "[Info]: Power On System After Update BIOS."
|
||||
#check power status. if Off, set to On.
|
||||
power_status=$(busctl get-property $power_obj $power_path $power_intf $power_prop)
|
||||
if [[ $power_status == *Off* ]]; then
|
||||
sleep 5
|
||||
busctl set-property $power_obj $power_path $power_intf RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.On
|
||||
fi
|
||||
}
|
||||
|
||||
check_env
|
||||
if [ "$bios_slot" = "Primary" ]; then
|
||||
switch_primary_flash_to_bmc
|
||||
flash_bios
|
||||
elif [ "$bios_slot" = "Backup" ]; then
|
||||
switch_secondary_flash_to_bmc
|
||||
flash_bios
|
||||
elif [ "$bios_slot" = "Both" ]; then
|
||||
switch_primary_flash_to_bmc
|
||||
flash_bios
|
||||
sleep 5
|
||||
switch_secondary_flash_to_bmc
|
||||
flash_bios
|
||||
fi
|
||||
switch_flash_to_cpu
|
||||
#power_on_system
|
||||
sleep 5
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
cpld_image=$(ls $1/*.svf)
|
||||
jtag_node="/dev/jtag1"
|
||||
|
||||
check_env() {
|
||||
echo "[Info]: Check Environment."
|
||||
#add action to prepare flash cpld.
|
||||
#check cpld exist ?
|
||||
|
||||
}
|
||||
|
||||
flash_cpld() {
|
||||
echo "[Info]: Flash CPLD."
|
||||
echo "[Info]: Switch CPLD JTAG mux to BMC."
|
||||
gpioset 0 124=1
|
||||
gpioset 0 122=0
|
||||
|
||||
echo "[Info]: CPLD Image:$cpld_image"
|
||||
/usr/bin/svf -n $jtag_node -s -p $cpld_image
|
||||
}
|
||||
|
||||
enable_new_fw() {
|
||||
echo "[Info]: Enable New Firmware."
|
||||
}
|
||||
|
||||
check_env
|
||||
flash_cpld
|
||||
enable_new_fw
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Flash image %I to CPLD
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=no
|
||||
ExecStartPre=/bin/sh -c 'touch /tmp/mbcpld_update_status'
|
||||
ExecStart=/usr/bin/flashcpld /tmp/images/%i
|
||||
ExecStopPost=/bin/sh -c 'echo $EXIT_STATUS > /tmp/mbcpld_update_status'
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Flash Host Bios image %I to Host
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=no
|
||||
ExecStartPre=/bin/sh -c 'touch /tmp/bios_update_status'
|
||||
ExecStart=/usr/bin/flashbios /tmp/images/%i
|
||||
ExecStopPost=/bin/sh -c 'echo $EXIT_STATUS > /tmp/bios_update_status'
|
||||
@@ -0,0 +1,32 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
|
||||
SRC_URI += " \
|
||||
file://obmc-flash-cpld@.service \
|
||||
file://obmc-flash-host-bios@.service \
|
||||
file://flashbios \
|
||||
file://flashcpld "
|
||||
|
||||
SRC_URI += " \
|
||||
file://0001-Add-CPLD-Update-for-SoftWare-Manager.patch \
|
||||
file://0003-add-shell-script-for-generate-cpld-image-tar.patch \
|
||||
file://0001-Detect-boot-image-source.patch \
|
||||
"
|
||||
|
||||
PACKAGECONFIG[cpld_update] = "-Dcpld-upgrade=enabled, -Dcpld-upgrade=disabled"
|
||||
PACKAGECONFIG += " cpld_update flash_bios static-dual-image"
|
||||
DEPENDS += "${@bb.utils.contains('PACKAGECONFIG', 'cpld_update', 'svf', '', d)}"
|
||||
|
||||
do_install:append() {
|
||||
install -d ${D}${bindir}
|
||||
install -d ${D}${systemd_system_unitdir}
|
||||
install -m 0755 ${WORKDIR}/flashbios ${D}${bindir}
|
||||
install -m 0755 ${WORKDIR}/flashcpld ${D}${bindir}
|
||||
install -m 0644 ${WORKDIR}/obmc-flash-cpld@.service ${D}${systemd_system_unitdir}
|
||||
install -m 0644 ${WORKDIR}/obmc-flash-host-bios@.service ${D}${systemd_system_unitdir}
|
||||
}
|
||||
|
||||
FILES:${PN}-updater += "\
|
||||
${systemd_system_unitdir}/obmc-flash-cpld@.service \
|
||||
${systemd_system_unitdir}/obmc-flash-host-bios@.service \
|
||||
${bindir}/flashbios \
|
||||
${bindir}/flashcpld "
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
|
||||
LICENSE = "CLOSED"
|
||||
SRC_URI += " \
|
||||
file://ast-jtag.c \
|
||||
file://ast-jtag.h \
|
||||
file://jtag.h \
|
||||
file://main.c \
|
||||
file://Makefile \
|
||||
file://svf.c \
|
||||
file://svf.h"
|
||||
TARGET_CC_ARCH += "${LDFLAGS}"
|
||||
inherit pkgconfig
|
||||
S = "${WORKDIR}"
|
||||
EXTRA_OEMAKE += "INSTALL_DIR=${D}${bindir}"
|
||||
|
||||
do_install(){
|
||||
install -d ${D}${bindir}
|
||||
install -m 0755 ${S}/svf ${D}${bindir}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
STATE RESET;
|
||||
HDR 0;
|
||||
HIR 0;
|
||||
TDR 0;
|
||||
TIR 0;
|
||||
ENDDR DRPAUSE;
|
||||
ENDIR IRPAUSE;
|
||||
! FREQUENCY 1.00e+006 HZ;
|
||||
STATE IDLE;
|
||||
SIR 8 TDI (E0);
|
||||
SDR 32 TDI (00000000)
|
||||
TDO (012B5043)
|
||||
MASK (FFFFFFFF);
|
||||
SIR 8 TDI (1C);
|
||||
SDR 664 TDI (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFF);
|
||||
SIR 8 TDI (3C);
|
||||
RUNTEST IDLE 2 TCK 1.00E-003 SEC;
|
||||
SDR 32 TDI (00000000)
|
||||
TDO (00000000)
|
||||
MASK (00000020);
|
||||
SIR 8 TDI (C6);
|
||||
SDR 8 TDI (00);
|
||||
RUNTEST IDLE 2 TCK 1.00E-003 SEC;
|
||||
SIR 8 TDI (0E);
|
||||
SDR 8 TDI (01);
|
||||
RUNTEST IDLE 2 TCK 1.00E+000 SEC;
|
||||
SIR 8 TDI (FF)
|
||||
TDO (00)
|
||||
MASK (C0);
|
||||
SIR 8 TDI (C6);
|
||||
SDR 8 TDI (08);
|
||||
RUNTEST IDLE 2 TCK 1.00E-003 SEC;
|
||||
SIR 8 TDI (3C);
|
||||
RUNTEST IDLE 2 TCK 1.00E-003 SEC;
|
||||
SDR 32 TDI (00000000)
|
||||
TDO (00000000)
|
||||
MASK (00024040);
|
||||
SIR 8 TDI (0E);
|
||||
SDR 8 TDI (0E);
|
||||
RUNTEST IDLE 2 TCK 3.00E+001 SEC;
|
||||
SIR 8 TDI (F0);
|
||||
SDR 1 TDI (0)
|
||||
TDO (0);
|
||||
SIR 8 TDI (3C);
|
||||
RUNTEST IDLE 2 TCK 1.00E-003 SEC;
|
||||
SDR 32 TDI (00000000)
|
||||
TDO (00000000)
|
||||
MASK (00003000);
|
||||
SIR 8 TDI (26);
|
||||
RUNTEST IDLE 2 TCK 1.00E+000 SEC;
|
||||
SIR 8 TDI (FF);
|
||||
RUNTEST IDLE 100 TCK 1.00E-001 SEC;
|
||||
STATE RESET;
|
||||
+67679
File diff suppressed because it is too large
Load Diff
+33872
File diff suppressed because it is too large
Load Diff
+13
@@ -0,0 +1,13 @@
|
||||
CFLAGS += -Wall
|
||||
OBJS = main.o ast-jtag.o svf.o
|
||||
EXE = svf
|
||||
.c.o:
|
||||
$(CC) -c $<
|
||||
$(EXE): $(OBJS)
|
||||
$(CC) $(OBJS) -o $@
|
||||
all:$(EXE)
|
||||
clean:
|
||||
rm -f $(EXE) $(OBJS)
|
||||
install:
|
||||
cp $(EXE) $(INSTALL_DIR)
|
||||
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 Aspeed Technology Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include "ast-jtag.h"
|
||||
|
||||
int jtag_fd;
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
#define ast_jtag_printf(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define ast_jtag_printf(...)
|
||||
#endif
|
||||
|
||||
/*************************************************************************************/
|
||||
/* AST JTAG LIB */
|
||||
int ast_jtag_open(char *dev)
|
||||
{
|
||||
jtag_fd = open(dev, O_RDWR);
|
||||
if (jtag_fd == -1) {
|
||||
printf("Can't open %s, please install driver!! \n", dev);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ast_jtag_close(void)
|
||||
{
|
||||
close(jtag_fd);
|
||||
}
|
||||
|
||||
unsigned int ast_get_jtag_freq(void)
|
||||
{
|
||||
int retval;
|
||||
unsigned int freq = 0;
|
||||
retval = ioctl(jtag_fd, JTAG_GIOCFREQ, &freq);
|
||||
if (retval == -1) {
|
||||
perror("ioctl JTAG get freq fail!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
int ast_set_jtag_mode(uint8_t sw_mode)
|
||||
{
|
||||
struct jtag_mode jtag_mode;
|
||||
int retval;
|
||||
|
||||
jtag_mode.feature = JTAG_XFER_MODE;
|
||||
jtag_mode.mode = sw_mode ? JTAG_XFER_SW_MODE : JTAG_XFER_HW_MODE;
|
||||
retval = ioctl(jtag_fd, JTAG_SIOCMODE, &jtag_mode);
|
||||
if (retval == -1) {
|
||||
perror("ioctl JTAG set mode fail!\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ast_set_jtag_freq(unsigned int freq)
|
||||
{
|
||||
int retval;
|
||||
unsigned int jtag_freq = freq;
|
||||
retval = ioctl(jtag_fd, JTAG_SIOCFREQ, &jtag_freq);
|
||||
if (retval == -1) {
|
||||
perror("ioctl JTAG set freq fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ast_get_tap_state(enum jtag_tapstate* tap_state)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (tap_state == NULL)
|
||||
return -1;
|
||||
retval = ioctl(jtag_fd, JTAG_GIOCSTATUS, tap_state);
|
||||
if (retval == -1) {
|
||||
perror("ioctl JTAG get tap state fail!\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ast_jtag_run_test_idle(unsigned char end, unsigned int tck)
|
||||
{
|
||||
|
||||
int retval;
|
||||
struct jtag_tap_state run_idle;
|
||||
|
||||
run_idle.from = JTAG_STATE_CURRENT;
|
||||
run_idle.reset = JTAG_NO_RESET;
|
||||
run_idle.endstate = end;
|
||||
run_idle.tck = tck;
|
||||
|
||||
ast_jtag_printf("from:%d, reset:%d, endstate:%d, tck:%d\n", run_idle.from, run_idle.reset, run_idle.endstate, run_idle.tck);
|
||||
|
||||
retval = ioctl(jtag_fd, JTAG_SIOCSTATE, &run_idle);
|
||||
if (retval == -1) {
|
||||
printf("ioctl JTAG run reset fail! error:%s\n",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(end)
|
||||
usleep(tck*2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
extern int svf_line_number;
|
||||
int ast_jtag_xfer(unsigned char endsts, unsigned int len, unsigned int *out, unsigned int *in, enum jtag_xfer_type type)
|
||||
{
|
||||
int retval;
|
||||
enum jtag_tapstate current_state;
|
||||
struct jtag_xfer xfer;
|
||||
unsigned int send_len_byte;
|
||||
|
||||
ast_get_tap_state(¤t_state);
|
||||
xfer.type = type;
|
||||
xfer.direction = JTAG_READ_WRITE_XFER;
|
||||
xfer.from = current_state;
|
||||
xfer.endstate = endsts;
|
||||
xfer.padding = 0;
|
||||
xfer.length = len;
|
||||
xfer.tdio = (unsigned int)out;
|
||||
send_len_byte = DIV_ROUND_UP(xfer.length, BITS_PER_BYTE);
|
||||
|
||||
#if DEBUG
|
||||
int i;
|
||||
for (i = 0; i < DIV_ROUND_UP(send_len_byte, 4); i++)
|
||||
printf("tdo:%08x\n", out[i]);
|
||||
#endif
|
||||
retval = ioctl(jtag_fd, JTAG_IOCXFER, &xfer);
|
||||
if (retval == -1) {
|
||||
perror("ioctl JTAG sir fail!\n");
|
||||
return -1;
|
||||
}
|
||||
memcpy(in, out, send_len_byte);
|
||||
#if DEBUG
|
||||
for (i = 0; i < DIV_ROUND_UP(send_len_byte, 4); i++)
|
||||
printf("tdi:%08x\n",out[i]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2020 Aspeed Technology Inc.
|
||||
*/
|
||||
#include "stdint.h"
|
||||
typedef uint8_t __u8;
|
||||
typedef uint32_t __u32;
|
||||
typedef unsigned long long __u64;
|
||||
|
||||
#include "jtag.h"
|
||||
|
||||
#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
||||
#define BITS_PER_BYTE 8
|
||||
/******************************************************************************************************************/
|
||||
int ast_jtag_open(char *dev);
|
||||
void ast_jtag_close(void);
|
||||
int ast_set_jtag_mode(uint8_t sw_mode);
|
||||
unsigned int ast_get_jtag_freq(void);
|
||||
int ast_set_jtag_freq(unsigned int freq);
|
||||
int ast_jtag_run_test_idle(unsigned char end, unsigned int tck);
|
||||
int ast_jtag_xfer(unsigned char endsts, unsigned int len, unsigned int *out, unsigned int *in, enum jtag_xfer_type type);
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved. */
|
||||
/* Copyright (c) 2018 Oleksandr Shamray <oleksandrs@mellanox.com> */
|
||||
/* Copyright (c) 2019 Intel Corporation */
|
||||
|
||||
#ifndef __UAPI_LINUX_JTAG_H
|
||||
#define __UAPI_LINUX_JTAG_H
|
||||
|
||||
/*
|
||||
* JTAG_XFER_MODE: JTAG transfer mode. Used to set JTAG controller transfer mode
|
||||
* This is bitmask for feature param in jtag_mode for ioctl JTAG_SIOCMODE
|
||||
*/
|
||||
#define JTAG_XFER_MODE 0
|
||||
/*
|
||||
* JTAG_CONTROL_MODE: JTAG controller mode. Used to set JTAG controller mode
|
||||
* This is bitmask for feature param in jtag_mode for ioctl JTAG_SIOCMODE
|
||||
*/
|
||||
#define JTAG_CONTROL_MODE 1
|
||||
/*
|
||||
* JTAG_MASTER_OUTPUT_DISABLE: JTAG master mode output disable, it is used to
|
||||
* enable other devices to own the JTAG bus.
|
||||
* This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
|
||||
*/
|
||||
#define JTAG_MASTER_OUTPUT_DISABLE 0
|
||||
/*
|
||||
* JTAG_MASTER_MODE: JTAG master mode. Used to set JTAG controller master mode
|
||||
* This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
|
||||
*/
|
||||
#define JTAG_MASTER_MODE 1
|
||||
/*
|
||||
* JTAG_XFER_HW_MODE: JTAG hardware mode. Used to set HW drived or bitbang
|
||||
* mode. This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
|
||||
*/
|
||||
#define JTAG_XFER_HW_MODE 1
|
||||
/*
|
||||
* JTAG_XFER_SW_MODE: JTAG software mode. Used to set SW drived or bitbang
|
||||
* mode. This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
|
||||
*/
|
||||
#define JTAG_XFER_SW_MODE 0
|
||||
|
||||
/**
|
||||
* enum jtag_tapstate:
|
||||
*
|
||||
* @JTAG_STATE_TLRESET: JTAG state machine Test Logic Reset state
|
||||
* @JTAG_STATE_IDLE: JTAG state machine IDLE state
|
||||
* @JTAG_STATE_SELECTDR: JTAG state machine SELECT_DR state
|
||||
* @JTAG_STATE_CAPTUREDR: JTAG state machine CAPTURE_DR state
|
||||
* @JTAG_STATE_SHIFTDR: JTAG state machine SHIFT_DR state
|
||||
* @JTAG_STATE_EXIT1DR: JTAG state machine EXIT-1 DR state
|
||||
* @JTAG_STATE_PAUSEDR: JTAG state machine PAUSE_DR state
|
||||
* @JTAG_STATE_EXIT2DR: JTAG state machine EXIT-2 DR state
|
||||
* @JTAG_STATE_UPDATEDR: JTAG state machine UPDATE DR state
|
||||
* @JTAG_STATE_SELECTIR: JTAG state machine SELECT_IR state
|
||||
* @JTAG_STATE_CAPTUREIR: JTAG state machine CAPTURE_IR state
|
||||
* @JTAG_STATE_SHIFTIR: JTAG state machine SHIFT_IR state
|
||||
* @JTAG_STATE_EXIT1IR: JTAG state machine EXIT-1 IR state
|
||||
* @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state
|
||||
* @JTAG_STATE_EXIT2IR: JTAG state machine EXIT-2 IR state
|
||||
* @JTAG_STATE_UPDATEIR: JTAG state machine UPDATE IR state
|
||||
* @JTAG_STATE_CURRENT: JTAG current state, saved by driver
|
||||
*/
|
||||
enum jtag_tapstate {
|
||||
JTAG_STATE_TLRESET,
|
||||
JTAG_STATE_IDLE,
|
||||
JTAG_STATE_SELECTDR,
|
||||
JTAG_STATE_CAPTUREDR,
|
||||
JTAG_STATE_SHIFTDR,
|
||||
JTAG_STATE_EXIT1DR,
|
||||
JTAG_STATE_PAUSEDR,
|
||||
JTAG_STATE_EXIT2DR,
|
||||
JTAG_STATE_UPDATEDR,
|
||||
JTAG_STATE_SELECTIR,
|
||||
JTAG_STATE_CAPTUREIR,
|
||||
JTAG_STATE_SHIFTIR,
|
||||
JTAG_STATE_EXIT1IR,
|
||||
JTAG_STATE_PAUSEIR,
|
||||
JTAG_STATE_EXIT2IR,
|
||||
JTAG_STATE_UPDATEIR,
|
||||
JTAG_STATE_CURRENT
|
||||
};
|
||||
|
||||
/**
|
||||
* enum jtag_reset:
|
||||
*
|
||||
* @JTAG_NO_RESET: JTAG run TAP from current state
|
||||
* @JTAG_FORCE_RESET: JTAG force TAP to reset state
|
||||
*/
|
||||
enum jtag_reset {
|
||||
JTAG_NO_RESET = 0,
|
||||
JTAG_FORCE_RESET = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum jtag_xfer_type:
|
||||
*
|
||||
* @JTAG_SIR_XFER: SIR transfer
|
||||
* @JTAG_SDR_XFER: SDR transfer
|
||||
*/
|
||||
enum jtag_xfer_type {
|
||||
JTAG_SIR_XFER = 0,
|
||||
JTAG_SDR_XFER = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum jtag_xfer_direction:
|
||||
*
|
||||
* @JTAG_READ_XFER: read transfer
|
||||
* @JTAG_WRITE_XFER: write transfer
|
||||
* @JTAG_READ_WRITE_XFER: read & write transfer
|
||||
*/
|
||||
enum jtag_xfer_direction {
|
||||
JTAG_READ_XFER = 1,
|
||||
JTAG_WRITE_XFER = 2,
|
||||
JTAG_READ_WRITE_XFER = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct jtag_tap_state - forces JTAG state machine to go into a TAPC
|
||||
* state
|
||||
*
|
||||
* @reset: 0 - run IDLE/PAUSE from current state
|
||||
* 1 - go through TEST_LOGIC/RESET state before IDLE/PAUSE
|
||||
* @end: completion flag
|
||||
* @tck: clock counter
|
||||
*
|
||||
* Structure provide interface to JTAG device for JTAG set state execution.
|
||||
*/
|
||||
struct jtag_tap_state {
|
||||
__u8 reset;
|
||||
__u8 from;
|
||||
__u8 endstate;
|
||||
__u32 tck;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* union pad_config - Padding Configuration:
|
||||
*
|
||||
* @type: transfer type
|
||||
* @pre_pad_number: Number of prepadding bits bit[11:0]
|
||||
* @post_pad_number: Number of prepadding bits bit[23:12]
|
||||
* @pad_data : Bit value to be used by pre and post padding bit[24]
|
||||
* @int_value: unsigned int packed padding configuration value bit[32:0]
|
||||
*
|
||||
* Structure provide pre and post padding configuration in a single __u32
|
||||
*/
|
||||
union pad_config {
|
||||
struct {
|
||||
__u32 pre_pad_number : 12;
|
||||
__u32 post_pad_number : 12;
|
||||
__u32 pad_data : 1;
|
||||
__u32 rsvd : 7;
|
||||
};
|
||||
__u32 int_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct jtag_xfer - jtag xfer:
|
||||
*
|
||||
* @type: transfer type
|
||||
* @direction: xfer direction
|
||||
* @from: xfer current state
|
||||
* @endstate: xfer end state
|
||||
* @padding: xfer padding
|
||||
* @length: xfer bits length
|
||||
* @tdio : xfer data array
|
||||
*
|
||||
* Structure provide interface to JTAG device for JTAG SDR/SIR xfer execution.
|
||||
*/
|
||||
struct jtag_xfer {
|
||||
__u8 type;
|
||||
__u8 direction;
|
||||
__u8 from;
|
||||
__u8 endstate;
|
||||
__u32 padding;
|
||||
__u32 length;
|
||||
__u64 tdio;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct bitbang_packet - jtag bitbang array packet:
|
||||
*
|
||||
* @data: JTAG Bitbang struct array pointer(input/output)
|
||||
* @length: array size (input)
|
||||
*
|
||||
* Structure provide interface to JTAG device for JTAG bitbang bundle execution
|
||||
*/
|
||||
struct bitbang_packet {
|
||||
struct tck_bitbang *data;
|
||||
__u32 length;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* struct jtag_bitbang - jtag bitbang:
|
||||
*
|
||||
* @tms: JTAG TMS
|
||||
* @tdi: JTAG TDI (input)
|
||||
* @tdo: JTAG TDO (output)
|
||||
*
|
||||
* Structure provide interface to JTAG device for JTAG bitbang execution.
|
||||
*/
|
||||
struct tck_bitbang {
|
||||
__u8 tms;
|
||||
__u8 tdi;
|
||||
__u8 tdo;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* struct jtag_mode - jtag mode:
|
||||
*
|
||||
* @feature: 0 - JTAG feature setting selector for JTAG controller HW/SW
|
||||
* 1 - JTAG feature setting selector for controller bus master
|
||||
* mode output (enable / disable).
|
||||
* @mode: (0 - SW / 1 - HW) for JTAG_XFER_MODE feature(0)
|
||||
* (0 - output disable / 1 - output enable) for JTAG_CONTROL_MODE
|
||||
* feature(1)
|
||||
*
|
||||
* Structure provide configuration modes to JTAG device.
|
||||
*/
|
||||
struct jtag_mode {
|
||||
__u32 feature;
|
||||
__u32 mode;
|
||||
};
|
||||
|
||||
/* ioctl interface */
|
||||
#define __JTAG_IOCTL_MAGIC 0xb2
|
||||
|
||||
#define JTAG_SIOCSTATE _IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_tap_state)
|
||||
#define JTAG_SIOCFREQ _IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int)
|
||||
#define JTAG_GIOCFREQ _IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int)
|
||||
#define JTAG_IOCXFER _IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer)
|
||||
#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtag_tapstate)
|
||||
#define JTAG_SIOCMODE _IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int)
|
||||
#define JTAG_IOCBITBANG _IOW(__JTAG_IOCTL_MAGIC, 6, unsigned int)
|
||||
|
||||
|
||||
/******************************************************************************************************************/
|
||||
int ast_jtag_open(char *dev);
|
||||
void ast_jtag_close(void);
|
||||
unsigned int ast_get_jtag_freq(void);
|
||||
int ast_set_jtag_freq(unsigned int freq);
|
||||
int ast_jtag_run_test_idle(unsigned char end, unsigned int tck);
|
||||
int ast_jtag_xfer(unsigned char endsts, unsigned int len, unsigned int *out, unsigned int *in, enum jtag_xfer_type type);
|
||||
int ast_jtag_state_reset_force(unsigned char end, unsigned int tck);
|
||||
|
||||
#endif /* __UAPI_LINUX_JTAG_H */
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 Aspeed Technology Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include "ast-jtag.h"
|
||||
#include "svf.h"
|
||||
|
||||
#define ERROR_OK (0)
|
||||
#define ERROR_NO_CONFIG_FILE (-2)
|
||||
#define ERROR_BUF_TOO_SMALL (-3)
|
||||
#define ERROR_FAIL (-4)
|
||||
#define ERROR_WAIT (-5)
|
||||
#define ERROR_TIMEOUT_REACHED (-6)
|
||||
|
||||
enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
|
||||
int loglevel = LOG_WARN;
|
||||
|
||||
static void
|
||||
usage(FILE *fp, int argc, char **argv)
|
||||
{
|
||||
if(0)
|
||||
{
|
||||
argc = argc;
|
||||
}
|
||||
fprintf(fp,
|
||||
"Usage: %s [options]\n\n"
|
||||
"Options:\n"
|
||||
" -h | --help Print this message\n"
|
||||
" -d | --debug Set log level, default = 3\n"
|
||||
" -n | --node jtag device node\n"
|
||||
" -f | --frequency frequency\n"
|
||||
" -p | --play play SVF file\n"
|
||||
" -s | --software software mode\n"
|
||||
"",
|
||||
argv[0]);
|
||||
}
|
||||
|
||||
static const char short_options [] = "hsd:n:f:p:";
|
||||
|
||||
|
||||
|
||||
static const struct option
|
||||
long_options [] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "debug", required_argument, NULL, 'd' },
|
||||
{ "node", required_argument, NULL, 'n' },
|
||||
{ "fequency", required_argument, NULL, 'f' },
|
||||
{ "play", required_argument, NULL, 'p' },
|
||||
{ "software", no_argument, NULL, 's' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*********************************************************************************/
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
|
||||
/*************************************************************************************/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
char option;
|
||||
char svf_name[100] = "";
|
||||
char dev_name[100] = "";
|
||||
int svf = 0;
|
||||
unsigned int freq = 0;
|
||||
unsigned int jtag_freq = 0;
|
||||
uint8_t sw_mode = 0;
|
||||
|
||||
while ((option = getopt_long(argc, argv, short_options, long_options, NULL)) != (char) -1) {
|
||||
switch (option) {
|
||||
case 'h':
|
||||
usage(stdout, argc, argv);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'd':
|
||||
loglevel = atol(optarg);
|
||||
printf("loglevel %d\n", loglevel);
|
||||
break;
|
||||
case 'n':
|
||||
strcpy(dev_name, optarg);
|
||||
if (!strcmp(dev_name, "")) {
|
||||
printf("No dev file name!\n");
|
||||
usage(stdout, argc, argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
freq = atol(optarg);
|
||||
printf("frequency %d\n", freq);
|
||||
break;
|
||||
case 'p':
|
||||
svf = 1;
|
||||
strcpy(svf_name, optarg);
|
||||
if (!strcmp(svf_name, "")) {
|
||||
printf("No out file name!\n");
|
||||
usage(stdout, argc, argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
sw_mode = 1;
|
||||
break;
|
||||
default:
|
||||
usage(stdout, argc, argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (!svf){
|
||||
usage(stdout, argc, argv);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#if 1
|
||||
if (ast_jtag_open(dev_name))
|
||||
exit(1);
|
||||
|
||||
ast_set_jtag_mode(sw_mode);
|
||||
//show current ast jtag configuration
|
||||
jtag_freq = ast_get_jtag_freq();
|
||||
|
||||
if (jtag_freq == 0) {
|
||||
perror("Jtag freq error !! \n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (freq) {
|
||||
ast_set_jtag_freq(freq);
|
||||
printf("JTAG Set Freq %d\n", freq);
|
||||
} else {
|
||||
printf("JTAG Freq %d\n", jtag_freq);
|
||||
}
|
||||
#endif
|
||||
if (svf) {
|
||||
printf("Playing %s \n", svf_name);
|
||||
ret = handle_svf_command(svf_name);
|
||||
if (ret == ERROR_OK) {
|
||||
printf("Success!\n");
|
||||
} else {
|
||||
printf("Error: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
ast_jtag_close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+1560
File diff suppressed because it is too large
Load Diff
+93
@@ -0,0 +1,93 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2005 by Dominic Rath
|
||||
* Dominic.Rath@gmx.de
|
||||
*
|
||||
* Copyright (C) 2007-2010 Øyvind Harboe
|
||||
* oyvind.harboe@zylin.com
|
||||
*/
|
||||
|
||||
#ifndef SVF_H
|
||||
#define SVF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*-----</Macros>-------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Defines JTAG Test Access Port states.
|
||||
*
|
||||
* These definitions were gleaned from the ARM7TDMI-S Technical
|
||||
* Reference Manual and validated against several other ARM core
|
||||
* technical manuals.
|
||||
*
|
||||
* FIXME some interfaces require specific numbers be used, as they
|
||||
* are handed-off directly to their hardware implementations.
|
||||
* Fix those drivers to map as appropriate ... then pick some
|
||||
* sane set of numbers here (where 0/uninitialized == INVALID).
|
||||
*/
|
||||
typedef enum tap_state {
|
||||
TAP_INVALID = -1,
|
||||
/* Proper ARM recommended numbers */
|
||||
TAP_DREXIT2 = 0x0,
|
||||
TAP_DREXIT1 = 0x1,
|
||||
TAP_DRSHIFT = 0x2,
|
||||
TAP_DRPAUSE = 0x3,
|
||||
TAP_IRSELECT = 0x4,
|
||||
TAP_DRUPDATE = 0x5,
|
||||
TAP_DRCAPTURE = 0x6,
|
||||
TAP_DRSELECT = 0x7,
|
||||
TAP_IREXIT2 = 0x8,
|
||||
TAP_IREXIT1 = 0x9,
|
||||
TAP_IRSHIFT = 0xa,
|
||||
TAP_IRPAUSE = 0xb,
|
||||
TAP_IDLE = 0xc,
|
||||
TAP_IRUPDATE = 0xd,
|
||||
TAP_IRCAPTURE = 0xe,
|
||||
TAP_RESET = 0x0f,
|
||||
} tap_state_t;
|
||||
|
||||
/**
|
||||
* Defines arguments for reset functions
|
||||
*/
|
||||
#define SRST_DEASSERT 0
|
||||
#define SRST_ASSERT 1
|
||||
#define TRST_DEASSERT 0
|
||||
#define TRST_ASSERT 1
|
||||
|
||||
/**
|
||||
* Function tap_state_name
|
||||
* Returns a string suitable for display representing the JTAG tap_state
|
||||
*/
|
||||
const char *tap_state_name(tap_state_t state);
|
||||
|
||||
/** Provides user-friendly name lookup of TAP states. */
|
||||
tap_state_t tap_state_by_name(const char *name);
|
||||
|
||||
/** The current TAP state of the pending JTAG command queue. */
|
||||
extern tap_state_t cmd_queue_cur_state;
|
||||
|
||||
/**
|
||||
* This structure defines a single scan field in the scan. It provides
|
||||
* fields for the field's width and pointers to scan input and output
|
||||
* values.
|
||||
*
|
||||
* In addition, this structure includes a value and mask that is used by
|
||||
* jtag_add_dr_scan_check() to validate the value that was scanned out.
|
||||
*/
|
||||
struct scan_field {
|
||||
/** The number of bits this field specifies */
|
||||
int num_bits;
|
||||
/** A pointer to value to be scanned into the device */
|
||||
const uint8_t *out_value;
|
||||
/** A pointer to a 32-bit memory location for data scanned out */
|
||||
uint8_t *in_value;
|
||||
|
||||
/** The value used to check the data scanned out. */
|
||||
uint8_t *check_value;
|
||||
/** The mask to go with check_value */
|
||||
uint8_t *check_mask;
|
||||
};
|
||||
|
||||
int handle_svf_command(char *filename);
|
||||
#endif /* SVF_H */
|
||||
Reference in New Issue
Block a user