tools/pci: add Nuvoton bridge configuration

The Nuvoton PCI device requires the Memory Space bit to be set in its
command register in order to access the mailbox over MMIO.

Signed-off-by: Benjamin Fair <benjaminfair@google.com>
Change-Id: Ic262b907ae55c622999aa68891b618650ccad3f2
diff --git a/tools/pci.cpp b/tools/pci.cpp
index 6e9cfe4..0efb75d 100644
--- a/tools/pci.cpp
+++ b/tools/pci.cpp
@@ -114,6 +114,56 @@
     std::memcpy(addr + dataOffset, data.data(), data.size());
 }
 
+void NuvotonPciBridge::enableBridge()
+{
+    std::uint8_t value;
+    int ret;
+
+    ret = pci->pci_device_cfg_read_u8(dev, &value, bridge);
+    if (ret)
+    {
+        throw std::system_error(ret, std::generic_category(),
+                                "Error reading bridge status");
+    }
+
+    if (value & bridgeEnabled)
+    {
+        std::fprintf(stderr, "Bridge already enabled\n");
+        return;
+    }
+
+    value |= bridgeEnabled;
+
+    ret = pci->pci_device_cfg_write_u8(dev, value, bridge);
+    if (ret)
+    {
+        throw std::system_error(ret, std::generic_category(),
+                                "Error enabling bridge");
+    }
+}
+
+void NuvotonPciBridge::disableBridge()
+{
+    std::uint8_t value;
+    int ret;
+
+    ret = pci->pci_device_cfg_read_u8(dev, &value, bridge);
+    if (ret)
+    {
+        std::fprintf(stderr, "Error reading bridge status: %s\n",
+                     std::strerror(ret));
+        return;
+    }
+    value &= ~bridgeEnabled;
+
+    ret = pci->pci_device_cfg_write_u8(dev, value, bridge);
+    if (ret)
+    {
+        std::fprintf(stderr, "Error disabling bridge: %s\n",
+                     std::strerror(ret));
+    }
+}
+
 void AspeedPciBridge::enableBridge()
 {
     /* We sent the open command before this, so the window should be open and