mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
add card config option "polling" to configure polling mode in IP cores; add json parsing of hwdef to dma IP core to replace hardcoded DMA settings.
This commit is contained in:
parent
7b2f0f3d96
commit
bac0b7309a
7 changed files with 146 additions and 28 deletions
|
@ -4,7 +4,8 @@
|
|||
"id": "10ee:7021",
|
||||
"slot": "0000:88:00.0",
|
||||
"do_reset": true,
|
||||
"ips": "etc/vc707-xbar-pcie/vc707-xbar-pcie.json"
|
||||
"ips": "etc/vc707-xbar-pcie/vc707-xbar-pcie.json",
|
||||
"polling": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ public: // TODO: make this private
|
|||
|
||||
bool doReset; // Reset VILLASfpga during startup?
|
||||
int affinity; // Affinity for MSI interrupts
|
||||
bool polling; // Poll on interrupts?
|
||||
|
||||
std::string name; // The name of the FPGA card
|
||||
|
||||
|
|
|
@ -302,6 +302,10 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
enum PollingMode {
|
||||
POLL,
|
||||
IRQ,
|
||||
};
|
||||
Logger
|
||||
getLogger() const
|
||||
{
|
||||
|
@ -318,6 +322,9 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual void configurePollingMode(Core& /* ip */, PollingMode /* mode */)
|
||||
{ }
|
||||
|
||||
virtual Vlnv getCompatibleVlnv() const = 0;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -127,6 +127,8 @@ private:
|
|||
XAxiDma xDma;
|
||||
XAxiDma_Config xConfig;
|
||||
bool hasSG;
|
||||
bool configSet = false;
|
||||
bool polling = false;
|
||||
|
||||
int delay;
|
||||
int coalesce;
|
||||
|
@ -161,8 +163,14 @@ public:
|
|||
return Vlnv("xilinx.com:ip:axi_dma:");
|
||||
}
|
||||
|
||||
//virtual bool
|
||||
//configureJson(Core& ip, json_t* json) override;*/
|
||||
virtual bool
|
||||
configureJson(Core& ip, json_t* json) override;
|
||||
|
||||
virtual void
|
||||
configurePollingMode(Core& ip, PollingMode mode)
|
||||
{
|
||||
dynamic_cast<Dma&>(ip).polling = (mode == POLL);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace ip */
|
||||
|
|
|
@ -57,13 +57,15 @@ PCIeCardFactory::make(json_t *json, std::shared_ptr<kernel::pci::DeviceList> pci
|
|||
const char* pci_id = nullptr;
|
||||
int do_reset = 0;
|
||||
int affinity = 0;
|
||||
int polling = 0;
|
||||
|
||||
int ret = json_unpack(json_card, "{ s: o, s?: i, s?: b, s?: s, s?: s }",
|
||||
int ret = json_unpack(json_card, "{ s: o, s?: i, s?: b, s?: s, s?: s, s?: b }",
|
||||
"ips", &json_ips,
|
||||
"affinity", &affinity,
|
||||
"do_reset", &do_reset,
|
||||
"slot", &pci_slot,
|
||||
"id", &pci_id);
|
||||
"id", &pci_id,
|
||||
"polling", &polling);
|
||||
|
||||
if (ret != 0) {
|
||||
logger->warn("Cannot parse JSON config");
|
||||
|
@ -77,6 +79,7 @@ PCIeCardFactory::make(json_t *json, std::shared_ptr<kernel::pci::DeviceList> pci
|
|||
card->vfioContainer = std::move(vc);
|
||||
card->affinity = affinity;
|
||||
card->doReset = do_reset != 0;
|
||||
card->polling = (polling != 0);
|
||||
|
||||
kernel::pci::Device filter = defaultFilter;
|
||||
|
||||
|
|
|
@ -249,6 +249,9 @@ CoreFactory::make(PCIeCard* card, json_t *json_ips)
|
|||
continue;
|
||||
}
|
||||
|
||||
// Set polling mode
|
||||
CoreFactory->configurePollingMode(*ip, (card->polling ? PollingMode::POLL : PollingMode::IRQ));
|
||||
|
||||
// IP has been configured now
|
||||
configuredIps.push_back(std::move(ip));
|
||||
}
|
||||
|
|
|
@ -47,29 +47,30 @@ bool Dma::init()
|
|||
delay = 0;
|
||||
|
||||
// If there is a scatter-gather interface, then this instance has it
|
||||
hasSG = busMasterInterfaces.count(sgInterface) == 1;
|
||||
logger->info("Scatter-Gather support: {}", hasScatterGather());
|
||||
// hasSG = busMasterInterfaces.count(sgInterface) == 1;
|
||||
if (hasScatterGather())
|
||||
logger->info("Scatter-Gather support: {}", hasScatterGather());
|
||||
|
||||
XAxiDma_Config xdma_cfg;
|
||||
xConfig.BaseAddr = getBaseAddr(registerMemory);
|
||||
if (!configSet) {
|
||||
xConfig.HasStsCntrlStrm = 0;
|
||||
xConfig.HasMm2S = 1;
|
||||
xConfig.HasMm2SDRE = 0;
|
||||
xConfig.Mm2SDataWidth = 32;
|
||||
xConfig.HasS2Mm = 1;
|
||||
xConfig.HasS2MmDRE = 0;
|
||||
xConfig.HasSg = hasScatterGather();
|
||||
xConfig.S2MmDataWidth = 32;
|
||||
xConfig.Mm2sNumChannels = 1;
|
||||
xConfig.S2MmNumChannels = 1;
|
||||
xConfig.Mm2SBurstSize = 16;
|
||||
xConfig.S2MmBurstSize = 16;
|
||||
xConfig.MicroDmaMode = 0;
|
||||
xConfig.AddrWidth = 32;
|
||||
xConfig.SgLengthWidth = 14;
|
||||
}
|
||||
|
||||
xdma_cfg.BaseAddr = getBaseAddr(registerMemory);
|
||||
xdma_cfg.HasStsCntrlStrm = 0;
|
||||
xdma_cfg.HasMm2S = 1;
|
||||
xdma_cfg.HasMm2SDRE = 0;
|
||||
xdma_cfg.Mm2SDataWidth = 32;
|
||||
xdma_cfg.HasS2Mm = 1;
|
||||
xdma_cfg.HasS2MmDRE = 0;
|
||||
xdma_cfg.HasSg = hasScatterGather();
|
||||
xdma_cfg.S2MmDataWidth = 32;
|
||||
xdma_cfg.Mm2sNumChannels = 1;
|
||||
xdma_cfg.S2MmNumChannels = 1;
|
||||
xdma_cfg.Mm2SBurstSize = 16;
|
||||
xdma_cfg.S2MmBurstSize = 16;
|
||||
xdma_cfg.MicroDmaMode = 0;
|
||||
xdma_cfg.AddrWidth = 32;
|
||||
xdma_cfg.SgLengthWidth = 14;
|
||||
|
||||
if (XAxiDma_CfgInitialize(&xDma, &xdma_cfg) != XST_SUCCESS)
|
||||
if (XAxiDma_CfgInitialize(&xDma, &xConfig) != XST_SUCCESS)
|
||||
{
|
||||
logger->error("Cannot initialize Xilinx DMA driver");
|
||||
return false;
|
||||
|
@ -94,9 +95,9 @@ bool Dma::init()
|
|||
XAxiDma_IntrEnable(&xDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);
|
||||
|
||||
// write interrupt
|
||||
irqs[mm2sInterrupt].irqController->enableInterrupt(irqs[mm2sInterrupt], false);
|
||||
irqs[mm2sInterrupt].irqController->enableInterrupt(irqs[mm2sInterrupt], polling);
|
||||
// read interrupt
|
||||
irqs[s2mmInterrupt].irqController->enableInterrupt(irqs[s2mmInterrupt], false);
|
||||
irqs[s2mmInterrupt].irqController->enableInterrupt(irqs[s2mmInterrupt], polling);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -606,3 +607,97 @@ void Dma::dump()
|
|||
logger->info("MM2S_DMACR: {:x}", XAxiDma_ReadReg(xDma.RegBase, XAXIDMA_TX_OFFSET + XAXIDMA_CR_OFFSET));
|
||||
logger->info("MM2S_DMASR: {:x}", XAxiDma_ReadReg(xDma.RegBase, XAXIDMA_TX_OFFSET + XAXIDMA_SR_OFFSET));
|
||||
}
|
||||
|
||||
bool
|
||||
DmaFactory::configureJson(Core& ip, json_t* json)
|
||||
{
|
||||
auto &dma = dynamic_cast<Dma&>(ip);
|
||||
enum DmaParameters {
|
||||
HasStsCntrlStrm,
|
||||
HasMm2S,
|
||||
HasMm2SDRE,
|
||||
Mm2SDataWidth,
|
||||
HasS2Mm,
|
||||
HasS2MmDRE,
|
||||
S2MmDataWidth,
|
||||
HasSg,
|
||||
Mm2sNumChannels,
|
||||
S2MmNumChannels,
|
||||
MicroDmaMode,
|
||||
AddrWidth,
|
||||
SgLengthWidth
|
||||
};
|
||||
static const std::map<const char*, DmaParameters> ParaMap = {
|
||||
{"c_sg_include_stscntrl_strm", HasStsCntrlStrm},
|
||||
{"c_include_mm2s", HasMm2S},
|
||||
{"c_include_mm2s_dre", HasMm2SDRE},
|
||||
{"c_m_axi_mm2s_data_width", Mm2SDataWidth},
|
||||
{"c_include_s2mm", HasS2Mm},
|
||||
{"c_include_s2mm_dre", HasS2MmDRE},
|
||||
{"c_m_axi_s2mm_data_width", S2MmDataWidth},
|
||||
{"c_include_sg", HasSg},
|
||||
{"c_num_mm2s_channels", Mm2sNumChannels},
|
||||
{"c_num_s2mm_channels", S2MmNumChannels},
|
||||
{"c_micro_dma", MicroDmaMode},
|
||||
{"c_addr_width", AddrWidth},
|
||||
{"c_sg_length_width", SgLengthWidth}
|
||||
};
|
||||
|
||||
json_t* json_params = json_object_get(json, "parameters");
|
||||
if (!json_is_object(json_params))
|
||||
return true;
|
||||
|
||||
const char* paramName;
|
||||
json_t* json_param;
|
||||
json_object_foreach(json_params, paramName, json_param) {
|
||||
auto it = ParaMap.find(paramName);
|
||||
if (it == ParaMap.end())
|
||||
continue;
|
||||
|
||||
switch (it->second) {
|
||||
case HasStsCntrlStrm:
|
||||
dma.xConfig.HasStsCntrlStrm = json_integer_value(json_param);
|
||||
break;
|
||||
case HasMm2S:
|
||||
dma.xConfig.HasMm2S = json_integer_value(json_param);
|
||||
break;
|
||||
case HasMm2SDRE:
|
||||
dma.xConfig.HasMm2SDRE = json_integer_value(json_param);
|
||||
break;
|
||||
case Mm2SDataWidth:
|
||||
dma.xConfig.Mm2SDataWidth = json_integer_value(json_param);
|
||||
break;
|
||||
case HasS2Mm:
|
||||
dma.xConfig.HasS2Mm = json_integer_value(json_param);
|
||||
break;
|
||||
case HasS2MmDRE:
|
||||
dma.xConfig.HasS2MmDRE = json_integer_value(json_param);
|
||||
break;
|
||||
case S2MmDataWidth:
|
||||
dma.xConfig.S2MmDataWidth = json_integer_value(json_param);
|
||||
break;
|
||||
case HasSg:
|
||||
dma.xConfig.HasSg = json_integer_value(json_param);
|
||||
break;
|
||||
case Mm2sNumChannels:
|
||||
dma.xConfig.Mm2sNumChannels = json_integer_value(json_param);
|
||||
break;
|
||||
case S2MmNumChannels:
|
||||
dma.xConfig.S2MmNumChannels = json_integer_value(json_param);
|
||||
break;
|
||||
case MicroDmaMode:
|
||||
dma.xConfig.MicroDmaMode = json_integer_value(json_param);
|
||||
break;
|
||||
case AddrWidth:
|
||||
dma.xConfig.AddrWidth = json_integer_value(json_param);
|
||||
break;
|
||||
case SgLengthWidth:
|
||||
dma.xConfig.SgLengthWidth = json_integer_value(json_param);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
dma.configSet = true;
|
||||
return true;
|
||||
}
|
Loading…
Add table
Reference in a new issue