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