From e8b593cf1febc4ad7307e28060e8a79198572f69 Mon Sep 17 00:00:00 2001 From: Pascal Henry Bauer Date: Thu, 26 Jan 2023 17:01:08 +0100 Subject: [PATCH] added card definitions Signed-off-by: Pascal Henry Bauer --- fpga/lib/card.cpp | 119 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/fpga/lib/card.cpp b/fpga/lib/card.cpp index 45ad4e4ab..f46b19528 100644 --- a/fpga/lib/card.cpp +++ b/fpga/lib/card.cpp @@ -4,6 +4,119 @@ * * Author: Steffen Vogel * Author: Daniel Krebs - * SPDX-FileCopyrightText: 2017 Institute for Automation of Complex Power Systems, EONERC - * SPDX-License-Identifier: Apache-2.0 - *********************************************************************************/ \ No newline at end of file + * SPDX-FileCopyrightText: 2017 Institute for Automation of Complex Power + *Systems, EONERC SPDX-License-Identifier: Apache-2.0 + *********************************************************************************/ + +#include + +using namespace villas; +using namespace villas::fpga; + +Card::~Card() +{ +} + +std::shared_ptr Card::lookupIp(const std::string &name) const +{ + for(auto &ip : ips) { + if(*ip == name) { + return ip; + } + } + + return nullptr; +} + +std::shared_ptr Card::lookupIp(const Vlnv &vlnv) const +{ + for(auto &ip : ips) { + if(*ip == vlnv) { + return ip; + } + } + + return nullptr; +} + +std::shared_ptr 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 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); + + return true; +}