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/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)