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