Skip to content

Commit

Permalink
Add devices and driver
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnoreWarnings committed Aug 14, 2024
1 parent 242edf1 commit 5dbe3d9
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 0 deletions.
22 changes: 22 additions & 0 deletions common/include/villas/kernel/devices/device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Device
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

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

class Device {
public:
virtual std::string name() const = 0;
virtual std::optional<Driver> driver() const = 0;
virtual int iommu_group() const = 0;
virtual void probe() const = 0;
virtual std::filesystem::path get_override_path() const = 0;
};
43 changes: 43 additions & 0 deletions common/include/villas/kernel/devices/driver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Driver
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* 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;

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;
void override(const Device &device) const;
void attach(const Device &device) const;
};
26 changes: 26 additions & 0 deletions common/include/villas/kernel/devices/ip_device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* IpDevice
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <filesystem>
#include <villas/kernel/devices/platform_device.hpp>

class IpDevice : public PlatformDevice {
public:
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) : PlatformDevice(path){};

public:
std::string ip_name() const;
size_t addr() const;
};
72 changes: 72 additions & 0 deletions common/include/villas/kernel/devices/platform_device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* Platform Device
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <filesystem>
#include <villas/kernel/devices/device.hpp>
#include <villas/kernel/devices/utils.hpp>

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

public:
const std::filesystem::path path;
const std::filesystem::path probe_path;
const std::filesystem::path override_path;

public:
PlatformDevice(const std::filesystem::path path)
: PlatformDevice(path, std::filesystem::path(PROBE_DEFAULT),
path / std::filesystem::path(OVERRIDE_DEFAULT)){};
PlatformDevice(const std::filesystem::path path,
const std::filesystem::path probe_path,
const std::filesystem::path override_path)
: path(path), probe_path(probe_path), override_path(override_path){};

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

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

if (!std::filesystem::is_symlink(driver_symlink))
return std::nullopt;

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

int iommu_group() const override {
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;
}

void probe() const override {
write_to_file(this->name(), this->probe_path);
};

virtual std::filesystem::path get_override_path() const override {
return this->override_path;
};
};
16 changes: 16 additions & 0 deletions common/include/villas/kernel/devices/utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* Utils
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* 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);
5 changes: 5 additions & 0 deletions common/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ add_library(villas-common SHARED
cpuset.cpp
dsp/pid.cpp
hist.cpp

kernel/devices/driver.cpp
kernel/devices/ip_device.cpp
kernel/devices/utils.cpp

kernel/kernel.cpp
kernel/rt.cpp
list.cpp
Expand Down
35 changes: 35 additions & 0 deletions common/lib/kernel/devices/driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Driver
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

#include <villas/kernel/devices/ip_device.hpp>
#include <villas/kernel/devices/utils.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);
};

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

void Driver::attach(const Device &device) const {
if (device.driver().has_value()) {
device.driver().value().unbind(device);
}
this->override(device);
device.probe();
};
53 changes: 53 additions & 0 deletions common/lib/kernel/devices/ip_device.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* IpDevice
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

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

#include <villas/kernel/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;
}
45 changes: 45 additions & 0 deletions common/lib/kernel/devices/utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Utils
*
* Author: Pascal Bauer <[email protected]>
*
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
* SPDX-License-Identifier: Apache-2.0
*/

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

void write_to_file(std::string data, const std::filesystem::path file) {
villas::Log::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;
}

0 comments on commit 5dbe3d9

Please sign in to comment.