1
0
Fork 0
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:
daniel-k 2017-12-13 14:31:32 +01:00
parent 09815a661e
commit e590d1a350
9 changed files with 100 additions and 114 deletions

View file

@ -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
/** @} */

View file

@ -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

View file

@ -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
/** @} */

View file

@ -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_ @} */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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");