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