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" 21*c893f43dSJason 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 static constexpr const char* jsonConfigurationPath = 48ded66d0fSJason Ling "/usr/share/phosphor-ipmi-flash/"; 49ded66d0fSJason Ling 50ded66d0fSJason Ling /** 51ded66d0fSJason Ling * Given a name and path, create a HandlerPack. 52ded66d0fSJason Ling * 53ded66d0fSJason Ling * @param[in] name - the blob id path for this 54ded66d0fSJason Ling * @param[in] path - the file path to write the contents. 55ded66d0fSJason Ling * @return the HandlerPack. 56ded66d0fSJason Ling */ 57ded66d0fSJason Ling HandlerPack CreateFileHandlerPack(const std::string& name, 58ded66d0fSJason Ling const std::string& path) 59ded66d0fSJason Ling { 60ded66d0fSJason Ling return HandlerPack(name, std::make_unique<FileHandler>(path)); 61ded66d0fSJason Ling } 62ded66d0fSJason Ling 63ded66d0fSJason Ling #ifdef NUVOTON_P2A_MBOX 64ded66d0fSJason Ling static constexpr std::size_t memoryRegionSize = 16 * 1024UL; 65ded66d0fSJason Ling #elif defined NUVOTON_P2A_VGA 66ded66d0fSJason Ling static constexpr std::size_t memoryRegionSize = 4 * 1024 * 1024UL; 67ded66d0fSJason Ling #else 68ded66d0fSJason Ling /* The maximum external buffer size we expect is 64KB. */ 69ded66d0fSJason Ling static constexpr std::size_t memoryRegionSize = 64 * 1024UL; 70ded66d0fSJason Ling #endif 71ded66d0fSJason Ling 72ded66d0fSJason Ling } // namespace 73ded66d0fSJason Ling } // namespace ipmi_flash 74ded66d0fSJason Ling 75ded66d0fSJason Ling extern "C" 76ded66d0fSJason Ling { 77ded66d0fSJason Ling std::unique_ptr<blobs::GenericBlobInterface> createHandler(); 78ded66d0fSJason Ling } 79ded66d0fSJason Ling 80ded66d0fSJason Ling std::unique_ptr<blobs::GenericBlobInterface> createHandler() 81ded66d0fSJason Ling { 82ded66d0fSJason Ling using namespace ipmi_flash; 83ded66d0fSJason Ling 84ded66d0fSJason Ling std::vector<DataHandlerPack> supportedTransports; 85ded66d0fSJason Ling 86ded66d0fSJason Ling supportedTransports.emplace_back(FirmwareFlags::UpdateFlags::ipmi, nullptr); 87ded66d0fSJason Ling 88ded66d0fSJason Ling #ifdef ENABLE_PCI_BRIDGE 89ded66d0fSJason Ling supportedTransports.emplace_back( 90ded66d0fSJason Ling FirmwareFlags::UpdateFlags::p2a, 91ded66d0fSJason Ling std::make_unique<PciDataHandler>(MAPPED_ADDRESS, memoryRegionSize)); 92ded66d0fSJason Ling #endif 93ded66d0fSJason Ling 94ded66d0fSJason Ling #ifdef ENABLE_LPC_BRIDGE 95ded66d0fSJason Ling #if defined(ASPEED_LPC) 96ded66d0fSJason Ling supportedTransports.emplace_back( 97ded66d0fSJason Ling FirmwareFlags::UpdateFlags::lpc, 98ded66d0fSJason Ling std::make_unique<LpcDataHandler>(LpcMapperAspeed::createAspeedMapper( 99ded66d0fSJason Ling MAPPED_ADDRESS, memoryRegionSize))); 100ded66d0fSJason Ling #elif defined(NUVOTON_LPC) 101ded66d0fSJason Ling supportedTransports.emplace_back( 102ded66d0fSJason Ling FirmwareFlags::UpdateFlags::lpc, 103ded66d0fSJason Ling std::make_unique<LpcDataHandler>(LpcMapperNuvoton::createNuvotonMapper( 104ded66d0fSJason Ling MAPPED_ADDRESS, memoryRegionSize))); 105ded66d0fSJason Ling #else 106ded66d0fSJason Ling #error "You must specify a hardware implementation." 107ded66d0fSJason Ling #endif 108ded66d0fSJason Ling #endif 109ded66d0fSJason Ling 110ded66d0fSJason Ling #ifdef ENABLE_NET_BRIDGE 111ded66d0fSJason Ling supportedTransports.emplace_back(FirmwareFlags::UpdateFlags::net, 112ded66d0fSJason Ling std::make_unique<NetDataHandler>()); 113ded66d0fSJason Ling #endif 114ded66d0fSJason Ling 115ded66d0fSJason Ling ActionMap actionPacks = {}; 116*c893f43dSJason Ling FirmwareHandlersBuilder builder; 117ded66d0fSJason Ling 118*c893f43dSJason Ling std::vector<HandlerConfig<ActionPack>> configsFromJson = 119*c893f43dSJason Ling builder.buildHandlerConfigs(jsonConfigurationPath); 120ded66d0fSJason Ling 121ded66d0fSJason Ling std::vector<HandlerPack> supportedFirmware; 122ded66d0fSJason Ling 123ded66d0fSJason Ling supportedFirmware.push_back( 124ded66d0fSJason Ling std::move(CreateFileHandlerPack(hashBlobId, HASH_FILENAME))); 125ded66d0fSJason Ling 126ded66d0fSJason Ling for (auto& config : configsFromJson) 127ded66d0fSJason Ling { 128ded66d0fSJason Ling supportedFirmware.emplace_back(config.blobId, 129ded66d0fSJason Ling std::move(config.handler)); 130ded66d0fSJason Ling actionPacks[config.blobId] = std::move(config.actions); 131ded66d0fSJason Ling 132ded66d0fSJason Ling std::fprintf(stderr, "config loaded: %s\n", config.blobId.c_str()); 133ded66d0fSJason Ling } 134ded66d0fSJason Ling 135ded66d0fSJason Ling auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler( 136ded66d0fSJason Ling std::move(supportedFirmware), std::move(supportedTransports), 137ded66d0fSJason Ling std::move(actionPacks)); 138ded66d0fSJason Ling 139ded66d0fSJason Ling if (!handler) 140ded66d0fSJason Ling { 141ded66d0fSJason Ling std::fprintf(stderr, "Firmware Handler has an invalid configuration"); 142ded66d0fSJason Ling return nullptr; 143ded66d0fSJason Ling } 144ded66d0fSJason Ling 145ded66d0fSJason Ling return handler; 146ded66d0fSJason Ling } 147