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