buffer: Implement "wraparoundRead"
This is a helper function for reading the circular buffer
Tested: Unit tested
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I0f7c0e3c0195c82fe932b36babbce0ab8c8405ed
diff --git a/src/buffer.cpp b/src/buffer.cpp
index c07bba6..0b6f460 100644
--- a/src/buffer.cpp
+++ b/src/buffer.cpp
@@ -109,4 +109,55 @@
cachedBufferHeader.bmcReadPtr = truncatedReadPtr;
}
+size_t BufferImpl::getQueueOffset()
+{
+ return sizeof(struct CircularBufferHeader) +
+ boost::endian::little_to_native(cachedBufferHeader.ueRegionSize);
+}
+
+std::vector<uint8_t>
+ BufferImpl::wraparoundRead(const uint32_t offset, const uint32_t length,
+ const uint32_t additionalBoundaryCheck)
+{
+ const size_t memoryRegionSize = dataInterface->getMemoryRegionSize();
+
+ size_t queueOffset = getQueueOffset();
+ if (queueOffset + length + additionalBoundaryCheck > memoryRegionSize)
+ {
+ throw std::runtime_error(fmt::format(
+ "[wraparoundRead] queueOffset '{}' + length '{}' "
+ "+ additionalBoundaryCheck '{}' + was bigger "
+ "than memoryRegionSize '{}'",
+ queueOffset, length, additionalBoundaryCheck, memoryRegionSize));
+ }
+
+ // Do a first read up to the end of the buffer (dataInerface->read should
+ // only read up to the end of the buffer)
+ std::vector<uint8_t> bytesRead = dataInterface->read(offset, length);
+ size_t updatedReadOffset = offset + bytesRead.size();
+ size_t bytesRemaining = length - bytesRead.size();
+
+ // If there are any more bytes to be read beyond the buffer, wrap around and
+ // read from the beginning of the buffer (offset by the queueOffset)
+ if (bytesRemaining > 0)
+ {
+ std::vector<uint8_t> wrappedBytesRead =
+ dataInterface->read(queueOffset, bytesRemaining);
+ bytesRemaining -= wrappedBytesRead.size();
+ if (bytesRemaining != 0)
+ {
+ throw std::runtime_error(fmt::format(
+ "[wraparoundRead] Buffer wrapped around but was not able to read "
+ "all of the requested info. Bytes remaining to read '{}' of '{}'",
+ bytesRemaining, length));
+ }
+ bytesRead.insert(bytesRead.end(), wrappedBytesRead.begin(),
+ wrappedBytesRead.end());
+ updatedReadOffset = queueOffset + wrappedBytesRead.size();
+ }
+ updateReadPtr(updatedReadOffset);
+
+ return bytesRead;
+}
+
} // namespace bios_bmc_smm_error_logger