11a3dc60dSBrandon Kim #include "config.h"
21a3dc60dSBrandon Kim
31a3dc60dSBrandon Kim #include "buffer.hpp"
41a3dc60dSBrandon Kim #include "pci_handler.hpp"
51a3dc60dSBrandon Kim #include "rde/external_storer_file.hpp"
61a3dc60dSBrandon Kim #include "rde/external_storer_interface.hpp"
71a3dc60dSBrandon Kim #include "rde/rde_handler.hpp"
81a3dc60dSBrandon Kim
9554fad0bSBrandon Kim #include <boost/asio.hpp>
101a3dc60dSBrandon Kim #include <boost/endian/conversion.hpp>
11a3b64fb6Skasunath #include <sdbusplus/asio/object_server.hpp>
121a3dc60dSBrandon Kim #include <stdplus/fd/create.hpp>
131a3dc60dSBrandon Kim #include <stdplus/fd/impl.hpp>
141a3dc60dSBrandon Kim #include <stdplus/fd/managed.hpp>
15*5de90619SPatrick Williams #include <stdplus/print.hpp>
16554fad0bSBrandon Kim
17554fad0bSBrandon Kim #include <chrono>
181a3dc60dSBrandon Kim #include <filesystem>
19*5de90619SPatrick Williams #include <format>
201a3dc60dSBrandon Kim #include <fstream>
21554fad0bSBrandon Kim #include <functional>
221a3dc60dSBrandon Kim #include <memory>
23554fad0bSBrandon Kim
24554fad0bSBrandon Kim namespace
25554fad0bSBrandon Kim {
261a3dc60dSBrandon Kim constexpr std::chrono::milliseconds readIntervalinMs(READ_INTERVAL_MS);
271a3dc60dSBrandon Kim constexpr std::size_t memoryRegionSize = MEMORY_REGION_SIZE;
281a3dc60dSBrandon Kim constexpr std::size_t memoryRegionOffset = MEMORY_REGION_OFFSET;
291a3dc60dSBrandon Kim constexpr uint32_t bmcInterfaceVersion = BMC_INTERFACE_VERSION;
301a3dc60dSBrandon Kim constexpr uint16_t queueSize = QUEUE_REGION_SIZE;
311a3dc60dSBrandon Kim constexpr uint16_t ueRegionSize = UE_REGION_SIZE;
321a3dc60dSBrandon Kim static constexpr std::array<uint32_t, 4> magicNumber = {
331a3dc60dSBrandon Kim MAGIC_NUMBER_BYTE1, MAGIC_NUMBER_BYTE2, MAGIC_NUMBER_BYTE3,
341a3dc60dSBrandon Kim MAGIC_NUMBER_BYTE4};
35554fad0bSBrandon Kim } // namespace
36554fad0bSBrandon Kim
371a3dc60dSBrandon Kim using namespace bios_bmc_smm_error_logger;
381a3dc60dSBrandon Kim
readLoop(boost::asio::steady_timer * t,const std::shared_ptr<BufferInterface> & bufferInterface,const std::shared_ptr<rde::RdeCommandHandler> & rdeCommandHandler,const boost::system::error_code & error)391a3dc60dSBrandon Kim void readLoop(boost::asio::steady_timer* t,
401a3dc60dSBrandon Kim const std::shared_ptr<BufferInterface>& bufferInterface,
411a3dc60dSBrandon Kim const std::shared_ptr<rde::RdeCommandHandler>& rdeCommandHandler,
421a3dc60dSBrandon Kim const boost::system::error_code& error)
43554fad0bSBrandon Kim {
441a3dc60dSBrandon Kim if (error)
451a3dc60dSBrandon Kim {
46*5de90619SPatrick Williams stdplus::print(stderr, "Async wait failed {}\n", error.message());
471a3dc60dSBrandon Kim return;
481a3dc60dSBrandon Kim }
491a3dc60dSBrandon Kim std::vector<EntryPair> entryPairs = bufferInterface->readErrorLogs();
501a3dc60dSBrandon Kim for (const auto& [entryHeader, entry] : entryPairs)
511a3dc60dSBrandon Kim {
52*5de90619SPatrick Williams stdplus::print(stderr, "Read an entry of '{}' bytes\n", entry.size());
531a3dc60dSBrandon Kim
541a3dc60dSBrandon Kim rde::RdeDecodeStatus rdeDecodeStatus =
551a3dc60dSBrandon Kim rdeCommandHandler->decodeRdeCommand(
561a3dc60dSBrandon Kim entry,
571a3dc60dSBrandon Kim static_cast<rde::RdeCommandType>(entryHeader.rdeCommandType));
581a3dc60dSBrandon Kim if (rdeDecodeStatus == rde::RdeDecodeStatus::RdeStopFlagReceived)
591a3dc60dSBrandon Kim {
601a3dc60dSBrandon Kim auto bufferHeader = bufferInterface->getCachedBufferHeader();
611a3dc60dSBrandon Kim auto newbmcFlags =
621a3dc60dSBrandon Kim boost::endian::little_to_native(bufferHeader.bmcFlags) |
631a3dc60dSBrandon Kim static_cast<uint32_t>(BmcFlags::ready);
641a3dc60dSBrandon Kim bufferInterface->updateBmcFlags(newbmcFlags);
651a3dc60dSBrandon Kim }
661a3dc60dSBrandon Kim }
671a3dc60dSBrandon Kim
681a3dc60dSBrandon Kim t->expires_from_now(readIntervalinMs);
691a3dc60dSBrandon Kim t->async_wait(
701a3dc60dSBrandon Kim std::bind_front(readLoop, t, bufferInterface, rdeCommandHandler));
71554fad0bSBrandon Kim }
72554fad0bSBrandon Kim
main()73554fad0bSBrandon Kim int main()
74554fad0bSBrandon Kim {
75554fad0bSBrandon Kim boost::asio::io_context io;
761a3dc60dSBrandon Kim boost::asio::steady_timer t(io, readIntervalinMs);
77554fad0bSBrandon Kim
781a3dc60dSBrandon Kim // bufferHandler initialization
791a3dc60dSBrandon Kim std::unique_ptr<stdplus::ManagedFd> managedFd =
801a3dc60dSBrandon Kim std::make_unique<stdplus::ManagedFd>(stdplus::fd::open(
811a3dc60dSBrandon Kim "/dev/mem",
821a3dc60dSBrandon Kim stdplus::fd::OpenFlags(stdplus::fd::OpenAccess::ReadWrite)
831a3dc60dSBrandon Kim .set(stdplus::fd::OpenFlag::Sync)));
841a3dc60dSBrandon Kim std::unique_ptr<DataInterface> pciDataHandler =
851a3dc60dSBrandon Kim std::make_unique<PciDataHandler>(memoryRegionOffset, memoryRegionSize,
861a3dc60dSBrandon Kim std::move(managedFd));
871a3dc60dSBrandon Kim std::shared_ptr<BufferInterface> bufferHandler =
881a3dc60dSBrandon Kim std::make_shared<BufferImpl>(std::move(pciDataHandler));
89554fad0bSBrandon Kim
901a3dc60dSBrandon Kim // rdeCommandHandler initialization
91a3b64fb6Skasunath std::shared_ptr<sdbusplus::asio::connection> conn =
92a3b64fb6Skasunath std::make_shared<sdbusplus::asio::connection>(io);
93a3b64fb6Skasunath conn->request_name("xyz.openbmc_project.bios_bmc_smm_error_logger");
94bea36e22SPatrick Williams sdbusplus::bus_t& bus = static_cast<sdbusplus::bus_t&>(*conn);
95a3b64fb6Skasunath
961a3dc60dSBrandon Kim std::unique_ptr<rde::FileHandlerInterface> fileIface =
971a3dc60dSBrandon Kim std::make_unique<rde::ExternalStorerFileWriter>();
981a3dc60dSBrandon Kim std::unique_ptr<rde::ExternalStorerInterface> exFileIface =
991a3dc60dSBrandon Kim std::make_unique<rde::ExternalStorerFileInterface>(
100a3b64fb6Skasunath bus, "/run/bmcweb", std::move(fileIface));
1011a3dc60dSBrandon Kim std::shared_ptr<rde::RdeCommandHandler> rdeCommandHandler =
1021a3dc60dSBrandon Kim std::make_unique<rde::RdeCommandHandler>(std::move(exFileIface));
1031a3dc60dSBrandon Kim
1041a3dc60dSBrandon Kim bufferHandler->initialize(bmcInterfaceVersion, queueSize, ueRegionSize,
1051a3dc60dSBrandon Kim magicNumber);
1061a3dc60dSBrandon Kim
1071a3dc60dSBrandon Kim t.async_wait(std::bind_front(readLoop, &t, std::move(bufferHandler),
1081a3dc60dSBrandon Kim std::move(rdeCommandHandler)));
109554fad0bSBrandon Kim io.run();
110554fad0bSBrandon Kim
111554fad0bSBrandon Kim return 0;
112554fad0bSBrandon Kim }
113