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