Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions fpga/include/villas/fpga/device/device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* Device
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <filesystem>
#include <optional>
#include <villas/fpga/devices/driver.hpp>
#include <villas/fpga/devices/utils.hpp>

class Device {
private:
static constexpr char PROBE_DEFAULT[] = "/sys/bus/platform/drivers_probe";

public:
const std::filesystem::path path;

private:
const std::filesystem::path probe_path;

public:
Device(const std::filesystem::path path)
: Device(path, std::filesystem::path(PROBE_DEFAULT)){};
Device(const std::filesystem::path path,
const std::filesystem::path probe_path)
: path(path), probe_path(probe_path){};

std::string name() const {
size_t pos = path.u8string().rfind('/');
return path.u8string().substr(pos + 1);
}

std::optional<Driver> driver() const {
std::filesystem::path driver_symlink =
this->path / std::filesystem::path("driver");

try {
std::filesystem::read_symlink(driver_symlink);
} catch (std::filesystem::filesystem_error &e) {
return std::nullopt;
}

std::filesystem::path driver_path =
std::filesystem::canonical(driver_symlink);
return Driver(driver_path);
};

void driver_override(const Driver &driver) const {
write_to_file(driver.name(),
this->path / std::filesystem::path("driver_override"));
};

void probe() const { write_to_file(this->name(), this->probe_path); };
};
42 changes: 42 additions & 0 deletions fpga/include/villas/fpga/device/driver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* Driver
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <fstream>
#include <iostream>

class Device;

class Driver {
private:
static constexpr char BIND_DEFAULT[] = "bind";
static constexpr char UNBIND_DEFAULT[] = "unbind";

public:
const std::filesystem::path path;

private:
const std::filesystem::path bind_path;
const std::filesystem::path unbind_path;
const std::filesystem::path probe_path;

public:
Driver(const std::filesystem::path path)
: Driver(path, path / std::filesystem::path(BIND_DEFAULT),
path / std::filesystem::path(UNBIND_DEFAULT)){};

Driver(const std::filesystem::path path,
const std::filesystem::path bind_path,
const std::filesystem::path unbind_path)
: path(path), bind_path(bind_path), unbind_path(unbind_path){};

std::string name() const;
void bind(const Device &device) const;
void unbind(const Device &device) const;
};
26 changes: 26 additions & 0 deletions fpga/include/villas/fpga/device/ip_device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* IpDevice
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <filesystem>
#include <villas/fpga/devices/device.hpp>

class IpDevice : public Device {
public:
static IpDevice from(const std::filesystem::path unsafe_path);
static bool is_path_valid(const std::filesystem::path unsafe_path);

private:
IpDevice(const std::filesystem::path valid_path) : Device(valid_path){};

public:
std::string ip_name() const;
size_t addr() const;
int iommu_group() const;
};
16 changes: 16 additions & 0 deletions fpga/include/villas/fpga/device/utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Utils
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <filesystem>
#include <string>
#include <vector>

void write_to_file(std::string data, const std::filesystem::path file);
std::vector<std::string> read_names_in_directory(const std::string &name);
24 changes: 24 additions & 0 deletions fpga/lib/device/driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Driver
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#include <villas/fpga/devices/utils.hpp>
#include <villas/fpga/devices/ip_device.hpp>

std::string Driver::name() const {
size_t pos = path.u8string().rfind('/');
return path.u8string().substr(pos + 1);
}

void Driver::bind(const Device &device) const {
write_to_file(device.name(), this->bind_path);
};

void Driver::unbind(const Device &device) const {
write_to_file(device.name(), this->unbind_path);
};

66 changes: 66 additions & 0 deletions fpga/lib/device/ip_device.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* IpDevice
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#include <filesystem>
#include <regex>
#include <stdexcept>

#include <villas/fpga/devices/ip_device.hpp>

IpDevice IpDevice::from(const std::filesystem::path unsafe_path) {
if (!is_path_valid(unsafe_path))
throw std::runtime_error(
"Path \"" + unsafe_path.u8string() +
"\" failed validation as IpDevicePath \"[adress in hex].[name]\". ");
return IpDevice(unsafe_path);
}

bool IpDevice::is_path_valid(const std::filesystem::path unsafe_path) {
// Split the string at last slash
int pos = unsafe_path.u8string().rfind('/');
std::string assumed_device_name = unsafe_path.u8string().substr(pos + 1);

// Match format of hexaddr.devicename
if (!std::regex_match(assumed_device_name,
std::regex(R"([0-9A-Fa-f]+\..*)"))) {
return false;
}

return true;
}

std::string IpDevice::ip_name() const {
int pos = name().find('.');
return name().substr(pos + 1);
}

size_t IpDevice::addr() const {
size_t pos = name().find('.');
std::string addr_hex = name().substr(0, pos);

// convert from hex string to number
std::stringstream ss;
ss << std::hex << addr_hex;
size_t addr = 0;
ss >> addr;

return addr;
}

int IpDevice::iommu_group() const {
std::filesystem::path symlink =
std::filesystem::path(this->path.u8string() + "/iommu_group");

std::filesystem::path link;
link = std::filesystem::read_symlink(symlink);

std::string delimiter = "iommu_groups/";
int pos = link.u8string().find(delimiter);
int iommu_group = std::stoi(link.u8string().substr(pos + delimiter.length()));
return iommu_group;
}
45 changes: 45 additions & 0 deletions fpga/lib/device/utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Utils
*
* Author: Pascal Bauer <pascal.bauer@rwth-aachen.de>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <pascal.bauer@rwth-aachen.de>
* SPDX-License-Identifier: Apache-2.0
*/

#include <filesystem>
#include <fstream>
#include <iostream>
#include <villas/fpga/devices/utils.hpp>
#include <villas/log.hpp>
#include <dirent.h>

void write_to_file(std::string data, const std::filesystem::path file) {
villas::logging.get("Filewriter")->debug("{} > {}", data, file.u8string());
std::ofstream outputFile(file.u8string());

if (outputFile.is_open()) {
// Write to file
outputFile << data;
outputFile.close();
} else {
throw std::filesystem::filesystem_error("Cannot open outputfile",
std::error_code());
}
}

std::vector<std::string> read_names_in_directory(const std::string &name) {
DIR *directory = opendir(name.c_str());

struct dirent *dp;
std::vector<std::string> names;
dp = readdir(directory);
while (dp != NULL) {
auto name = std::string(dp->d_name);
if (name != "." && name != "..") {
names.push_back(name);
}
dp = readdir(directory);
}
closedir(directory);
return names;
}