tools: p2a: check aspeed bridge

Check whether the pci-to-ahb bridge is enabled.  It should be enabled
because this comes after the firmware blob is opened for writing.

Tested: Verified it reports the correct state of the value.
Change-Id: I04bd21fdbf65938164f5845c0ec46e2231b17bd9
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/tools/p2a.cpp b/tools/p2a.cpp
index 6d0ab37..6d4b693 100644
--- a/tools/p2a.cpp
+++ b/tools/p2a.cpp
@@ -24,17 +24,56 @@
 bool P2aDataHandler::sendContents(const std::string& input,
                                   std::uint16_t session)
 {
+    PciDevice result;
     PciUtilImpl pci;
     PciFilter filter;
 
     filter.vid = aspeedVendorId;
     filter.did = aspeedDeviceId;
 
+    /* Find the ASPEED PCI device entry we want. */
     auto output = pci.getPciDevices(filter);
     for (const auto& d : output)
     {
-        std::fprintf(stderr, "0x%x", d.vid);
+        std::fprintf(stderr, "[0x%x 0x%x] ", d.vid, d.did);
+
+        /* Verify it's a memory-based bar -- we want bar1. */
+        pciaddr_t bar1 = d.bars[1];
+        if ((bar1 & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+        {
+            /* We want it to not be IO-based access. */
+            continue;
+        }
+
+        result = d;
     }
+    std::fprintf(stderr, "\n");
+
+    /* We sent the open command before this, so the window should be open and
+     * the bridge enabled.
+     */
+    std::uint32_t value;
+    if (!io->read(result.bars[1] | aspeedP2aConfig, sizeof(value), &value))
+    {
+        if (0 == (value & p2ABridgeEnabled))
+        {
+            std::fprintf(stderr, "Bridge not enabled.\n");
+            return false;
+        }
+    }
+
+    std::fprintf(stderr, "The bridge is enabled!\n");
+
+    /* Read the configuration via blobs metadata (stat). */
+
+#if 0
+    /* Configure the mmio to point there. */
+    if (!io->IoWrite(bar | kAspeedP2aBridge, sizeof(phys), &phys)) {
+        // Failed to set it up, so fall back.
+        std::fprintf(stderr, "Failed to update the bridge address\n");
+        return false;
+    }
+#endif
 
     return false;
 }
diff --git a/tools/p2a.hpp b/tools/p2a.hpp
index 4c02107..f229449 100644
--- a/tools/p2a.hpp
+++ b/tools/p2a.hpp
@@ -9,6 +9,9 @@
 
 constexpr std::uint16_t aspeedVendorId = 0x1a03;
 constexpr std::uint16_t aspeedDeviceId = 0x2000;
+constexpr std::size_t aspeedP2aConfig = 0x0f000;
+constexpr std::size_t aspeedP2aBridge = 0x0f004;
+constexpr std::uint32_t p2ABridgeEnabled = 0x1;
 
 namespace host_tool
 {
diff --git a/tools/pci.cpp b/tools/pci.cpp
index 2f283e6..b502a34 100644
--- a/tools/pci.cpp
+++ b/tools/pci.cpp
@@ -20,6 +20,7 @@
 #include <pci/pci.h>
 } // extern "C"
 
+#include <cstring>
 #include <optional>
 #include <vector>
 
@@ -53,6 +54,7 @@
         item.func = dev->func;
         item.vid = dev->vendor_id;
         item.did = dev->device_id;
+        std::memcpy(item.bars, dev->base_addr, sizeof(dev->base_addr));
 
         if (check)
         {
diff --git a/tools/pci.hpp b/tools/pci.hpp
index 96f1ea4..37cd736 100644
--- a/tools/pci.hpp
+++ b/tools/pci.hpp
@@ -18,11 +18,12 @@
  */
 struct PciDevice
 {
-    int vid;
-    int did;
-    int bus;
-    int dev;
-    int func;
+    std::uint16_t vid;
+    std::uint16_t did;
+    std::uint8_t bus;
+    std::uint8_t dev;
+    std::uint8_t func;
+    pciaddr_t bars[6];
 };
 
 /**
@@ -31,8 +32,8 @@
  */
 struct PciFilter
 {
-    int vid;
-    int did;
+    std::uint16_t vid;
+    std::uint16_t did;
 };
 
 class PciUtilInterface