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>
7*5de90619SPatrick Williams #include <stdplus/print.hpp>
855dcadaeSBrandon Kim
955dcadaeSBrandon Kim #include <cstdint>
1055dcadaeSBrandon Kim #include <cstring>
11*5de90619SPatrick 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) :
213cbb6ef6SEdward Lee regionSize(regionSize),
223cbb6ef6SEdward Lee fd(std::move(fd)),
2355dcadaeSBrandon Kim mmap(stdplus::fd::MMap(
2455dcadaeSBrandon Kim *this->fd, regionSize, stdplus::fd::ProtFlags{PROT_READ | PROT_WRITE},
2555dcadaeSBrandon Kim stdplus::fd::MMapFlags{stdplus::fd::MMapAccess::Shared}, regionAddress))
2655dcadaeSBrandon Kim {}
2755dcadaeSBrandon Kim
read(const uint32_t offset,const uint32_t length)2855dcadaeSBrandon Kim std::vector<uint8_t> PciDataHandler::read(const uint32_t offset,
2955dcadaeSBrandon Kim const uint32_t length)
3055dcadaeSBrandon Kim {
3155dcadaeSBrandon Kim if (offset > regionSize || length == 0)
3255dcadaeSBrandon Kim {
33*5de90619SPatrick Williams stdplus::print(stderr,
3455dcadaeSBrandon Kim "[read] Offset [{}] was bigger than regionSize [{}] "
3555dcadaeSBrandon Kim "OR length [{}] was equal to 0\n",
3655dcadaeSBrandon Kim offset, regionSize, length);
3755dcadaeSBrandon Kim return {};
3855dcadaeSBrandon Kim }
3955dcadaeSBrandon Kim
4055dcadaeSBrandon Kim // Read up to regionSize in case the offset + length overflowed
41b8125763SPatrick Williams uint32_t finalLength = (offset + length < regionSize) ? length
42b8125763SPatrick Williams : regionSize - offset;
4355dcadaeSBrandon Kim std::vector<uint8_t> results(finalLength);
4455dcadaeSBrandon Kim
4555dcadaeSBrandon Kim std::memcpy(results.data(), mmap.get().data() + offset, finalLength);
4655dcadaeSBrandon Kim return results;
4755dcadaeSBrandon Kim }
4855dcadaeSBrandon Kim
write(const uint32_t offset,const std::span<const uint8_t> bytes)4955dcadaeSBrandon Kim uint32_t PciDataHandler::write(const uint32_t offset,
5055dcadaeSBrandon Kim const std::span<const uint8_t> bytes)
5155dcadaeSBrandon Kim {
5255dcadaeSBrandon Kim const size_t length = bytes.size();
5355dcadaeSBrandon Kim if (offset > regionSize || length == 0)
5455dcadaeSBrandon Kim {
55*5de90619SPatrick Williams stdplus::print(stderr,
5655dcadaeSBrandon Kim "[write] Offset [{}] was bigger than regionSize [{}] "
5755dcadaeSBrandon Kim "OR length [{}] was equal to 0\n",
5855dcadaeSBrandon Kim offset, regionSize, length);
5955dcadaeSBrandon Kim return 0;
6055dcadaeSBrandon Kim }
6155dcadaeSBrandon Kim
6255dcadaeSBrandon Kim // Write up to regionSize in case the offset + length overflowed
63b8125763SPatrick Williams uint16_t finalLength = (offset + length < regionSize) ? length
64b8125763SPatrick Williams : regionSize - offset;
6555dcadaeSBrandon Kim std::memcpy(mmap.get().data() + offset, bytes.data(), finalLength);
6655dcadaeSBrandon Kim return finalLength;
6755dcadaeSBrandon Kim }
6855dcadaeSBrandon Kim
getMemoryRegionSize()6955dcadaeSBrandon Kim uint32_t PciDataHandler::getMemoryRegionSize()
7055dcadaeSBrandon Kim {
7155dcadaeSBrandon Kim return regionSize;
7255dcadaeSBrandon Kim }
7355dcadaeSBrandon Kim
7455dcadaeSBrandon Kim } // namespace bios_bmc_smm_error_logger
75