blob: 0b520a9bb64c2fcef9b43f23bc8dc354aab59ea4 [file] [log] [blame]
Brandon Kim1a3dc602022-06-17 11:34:33 -07001#include "config.h"
2
3#include "buffer.hpp"
4#include "pci_handler.hpp"
5#include "rde/external_storer_file.hpp"
6#include "rde/external_storer_interface.hpp"
7#include "rde/rde_handler.hpp"
8
9#include <fmt/format.h>
10
Brandon Kim554fad02022-05-15 15:41:05 -070011#include <boost/asio.hpp>
Brandon Kim1a3dc602022-06-17 11:34:33 -070012#include <boost/endian/conversion.hpp>
13#include <stdplus/fd/create.hpp>
14#include <stdplus/fd/impl.hpp>
15#include <stdplus/fd/managed.hpp>
Brandon Kim554fad02022-05-15 15:41:05 -070016
17#include <chrono>
Brandon Kim1a3dc602022-06-17 11:34:33 -070018#include <filesystem>
19#include <fstream>
Brandon Kim554fad02022-05-15 15:41:05 -070020#include <functional>
Brandon Kim1a3dc602022-06-17 11:34:33 -070021#include <memory>
Brandon Kim554fad02022-05-15 15:41:05 -070022
23namespace
24{
Brandon Kim1a3dc602022-06-17 11:34:33 -070025constexpr std::chrono::milliseconds readIntervalinMs(READ_INTERVAL_MS);
26constexpr std::size_t memoryRegionSize = MEMORY_REGION_SIZE;
27constexpr std::size_t memoryRegionOffset = MEMORY_REGION_OFFSET;
28constexpr uint32_t bmcInterfaceVersion = BMC_INTERFACE_VERSION;
29constexpr uint16_t queueSize = QUEUE_REGION_SIZE;
30constexpr uint16_t ueRegionSize = UE_REGION_SIZE;
31static constexpr std::array<uint32_t, 4> magicNumber = {
32 MAGIC_NUMBER_BYTE1, MAGIC_NUMBER_BYTE2, MAGIC_NUMBER_BYTE3,
33 MAGIC_NUMBER_BYTE4};
Brandon Kim554fad02022-05-15 15:41:05 -070034} // namespace
35
Brandon Kim1a3dc602022-06-17 11:34:33 -070036using namespace bios_bmc_smm_error_logger;
37
38void readLoop(boost::asio::steady_timer* t,
39 const std::shared_ptr<BufferInterface>& bufferInterface,
40 const std::shared_ptr<rde::RdeCommandHandler>& rdeCommandHandler,
41 const boost::system::error_code& error)
Brandon Kim554fad02022-05-15 15:41:05 -070042{
Brandon Kim1a3dc602022-06-17 11:34:33 -070043 if (error)
44 {
45 fmt::print(stderr, "Async wait failed {}\n", error.message());
46 return;
47 }
48 std::vector<EntryPair> entryPairs = bufferInterface->readErrorLogs();
49 for (const auto& [entryHeader, entry] : entryPairs)
50 {
51 fmt::print(stderr, "Read an entry of '{}' bytes\n", entry.size());
52
53 rde::RdeDecodeStatus rdeDecodeStatus =
54 rdeCommandHandler->decodeRdeCommand(
55 entry,
56 static_cast<rde::RdeCommandType>(entryHeader.rdeCommandType));
57 if (rdeDecodeStatus == rde::RdeDecodeStatus::RdeStopFlagReceived)
58 {
59 auto bufferHeader = bufferInterface->getCachedBufferHeader();
60 auto newbmcFlags =
61 boost::endian::little_to_native(bufferHeader.bmcFlags) |
62 static_cast<uint32_t>(BmcFlags::ready);
63 bufferInterface->updateBmcFlags(newbmcFlags);
64 }
65 }
66
67 t->expires_from_now(readIntervalinMs);
68 t->async_wait(
69 std::bind_front(readLoop, t, bufferInterface, rdeCommandHandler));
Brandon Kim554fad02022-05-15 15:41:05 -070070}
71
72int main()
73{
74 boost::asio::io_context io;
Brandon Kim1a3dc602022-06-17 11:34:33 -070075 boost::asio::steady_timer t(io, readIntervalinMs);
Brandon Kim554fad02022-05-15 15:41:05 -070076
Brandon Kim1a3dc602022-06-17 11:34:33 -070077 // bufferHandler initialization
78 std::unique_ptr<stdplus::ManagedFd> managedFd =
79 std::make_unique<stdplus::ManagedFd>(stdplus::fd::open(
80 "/dev/mem",
81 stdplus::fd::OpenFlags(stdplus::fd::OpenAccess::ReadWrite)
82 .set(stdplus::fd::OpenFlag::Sync)));
83 std::unique_ptr<DataInterface> pciDataHandler =
84 std::make_unique<PciDataHandler>(memoryRegionOffset, memoryRegionSize,
85 std::move(managedFd));
86 std::shared_ptr<BufferInterface> bufferHandler =
87 std::make_shared<BufferImpl>(std::move(pciDataHandler));
Brandon Kim554fad02022-05-15 15:41:05 -070088
Brandon Kim1a3dc602022-06-17 11:34:33 -070089 // rdeCommandHandler initialization
90 std::unique_ptr<rde::FileHandlerInterface> fileIface =
91 std::make_unique<rde::ExternalStorerFileWriter>();
92 std::unique_ptr<rde::ExternalStorerInterface> exFileIface =
93 std::make_unique<rde::ExternalStorerFileInterface>(
94 "/run/bmcweb", std::move(fileIface));
95 std::shared_ptr<rde::RdeCommandHandler> rdeCommandHandler =
96 std::make_unique<rde::RdeCommandHandler>(std::move(exFileIface));
97
98 bufferHandler->initialize(bmcInterfaceVersion, queueSize, ueRegionSize,
99 magicNumber);
100
101 t.async_wait(std::bind_front(readLoop, &t, std::move(bufferHandler),
102 std::move(rdeCommandHandler)));
Brandon Kim554fad02022-05-15 15:41:05 -0700103 io.run();
104
105 return 0;
106}