pci_handler: add support for opening, mapping, closing
Add support for opening, mapping, closing the aspeed-p2a-ctrl.
Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I8a9361d69af0218365ab752ea69f9276bd0e767a
diff --git a/main.cpp b/main.cpp
index a0716ef..e9de21c 100644
--- a/main.cpp
+++ b/main.cpp
@@ -54,7 +54,7 @@
#ifdef ENABLE_PCI_BRIDGE
#if defined(ASPEED_P2A)
-PciDataHandler pciDataHandler(MAPPED_ADDRESS);
+PciDataHandler pciDataHandler(MAPPED_ADDRESS, memoryRegionSize);
#else
#error "You must specify a hardware implementation."
#endif
diff --git a/pci_handler.cpp b/pci_handler.cpp
index b82d16a..51a2ca5 100644
--- a/pci_handler.cpp
+++ b/pci_handler.cpp
@@ -16,6 +16,9 @@
#include "pci_handler.hpp"
+#include <fcntl.h>
+#include <linux/aspeed-p2a-ctrl.h>
+
#include <cstdint>
#include <cstring>
#include <string>
@@ -28,17 +31,69 @@
bool PciDataHandler::open()
{
- /* TODO: For the ASPEED P2A driver, this method will enable the memory
- * region to use.
+ mappedFd = sys->open(p2aControlPath.c_str(), O_RDWR);
+ if (mappedFd == -1)
+ {
+ return false;
+ }
+
+ struct aspeed_p2a_ctrl_mapping map;
+ map.addr = regionAddress;
+ map.length = memoryRegionSize;
+ map.flags = ASPEED_P2A_CTRL_READWRITE;
+
+ if (sys->ioctl(mappedFd, ASPEED_P2A_CTRL_IOCTL_SET_WINDOW, &map))
+ {
+ sys->close(mappedFd);
+ mappedFd = -1;
+
+ return false;
+ }
+
+ if (sys->ioctl(mappedFd, ASPEED_P2A_CTRL_IOCTL_GET_MEMORY_CONFIG, &map))
+ {
+ sys->close(mappedFd);
+ mappedFd = -1;
+
+ return false;
+ }
+
+ /* The length of the region reserved is reported, and it's important
+ * because the offset + memory region could be beyond that reserved
+ * region.
*/
- return false;
+ std::uint64_t offset = regionAddress - map.addr;
+
+ mapped = reinterpret_cast<std::uint8_t*>(
+ mmap(0, memoryRegionSize, PROT_READ, MAP_SHARED, mappedFd, offset));
+ if (mapped == MAP_FAILED)
+ {
+ sys->close(mappedFd);
+ mappedFd = -1;
+
+ return false;
+ }
+
+ return true;
}
bool PciDataHandler::close()
{
/* TODO: Turn off the P2A bridge and region to disable host-side access.
*/
- return false;
+ if (mapped)
+ {
+ sys->munmap(mapped, memoryRegionSize);
+ mapped = nullptr;
+ }
+
+ if (mappedFd != -1)
+ {
+ sys->close(mappedFd);
+ mappedFd = -1;
+ }
+
+ return true;
}
std::vector<std::uint8_t> PciDataHandler::copyFrom(std::uint32_t length)
diff --git a/pci_handler.hpp b/pci_handler.hpp
index f99a811..f3ae798 100644
--- a/pci_handler.hpp
+++ b/pci_handler.hpp
@@ -24,10 +24,10 @@
class PciDataHandler : public DataInterface
{
public:
- PciDataHandler(std::uint32_t regionAddress,
+ PciDataHandler(std::uint32_t regionAddress, std::size_t regionSize,
const internal::Sys* sys = &internal::sys_impl) :
regionAddress(regionAddress),
- sys(sys){};
+ memoryRegionSize(regionSize), sys(sys){};
bool open() override;
bool close() override;
@@ -37,7 +37,11 @@
private:
std::uint32_t regionAddress;
+ std::uint32_t memoryRegionSize;
const internal::Sys* sys;
+
+ int mappedFd = -1;
+ std::uint8_t* mapped = nullptr;
static const std::string p2aControlPath;
};