mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
fix parsing of IP parameters
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
This commit is contained in:
parent
75bfb6ff34
commit
14c7e57a8a
14 changed files with 120 additions and 136 deletions
|
@ -1276,7 +1276,6 @@
|
|||
"target": "axi_dma_0:S2MM",
|
||||
"name": "M04_AXIS"
|
||||
}
|
||||
],
|
||||
"num_ports": 5
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -312,17 +312,17 @@ protected:
|
|||
return villas::logging.get(getName());
|
||||
}
|
||||
|
||||
// Configure IP instance from JSON config
|
||||
virtual
|
||||
void configure(Core &, json_t *)
|
||||
{ }
|
||||
|
||||
private:
|
||||
// Create a concrete IP instance
|
||||
virtual Core* create() = 0;
|
||||
|
||||
// Configure IP instance from JSON config
|
||||
virtual bool configureJson(Core& /* ip */, json_t* /* json */)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void configurePollingMode(Core& /* ip */, PollingMode /* mode */)
|
||||
virtual
|
||||
void configurePollingMode(Core &, PollingMode)
|
||||
{ }
|
||||
|
||||
virtual Vlnv getCompatibleVlnv() const = 0;
|
||||
|
|
|
@ -57,7 +57,7 @@ private:
|
|||
class BramFactory : public CoreFactory {
|
||||
public:
|
||||
|
||||
bool configureJson(Core &ip, json_t *json_ip);
|
||||
void configure(Core &ip, json_t *cfg);
|
||||
|
||||
Core* create()
|
||||
{
|
||||
|
|
|
@ -176,8 +176,8 @@ public:
|
|||
return Vlnv("xilinx.com:ip:axi_dma:");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
configureJson(Core& ip, json_t* json) override;
|
||||
virtual
|
||||
void configure(Core& ip, json_t* json) override;
|
||||
|
||||
virtual void
|
||||
configurePollingMode(Core& ip, PollingMode mode) override
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
return "xilinx.com:ip:axi_pcie:";
|
||||
}
|
||||
|
||||
bool configureJson(Core &ip, json_t *json_ip);
|
||||
void configure(Core &ip, json_t *cfg);
|
||||
|
||||
Core* create()
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
return "xilinx.com:ip:axis_switch:";
|
||||
}
|
||||
|
||||
bool configureJson(Core &ip, json_t *json_ip);
|
||||
void configure(Core &ip, json_t *cfg);
|
||||
|
||||
Core* create()
|
||||
{
|
||||
|
|
|
@ -168,7 +168,8 @@ class NodeFactory : public CoreFactory {
|
|||
public:
|
||||
using CoreFactory::CoreFactory;
|
||||
|
||||
virtual bool configureJson(Core &ip, json_t *json_ip);
|
||||
virtual
|
||||
void configure(Core &ip, json_t *cfg);
|
||||
};
|
||||
|
||||
} /* namespace ip */
|
||||
|
|
|
@ -59,7 +59,8 @@ PCIeCardFactory::make(json_t *json, std::shared_ptr<kernel::pci::DeviceList> pci
|
|||
int affinity = 0;
|
||||
int polling = 0;
|
||||
|
||||
int ret = json_unpack(json_card, "{ s: o, s?: i, s?: b, s?: s, s?: s, s?: b }",
|
||||
json_error_t err;
|
||||
int ret = json_unpack_ex(json_card, &err, 0, "{ s: o, s?: i, s?: b, s?: s, s?: s, s?: b }",
|
||||
"ips", &json_ips,
|
||||
"affinity", &affinity,
|
||||
"do_reset", &do_reset,
|
||||
|
@ -67,10 +68,8 @@ PCIeCardFactory::make(json_t *json, std::shared_ptr<kernel::pci::DeviceList> pci
|
|||
"id", &pci_id,
|
||||
"polling", &polling);
|
||||
|
||||
if (ret != 0) {
|
||||
logger->warn("Cannot parse JSON config");
|
||||
continue;
|
||||
}
|
||||
if (ret != 0)
|
||||
throw ConfigError(json_card, err, "", "Failed to parse card");
|
||||
|
||||
auto card = std::unique_ptr<PCIeCard>(create());
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <villas/exceptions.hpp>
|
||||
#include <villas/log.hpp>
|
||||
#include <villas/memory.hpp>
|
||||
#include <villas/utils.hpp>
|
||||
|
@ -66,10 +67,11 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
json_t* json_ip;
|
||||
json_object_foreach(json_ips, ipName, json_ip) {
|
||||
const char* vlnv;
|
||||
if (json_unpack(json_ip, "{ s: s }", "vlnv", &vlnv) != 0) {
|
||||
loggerStatic->warn("IP {} has no VLNV", ipName);
|
||||
continue;
|
||||
}
|
||||
|
||||
json_error_t err;
|
||||
int ret = json_unpack_ex(json_ip, &err, 0, "{ s: s }", "vlnv", &vlnv);
|
||||
if (ret != 0)
|
||||
throw ConfigError(json_ip, err, "", "IP {} has no VLNV", ipName);
|
||||
|
||||
allIps.push_back({vlnv, ipName});
|
||||
}
|
||||
|
@ -212,17 +214,16 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
json_object_foreach(json_instance, block_name, json_block) {
|
||||
|
||||
json_int_t base, high, size;
|
||||
int ret = json_unpack(json_block, "{ s: I, s: I, s: I }",
|
||||
"baseaddr", &base,
|
||||
"highaddr", &high,
|
||||
"size", &size);
|
||||
if (ret != 0) {
|
||||
logger->error("Cannot parse address block {}/{}/{}/{}",
|
||||
json_error_t err;
|
||||
int ret = json_unpack_ex(json_block, &err, 0, "{ s: I, s: I, s: I }",
|
||||
"baseaddr", &base,
|
||||
"highaddr", &high,
|
||||
"size", &size
|
||||
);
|
||||
if (ret != 0)
|
||||
throw ConfigError(json_block, err, "", "Cannot parse address block {}/{}/{}/{}",
|
||||
ip->getInstanceName(),
|
||||
bus_name, instance_name, block_name);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// Get or create the slave address space
|
||||
const std::string slaveAddrSpace =
|
||||
|
@ -244,10 +245,7 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
}
|
||||
|
||||
// IP-specific setup via JSON config
|
||||
if (not CoreFactory->configureJson(*ip, json_ip)) {
|
||||
logger->warn("Cannot configure IP from JSON");
|
||||
continue;
|
||||
}
|
||||
CoreFactory->configure(*ip, json_ip);
|
||||
|
||||
// Set polling mode
|
||||
CoreFactory->configurePollingMode(*ip, (card->polling ? PollingMode::POLL : PollingMode::IRQ));
|
||||
|
|
|
@ -20,23 +20,25 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <villas/exceptions.hpp>
|
||||
#include <villas/fpga/ips/bram.hpp>
|
||||
|
||||
using namespace villas::fpga::ip;
|
||||
|
||||
static BramFactory factory;
|
||||
|
||||
bool
|
||||
BramFactory::configureJson(Core &ip, json_t* json_ip)
|
||||
void BramFactory::configure(Core &ip, json_t* cfg)
|
||||
{
|
||||
CoreFactory::configure(ip, cfg);
|
||||
|
||||
auto &bram = dynamic_cast<Bram&>(ip);
|
||||
|
||||
if (json_unpack(json_ip, "{ s: i }", "size", &bram.size) != 0) {
|
||||
getLogger()->error("Cannot parse 'size'");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
json_error_t err;
|
||||
auto ret = json_unpack_ex(cfg, &err, 0, "{ s: i }",
|
||||
"size", &bram.size
|
||||
);
|
||||
if (ret != 0)
|
||||
throw ConfigError(cfg, err, "", "Cannot parse BRAM config");
|
||||
}
|
||||
|
||||
bool Bram::init()
|
||||
|
|
|
@ -618,16 +618,11 @@ void Dma::dump()
|
|||
logger->info("MM2S_DMASR: {:x}", XAxiDma_ReadReg(xDma.RegBase, XAXIDMA_TX_OFFSET + XAXIDMA_SR_OFFSET));
|
||||
}
|
||||
|
||||
bool
|
||||
DmaFactory::configureJson(Core& ip, json_t* json)
|
||||
void DmaFactory::configure(Core &ip, json_t *cfg)
|
||||
{
|
||||
if (not NodeFactory::configureJson(ip, json))
|
||||
return false;
|
||||
NodeFactory::configure(ip, cfg);
|
||||
|
||||
auto &dma = dynamic_cast<Dma&>(ip);
|
||||
json_t* json_params = json_object_get(json, "parameters");
|
||||
if (!json_is_object(json_params))
|
||||
return false;
|
||||
|
||||
// Sensible default configuration
|
||||
dma.xConfig.HasStsCntrlStrm = 0;
|
||||
|
@ -646,25 +641,23 @@ DmaFactory::configureJson(Core& ip, json_t* json)
|
|||
dma.xConfig.AddrWidth = 32;
|
||||
dma.xConfig.SgLengthWidth = 14;
|
||||
|
||||
int ret = json_unpack(json_params, "{ s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i }",
|
||||
"c_sg_include_stscntrl_strm", &dma.xConfig.HasStsCntrlStrm,
|
||||
"c_include_mm2s", &dma.xConfig.HasMm2S,
|
||||
"c_include_mm2s_dre", &dma.xConfig.HasMm2SDRE,
|
||||
"c_m_axi_mm2s_data_width", &dma.xConfig.Mm2SDataWidth,
|
||||
"c_include_s2mm", &dma.xConfig.HasS2Mm,
|
||||
"c_include_s2mm_dre", &dma.xConfig.HasS2MmDRE,
|
||||
"c_m_axi_s2mm_data_width", &dma.xConfig.S2MmDataWidth,
|
||||
"c_include_sg", &dma.xConfig.HasSg,
|
||||
"c_num_mm2s_channels", &dma.xConfig.Mm2sNumChannels,
|
||||
"c_num_s2mm_channels", &dma.xConfig.S2MmNumChannels,
|
||||
"c_micro_dma", &dma.xConfig.MicroDmaMode,
|
||||
"c_addr_width", &dma.xConfig.AddrWidth,
|
||||
"c_sg_length_width", &dma.xConfig.SgLengthWidth
|
||||
json_error_t err;
|
||||
int ret = json_unpack_ex(cfg, &err, 0, "{ s: { s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i, s?: i } }",
|
||||
"parameters",
|
||||
"c_sg_include_stscntrl_strm", &dma.xConfig.HasStsCntrlStrm,
|
||||
"c_include_mm2s", &dma.xConfig.HasMm2S,
|
||||
"c_include_mm2s_dre", &dma.xConfig.HasMm2SDRE,
|
||||
"c_m_axi_mm2s_data_width", &dma.xConfig.Mm2SDataWidth,
|
||||
"c_include_s2mm", &dma.xConfig.HasS2Mm,
|
||||
"c_include_s2mm_dre", &dma.xConfig.HasS2MmDRE,
|
||||
"c_m_axi_s2mm_data_width", &dma.xConfig.S2MmDataWidth,
|
||||
"c_include_sg", &dma.xConfig.HasSg,
|
||||
"c_num_mm2s_channels", &dma.xConfig.Mm2sNumChannels,
|
||||
"c_num_s2mm_channels", &dma.xConfig.S2MmNumChannels,
|
||||
"c_micro_dma", &dma.xConfig.MicroDmaMode,
|
||||
"c_addr_width", &dma.xConfig.AddrWidth,
|
||||
"c_sg_length_width", &dma.xConfig.SgLengthWidth
|
||||
);
|
||||
if (ret != 0) {
|
||||
logger->error("Failed to parse DMA configuration");
|
||||
return false;
|
||||
}
|
||||
dma.configDone = true;
|
||||
return true;
|
||||
if (ret != 0)
|
||||
throw ConfigError(cfg, err, "", "Failed to parse DMA configuration");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <limits>
|
||||
#include <jansson.h>
|
||||
|
||||
#include <villas/exceptions.hpp>
|
||||
#include <villas/memory.hpp>
|
||||
|
||||
#include <villas/fpga/card.hpp>
|
||||
|
@ -111,9 +112,11 @@ AxiPciExpressBridge::init()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AxiPciExpressBridgeFactory::configureJson(Core &ip, json_t* json_ip)
|
||||
void
|
||||
AxiPciExpressBridgeFactory::configure(Core &ip, json_t *cfg)
|
||||
{
|
||||
CoreFactory::configure(ip, cfg);
|
||||
|
||||
auto logger = getLogger();
|
||||
auto &pcie = dynamic_cast<AxiPciExpressBridge&>(ip);
|
||||
|
||||
|
@ -121,31 +124,29 @@ AxiPciExpressBridgeFactory::configureJson(Core &ip, json_t* json_ip)
|
|||
"axi_bars",
|
||||
"pcie_bars"
|
||||
}) {
|
||||
json_t* json_bars = json_object_get(json_ip, barType.c_str());
|
||||
if (not json_is_object(json_bars)) {
|
||||
return false;
|
||||
}
|
||||
json_t *json_bars = json_object_get(cfg, barType.c_str());
|
||||
if (not json_is_object(json_bars))
|
||||
throw ConfigError(cfg, "", "Missing BAR config: {}", barType);
|
||||
|
||||
json_t* json_bar;
|
||||
const char* bar_name;
|
||||
json_object_foreach(json_bars, bar_name, json_bar) {
|
||||
unsigned int translation;
|
||||
int ret = json_unpack(json_bar, "{ s: i }", "translation", &translation);
|
||||
if (ret != 0) {
|
||||
logger->error("Cannot parse {}/{}", barType, bar_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
json_error_t err;
|
||||
int ret = json_unpack_ex(json_bar, &err, 0, "{ s: i }", "translation", &translation);
|
||||
if (ret != 0)
|
||||
throw ConfigError(json_bar, err, "", "Cannot parse {}/{}", barType, bar_name);
|
||||
|
||||
if (barType == "axi_bars") {
|
||||
json_int_t base, high, size;
|
||||
int ret = json_unpack(json_bar, "{ s: I, s: I, s: I }",
|
||||
"baseaddr", &base,
|
||||
"highaddr", &high,
|
||||
"size", &size);
|
||||
if (ret != 0) {
|
||||
logger->error("Cannot parse {}/{}", barType, bar_name);
|
||||
return false;
|
||||
}
|
||||
int ret = json_unpack_ex(json_bar, &err, 0, "{ s: I, s: I, s: I }",
|
||||
"baseaddr", &base,
|
||||
"highaddr", &high,
|
||||
"size", &size
|
||||
);
|
||||
if (ret != 0)
|
||||
throw ConfigError(json_bar, err, "", "Cannot parse {}/{}", barType, bar_name);
|
||||
|
||||
pcie.axiToPcieTranslations[bar_name] = {
|
||||
.base = static_cast<uintptr_t>(base),
|
||||
|
@ -158,6 +159,4 @@ AxiPciExpressBridgeFactory::configureJson(Core &ip, json_t* json_ip)
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <jansson.h>
|
||||
#include <xilinx/xaxis_switch.h>
|
||||
|
||||
#include <villas/exceptions.hpp>
|
||||
#include <villas/fpga/ips/switch.hpp>
|
||||
|
||||
namespace villas {
|
||||
|
@ -34,15 +35,9 @@ namespace ip {
|
|||
|
||||
static AxiStreamSwitchFactory factory;
|
||||
|
||||
bool
|
||||
AxiStreamSwitch::init()
|
||||
bool AxiStreamSwitch::init()
|
||||
{
|
||||
// Setup AXI-stream switch
|
||||
XAxis_Switch_Config sw_cfg;
|
||||
sw_cfg.MaxNumMI = num_ports;
|
||||
sw_cfg.MaxNumSI = num_ports;
|
||||
|
||||
if (XAxisScr_CfgInitialize(&xSwitch, &sw_cfg, getBaseAddr(registerMemory)) != XST_SUCCESS) {
|
||||
if (XAxisScr_CfgInitialize(&xSwitch, &xConfig, getBaseAddr(registerMemory)) != XST_SUCCESS) {
|
||||
logger->error("Cannot initialize switch");
|
||||
return false;
|
||||
}
|
||||
|
@ -135,22 +130,26 @@ AxiStreamSwitch::portNameToNum(const std::string &portName)
|
|||
return std::stoi(number);
|
||||
}
|
||||
|
||||
bool
|
||||
AxiStreamSwitchFactory::configureJson(Core &ip, json_t* json_ip)
|
||||
void AxiStreamSwitchFactory::configure(Core &ip, json_t *cfg)
|
||||
{
|
||||
if (not NodeFactory::configureJson(ip, json_ip))
|
||||
return false;
|
||||
NodeFactory::configure(ip, cfg);
|
||||
|
||||
auto logger = getLogger();
|
||||
|
||||
auto &axiSwitch = dynamic_cast<AxiStreamSwitch&>(ip);
|
||||
|
||||
if (json_unpack(json_ip, "{ s: i }", "num_ports", &axiSwitch.num_ports) != 0) {
|
||||
logger->error("Cannot parse 'num_ports'");
|
||||
return false;
|
||||
}
|
||||
int num_si, num_mi;
|
||||
json_error_t err;
|
||||
auto ret = json_unpack_ex(cfg, &err, 0, "{ s: { s: i, s: i } }",
|
||||
"parameters",
|
||||
"num_si", &num_si,
|
||||
"num_mi", &num_mi
|
||||
);
|
||||
if (ret != 0)
|
||||
throw ConfigError(cfg, err, "", "Cannot parse switch config");
|
||||
|
||||
return true;
|
||||
axiSwitch.xConfig.MaxNumMI = num_mi;
|
||||
axiSwitch.xConfig.MaxNumSI = num_si;
|
||||
}
|
||||
|
||||
} /* namespace ip */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdexcept>
|
||||
#include <jansson.h>
|
||||
|
||||
#include <villas/exceptions.hpp>
|
||||
#include <villas/utils.hpp>
|
||||
|
||||
#include <villas/fpga/card.hpp>
|
||||
|
@ -35,41 +36,36 @@ using namespace villas::fpga::ip;
|
|||
StreamGraph
|
||||
Node::streamGraph;
|
||||
|
||||
bool
|
||||
NodeFactory::configureJson(Core &ip, json_t* json_ip)
|
||||
void NodeFactory::configure(Core &ip, json_t *cfg)
|
||||
{
|
||||
CoreFactory::configure(ip, cfg);
|
||||
|
||||
auto &Node = dynamic_cast<ip::Node&>(ip);
|
||||
auto logger = getLogger();
|
||||
|
||||
json_t* json_ports = json_object_get(json_ip, "ports");
|
||||
if (not json_is_array(json_ports)) {
|
||||
logger->debug("IP has no ports");
|
||||
return true;
|
||||
}
|
||||
json_t* json_ports = json_object_get(cfg, "ports");
|
||||
if (not json_is_array(json_ports))
|
||||
throw ConfigError(json_ports, "", "IP port list must be an array");
|
||||
|
||||
size_t index;
|
||||
json_t* json_port;
|
||||
json_t *json_port;
|
||||
json_array_foreach(json_ports, index, json_port) {
|
||||
if (not json_is_object(json_port)) {
|
||||
logger->error("Port {} is not an object", index);
|
||||
return false;
|
||||
}
|
||||
if (not json_is_object(json_port))
|
||||
throw ConfigError(json_port, "", "Port {} is not an object", index);
|
||||
|
||||
const char *role_raw, *target_raw, *name_raw;
|
||||
int ret = json_unpack(json_port, "{ s: s, s: s, s: s }",
|
||||
"role", &role_raw,
|
||||
"target", &target_raw,
|
||||
"name", &name_raw);
|
||||
if (ret != 0) {
|
||||
logger->error("Cannot parse port {}", index);
|
||||
return false;
|
||||
}
|
||||
|
||||
json_error_t err;
|
||||
int ret = json_unpack_ex(json_port, &err, 0, "{ s: s, s: s, s: s }",
|
||||
"role", &role_raw,
|
||||
"target", &target_raw,
|
||||
"name", &name_raw);
|
||||
if (ret != 0)
|
||||
throw ConfigError(json_port, err, "", "Cannot parse port {}", index);
|
||||
|
||||
const auto tokens = utils::tokenize(target_raw, ":");
|
||||
if (tokens.size() != 2) {
|
||||
logger->error("Cannot parse 'target' of port {}", index);
|
||||
return false;
|
||||
}
|
||||
if (tokens.size() != 2)
|
||||
throw ConfigError(json_port, err, "", "Cannot parse 'target' of port {}", index);
|
||||
|
||||
const std::string role(role_raw);
|
||||
const bool isMaster = (role == "master" or role == "initiator");
|
||||
|
@ -92,8 +88,6 @@ NodeFactory::configureJson(Core &ip, json_t* json_ip)
|
|||
else // Slave
|
||||
Node.portsSlave[name_raw] = thisVertex;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string>
|
||||
|
|
Loading…
Add table
Reference in a new issue