xref: /openbmc/bios-bmc-smm-error-logger/src/pci_handler.cpp (revision 1a64356f6dc40bfbc76594a51df1ec3f32bbbd69)
155dcadaeSBrandon Kim #include "pci_handler.hpp"
255dcadaeSBrandon Kim 
355dcadaeSBrandon Kim #include <fcntl.h>
455dcadaeSBrandon Kim 
555dcadaeSBrandon Kim #include <stdplus/fd/managed.hpp>
655dcadaeSBrandon Kim #include <stdplus/fd/mmap.hpp>
75de90619SPatrick Williams #include <stdplus/print.hpp>
855dcadaeSBrandon Kim 
955dcadaeSBrandon Kim #include <cstdint>
1055dcadaeSBrandon Kim #include <cstring>
115de90619SPatrick Williams #include <format>
1255dcadaeSBrandon Kim #include <memory>
1355dcadaeSBrandon Kim #include <span>
1455dcadaeSBrandon Kim #include <vector>
1555dcadaeSBrandon Kim 
1655dcadaeSBrandon Kim namespace bios_bmc_smm_error_logger
1755dcadaeSBrandon Kim {
1855dcadaeSBrandon Kim 
PciDataHandler(uint32_t regionAddress,size_t regionSize,std::unique_ptr<stdplus::fd::Fd> fd)1955dcadaeSBrandon Kim PciDataHandler::PciDataHandler(uint32_t regionAddress, size_t regionSize,
2055dcadaeSBrandon Kim                                std::unique_ptr<stdplus::fd::Fd> fd) :
21*1a64356fSPatrick Williams     regionSize(regionSize), fd(std::move(fd)),
2255dcadaeSBrandon Kim     mmap(stdplus::fd::MMap(
2355dcadaeSBrandon Kim         *this->fd, regionSize, stdplus::fd::ProtFlags{PROT_READ | PROT_WRITE},
2455dcadaeSBrandon Kim         stdplus::fd::MMapFlags{stdplus::fd::MMapAccess::Shared}, regionAddress))
2555dcadaeSBrandon Kim {}
2655dcadaeSBrandon Kim 
read(const uint32_t offset,const uint32_t length)2755dcadaeSBrandon Kim std::vector<uint8_t> PciDataHandler::read(const uint32_t offset,
2855dcadaeSBrandon Kim                                           const uint32_t length)
2955dcadaeSBrandon Kim {
3055dcadaeSBrandon Kim     if (offset > regionSize || length == 0)
3155dcadaeSBrandon Kim     {
325de90619SPatrick Williams         stdplus::print(stderr,
3355dcadaeSBrandon Kim                        "[read] Offset [{}] was bigger than regionSize [{}] "
3455dcadaeSBrandon Kim                        "OR length [{}] was equal to 0\n",
3555dcadaeSBrandon Kim                        offset, regionSize, length);
3655dcadaeSBrandon Kim         return {};
3755dcadaeSBrandon Kim     }
3855dcadaeSBrandon Kim 
3955dcadaeSBrandon Kim     // Read up to regionSize in case the offset + length overflowed
40*1a64356fSPatrick Williams     uint32_t finalLength =
41*1a64356fSPatrick Williams         (offset + length < regionSize) ? length : regionSize - offset;
4255dcadaeSBrandon Kim     std::vector<uint8_t> results(finalLength);
4355dcadaeSBrandon Kim 
4455dcadaeSBrandon Kim     std::memcpy(results.data(), mmap.get().data() + offset, finalLength);
4555dcadaeSBrandon Kim     return results;
4655dcadaeSBrandon Kim }
4755dcadaeSBrandon Kim 
write(const uint32_t offset,const std::span<const uint8_t> bytes)4855dcadaeSBrandon Kim uint32_t PciDataHandler::write(const uint32_t offset,
4955dcadaeSBrandon Kim                                const std::span<const uint8_t> bytes)
5055dcadaeSBrandon Kim {
5155dcadaeSBrandon Kim     const size_t length = bytes.size();
5255dcadaeSBrandon Kim     if (offset > regionSize || length == 0)
5355dcadaeSBrandon Kim     {
545de90619SPatrick Williams         stdplus::print(stderr,
5555dcadaeSBrandon Kim                        "[write] Offset [{}] was bigger than regionSize [{}] "
5655dcadaeSBrandon Kim                        "OR length [{}] was equal to 0\n",
5755dcadaeSBrandon Kim                        offset, regionSize, length);
5855dcadaeSBrandon Kim         return 0;
5955dcadaeSBrandon Kim     }
6055dcadaeSBrandon Kim 
6155dcadaeSBrandon Kim     // Write up to regionSize in case the offset + length overflowed
62*1a64356fSPatrick Williams     uint16_t finalLength =
63*1a64356fSPatrick Williams         (offset + length < regionSize) ? length : regionSize - offset;
6455dcadaeSBrandon Kim     std::memcpy(mmap.get().data() + offset, bytes.data(), finalLength);
6555dcadaeSBrandon Kim     return finalLength;
6655dcadaeSBrandon Kim }
6755dcadaeSBrandon Kim 
getMemoryRegionSize()6855dcadaeSBrandon Kim uint32_t PciDataHandler::getMemoryRegionSize()
6955dcadaeSBrandon Kim {
7055dcadaeSBrandon Kim     return regionSize;
7155dcadaeSBrandon Kim }
7255dcadaeSBrandon Kim 
7355dcadaeSBrandon Kim } // namespace bios_bmc_smm_error_logger
74