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