mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
ips/dma: let user deal with making memory accessible to DMA
It is probably too costly to do (and verify) it on every read or write. Furthermore, the user knows better how to make a certain memory available to the DMA.
This commit is contained in:
parent
f823dde0f4
commit
7dcdfaccd9
3 changed files with 56 additions and 12 deletions
|
@ -193,6 +193,10 @@ protected:
|
|||
InterruptController*
|
||||
getInterruptController(const std::string& interruptName) const;
|
||||
|
||||
MemoryManager::AddressSpaceId
|
||||
getMasterAddrSpaceByInterface(const std::string& masterInterfaceName) const
|
||||
{ return busMasterInterfaces.at(masterInterfaceName); }
|
||||
|
||||
protected:
|
||||
struct IrqPort {
|
||||
int num;
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
bool memcpy(const MemoryBlock& src, const MemoryBlock& dst, size_t len);
|
||||
|
||||
bool makeAccesibleFromVA(const MemoryBlock& mem);
|
||||
|
||||
inline bool
|
||||
hasScatterGather() const
|
||||
{ return hasSG; }
|
||||
|
@ -72,6 +74,8 @@ private:
|
|||
bool writeCompleteSimple();
|
||||
bool readCompleteSimple();
|
||||
|
||||
bool isMemoryBlockAccesible(const MemoryBlock& mem, const std::string& interface);
|
||||
|
||||
private:
|
||||
static constexpr char registerMemory[] = "Reg";
|
||||
|
||||
|
|
|
@ -159,17 +159,14 @@ Dma::memcpy(const MemoryBlock& src, const MemoryBlock& dst, size_t len)
|
|||
size_t
|
||||
Dma::write(const MemoryBlock& mem, size_t len)
|
||||
{
|
||||
// make sure memory is reachable
|
||||
if(not card->mapMemoryBlock(mem)) {
|
||||
logger->error("Memory not accessible by DMA");
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& mm = MemoryManager::get();
|
||||
|
||||
// user has to make sure that memory is accessible, otherwise this will throw
|
||||
auto translation = mm.getTranslation(busMasterInterfaces[mm2sInterface],
|
||||
mem.getAddrSpaceId());
|
||||
const void* buf = reinterpret_cast<void*>(translation.getLocalAddr(0));
|
||||
|
||||
logger->debug("Write to address: {:p}", buf);
|
||||
return hasScatterGather() ? writeSG(buf, len) : writeSimple(buf, len);
|
||||
}
|
||||
|
||||
|
@ -177,17 +174,14 @@ Dma::write(const MemoryBlock& mem, size_t len)
|
|||
size_t
|
||||
Dma::read(const MemoryBlock& mem, size_t len)
|
||||
{
|
||||
// make sure memory is reachable
|
||||
if(not card->mapMemoryBlock(mem)) {
|
||||
logger->error("Memory not accessible by DMA");
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& mm = MemoryManager::get();
|
||||
|
||||
// user has to make sure that memory is accessible, otherwise this will throw
|
||||
auto translation = mm.getTranslation(busMasterInterfaces[s2mmInterface],
|
||||
mem.getAddrSpaceId());
|
||||
void* buf = reinterpret_cast<void*>(translation.getLocalAddr(0));
|
||||
|
||||
logger->debug("Read from address: {:p}", buf);
|
||||
return hasScatterGather() ? readSG(buf, len) : readSimple(buf, len);
|
||||
}
|
||||
|
||||
|
@ -356,6 +350,48 @@ Dma::readCompleteSimple()
|
|||
}
|
||||
|
||||
|
||||
bool
|
||||
Dma::makeAccesibleFromVA(const MemoryBlock& mem)
|
||||
{
|
||||
// only symmetric mapping supported currently
|
||||
if(isMemoryBlockAccesible(mem, s2mmInterface) and
|
||||
isMemoryBlockAccesible(mem, mm2sInterface)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// try mapping via FPGA-card (VFIO)
|
||||
if(not card->mapMemoryBlock(mem)) {
|
||||
logger->error("Memory not accessible by DMA");
|
||||
return false;
|
||||
}
|
||||
|
||||
// sanity-check if mapping worked, this shouldn't be neccessary
|
||||
if(not isMemoryBlockAccesible(mem, s2mmInterface) or
|
||||
not isMemoryBlockAccesible(mem, mm2sInterface)) {
|
||||
logger->error("Mapping memory via card didn't work, but reported success?!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Dma::isMemoryBlockAccesible(const MemoryBlock& mem, const std::string& interface)
|
||||
{
|
||||
auto& mm = MemoryManager::get();
|
||||
|
||||
try {
|
||||
mm.findPath(getMasterAddrSpaceByInterface(interface), mem.getAddrSpaceId());
|
||||
} catch(const std::out_of_range&) {
|
||||
// not (yet) accessible
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ip
|
||||
} // namespace fpga
|
||||
} // namespace villas
|
||||
|
|
Loading…
Add table
Reference in a new issue