Add overflow flag checking

This is to ensure that we check for and flag buffer overflow flag from
the BIOS.

The logic should be:

```
1. BIOS_switch ^ BMC_switch == 0 → No overflow incident
  a. CONTINUE
2. BIOS_switch ^ BMC_switch == 1 → an unlogged overflow incident has occurred
  b. Log the overflow incident
  c. Toggle the BMC overflow flag
```

Tested: Added unit test

Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I25c50a8de93900480413389d7d2a89b9be4b5643
diff --git a/test/buffer_test.cpp b/test/buffer_test.cpp
index 675be79..d6f355a 100644
--- a/test/buffer_test.cpp
+++ b/test/buffer_test.cpp
@@ -420,6 +420,60 @@
         std::runtime_error);
 }
 
+TEST_F(BufferTest, CheckOverflow_NotPresentDueToFlags)
+{
+    struct CircularBufferHeader header = testInitializationHeader;
+    // Flags are the same, so no new overflow
+    header.biosFlags = boost::endian::native_to_little<uint32_t>(
+        static_cast<uint32_t>(BufferFlags::overflow));
+    header.bmcFlags = boost::endian::native_to_little<uint32_t>(
+        static_cast<uint32_t>(BufferFlags::overflow));
+
+    uint8_t* headerPtr = reinterpret_cast<uint8_t*>(&header);
+    std::vector<uint8_t> headerBytes(headerPtr, headerPtr + bufferHeaderSize);
+    EXPECT_CALL(*dataInterfaceMockPtr, read(0, bufferHeaderSize))
+        .WillOnce(Return(headerBytes));
+
+    bool overflowDetected = bufferImpl->checkForOverflowAndAcknowledge();
+    ASSERT_FALSE(overflowDetected);
+}
+
+TEST_F(BufferTest, CheckOverflow_PresentAndAcknowledged)
+{
+    struct CircularBufferHeader header = testInitializationHeader;
+    header.biosFlags = boost::endian::native_to_little<uint32_t>(
+        static_cast<uint32_t>(BufferFlags::overflow));
+    header.bmcFlags =
+        boost::endian::native_to_little<uint32_t>(0); // BIOS set, BMC not yet
+
+    uint8_t* headerPtr = reinterpret_cast<uint8_t*>(&header);
+    std::vector<uint8_t> headerBytes(headerPtr, headerPtr + bufferHeaderSize);
+    EXPECT_CALL(*dataInterfaceMockPtr, read(0, bufferHeaderSize))
+        .WillOnce(Return(headerBytes));
+
+    uint32_t expectedNewBmcFlags =
+        static_cast<uint32_t>(BufferFlags::overflow); // BMC toggles its bit
+    little_uint32_t littleExpectedNewBmcFlags =
+        boost::endian::native_to_little(expectedNewBmcFlags);
+    uint8_t* flagPtr = reinterpret_cast<uint8_t*>(&littleExpectedNewBmcFlags);
+    std::vector<uint8_t> expectedFlagWrite(flagPtr,
+                                           flagPtr + sizeof(little_uint32_t));
+    constexpr uint8_t bmcFlagsOffset =
+        offsetof(struct CircularBufferHeader, bmcFlags);
+
+    EXPECT_CALL(*dataInterfaceMockPtr,
+                write(bmcFlagsOffset, ElementsAreArray(expectedFlagWrite)))
+        .WillOnce(Return(sizeof(little_uint32_t)));
+
+    bool overflowDetected = bufferImpl->checkForOverflowAndAcknowledge();
+    ASSERT_TRUE(overflowDetected);
+
+    struct CircularBufferHeader updatedCachedHeader =
+        bufferImpl->getCachedBufferHeader();
+    EXPECT_EQ(boost::endian::little_to_native(updatedCachedHeader.bmcFlags),
+              expectedNewBmcFlags);
+}
+
 class BufferWraparoundReadTest : public BufferTest
 {
   protected: