main: Integrating the buffer and rde handler
This will loop upon start up of the system and decode any incoming
payloads.
Tested:
Tested on a real hardware with a real BIOS
Change-Id: Iddbdafbf9a6e94d7a3556335ea59b935e1931c83
Signed-off-by: Brandon Kim <brandonkim@google.com>
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/src/main.cpp b/src/main.cpp
index 9db1969..0b520a9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,30 +1,105 @@
+#include "config.h"
+
+#include "buffer.hpp"
+#include "pci_handler.hpp"
+#include "rde/external_storer_file.hpp"
+#include "rde/external_storer_interface.hpp"
+#include "rde/rde_handler.hpp"
+
+#include <fmt/format.h>
+
#include <boost/asio.hpp>
+#include <boost/endian/conversion.hpp>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/fd/impl.hpp>
+#include <stdplus/fd/managed.hpp>
#include <chrono>
+#include <filesystem>
+#include <fstream>
#include <functional>
+#include <memory>
namespace
{
-// Set the read loop interval to be 1 second for now
-// TODO: Make this a configuration option
-static constexpr std::chrono::seconds readIntervalSec(1);
+constexpr std::chrono::milliseconds readIntervalinMs(READ_INTERVAL_MS);
+constexpr std::size_t memoryRegionSize = MEMORY_REGION_SIZE;
+constexpr std::size_t memoryRegionOffset = MEMORY_REGION_OFFSET;
+constexpr uint32_t bmcInterfaceVersion = BMC_INTERFACE_VERSION;
+constexpr uint16_t queueSize = QUEUE_REGION_SIZE;
+constexpr uint16_t ueRegionSize = UE_REGION_SIZE;
+static constexpr std::array<uint32_t, 4> magicNumber = {
+ MAGIC_NUMBER_BYTE1, MAGIC_NUMBER_BYTE2, MAGIC_NUMBER_BYTE3,
+ MAGIC_NUMBER_BYTE4};
} // namespace
-// boost::async_wait requires `const boost::system::error_code&` parameter
-void readLoop(boost::asio::steady_timer* t, const boost::system::error_code&)
+using namespace bios_bmc_smm_error_logger;
+
+void 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)
{
- /* This will run every readIntervalSec second for now */
- t->expires_from_now(readIntervalSec);
- t->async_wait(std::bind_front(readLoop, t));
+ if (error)
+ {
+ fmt::print(stderr, "Async wait failed {}\n", error.message());
+ return;
+ }
+ std::vector<EntryPair> entryPairs = bufferInterface->readErrorLogs();
+ for (const auto& [entryHeader, entry] : entryPairs)
+ {
+ fmt::print(stderr, "Read an entry of '{}' bytes\n", entry.size());
+
+ rde::RdeDecodeStatus rdeDecodeStatus =
+ rdeCommandHandler->decodeRdeCommand(
+ entry,
+ static_cast<rde::RdeCommandType>(entryHeader.rdeCommandType));
+ if (rdeDecodeStatus == rde::RdeDecodeStatus::RdeStopFlagReceived)
+ {
+ auto bufferHeader = bufferInterface->getCachedBufferHeader();
+ auto newbmcFlags =
+ boost::endian::little_to_native(bufferHeader.bmcFlags) |
+ static_cast<uint32_t>(BmcFlags::ready);
+ bufferInterface->updateBmcFlags(newbmcFlags);
+ }
+ }
+
+ t->expires_from_now(readIntervalinMs);
+ t->async_wait(
+ std::bind_front(readLoop, t, bufferInterface, rdeCommandHandler));
}
int main()
{
boost::asio::io_context io;
- boost::asio::steady_timer t(io, readIntervalSec);
+ boost::asio::steady_timer t(io, readIntervalinMs);
- t.async_wait(std::bind_front(readLoop, &t));
+ // bufferHandler initialization
+ std::unique_ptr<stdplus::ManagedFd> managedFd =
+ std::make_unique<stdplus::ManagedFd>(stdplus::fd::open(
+ "/dev/mem",
+ stdplus::fd::OpenFlags(stdplus::fd::OpenAccess::ReadWrite)
+ .set(stdplus::fd::OpenFlag::Sync)));
+ std::unique_ptr<DataInterface> pciDataHandler =
+ std::make_unique<PciDataHandler>(memoryRegionOffset, memoryRegionSize,
+ std::move(managedFd));
+ std::shared_ptr<BufferInterface> bufferHandler =
+ std::make_shared<BufferImpl>(std::move(pciDataHandler));
+ // rdeCommandHandler initialization
+ std::unique_ptr<rde::FileHandlerInterface> fileIface =
+ std::make_unique<rde::ExternalStorerFileWriter>();
+ std::unique_ptr<rde::ExternalStorerInterface> exFileIface =
+ std::make_unique<rde::ExternalStorerFileInterface>(
+ "/run/bmcweb", std::move(fileIface));
+ std::shared_ptr<rde::RdeCommandHandler> rdeCommandHandler =
+ std::make_unique<rde::RdeCommandHandler>(std::move(exFileIface));
+
+ bufferHandler->initialize(bmcInterfaceVersion, queueSize, ueRegionSize,
+ magicNumber);
+
+ t.async_wait(std::bind_front(readLoop, &t, std::move(bufferHandler),
+ std::move(rdeCommandHandler)));
io.run();
return 0;