1 #pragma once
2 
3 #include "pci_handler.hpp"
4 
5 #include <boost/endian/arithmetic.hpp>
6 
7 #include <array>
8 #include <cstdint>
9 #include <memory>
10 #include <tuple>
11 
12 namespace bios_bmc_smm_error_logger
13 {
14 
15 /* Adding endianness */
16 using boost::endian::little_uint16_t;
17 using boost::endian::little_uint32_t;
18 using boost::endian::little_uint64_t;
19 
20 struct CircularBufferHeader
21 {
22     little_uint32_t bmcInterfaceVersion;        // Offset 0x0
23     little_uint32_t biosInterfaceVersion;       // Offset 0x4
24     std::array<little_uint32_t, 4> magicNumber; // Offset 0x8
25     little_uint16_t queueSize;                  // Offset 0x18
26     little_uint16_t ueRegionSize;               // Offset 0x1a
27     little_uint32_t bmcFlags;                   // Offset 0x1c
28     little_uint16_t bmcReadPtr;                 // Offset 0x20
29     std::array<uint8_t, 6> reserved1;           // Offset 0x22
30     little_uint32_t biosFlags;                  // Offset 0x28
31     little_uint16_t biosWritePtr;               // Offset 0x2c
32     std::array<uint8_t, 2> reserved2;           // Offset 0x2e
33     // UE reserved region:                         Offset 0x30
34     // Error log queue:       Offset 0x30 + UE reserved region
35 
36     bool operator==(const CircularBufferHeader& other) const
37     {
38         /* Skip comparing reserved1 and reserved2 */
39         return std::tie(this->bmcInterfaceVersion, this->biosInterfaceVersion,
40                         this->magicNumber, this->queueSize, this->ueRegionSize,
41                         this->bmcFlags, this->bmcReadPtr, this->biosFlags,
42                         this->biosWritePtr) ==
43                std::tie(other.bmcInterfaceVersion, other.biosInterfaceVersion,
44                         other.magicNumber, other.queueSize, other.ueRegionSize,
45                         other.bmcFlags, other.bmcReadPtr, other.biosFlags,
46                         other.biosWritePtr);
47     }
48 };
49 static_assert(sizeof(CircularBufferHeader) == 0x30,
50               "Size of CircularBufferHeader struct is incorrect.");
51 
52 /**
53  * An interface class for the buffer helper APIs
54  */
55 class BufferInterface
56 {
57   public:
58     virtual ~BufferInterface() = default;
59 
60     /**
61      * Zero out the buffer first before populating the header
62      *
63      * @param[in] bmcInterfaceVersion - Used to initialize the header
64      * @param[in] queueSize - Used to initialize the header
65      * @param[in] ueRegionSize - Used to initialize the header
66      * @param[in] magicNumber - Used to initialize the header
67      * @return true if successful
68      */
69     virtual void initialize(uint32_t bmcInterfaceVersion, uint16_t queueSize,
70                             uint16_t ueRegionSize,
71                             const std::array<uint32_t, 4>& magicNumber) = 0;
72 
73     /**
74      * Read the buffer header from shared buffer
75      */
76     virtual void readBufferHeader() = 0;
77 
78     /**
79      * Getter API for the cached buffer header
80      * @return cached CircularBufferHeader
81      */
82     virtual struct CircularBufferHeader getCachedBufferHeader() const = 0;
83 };
84 
85 /**
86  * Buffer implementation class
87  */
88 class BufferImpl : public BufferInterface
89 {
90   public:
91     /** @brief Constructor for BufferImpl
92      *  @param[in] dataInterface     - DataInterface for this object
93      */
94     explicit BufferImpl(std::unique_ptr<DataInterface> dataInterface);
95     void initialize(uint32_t bmcInterfaceVersion, uint16_t queueSize,
96                     uint16_t ueRegionSize,
97                     const std::array<uint32_t, 4>& magicNumber) override;
98     void readBufferHeader() override;
99     struct CircularBufferHeader getCachedBufferHeader() const override;
100 
101   private:
102     std::unique_ptr<DataInterface> dataInterface;
103     struct CircularBufferHeader cachedBufferHeader = {};
104 };
105 
106 } // namespace bios_bmc_smm_error_logger
107