xref: /openbmc/phosphor-bmc-code-mgmt/bmc/static/flash.cpp (revision f60952b07574123e7e2084f1eb704ed829a9c6d8)
1 #include "config.h"
2 
3 #include "flash.hpp"
4 
5 #include "activation.hpp"
6 #include "images.hpp"
7 #include "item_updater.hpp"
8 
9 #include <phosphor-logging/lg2.hpp>
10 
11 #include <filesystem>
12 #include <system_error>
13 
14 namespace
15 {
16 constexpr auto PATH_INITRAMFS = "/run/initramfs";
17 constexpr auto FLASH_ALT_SERVICE_TMPL = "obmc-flash-bmc-alt@";
18 } // namespace
19 
20 namespace phosphor
21 {
22 namespace software
23 {
24 namespace updater
25 {
26 
27 PHOSPHOR_LOG2_USING;
28 
29 namespace fs = std::filesystem;
30 using namespace phosphor::software::image;
31 
flashWrite()32 void Activation::flashWrite()
33 {
34 #ifdef BMC_STATIC_DUAL_IMAGE
35     if (parent.runningImageSlot != 0)
36     {
37         // It's running on the secondary chip, update the primary one
38         info("Flashing primary flash from secondary, id: {ID}", "ID",
39              versionId);
40         auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
41                                           SYSTEMD_INTERFACE, "StartUnit");
42         auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service";
43         method.append(serviceFile, "replace");
44         bus.call_noreply(method);
45         return;
46     }
47 #endif
48     // For static layout code update, just put images in /run/initramfs.
49     // It expects user to trigger a reboot and an updater script will program
50     // the image to flash during reboot.
51     fs::path uploadDir(IMG_UPLOAD_DIR);
52     fs::path toPath(PATH_INITRAMFS);
53 
54     for (const auto& bmcImage : parent.imageUpdateList)
55     {
56         std::error_code ec;
57         fs::copy_file(uploadDir / versionId / bmcImage, toPath / bmcImage,
58                       fs::copy_options::overwrite_existing, ec);
59     }
60     for (const auto& optionalImaage : getOptionalImages())
61     {
62         std::error_code ec;
63         fs::copy_file(uploadDir / versionId / optionalImaage,
64                       toPath / optionalImaage,
65                       fs::copy_options::overwrite_existing, ec);
66     }
67 }
68 
onStateChanges(sdbusplus::message_t & msg)69 void Activation::onStateChanges([[maybe_unused]] sdbusplus::message_t& msg)
70 {
71 #ifdef BMC_STATIC_DUAL_IMAGE
72     uint32_t newStateID;
73     auto serviceFile = FLASH_ALT_SERVICE_TMPL + versionId + ".service";
74     sdbusplus::message::object_path newStateObjPath;
75     std::string newStateUnit{};
76     std::string newStateResult{};
77     msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
78 
79     if (newStateUnit != serviceFile)
80     {
81         return;
82     }
83     if (newStateResult == "done")
84     {
85         activationProgress->progress(90);
86         onFlashWriteSuccess();
87     }
88     else
89     {
90         Activation::activation(sdbusplus::server::xyz::openbmc_project::
91                                    software::Activation::Activations::Failed);
92     }
93 #endif
94 }
95 
96 } // namespace updater
97 } // namespace software
98 } // namespace phosphor
99