diff --git a/fpga/include/villas/fpga/ips/pcie.hpp b/fpga/include/villas/fpga/ips/pcie.hpp index 94c091825..85960bf8d 100644 --- a/fpga/include/villas/fpga/ips/pcie.hpp +++ b/fpga/include/villas/fpga/ips/pcie.hpp @@ -24,8 +24,8 @@ public: virtual bool init() override; -private: - static constexpr char axiInterface[] = "M_AXI"; +protected: + virtual const char *getAxiInterfaceName() { return "M_AXI"; }; static constexpr char pcieMemory[] = "BAR0"; struct AxiBar { @@ -42,6 +42,11 @@ private: std::map pcieToAxiTranslations; }; +class XDmaBridge : public AxiPciExpressBridge { +protected: + virtual const char *getAxiInterfaceName() { return "M_AXI_B"; }; +}; + class AxiPciExpressBridgeFactory : CoreFactory { public: @@ -63,6 +68,20 @@ protected: virtual void parse(Core &, json_t *) override; }; +class XDmaBridgeFactory : public AxiPciExpressBridgeFactory { + +public: + virtual std::string getDescription() const { + return "Xilinx's XDMA IP configured as AXI-PCIe Bridge"; + } + +private: + virtual Vlnv getCompatibleVlnv() const { return Vlnv("xilinx.com:ip:xdma:"); } + + // Create a concrete IP instance + Core *make() const { return new XDmaBridge; }; +}; + } // namespace ip } // namespace fpga } // namespace villas diff --git a/fpga/lib/core.cpp b/fpga/lib/core.cpp index 2af5a1752..2e3235c5d 100644 --- a/fpga/lib/core.cpp +++ b/fpga/lib/core.cpp @@ -31,6 +31,7 @@ using namespace villas::fpga::ip; // first. static std::list vlnvInitializationOrder = { Vlnv("xilinx.com:ip:axi_pcie:"), + Vlnv("xilinx.com:ip:xdma:"), Vlnv("xilinx.com:module_ref:axi_pcie_intc:"), Vlnv("xilinx.com:ip:axis_switch:"), Vlnv("xilinx.com:ip:axi_iic:"), diff --git a/fpga/lib/ips/pcie.cpp b/fpga/lib/ips/pcie.cpp index c6b12025d..17529a41b 100644 --- a/fpga/lib/ips/pcie.cpp +++ b/fpga/lib/ips/pcie.cpp @@ -22,7 +22,7 @@ bool AxiPciExpressBridge::init() { // Throw an exception if the is no bus master interface and thus no // address space we can use for translation -> error - card->addrSpaceIdHostToDevice = busMasterInterfaces.at(axiInterface); + card->addrSpaceIdHostToDevice = busMasterInterfaces.at(getAxiInterfaceName()); // Map PCIe BAR0 via VFIO const void *bar0_mapped = @@ -139,3 +139,4 @@ void AxiPciExpressBridgeFactory::parse(Core &ip, json_t *cfg) { } static AxiPciExpressBridgeFactory p; +static XDmaBridgeFactory p2; diff --git a/tools/hwdef-parse.py b/tools/hwdef-parse.py index 13981aa06..aa87c6619 100755 --- a/tools/hwdef-parse.py +++ b/tools/hwdef-parse.py @@ -43,6 +43,7 @@ whitelist = [ ["xilinx.com", "ip", "axi_gpio"], ["xilinx.com", "ip", "axi_bram_ctrl"], ["xilinx.com", "ip", "axi_pcie"], + ["xilinx.com", "ip", "xdma"], ["xilinx.com", "ip", "axi_iic"], ["xilinx.com", "module_ref", "dinoif_fast"], ["xilinx.com", "module_ref", "dinoif_dac"], @@ -322,7 +323,7 @@ for bram in brams: if instance in ips: ips[instance]["size"] = int(size) -pcies = root.xpath('.//MODULE[@MODTYPE="axi_pcie"]') +pcies = root.xpath('.//MODULE[@MODTYPE="axi_pcie" or @MODTYPE="xdma"]') for pcie in pcies: instance = pcie.get("INSTANCE") axi_bars = ips[instance].setdefault("axi_bars", {}) @@ -332,8 +333,11 @@ for pcie in pcies: ("AXIBAR", "PCIEBAR", axi_bars), ("PCIEBAR", "AXIBAR", pcie_bars), ): + barnum = pcie.find('.//PARAMETER[@NAME="C_{}_NUM"]'.format(from_bar)) + if barnum == None: + barnum = pcie.find('.//PARAMETER[@NAME="{}_NUM"]'.format(from_bar)) from_bar_num = int( - pcie.find('.//PARAMETER[@NAME="C_{}_NUM"]'.format(from_bar)).get("VALUE") + barnum.get("VALUE") ) for i in range(0, from_bar_num):