blob: ad845c401f9effa52f7824bf4acdde3b40e6304d [file] [log] [blame]
#pragma once
#include "pci_handler.hpp"
#include <boost/endian/arithmetic.hpp>
#include <array>
#include <cstdint>
#include <memory>
#include <tuple>
namespace bios_bmc_smm_error_logger
{
/* Adding endianness */
using boost::endian::little_uint16_t;
using boost::endian::little_uint32_t;
using boost::endian::little_uint64_t;
struct CircularBufferHeader
{
little_uint32_t bmcInterfaceVersion; // Offset 0x0
little_uint32_t biosInterfaceVersion; // Offset 0x4
std::array<little_uint32_t, 4> magicNumber; // Offset 0x8
little_uint16_t queueSize; // Offset 0x18
little_uint16_t ueRegionSize; // Offset 0x1a
little_uint32_t bmcFlags; // Offset 0x1c
little_uint16_t bmcReadPtr; // Offset 0x20
std::array<uint8_t, 6> reserved1; // Offset 0x22
little_uint32_t biosFlags; // Offset 0x28
little_uint16_t biosWritePtr; // Offset 0x2c
std::array<uint8_t, 2> reserved2; // Offset 0x2e
// UE reserved region: Offset 0x30
// Error log queue: Offset 0x30 + UE reserved region
bool operator==(const CircularBufferHeader& other) const
{
/* Skip comparing reserved1 and reserved2 */
return std::tie(this->bmcInterfaceVersion, this->biosInterfaceVersion,
this->magicNumber, this->queueSize, this->ueRegionSize,
this->bmcFlags, this->bmcReadPtr, this->biosFlags,
this->biosWritePtr) ==
std::tie(other.bmcInterfaceVersion, other.biosInterfaceVersion,
other.magicNumber, other.queueSize, other.ueRegionSize,
other.bmcFlags, other.bmcReadPtr, other.biosFlags,
other.biosWritePtr);
}
};
static_assert(sizeof(CircularBufferHeader) == 0x30,
"Size of CircularBufferHeader struct is incorrect.");
/**
* An interface class for the buffer helper APIs
*/
class BufferInterface
{
public:
virtual ~BufferInterface() = default;
/**
* Zero out the buffer first before populating the header
*
* @param[in] bmcInterfaceVersion - Used to initialize the header
* @param[in] queueSize - Used to initialize the header
* @param[in] ueRegionSize - Used to initialize the header
* @param[in] magicNumber - Used to initialize the header
* @return true if successful
*/
virtual void initialize(uint32_t bmcInterfaceVersion, uint16_t queueSize,
uint16_t ueRegionSize,
const std::array<uint32_t, 4>& magicNumber) = 0;
/**
* Read the buffer header from shared buffer
*/
virtual void readBufferHeader() = 0;
/**
* Getter API for the cached buffer header
* @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;
/**
* Wrapper for the dataInterface->read, performs wraparound read
*
* @param[in] offset - offset to read from
* @param[in] length - bytes to read
* @param[in] additionalBoundaryCheck - bytes to add to the boundary check
* for added restriction
* @return the bytes read
*/
virtual std::vector<uint8_t>
wraparoundRead(const uint32_t offset, const uint32_t length,
const uint32_t additionalBoundaryCheck) = 0;
};
/**
* Buffer implementation class
*/
class BufferImpl : public BufferInterface
{
public:
/** @brief Constructor for BufferImpl
* @param[in] dataInterface - DataInterface for this object
*/
explicit BufferImpl(std::unique_ptr<DataInterface> dataInterface);
void initialize(uint32_t bmcInterfaceVersion, uint16_t queueSize,
uint16_t ueRegionSize,
const std::array<uint32_t, 4>& magicNumber) override;
void readBufferHeader() override;
struct CircularBufferHeader getCachedBufferHeader() const override;
void updateReadPtr(const uint32_t newReadPtr) override;
std::vector<uint8_t>
wraparoundRead(const uint32_t offset, const uint32_t length,
const uint32_t additionalBoundaryCheck = 0) override;
private:
/** @brief The Error log queue starts after the UE region, which is where
* the read and write pointers are offset from relatively
* @return relative offset for read and write pointers
*/
size_t getQueueOffset();
std::unique_ptr<DataInterface> dataInterface;
struct CircularBufferHeader cachedBufferHeader = {};
};
} // namespace bios_bmc_smm_error_logger