mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
add namespace villas::fpga and villas::fpga::ip and some renaming
This commit is contained in:
parent
09815a661e
commit
e590d1a350
9 changed files with 100 additions and 114 deletions
|
@ -37,7 +37,6 @@
|
|||
#include "kernel/pci.h"
|
||||
#include "kernel/vfio.h"
|
||||
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
|
@ -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<FpgaIp*>;
|
||||
using IpList = std::list<ip::IpCore*>;
|
||||
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<FpgaCard*>
|
||||
static std::list<PCIeCard*>
|
||||
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
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -45,29 +45,21 @@
|
|||
|
||||
#include <jansson.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
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
|
||||
|
|
|
@ -32,8 +32,11 @@
|
|||
#include <xilinx/xintc.h>
|
||||
|
||||
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
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -32,16 +32,18 @@
|
|||
#include <iostream>
|
||||
|
||||
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_ @} */
|
||||
|
|
|
@ -40,14 +40,15 @@
|
|||
#include "log.hpp"
|
||||
|
||||
namespace villas {
|
||||
namespace fpga {
|
||||
|
||||
static FpgaCardPlugin
|
||||
fpgaCardPlugin;
|
||||
// instantiate factory to register
|
||||
static PCIeCardFactory PCIeCardFactory;
|
||||
|
||||
std::list<FpgaCard*>
|
||||
FpgaCardPlugin::make(json_t *json, struct pci* pci, ::vfio_container* vc)
|
||||
std::list<fpga::PCIeCard*>
|
||||
fpga::PCIeCardFactory::make(json_t *json, struct pci* pci, ::vfio_container* vc)
|
||||
{
|
||||
std::list<FpgaCard*> cards;
|
||||
std::list<fpga::PCIeCard*> 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
|
||||
|
|
|
@ -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<FpgaIpFactory *>(ip);
|
||||
IpCoreFactory* ipCoreFactory = dynamic_cast<IpCoreFactory*>(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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<villas::FpgaCardPlugin*>(plugin);
|
||||
villas::fpga::PCIeCardFactory* fpgaCardPlugin = dynamic_cast<villas::fpga::PCIeCardFactory*>(plugin);
|
||||
|
||||
// create an FPGA card instance using the corresponding plugin
|
||||
// villas::FpgaCard* fpgaCard = fpgaCardPlugin->make(json_);
|
||||
|
||||
std::list<villas::FpgaCard*> fpgaCards = fpgaCardPlugin->make(fpgas, &pci, &vc);
|
||||
std::list<villas::fpga::PCIeCard*> 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");
|
||||
|
|
Loading…
Add table
Reference in a new issue