buffer: Implement "updateReadPtr"
This is a helper function for reading the circular buffer
Tested: Unit tested
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I1c34a40bd279ee601de33669aabfec27a959ec44
diff --git a/include/buffer.hpp b/include/buffer.hpp
index 08d400d..6c42401 100644
--- a/include/buffer.hpp
+++ b/include/buffer.hpp
@@ -80,6 +80,12 @@
* @return cached CircularBufferHeader
*/
virtual struct CircularBufferHeader getCachedBufferHeader() const = 0;
+
+ /**
+ * Write to the bufferHeader and update the read pointer
+ * @param[in] newReadPtr - read pointer to update to
+ */
+ virtual void updateReadPtr(const uint32_t newReadPtr) = 0;
};
/**
@@ -97,6 +103,7 @@
const std::array<uint32_t, 4>& magicNumber) override;
void readBufferHeader() override;
struct CircularBufferHeader getCachedBufferHeader() const override;
+ void updateReadPtr(const uint32_t newReadPtr) override;
private:
std::unique_ptr<DataInterface> dataInterface;
diff --git a/src/buffer.cpp b/src/buffer.cpp
index 524984a..c07bba6 100644
--- a/src/buffer.cpp
+++ b/src/buffer.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include <array>
+#include <cstddef>
#include <cstdint>
#include <memory>
#include <span>
@@ -85,4 +86,27 @@
return cachedBufferHeader;
}
+void BufferImpl::updateReadPtr(const uint32_t newReadPtr)
+{
+ constexpr uint8_t bmcReadPtrOffset =
+ offsetof(struct CircularBufferHeader, bmcReadPtr);
+
+ little_uint16_t truncatedReadPtr =
+ boost::endian::native_to_little(newReadPtr & 0xffff);
+ uint8_t* truncatedReadPtrPtr =
+ reinterpret_cast<uint8_t*>(&truncatedReadPtr);
+
+ size_t writtenSize = dataInterface->write(
+ bmcReadPtrOffset, std::span<const uint8_t>{
+ truncatedReadPtrPtr,
+ truncatedReadPtrPtr + sizeof(little_uint16_t)});
+ if (writtenSize != sizeof(little_uint16_t))
+ {
+ throw std::runtime_error(fmt::format(
+ "[updateReadPtr] Wrote '{}' bytes, instead of expected '{}'",
+ writtenSize, sizeof(little_uint16_t)));
+ }
+ cachedBufferHeader.bmcReadPtr = truncatedReadPtr;
+}
+
} // namespace bios_bmc_smm_error_logger
diff --git a/test/buffer_test.cpp b/test/buffer_test.cpp
index e8943a9..4307825 100644
--- a/test/buffer_test.cpp
+++ b/test/buffer_test.cpp
@@ -152,5 +152,37 @@
EXPECT_EQ(bufferImpl->getCachedBufferHeader(), testInitializationHeader);
}
+TEST_F(BufferTest, BufferUpdateReadPtrFail)
+{
+ // Return write size that is not 2 which is sizeof(little_uint16_t)
+ constexpr size_t wrongWriteSize = 1;
+ EXPECT_CALL(*dataInterfaceMockPtr, write(_, _))
+ .WillOnce(Return(wrongWriteSize));
+ EXPECT_THROW(
+ try {
+ bufferImpl->updateReadPtr(0);
+ } catch (const std::runtime_error& e) {
+ EXPECT_STREQ(
+ e.what(),
+ "[updateReadPtr] Wrote '1' bytes, instead of expected '2'");
+ throw;
+ },
+ std::runtime_error);
+}
+
+TEST_F(BufferTest, BufferUpdateReadPtrPass)
+{
+ constexpr size_t expectedWriteSize = 2;
+ constexpr uint8_t expectedBmcReadPtrOffset = 0x20;
+ // Check that we truncate the highest 16bits
+ const uint32_t testNewReadPtr = 0x99881234;
+ const std::vector<uint8_t> expectedReadPtr{0x34, 0x12};
+
+ EXPECT_CALL(*dataInterfaceMockPtr, write(expectedBmcReadPtrOffset,
+ ElementsAreArray(expectedReadPtr)))
+ .WillOnce(Return(expectedWriteSize));
+ EXPECT_NO_THROW(bufferImpl->updateReadPtr(testNewReadPtr));
+}
+
} // namespace
} // namespace bios_bmc_smm_error_logger