mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-30 00:00:11 +01:00

This edits the headers in every file so the copyright notice mentions RWTH Aachen University. We also update some copyright years and fix various comments so the header is the same across all of VILLASframework. * Harmonize comment and code-style Signed-off-by: Steffen Vogel <steffen.vogel@opal-rt.com> * Harmonize comment and code-style Signed-off-by: Steffen Vogel <steffen.vogel@opal-rt.com> --------- Signed-off-by: Steffen Vogel <steffen.vogel@opal-rt.com>
129 lines
3.5 KiB
C++
129 lines
3.5 KiB
C++
/* FPGA card
|
|
*
|
|
* This class represents a FPGA device.
|
|
*
|
|
* Author: Steffen Vogel <post@steffenvogel.de>
|
|
* Author: Daniel Krebs <github@daniel-krebs.net>
|
|
* SPDX-FileCopyrightText: 2017 Institute for Automation of Complex Power Systems, RWTH Aachen University
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <villas/fpga/card.hpp>
|
|
|
|
using namespace villas;
|
|
using namespace villas::fpga;
|
|
|
|
Card::~Card()
|
|
{
|
|
// Ensure IP destructors are called before memory is unmapped
|
|
ips.clear();
|
|
|
|
auto &mm = MemoryManager::get();
|
|
|
|
// Unmap all memory blocks
|
|
for (auto &mappedMemoryBlock : memoryBlocksMapped) {
|
|
auto translation = mm.getTranslation(addrSpaceIdDeviceToHost, mappedMemoryBlock.first);
|
|
|
|
const uintptr_t iova = translation.getLocalAddr(0);
|
|
const size_t size = translation.getSize();
|
|
|
|
logger->debug("Unmap block {} at IOVA {:#x} of size {:#x}",
|
|
mappedMemoryBlock.first, iova, size);
|
|
vfioContainer->memoryUnmap(iova, size);
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<ip::Core> Card::lookupIp(const std::string &name) const
|
|
{
|
|
for(auto &ip : ips) {
|
|
if(*ip == name) {
|
|
return ip;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<ip::Core> Card::lookupIp(const Vlnv &vlnv) const
|
|
{
|
|
for(auto &ip : ips) {
|
|
if(*ip == vlnv) {
|
|
return ip;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<ip::Core> Card::lookupIp(const ip::IpIdentifier &id) const
|
|
{
|
|
for (auto &ip : ips) {
|
|
if (*ip == id) {
|
|
return ip;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool Card::unmapMemoryBlock(const MemoryBlock& block)
|
|
{
|
|
if (memoryBlocksMapped.find(block.getAddrSpaceId()) == memoryBlocksMapped.end()) {
|
|
throw std::runtime_error("Block " + std::to_string(block.getAddrSpaceId()) + " is not mapped but was requested to be unmapped.");
|
|
}
|
|
|
|
auto &mm = MemoryManager::get();
|
|
|
|
auto translation = mm.getTranslation(addrSpaceIdDeviceToHost, block.getAddrSpaceId());
|
|
|
|
const uintptr_t iova = translation.getLocalAddr(0);
|
|
const size_t size = translation.getSize();
|
|
|
|
logger->debug("Unmap block {} at IOVA {:#x} of size {:#x}",
|
|
block.getAddrSpaceId(), iova, size);
|
|
vfioContainer->memoryUnmap(iova, size);
|
|
|
|
memoryBlocksMapped.erase(block.getAddrSpaceId());
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool Card::mapMemoryBlock(const std::shared_ptr<MemoryBlock> block)
|
|
{
|
|
if (not vfioContainer->isIommuEnabled()) {
|
|
logger->warn("VFIO mapping not supported without IOMMU");
|
|
return false;
|
|
}
|
|
|
|
auto &mm = MemoryManager::get();
|
|
const auto &addrSpaceId = block->getAddrSpaceId();
|
|
|
|
if (memoryBlocksMapped.find(addrSpaceId) != memoryBlocksMapped.end())
|
|
// Block already mapped
|
|
return true;
|
|
else
|
|
logger->debug("Create VFIO mapping for {}", addrSpaceId);
|
|
|
|
auto translationFromProcess = mm.getTranslationFromProcess(addrSpaceId);
|
|
uintptr_t processBaseAddr = translationFromProcess.getLocalAddr(0);
|
|
uintptr_t iovaAddr = vfioContainer->memoryMap(processBaseAddr,
|
|
UINTPTR_MAX,
|
|
block->getSize());
|
|
|
|
if (iovaAddr == UINTPTR_MAX) {
|
|
logger->error("Cannot map memory at {:#x} of size {:#x}",
|
|
processBaseAddr, block->getSize());
|
|
return false;
|
|
}
|
|
|
|
mm.createMapping(iovaAddr, 0, block->getSize(),
|
|
"VFIO-D2H",
|
|
this->addrSpaceIdDeviceToHost,
|
|
addrSpaceId);
|
|
|
|
// Remember that this block has already been mapped for later
|
|
memoryBlocksMapped.insert({addrSpaceId, block});
|
|
|
|
return true;
|
|
}
|