1 #include "pci_handler.hpp"
2 
3 #include <fcntl.h>
4 #include <fmt/format.h>
5 
6 #include <stdplus/fd/managed.hpp>
7 #include <stdplus/fd/mmap.hpp>
8 
9 #include <cstdint>
10 #include <cstring>
11 #include <memory>
12 #include <span>
13 #include <vector>
14 
15 namespace bios_bmc_smm_error_logger
16 {
17 
18 PciDataHandler::PciDataHandler(uint32_t regionAddress, size_t regionSize,
19                                std::unique_ptr<stdplus::fd::Fd> fd) :
20     regionSize(regionSize),
21     fd(std::move(fd)),
22     mmap(stdplus::fd::MMap(
23         *this->fd, regionSize, stdplus::fd::ProtFlags{PROT_READ | PROT_WRITE},
24         stdplus::fd::MMapFlags{stdplus::fd::MMapAccess::Shared}, regionAddress))
25 {}
26 
27 std::vector<uint8_t> PciDataHandler::read(const uint32_t offset,
28                                           const uint32_t length)
29 {
30     if (offset > regionSize || length == 0)
31     {
32         fmt::print(stderr,
33                    "[read] Offset [{}] was bigger than regionSize [{}] "
34                    "OR length [{}] was equal to 0\n",
35                    offset, regionSize, length);
36         return {};
37     }
38 
39     // Read up to regionSize in case the offset + length overflowed
40     uint32_t finalLength = (offset + length < regionSize) ? length
41                                                           : regionSize - offset;
42     std::vector<uint8_t> results(finalLength);
43 
44     std::memcpy(results.data(), mmap.get().data() + offset, finalLength);
45     return results;
46 }
47 
48 uint32_t PciDataHandler::write(const uint32_t offset,
49                                const std::span<const uint8_t> bytes)
50 {
51     const size_t length = bytes.size();
52     if (offset > regionSize || length == 0)
53     {
54         fmt::print(stderr,
55                    "[write] Offset [{}] was bigger than regionSize [{}] "
56                    "OR length [{}] was equal to 0\n",
57                    offset, regionSize, length);
58         return 0;
59     }
60 
61     // Write up to regionSize in case the offset + length overflowed
62     uint16_t finalLength = (offset + length < regionSize) ? length
63                                                           : regionSize - offset;
64     std::memcpy(mmap.get().data() + offset, bytes.data(), finalLength);
65     return finalLength;
66 }
67 
68 uint32_t PciDataHandler::getMemoryRegionSize()
69 {
70     return regionSize;
71 }
72 
73 } // namespace bios_bmc_smm_error_logger
74