1 /*
2 * Copyright 2018 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "config.h"
18
19 #include "file_handler.hpp"
20 #include "firmware_handler.hpp"
21 #include "firmware_handlers_builder.hpp"
22 #include "flags.hpp"
23 #include "general_systemd.hpp"
24 #include "image_handler.hpp"
25 #include "lpc_aspeed.hpp"
26 #include "lpc_handler.hpp"
27 #include "lpc_nuvoton.hpp"
28 #include "net_handler.hpp"
29 #include "pci_handler.hpp"
30 #include "status.hpp"
31 #include "util.hpp"
32
33 #include <sdbusplus/bus.hpp>
34
35 #include <cstdint>
36 #include <memory>
37 #include <string>
38 #include <unordered_map>
39 #include <vector>
40
41 namespace ipmi_flash
42 {
43
44 namespace
45 {
46
47 /**
48 * Given a name and path, create a HandlerPack.
49 *
50 * @param[in] name - the blob id path for this
51 * @param[in] path - the file path to write the contents.
52 * @return the HandlerPack.
53 */
CreateFileHandlerPack(const std::string & name,const std::string & path)54 HandlerPack CreateFileHandlerPack(const std::string& name,
55 const std::string& path)
56 {
57 return HandlerPack(name, std::make_unique<FileHandler>(path));
58 }
59
60 #ifdef NUVOTON_P2A_MBOX
61 static constexpr std::size_t memoryRegionSize = 16 * 1024UL;
62 #elif defined NUVOTON_P2A_VGA
63 static constexpr std::size_t memoryRegionSize = 4 * 1024 * 1024UL;
64 #else
65 /* The maximum external buffer size we expect is 64KB. */
66 static constexpr std::size_t memoryRegionSize = 64 * 1024UL;
67 #endif
68
69 } // namespace
70 } // namespace ipmi_flash
71
72 extern "C"
73 {
74 std::unique_ptr<blobs::GenericBlobInterface> createHandler();
75 }
76
createHandler()77 std::unique_ptr<blobs::GenericBlobInterface> createHandler()
78 {
79 using namespace ipmi_flash;
80
81 std::vector<DataHandlerPack> supportedTransports;
82
83 supportedTransports.emplace_back(FirmwareFlags::UpdateFlags::ipmi, nullptr);
84
85 #ifdef ENABLE_PCI_BRIDGE
86 supportedTransports.emplace_back(
87 FirmwareFlags::UpdateFlags::p2a,
88 std::make_unique<PciDataHandler>(MAPPED_ADDRESS, memoryRegionSize));
89 #endif
90
91 #ifdef ENABLE_LPC_BRIDGE
92 #if defined(ASPEED_LPC)
93 supportedTransports.emplace_back(
94 FirmwareFlags::UpdateFlags::lpc,
95 std::make_unique<LpcDataHandler>(LpcMapperAspeed::createAspeedMapper(
96 MAPPED_ADDRESS, memoryRegionSize)));
97 #elif defined(NUVOTON_LPC)
98 supportedTransports.emplace_back(
99 FirmwareFlags::UpdateFlags::lpc,
100 std::make_unique<LpcDataHandler>(LpcMapperNuvoton::createNuvotonMapper(
101 MAPPED_ADDRESS, memoryRegionSize)));
102 #else
103 #error "You must specify a hardware implementation."
104 #endif
105 #endif
106
107 #ifdef ENABLE_NET_BRIDGE
108 supportedTransports.emplace_back(FirmwareFlags::UpdateFlags::net,
109 std::make_unique<NetDataHandler>());
110 #endif
111
112 ActionMap actionPacks = {};
113 FirmwareHandlersBuilder builder;
114
115 auto configsFromJson = builder.buildHandlerConfigsFromDefaultPaths();
116
117 std::vector<HandlerPack> supportedFirmware;
118
119 supportedFirmware.push_back(
120 std::move(CreateFileHandlerPack(hashBlobId, HASH_FILENAME)));
121
122 for (auto& config : configsFromJson)
123 {
124 supportedFirmware.emplace_back(config.blobId,
125 std::move(config.handler));
126 actionPacks[config.blobId] = std::move(config.actions);
127
128 std::fprintf(stderr, "config loaded: %s\n", config.blobId.c_str());
129 }
130
131 auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
132 std::move(supportedFirmware), std::move(supportedTransports),
133 std::move(actionPacks));
134
135 if (!handler)
136 {
137 std::fprintf(stderr, "Firmware Handler has an invalid configuration");
138 return nullptr;
139 }
140
141 return handler;
142 }
143