diff options
-rw-r--r-- | README.md | 27 | ||||
-rw-r--r-- | bmc/Makefile.am | 6 | ||||
-rw-r--r-- | bmc/main.cpp | 31 | ||||
-rw-r--r-- | bmc/phosphor-ipmi-flash-bios-prepare.target.in | 2 | ||||
-rw-r--r-- | bmc/phosphor-ipmi-flash-bios-update.target.in | 2 | ||||
-rw-r--r-- | bmc/phosphor-ipmi-flash-bios-verify.target.in | 2 | ||||
-rw-r--r-- | bmc/test/firmware_multiplebundle_unittest.cpp | 14 | ||||
-rw-r--r-- | configure.ac | 81 | ||||
-rw-r--r-- | util.cpp | 1 | ||||
-rw-r--r-- | util.hpp | 1 |
10 files changed, 147 insertions, 20 deletions
@@ -115,7 +115,8 @@ TODO: Flesh out the UBI approach. To use `phosphor-ipmi-flash` a platform must provide a configuration. A platform can configure multiple interfaces, such as both lpc and pci. However, a platform should only configure either static layout updates, or ubi. If -enabling lpc, the platform must specify either aspeed or nuvoton. +enabling lpc, the platform must specify either aspeed or nuvoton. The system +also supports receiving BIOS updates. The following are the two primary configuration options, which control how the update is treated. @@ -124,6 +125,7 @@ Option | Meaning ------------------------ | ------- `--enable-static-layout` | Enable treating the update as a static layout update. `--enable-tarball-ubi` | Enable treating the update as a tarball for UBI update. +`--enable-host-bios` | Enable receiving the update for a host bios update. The following are configuration options for how the host and BMC are meant to transfer the data. By default, the data-in-IPMI mechanism is enabled. @@ -175,15 +177,20 @@ Option | Meaning The following variables can be set to whatever you wish, however they have usable default values. -Variable | Default | Meaning ----------------------------- | -------------------------- | ------------------------------------------------------------------------- -`STATIC_HANDLER_STAGED_NAME` | `/run/initramfs/bmc-image` | The filename where to write the staged firmware image for static updates. -`TARBALL_STAGED_NAME` | `/tmp/image-update.tar` | The filename where to write the UBI update tarball. -`HASH_FILENAME` | `/tmp/bmc.sig` | The file to use for the hash provided. -`PREPARATION_DBUS_SERVICE` | `phosphor-ipmi-flash-bmc-prepare.target` | The systemd service started when the host starts to send an update. -`VERIFY_STATUS_FILENAME` | `/tmp/bmc.verify` | The file checked for the verification status. -`VERIFY_DBUS_SERVICE` | `phosphor-ipmi-flash-bmc-verify.target` | The systemd service started for verification. -`UPDATE_DBUS_SERVICE` | `phosphor-ipmi-flash-bmc-update.target` | The systemd service started for updating the BMC. +Variable | Default | Meaning +----------------------------- | -------------------------- | ------------------------------------------------------------------------- +`STATIC_HANDLER_STAGED_NAME` | `/run/initramfs/bmc-image` | The filename where to write the staged firmware image for static updates. +`TARBALL_STAGED_NAME` | `/tmp/image-update.tar` | The filename where to write the UBI update tarball. +`HASH_FILENAME` | `/tmp/bmc.sig` | The file to use for the hash provided. +`PREPARATION_DBUS_SERVICE` | `phosphor-ipmi-flash-bmc-prepare.target` | The systemd target started when the host starts to send an update. +`VERIFY_STATUS_FILENAME` | `/tmp/bmc.verify` | The file checked for the verification status. +`VERIFY_DBUS_SERVICE` | `phosphor-ipmi-flash-bmc-verify.target` | The systemd target started for verification. +`UPDATE_DBUS_SERVICE` | `phosphor-ipmi-flash-bmc-update.target` | The systemd target started for updating the BMC. +`BIOS_STAGED_NAME` | `/tmp/bios-image` | The file to use for staging the bios firmware update. +`BIOS_VERIFY_STATUS_FILENAME` | `/tmp/bios.verify` | The file checked for the verification status. +`PREPARATION_BIOS_TARGET` | `phosphor-ipmi-flash-bios-prepare.target` | The systemd target when the host starts to send an update. +`VERIFY_BIOS_TARGET` | `phosphor-ipmi-flash-bios-verify.target` | The systemd target started for verification. +`UPDATE_BIOS_TARGET` | `phosphor-ipmi-flash-bios-update.target` | The systemd target started for updating the BIOS. ## Flash State Machine Details diff --git a/bmc/Makefile.am b/bmc/Makefile.am index 6378ffb..8ada86b 100644 --- a/bmc/Makefile.am +++ b/bmc/Makefile.am @@ -5,6 +5,12 @@ systemdsystemunit_DATA = \ phosphor-ipmi-flash-bmc-prepare.target \ phosphor-ipmi-flash-bmc-verify.target \ phosphor-ipmi-flash-bmc-update.target +if ENABLE_HOST_BIOS +systemdsystemunit_DATA += \ + phosphor-ipmi-flash-bios-prepare.target \ + phosphor-ipmi-flash-bios-verify.target \ + phosphor-ipmi-flash-bios-update.target +endif endif noinst_LTLIBRARIES = libfirmwareblob_common.la diff --git a/bmc/main.cpp b/bmc/main.cpp index d89369c..9f1088a 100644 --- a/bmc/main.cpp +++ b/bmc/main.cpp @@ -49,6 +49,9 @@ FileHandler staticLayoutHandler(STATIC_HANDLER_STAGED_NAME); #ifdef ENABLE_TARBALL_UBI FileHandler ubitarballHandler(TARBALL_STAGED_NAME); #endif +#ifdef ENABLE_HOST_BIOS +FileHandler biosHandler(BIOS_STAGED_NAME); +#endif /* The maximum external buffer size we expect is 64KB. */ static constexpr std::size_t memoryRegionSize = 64 * 1024UL; @@ -81,6 +84,9 @@ std::vector<HandlerPack> supportedFirmware = { #ifdef ENABLE_TARBALL_UBI {ubiTarballBlobId, &ubitarballHandler}, #endif +#ifdef ENABLE_HOST_BIOS + {biosBlobId, &biosHandler}, +#endif }; std::vector<DataHandlerPack> supportedTransports = { @@ -102,6 +108,8 @@ std::unique_ptr<blobs::GenericBlobInterface> createHandler(); std::unique_ptr<blobs::GenericBlobInterface> createHandler() { + ipmi_flash::ActionMap actionPacks = {}; + #ifdef ENABLE_REBOOT_UPDATE static constexpr auto rebootTarget = "reboot.target"; static constexpr auto rebootMode = "replace-irreversibly"; @@ -120,8 +128,6 @@ std::unique_ptr<blobs::GenericBlobInterface> createHandler() sdbusplus::bus::new_default(), VERIFY_STATUS_FILENAME, VERIFY_DBUS_SERVICE); - ipmi_flash::ActionMap actionPacks = {}; - /* TODO: for bios should the name be, bios or /flash/bios?, these are * /flash/... and it simplifies a few other things later (open/etc) */ @@ -139,6 +145,27 @@ std::unique_ptr<blobs::GenericBlobInterface> createHandler() bmcPack->update = std::move(updater); actionPacks[bmcName] = std::move(bmcPack); +#ifdef ENABLE_HOST_BIOS + { + auto biosPack = std::make_unique<ipmi_flash::ActionPack>(); + + biosPack->preparation = + ipmi_flash::SystemdPreparation::CreatePreparation( + sdbusplus::bus::new_default(), PREPARATION_BIOS_TARGET); + + biosPack->verification = + ipmi_flash::SystemdVerification::CreateVerification( + sdbusplus::bus::new_default(), BIOS_VERIFY_STATUS_FILENAME, + VERIFY_BIOS_TARGET); + + biosPack->update = + ipmi_flash::SystemdUpdateMechanism::CreateSystemdUpdate( + sdbusplus::bus::new_default(), UPDATE_BIOS_TARGET); + + actionPacks[ipmi_flash::biosBlobId] = std::move(biosPack); + } +#endif + auto handler = ipmi_flash::FirmwareBlobHandler::CreateFirmwareBlobHandler( ipmi_flash::supportedFirmware, ipmi_flash::supportedTransports, std::move(actionPacks)); diff --git a/bmc/phosphor-ipmi-flash-bios-prepare.target.in b/bmc/phosphor-ipmi-flash-bios-prepare.target.in new file mode 100644 index 0000000..b50e644 --- /dev/null +++ b/bmc/phosphor-ipmi-flash-bios-prepare.target.in @@ -0,0 +1,2 @@ +[Unit] +Description=Phosphor-ipmi-flash Prepare BIOS to receive update diff --git a/bmc/phosphor-ipmi-flash-bios-update.target.in b/bmc/phosphor-ipmi-flash-bios-update.target.in new file mode 100644 index 0000000..46759ed --- /dev/null +++ b/bmc/phosphor-ipmi-flash-bios-update.target.in @@ -0,0 +1,2 @@ +[Unit] +Description=Phosphor-ipmi-flash update the BIOS image diff --git a/bmc/phosphor-ipmi-flash-bios-verify.target.in b/bmc/phosphor-ipmi-flash-bios-verify.target.in new file mode 100644 index 0000000..d45da94 --- /dev/null +++ b/bmc/phosphor-ipmi-flash-bios-verify.target.in @@ -0,0 +1,2 @@ +[Unit] +Description=Phosphor-ipmi-flash verify the image contents diff --git a/bmc/test/firmware_multiplebundle_unittest.cpp b/bmc/test/firmware_multiplebundle_unittest.cpp index b8d738d..2c450f4 100644 --- a/bmc/test/firmware_multiplebundle_unittest.cpp +++ b/bmc/test/firmware_multiplebundle_unittest.cpp @@ -33,7 +33,7 @@ class IpmiOnlyTwoFirmwaresTest : public ::testing::Test blobs = { {hashBlobId, &hashImageMock}, {staticLayoutBlobId, &staticImageMock}, - {biosId, &biosImageMock}, + {biosBlobId, &biosImageMock}, }; std::unique_ptr<TriggerableActionInterface> bmcPrepareMock = @@ -77,7 +77,7 @@ class IpmiOnlyTwoFirmwaresTest : public ::testing::Test biosPack->update = std::move(biosUpdateMock); packs[staticLayoutBlobId] = std::move(bmcPack); - packs[biosId] = std::move(biosPack); + packs[biosBlobId] = std::move(biosPack); handler = FirmwareBlobHandler::CreateFirmwareBlobHandler( blobs, data, std::move(packs)); @@ -103,8 +103,6 @@ class IpmiOnlyTwoFirmwaresTest : public ::testing::Test std::uint16_t session = 1; std::uint16_t flags = blobs::OpenFlags::write | FirmwareFlags::UpdateFlags::ipmi; - - const std::string biosId = "/flash/bios"; }; TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningBiosAfterBlobFails) @@ -124,8 +122,8 @@ TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningBiosAfterBlobFails) expectedState(FirmwareBlobHandler::UpdateState::verificationPending); - EXPECT_CALL(biosImageMock, open(biosId)).Times(0); - EXPECT_FALSE(handler->open(session, flags, biosId)); + EXPECT_CALL(biosImageMock, open(biosBlobId)).Times(0); + EXPECT_FALSE(handler->open(session, flags, biosBlobId)); } TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningHashBeforeBiosSucceeds) @@ -142,8 +140,8 @@ TEST_F(IpmiOnlyTwoFirmwaresTest, OpeningHashBeforeBiosSucceeds) expectedState(FirmwareBlobHandler::UpdateState::verificationPending); ASSERT_FALSE(handler->canHandleBlob(verifyBlobId)); - EXPECT_CALL(biosImageMock, open(biosId)).WillOnce(Return(true)); - EXPECT_TRUE(handler->open(session, flags, biosId)); + EXPECT_CALL(biosImageMock, open(biosBlobId)).WillOnce(Return(true)); + EXPECT_TRUE(handler->open(session, flags, biosBlobId)); expectedState(FirmwareBlobHandler::UpdateState::uploadInProgress); diff --git a/configure.ac b/configure.ac index e6a1a8b..aea5d42 100644 --- a/configure.ac +++ b/configure.ac @@ -58,6 +58,12 @@ AC_ARG_ENABLE([build-bmc-blob-handler], ) AM_CONDITIONAL([BUILD_BMC_HANDLER], [test "x$enable_build_bmc_blob_handler" != "xno"]) +# Enable building host-bios support into the BMC (default: no) +# This is only set if build-bmc-blob-handler is not "no." +AC_ARG_ENABLE([host-bios], + AC_HELP_STRING([--enable-host-bios], [Enable supporting the host bios]) +) + # Build the BMC by default, so check if set to no. AS_IF([test "x$enable_build_bmc_blob_handler" != "xno"], [ PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 221]) @@ -97,6 +103,10 @@ AS_IF([test "x$enable_build_bmc_blob_handler" != "xno"], [ [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])] ) AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"]) + + # Only set if build-bmc-blob-handler wasn't unset. + AM_CONDITIONAL([ENABLE_HOST_BIOS], [test "$enable_host_bios" = "xyes"]) + AX_APPEND_COMPILE_FLAGS([-DENABLE_HOST_BIOS], [CXXFLAGS]) ]) # If not building the host-tool, we're building the BMC. @@ -254,6 +264,20 @@ AC_DEFINE_UNQUOTED( ) AC_ARG_VAR( + BIOS_STAGED_NAME, + [The file to use for staging the bios firmware update.] +) +AS_IF( + [test "x$BIOS_STAGED_NAME" == "x"], + [BIOS_STAGED_NAME="/tmp/bios-image"] +) +AC_DEFINE_UNQUOTED( + [BIOS_STAGED_NAME], + ["$BIOS_STAGED_NAME"], + [The file to use for staging the bios firmware update.] +) + +AC_ARG_VAR( HASH_FILENAME, [The file to use for the hash provided.] ) @@ -296,6 +320,20 @@ AC_DEFINE_UNQUOTED( ) AC_ARG_VAR( + BIOS_VERIFY_STATUS_FILENAME, + [The file checked for the verification status.] +) +AS_IF( + [test "x$BIOS_VERIFY_STATUS_FILENAME" == "x"], + [BIOS_VERIFY_STATUS_FILENAME="/tmp/bios.verify"] +) +AC_DEFINE_UNQUOTED( + [BIOS_VERIFY_STATUS_FILENAME], + ["$BIOS_VERIFY_STATUS_FILENAME"], + [The file checked for the verification status.] +) + +AC_ARG_VAR( VERIFY_DBUS_SERVICE, [The systemd target started for verification.] ) @@ -323,6 +361,46 @@ AC_DEFINE_UNQUOTED( [The systemd target started for updating the BMC.] ) +AC_ARG_VAR( + PREPARATION_BIOS_TARGET, + [The systemd target started when the host starts to send an update.] +) +AS_IF( + [test "x$PREPARATION_BIOS_TARGET" == "x"], + [PREPARATION_BIOS_TARGET="phosphor-ipmi-flash-bios-prepare.target"] +) +AC_DEFINE_UNQUOTED( + [PREPARATION_BIOS_TARGET], + ["$PREPARATION_BIOS_TARGET"], + [The systemd target started when the host starts to send an update.] +) +AC_ARG_VAR( + VERIFY_BIOS_TARGET, + [The systemd target started for verifying the BIOS image.] +) +AS_IF( + [test "x$VERIFY_BIOS_TARGET" == "x"], + [VERIFY_BIOS_TARGET="phosphor-ipmi-flash-bios-verify.target"] +) +AC_DEFINE_UNQUOTED( + [VERIFY_BIOS_TARGET], + ["$VERIFY_BIOS_TARGET"], + [The systemd target started for verifying the BIOS image.] +) +AC_ARG_VAR( + UPDATE_BIOS_TARGET, + [The systemd target started for updating the BIOS.] +) +AS_IF( + [test "x$UPDATE_BIOS_TARGET" == "x"], + [UPDATE_BIOS_TARGET="phosphor-ipmi-flash-bios-update.target"] +) +AC_DEFINE_UNQUOTED( + [UPDATE_BIOS_TARGET], + ["$UPDATE_BIOS_TARGET"], + [The systemd target started for updating the BIOS.] +) + AC_CHECK_HEADER(linux/ipmi.h, [HAVE_LINUX_IPMI_H=""], [HAVE_LINUX_IPMI_H="-I linux/ipmi.h"]) AS_IF([test "$HAVE_LINUX_IPMI_H" != ""], AC_MSG_WARN([Could not find linux/ipmi.h: Attempting to download locally for building from openbmc/linux/+/dev-4.18]) @@ -458,4 +536,7 @@ AC_CONFIG_FILES([cleanup/Makefile cleanup/test/Makefile]) AC_CONFIG_FILES([bmc/phosphor-ipmi-flash-bmc-prepare.target]) AC_CONFIG_FILES([bmc/phosphor-ipmi-flash-bmc-verify.target]) AC_CONFIG_FILES([bmc/phosphor-ipmi-flash-bmc-update.target]) +AC_CONFIG_FILES([bmc/phosphor-ipmi-flash-bios-prepare.target]) +AC_CONFIG_FILES([bmc/phosphor-ipmi-flash-bios-verify.target]) +AC_CONFIG_FILES([bmc/phosphor-ipmi-flash-bios-update.target]) AC_OUTPUT @@ -19,6 +19,7 @@ namespace ipmi_flash { +const std::string biosBlobId = "/flash/bios"; const std::string updateBlobId = "/flash/update"; const std::string verifyBlobId = "/flash/verify"; const std::string hashBlobId = "/flash/hash"; @@ -5,6 +5,7 @@ namespace ipmi_flash { +extern const std::string biosBlobId; extern const std::string updateBlobId; extern const std::string verifyBlobId; extern const std::string hashBlobId; |