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/meson.build b/meson.build
index 1b989ae..cda8014 100644
--- a/meson.build
+++ b/meson.build
@@ -13,8 +13,28 @@
bios_bmc_smm_error_logger_inc = include_directories('include')
rde_inc = include_directories('include')
-subdir('src')
+# Setting up config data
+conf_data = configuration_data()
+
+conf_data.set('READ_INTERVAL_MS', get_option('read-interval-ms'))
+
+conf_data.set('MEMORY_REGION_SIZE', get_option('memory-region-size'))
+conf_data.set('MEMORY_REGION_OFFSET', get_option('memory-region-offset'))
+conf_data.set('BMC_INTERFACE_VERSION', get_option('bmc-interface-version'))
+
+conf_data.set('QUEUE_REGION_SIZE', get_option('queue-region-size'))
+conf_data.set('UE_REGION_SIZE', get_option('ue-region-size'))
+conf_data.set('MAGIC_NUMBER_BYTE1', get_option('magic-number-byte1'))
+conf_data.set('MAGIC_NUMBER_BYTE2', get_option('magic-number-byte2'))
+conf_data.set('MAGIC_NUMBER_BYTE3', get_option('magic-number-byte3'))
+conf_data.set('MAGIC_NUMBER_BYTE4', get_option('magic-number-byte4'))
+
+conf_h = configure_file(
+ output: 'config.h',
+ configuration: conf_data)
+
subdir('src/rde')
+subdir('src')
if not get_option('tests').disabled()
subdir('test')
endif
diff --git a/meson_options.txt b/meson_options.txt
index 0fc2767..ec979e3 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1 +1,19 @@
option('tests', type: 'feature', description: 'Build tests')
+
+# Tinmer constant
+option('read-interval-ms', type: 'integer', value: 10, description: 'Read loop interval in millisecond (ms)')
+
+# Memory constants
+option('memory-region-size', type: 'integer', value: 16384, description: 'Memory size allcated')
+# Default value 4035215360 is 0xF0848000 below
+option('memory-region-offset', type: 'integer', value: 4035215360, description: 'Where the memory region is located')
+
+# Circular Buffer header constants
+option('bmc-interface-version', type: 'integer', value: 0, description: 'BMC interface version to easily see compatibility')
+option('queue-region-size', type: 'integer', value: 0, description: 'Normal error queue region size')
+option('ue-region-size', type: 'integer', value: 0, description: 'Uncorrectable error region size')
+# Magic Number Array Constants
+option('magic-number-byte1', type: 'integer', value: 1, description: 'Magic Number array[0] for validity, consists of 4 * uint32_t')
+option('magic-number-byte2', type: 'integer', value: 2, description: 'Magic Number array[1] for validity, consists of 4 * uint32_t')
+option('magic-number-byte3', type: 'integer', value: 3, description: 'Magic Number array[2] for validity, consists of 4 * uint32_t')
+option('magic-number-byte4', type: 'integer', value: 4, description: 'Magic Number array[3] for validity, consists of 4 * uint32_t')
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;
diff --git a/src/meson.build b/src/meson.build
index fd0ead4..8e5a8ff 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -35,8 +35,9 @@
executable(
'bios-bmc-smm-error-logger',
'main.cpp',
+ conf_h,
implicit_include_directories: false,
- dependencies: bios_bmc_smm_error_logger_dep,
+ dependencies: [bios_bmc_smm_error_logger_dep, rde_dep],
install: true,
install_dir: get_option('bindir')
)
diff --git a/test/buffer_test.cpp b/test/buffer_test.cpp
index 0b3d8e2..712c801 100644
--- a/test/buffer_test.cpp
+++ b/test/buffer_test.cpp
@@ -655,7 +655,7 @@
EXPECT_NO_THROW(entryPairs = bufferImpl->readErrorLogs());
// Check that we only read one entryPair and that the content is correct
- EXPECT_EQ(entryPairs.size(), 1);
+ EXPECT_EQ(entryPairs.size(), 1U);
EXPECT_EQ(entryPairs[0].first, testEntryHeader);
EXPECT_THAT(entryPairs[0].second, ElementsAreArray(testEntryVector));
}