tools: io: add read method

Add method for reading the host's memory to enable reading the PCI
configuration.

Tested: Verified it's able to read a memory BAR associated with the
ASPEED ast2400.

Change-Id: Id06f30b063e69825f2dfa69786b69392657f7b1c
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/tools/io.cpp b/tools/io.cpp
index e25216e..75677f4 100644
--- a/tools/io.cpp
+++ b/tools/io.cpp
@@ -13,6 +13,37 @@
 
 const std::string DevMemDevice::devMemPath = "/dev/mem";
 
+bool DevMemDevice::read(const std::size_t offset, const std::size_t length,
+                        void* const destination)
+{
+    if (!opened)
+    {
+        devMemFd = sys->open(devMemPath.c_str(), O_RDWR);
+        if (devMemFd < 0)
+        {
+            return false;
+        }
+
+        opened = true;
+    }
+
+    // addr, length, prot, flags, fd, offset
+    devMemMapped =
+        sys->mmap(0, length, PROT_WRITE, MAP_SHARED, devMemFd, offset);
+    if (devMemMapped == MAP_FAILED)
+    {
+        return false; /* but leave the file open. */
+    }
+
+    /* Copy the bytes. */
+    std::memcpy(destination, devMemMapped, length);
+
+    /* Close the map between reads for now. */
+    sys->munmap(devMemMapped, length);
+
+    return true;
+}
+
 bool DevMemDevice::write(const std::size_t offset, const std::size_t length,
                          const void* const source)
 {