diff --git a/fpga/include/villas/fpga/card.hpp b/fpga/include/villas/fpga/card.hpp index 0f4c002f1..840c49a74 100644 --- a/fpga/include/villas/fpga/card.hpp +++ b/fpga/include/villas/fpga/card.hpp @@ -37,7 +37,6 @@ #include "kernel/pci.h" #include "kernel/vfio.h" - #include #include @@ -45,7 +44,7 @@ #include "config.h" -#define PCI_FILTER_DEFAULT_FPGA { \ +#define PCI_FILTER_DEFAULT_FPGA { \ .id = { \ .vendor = FPGA_PCI_VID_XILINX, \ .device = FPGA_PCI_PID_VFPGA \ @@ -53,19 +52,24 @@ } namespace villas { +namespace fpga { + /* Forward declarations */ -struct fpga_ip; struct vfio_container; -class FpgaCardPlugin; -class FpgaIp; +class PCIeCardFactory; -class FpgaCard { +namespace ip { +class IpCore; +} + + +class PCIeCard { public: - friend FpgaCardPlugin; + friend PCIeCardFactory; - FpgaCard() : filter(PCI_FILTER_DEFAULT_FPGA) {} + PCIeCard() : filter(PCI_FILTER_DEFAULT_FPGA) {} bool start(); bool stop() { return true; } @@ -74,7 +78,7 @@ public: void dump() { } - using IpList = std::list; + using IpList = std::list; IpList ips; ///< IPs located on this FPGA card bool do_reset; /**< Reset VILLASfpga during startup? */ @@ -89,62 +93,29 @@ public: ::vfio_container *vfio_container; struct vfio_device vfio_device; /**< VFIO device handle. */ - -// struct list ips; /**< List of IP components on FPGA. */ - char *map; /**< PCI BAR0 mapping for register access */ size_t maplen; size_t dmalen; - - /* Some IP cores are special and referenced here */ -// struct fpga_ip *intc; -// struct fpga_ip *reset; -// struct fpga_ip *sw; }; -class FpgaCardPlugin : public Plugin { +class PCIeCardFactory : public Plugin { public: - FpgaCardPlugin() : + PCIeCardFactory() : Plugin("FPGA Card plugin") { pluginType = Plugin::Type::FpgaCard; } - static std::list + static std::list make(json_t *json, struct pci* pci, ::vfio_container* vc); - static FpgaCard* + static PCIeCard* create(); }; -/** Initialize FPGA card and its IP components. */ -int fpga_card_init(struct fpga_card *c, struct pci *pci, struct vfio_container *vc); - -/** Parse configuration of FPGA card including IP cores from config. */ -int fpga_card_parse(struct fpga_card *c, json_t *cfg, const char *name); - -int fpga_card_parse_list(struct list *l, json_t *cfg); - -/** Check if the FPGA card configuration is plausible. */ -int fpga_card_check(struct fpga_card *c); - -/** Start FPGA card. */ -int fpga_card_start(struct fpga_card *c); - -/** Stop FPGA card. */ -int fpga_card_stop(struct fpga_card *c); - -/** Destroy FPGA card. */ -int fpga_card_destroy(struct fpga_card *c); - -/** Dump details of FPGA card to stdout. */ -void fpga_card_dump(struct fpga_card *c); - -/** Reset the FPGA to a known state */ -int fpga_card_reset(struct fpga_card *c); - +} // namespace fpga } // namespace villas /** @} */ diff --git a/fpga/include/villas/fpga/ip.hpp b/fpga/include/villas/fpga/ip.hpp index 9b61414d9..df0d17422 100644 --- a/fpga/include/villas/fpga/ip.hpp +++ b/fpga/include/villas/fpga/ip.hpp @@ -45,29 +45,21 @@ #include -#include namespace villas { - -//enum fpga_ip_types { -// FPGA_IP_TYPE_DM_DMA, /**< A datamover IP exchanges streaming data between the FPGA and the CPU. */ -// FPGA_IP_TYPE_DM_FIFO, /**< A datamover IP exchanges streaming data between the FPGA and the CPU. */ -// FPGA_IP_TYPE_MODEL, /**< A model IP simulates a system on the FPGA. */ -// FPGA_IP_TYPE_MATH, /**< A math IP performs some kind of mathematical operation on the streaming data */ -// FPGA_IP_TYPE_MISC, /**< Other IP components like timer, counters, interrupt conctrollers or routing. */ -// FPGA_IP_TYPE_INTERFACE /**< A interface IP connects the FPGA to another system or controller. */ -//} type; +namespace fpga { +namespace ip { -class FpgaIpFactory; +class IpCoreFactory; -class FpgaIp { +class IpCore { public: - friend FpgaIpFactory; + friend IpCoreFactory; - FpgaIp() : card(nullptr), baseaddr(0), irq(-1), port(-1) {} - virtual ~FpgaIp() {} + IpCore() : card(nullptr), baseaddr(0), irq(-1), port(-1) {} + virtual ~IpCore() {} // IPs can implement this interface virtual bool check() { return true; } @@ -86,42 +78,44 @@ protected: protected: // populated by FpgaIpFactory - FpgaCard* card; /**< FPGA card this IP is instantiated on */ + PCIeCard* card; /**< FPGA card this IP is instantiated on */ std::string name; /**< Name defined in JSON config */ - FpgaVlnv vlnv; /**< VLNV defined in JSON config */ + Vlnv vlnv; /**< VLNV defined in JSON config */ uintptr_t baseaddr; /**< The baseadress of this FPGA IP component */ int irq; /**< The interrupt number of the FPGA IP component. */ int port; /**< The port of the AXI4-Stream switch to which this FPGA IP component is connected. */ }; -class FpgaIpFactory : public Plugin { +class IpCoreFactory : public Plugin { public: - FpgaIpFactory(std::string concreteName) : - Plugin(std::string("FPGA IP Factory: ") + concreteName) + IpCoreFactory(std::string concreteName) : + Plugin(std::string("FPGA IpCore Factory: ") + concreteName) { pluginType = Plugin::Type::FpgaIp; } /// Returns a running and checked FPGA IP - static FpgaIp* - make(FpgaCard* card, json_t *json, std::string name); + static IpCore* + make(PCIeCard* card, json_t *json, std::string name); private: /// Create a concrete IP instance - virtual FpgaIp* create() = 0; + virtual IpCore* create() = 0; /// Configure IP instance from JSON config - virtual bool configureJson(FpgaIp* ip, json_t *json) + virtual bool configureJson(IpCore* ip, json_t *json) { return true; } - virtual FpgaVlnv getCompatibleVlnv() const = 0; + virtual Vlnv getCompatibleVlnv() const = 0; virtual std::string getName() const = 0; virtual std::string getDescription() const = 0; private: - static FpgaIpFactory* - lookup(const FpgaVlnv& vlnv); + static IpCoreFactory* + lookup(const Vlnv& vlnv); }; /** @} */ +} // namespace ip +} // namespace fpga } // namespace villas diff --git a/fpga/include/villas/fpga/ips/intc.hpp b/fpga/include/villas/fpga/ips/intc.hpp index 922bacca7..7d8d5daf5 100644 --- a/fpga/include/villas/fpga/ips/intc.hpp +++ b/fpga/include/villas/fpga/ips/intc.hpp @@ -32,8 +32,11 @@ #include namespace villas { +namespace fpga { +namespace ip { -class InterruptController : public FpgaIp + +class InterruptController : public IpCore { public: using IrqMaskType = uint32_t; @@ -62,14 +65,14 @@ private: -class InterruptControllerFactory : public FpgaIpFactory { +class InterruptControllerFactory : public IpCoreFactory { public: InterruptControllerFactory() : - FpgaIpFactory(getName()) + IpCoreFactory(getName()) {} - FpgaIp* create() + IpCore* create() { return new InterruptController; } std::string @@ -80,10 +83,12 @@ public: getDescription() const { return "Xilinx's programmable interrupt controller"; } - FpgaVlnv getCompatibleVlnv() const - { return FpgaVlnv("acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:"); } + Vlnv getCompatibleVlnv() const + { return Vlnv("acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:"); } }; +} // namespace ip +} // namespace fpga } // namespace villas /** @} */ diff --git a/fpga/include/villas/fpga/vlnv.hpp b/fpga/include/villas/fpga/vlnv.hpp index 7785c56d2..97e603cba 100644 --- a/fpga/include/villas/fpga/vlnv.hpp +++ b/fpga/include/villas/fpga/vlnv.hpp @@ -32,16 +32,18 @@ #include namespace villas { +namespace fpga { -class FpgaVlnv { + +class Vlnv { public: static constexpr char delimiter = ':'; - FpgaVlnv() : + Vlnv() : vendor(""), library(""), name(""), version("") {} - FpgaVlnv(std::string s) { + Vlnv(std::string s) { parseFromString(s); } @@ -58,10 +60,10 @@ public: } bool - operator==(const FpgaVlnv& other) const; + operator==(const Vlnv& other) const; friend std::ostream& - operator<< (std::ostream& stream, const FpgaVlnv& vlnv) + operator<< (std::ostream& stream, const Vlnv& vlnv) { return stream << (vlnv.vendor.empty() ? "*" : vlnv.vendor) << ":" @@ -80,6 +82,7 @@ private: std::string version; }; +} // namespace fpga } // namespace villas /** _FPGA_VLNV_HPP_ @} */ diff --git a/fpga/lib/card.cpp b/fpga/lib/card.cpp index 872275dd9..68662a448 100644 --- a/fpga/lib/card.cpp +++ b/fpga/lib/card.cpp @@ -40,14 +40,15 @@ #include "log.hpp" namespace villas { +namespace fpga { -static FpgaCardPlugin -fpgaCardPlugin; +// instantiate factory to register +static PCIeCardFactory PCIeCardFactory; -std::list -FpgaCardPlugin::make(json_t *json, struct pci* pci, ::vfio_container* vc) +std::list +fpga::PCIeCardFactory::make(json_t *json, struct pci* pci, ::vfio_container* vc) { - std::list cards; + std::list cards; const char *card_name; json_t *json_card; @@ -73,7 +74,7 @@ FpgaCardPlugin::make(json_t *json, struct pci* pci, ::vfio_container* vc) continue; } - FpgaCard* card = create(); + fpga::PCIeCard* card = create(); // populate generic properties card->name = std::string(card_name); @@ -108,7 +109,7 @@ FpgaCardPlugin::make(json_t *json, struct pci* pci, ::vfio_container* vc) cpp_info << "Found IP: " << ip_name; Logger::Indenter indent = cpp_debug.indent(); - FpgaIp* ip = FpgaIpFactory::make(card, json_ip, ip_name); + ip::IpCore* ip = ip::IpCoreFactory::make(card, json_ip, ip_name); if(ip == nullptr) { cpp_warn << "Cannot initialize, ignoring ..."; continue; @@ -129,14 +130,14 @@ FpgaCardPlugin::make(json_t *json, struct pci* pci, ::vfio_container* vc) return cards; } -FpgaCard* -FpgaCardPlugin::create() +fpga::PCIeCard* +fpga::PCIeCardFactory::create() { - return new FpgaCard; + return new fpga::PCIeCard; } -bool FpgaCard::start() +bool fpga::PCIeCard::start() { int ret; struct pci_device *pdev; @@ -475,4 +476,5 @@ int fpga_card_reset(struct fpga_card *c) #endif +} // namespace fpga } // namespace villas diff --git a/fpga/lib/ip.cpp b/fpga/lib/ip.cpp index bb7cb724a..f94074408 100644 --- a/fpga/lib/ip.cpp +++ b/fpga/lib/ip.cpp @@ -32,26 +32,29 @@ #include "log.hpp" namespace villas { +namespace fpga { +namespace ip { -void FpgaIp::dump() { + +void IpCore::dump() { info("IP %s: vlnv=%s baseaddr=%#jx, irq=%d, port=%d", name.c_str(), vlnv.toString().c_str(), baseaddr, irq, port); } -FpgaIpFactory* FpgaIpFactory::lookup(const FpgaVlnv &vlnv) +IpCoreFactory* IpCoreFactory::lookup(const Vlnv &vlnv) { for(auto& ip : Plugin::lookup(Plugin::Type::FpgaIp)) { - FpgaIpFactory* fpgaIpFactory = dynamic_cast(ip); + IpCoreFactory* ipCoreFactory = dynamic_cast(ip); - if(fpgaIpFactory->getCompatibleVlnv() == vlnv) - return fpgaIpFactory; + if(ipCoreFactory->getCompatibleVlnv() == vlnv) + return ipCoreFactory; } return nullptr; } -FpgaIp *FpgaIpFactory::make(FpgaCard* card, json_t *json, std::string name) +IpCore *IpCoreFactory::make(fpga::PCIeCard* card, json_t *json, std::string name) { int ret; const char* vlnv_raw; @@ -65,29 +68,29 @@ FpgaIp *FpgaIpFactory::make(FpgaCard* card, json_t *json, std::string name) } // parse VLNV - FpgaVlnv vlnv(vlnv_raw); + Vlnv vlnv(vlnv_raw); // find the appropriate factory that can create the specified VLNV // Note: // This is the magic part! Factories automatically register as a plugin // as soon as they are instantiated. If there are multiple candidates, // the first suitable factory will be used. - FpgaIpFactory* fpgaIpFactory = lookup(vlnv); + IpCoreFactory* ipCoreFactory = lookup(vlnv); - if(fpgaIpFactory == nullptr) { + if(ipCoreFactory == nullptr) { cpp_warn << "No plugin found to handle " << vlnv; return nullptr; } - cpp_debug << "Using " << fpgaIpFactory->getName() << " for IP " << vlnv; + cpp_debug << "Using " << ipCoreFactory->getName() << " for IP " << vlnv; // Create new IP instance. Since this function is virtual, it will construct // the right, specialized type without knowing it here because we have // already picked the right factory. - FpgaIp* ip = fpgaIpFactory->create(); + IpCore* ip = ipCoreFactory->create(); if(ip == nullptr) { - cpp_warn << "Cannot create an instance of " << fpgaIpFactory->getName(); + cpp_warn << "Cannot create an instance of " << ipCoreFactory->getName(); goto fail; } @@ -107,7 +110,7 @@ FpgaIp *FpgaIpFactory::make(FpgaCard* card, json_t *json, std::string name) } // IP-specific setup via JSON config - fpgaIpFactory->configureJson(ip, json); + ipCoreFactory->configureJson(ip, json); // TODO: currently fails, fix and remove comment // if(not ip->start()) { @@ -127,4 +130,6 @@ fail: return nullptr; } +} // namespace ip +} // namespace fpga } // namespace villas diff --git a/fpga/lib/ips/intc.cpp b/fpga/lib/ips/intc.cpp index 8f4946824..78f598aab 100644 --- a/fpga/lib/ips/intc.cpp +++ b/fpga/lib/ips/intc.cpp @@ -34,6 +34,9 @@ #include "fpga/ips/intc.hpp" namespace villas { +namespace fpga { +namespace ip { + // instantiate factory to make available to plugin infrastructure static InterruptControllerFactory factory; @@ -150,4 +153,6 @@ uint64_t InterruptController::waitForInterrupt(int irq) } } +} // namespace ip +} // namespace fpga } // namespace villas diff --git a/fpga/lib/vlnv.cpp b/fpga/lib/vlnv.cpp index cf44c483f..f9eaa6bb1 100644 --- a/fpga/lib/vlnv.cpp +++ b/fpga/lib/vlnv.cpp @@ -30,9 +30,10 @@ #include "fpga/ip.hpp" namespace villas { +namespace fpga { bool -FpgaVlnv::operator==(const FpgaVlnv &other) const +Vlnv::operator==(const Vlnv &other) const { // if a field is empty, it means wildcard matching everything const bool vendorWildcard = vendor.empty() or other.vendor.empty(); @@ -49,7 +50,7 @@ FpgaVlnv::operator==(const FpgaVlnv &other) const } void -FpgaVlnv::parseFromString(std::string vlnv) +Vlnv::parseFromString(std::string vlnv) { // tokenize by delimiter std::stringstream sstream(vlnv); @@ -65,5 +66,5 @@ FpgaVlnv::parseFromString(std::string vlnv) if(version == "*") version = ""; } - +} // namespace fpga } // namespace villas diff --git a/fpga/tests/main.cpp b/fpga/tests/main.cpp index 900caee81..1d3cd11ea 100644 --- a/fpga/tests/main.cpp +++ b/fpga/tests/main.cpp @@ -75,12 +75,12 @@ static void init() // get the FPGA card plugin villas::Plugin* plugin = villas::Plugin::lookup(villas::Plugin::Type::FpgaCard, ""); cr_assert_not_null(plugin, "No plugin for FPGA card found"); - villas::FpgaCardPlugin* fpgaCardPlugin = dynamic_cast(plugin); + villas::fpga::PCIeCardFactory* fpgaCardPlugin = dynamic_cast(plugin); // create an FPGA card instance using the corresponding plugin // villas::FpgaCard* fpgaCard = fpgaCardPlugin->make(json_); - std::list fpgaCards = fpgaCardPlugin->make(fpgas, &pci, &vc); + std::list fpgaCards = fpgaCardPlugin->make(fpgas, &pci, &vc); json_t *json_card = json_object_get(fpgas, FPGA_CARD); cr_assert_not_null(json_card, "FPGA card " FPGA_CARD " not found");