Skip to content

Commit 5dbe3d9

Browse files
Add devices and driver
1 parent 242edf1 commit 5dbe3d9

File tree

9 files changed

+317
-0
lines changed

9 files changed

+317
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* Device
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#pragma once
10+
11+
#include <filesystem>
12+
#include <optional>
13+
#include <villas/kernel/devices/driver.hpp>
14+
15+
class Device {
16+
public:
17+
virtual std::string name() const = 0;
18+
virtual std::optional<Driver> driver() const = 0;
19+
virtual int iommu_group() const = 0;
20+
virtual void probe() const = 0;
21+
virtual std::filesystem::path get_override_path() const = 0;
22+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* Driver
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#pragma once
10+
11+
#include <fstream>
12+
#include <iostream>
13+
14+
class Device;
15+
16+
class Driver {
17+
private:
18+
static constexpr char BIND_DEFAULT[] = "bind";
19+
static constexpr char UNBIND_DEFAULT[] = "unbind";
20+
21+
public:
22+
const std::filesystem::path path;
23+
24+
private:
25+
const std::filesystem::path bind_path;
26+
const std::filesystem::path unbind_path;
27+
28+
public:
29+
Driver(const std::filesystem::path path)
30+
: Driver(path, path / std::filesystem::path(BIND_DEFAULT),
31+
path / std::filesystem::path(UNBIND_DEFAULT)){};
32+
33+
Driver(const std::filesystem::path path,
34+
const std::filesystem::path bind_path,
35+
const std::filesystem::path unbind_path)
36+
: path(path), bind_path(bind_path), unbind_path(unbind_path){};
37+
38+
std::string name() const;
39+
void bind(const Device &device) const;
40+
void unbind(const Device &device) const;
41+
void override(const Device &device) const;
42+
void attach(const Device &device) const;
43+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* IpDevice
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#pragma once
10+
11+
#include <filesystem>
12+
#include <villas/kernel/devices/platform_device.hpp>
13+
14+
class IpDevice : public PlatformDevice {
15+
public:
16+
public:
17+
static IpDevice from(const std::filesystem::path unsafe_path);
18+
static bool is_path_valid(const std::filesystem::path unsafe_path);
19+
20+
private:
21+
IpDevice(const std::filesystem::path valid_path) : PlatformDevice(path){};
22+
23+
public:
24+
std::string ip_name() const;
25+
size_t addr() const;
26+
};
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* Platform Device
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#pragma once
10+
11+
#include <filesystem>
12+
#include <villas/kernel/devices/device.hpp>
13+
#include <villas/kernel/devices/utils.hpp>
14+
15+
class PlatformDevice : public Device {
16+
private:
17+
static constexpr char PROBE_DEFAULT[] = "/sys/bus/platform/drivers_probe";
18+
static constexpr char OVERRIDE_DEFAULT[] = "driver_override";
19+
20+
public:
21+
const std::filesystem::path path;
22+
const std::filesystem::path probe_path;
23+
const std::filesystem::path override_path;
24+
25+
public:
26+
PlatformDevice(const std::filesystem::path path)
27+
: PlatformDevice(path, std::filesystem::path(PROBE_DEFAULT),
28+
path / std::filesystem::path(OVERRIDE_DEFAULT)){};
29+
PlatformDevice(const std::filesystem::path path,
30+
const std::filesystem::path probe_path,
31+
const std::filesystem::path override_path)
32+
: path(path), probe_path(probe_path), override_path(override_path){};
33+
34+
std::string name() const override {
35+
size_t pos = path.u8string().rfind('/');
36+
return path.u8string().substr(pos + 1);
37+
}
38+
39+
std::optional<Driver> driver() const override {
40+
std::filesystem::path driver_symlink =
41+
this->path / std::filesystem::path("driver");
42+
43+
if (!std::filesystem::is_symlink(driver_symlink))
44+
return std::nullopt;
45+
46+
std::filesystem::path driver_path =
47+
std::filesystem::canonical(driver_symlink);
48+
return Driver(driver_path);
49+
};
50+
51+
int iommu_group() const override {
52+
std::filesystem::path symlink =
53+
std::filesystem::path(this->path.u8string() + "/iommu_group");
54+
55+
std::filesystem::path link;
56+
link = std::filesystem::read_symlink(symlink);
57+
58+
std::string delimiter = "iommu_groups/";
59+
int pos = link.u8string().find(delimiter);
60+
int iommu_group =
61+
std::stoi(link.u8string().substr(pos + delimiter.length()));
62+
return iommu_group;
63+
}
64+
65+
void probe() const override {
66+
write_to_file(this->name(), this->probe_path);
67+
};
68+
69+
virtual std::filesystem::path get_override_path() const override {
70+
return this->override_path;
71+
};
72+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* Utils
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#pragma once
10+
11+
#include <filesystem>
12+
#include <string>
13+
#include <vector>
14+
15+
void write_to_file(std::string data, const std::filesystem::path file);
16+
std::vector<std::string> read_names_in_directory(const std::string &name);

common/lib/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ add_library(villas-common SHARED
1515
cpuset.cpp
1616
dsp/pid.cpp
1717
hist.cpp
18+
19+
kernel/devices/driver.cpp
20+
kernel/devices/ip_device.cpp
21+
kernel/devices/utils.cpp
22+
1823
kernel/kernel.cpp
1924
kernel/rt.cpp
2025
list.cpp
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* Driver
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#include <villas/kernel/devices/ip_device.hpp>
10+
#include <villas/kernel/devices/utils.hpp>
11+
12+
std::string Driver::name() const {
13+
size_t pos = path.u8string().rfind('/');
14+
return path.u8string().substr(pos + 1);
15+
}
16+
17+
void Driver::bind(const Device &device) const {
18+
write_to_file(device.name(), this->bind_path);
19+
};
20+
21+
void Driver::unbind(const Device &device) const {
22+
write_to_file(device.name(), this->unbind_path);
23+
};
24+
25+
void Driver::override(const Device &device) const {
26+
write_to_file(this->name(), device.get_override_path());
27+
};
28+
29+
void Driver::attach(const Device &device) const {
30+
if (device.driver().has_value()) {
31+
device.driver().value().unbind(device);
32+
}
33+
this->override(device);
34+
device.probe();
35+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* IpDevice
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#include <filesystem>
10+
#include <regex>
11+
#include <stdexcept>
12+
13+
#include <villas/kernel/devices/ip_device.hpp>
14+
15+
IpDevice IpDevice::from(const std::filesystem::path unsafe_path) {
16+
if (!is_path_valid(unsafe_path))
17+
throw std::runtime_error(
18+
"Path \"" + unsafe_path.u8string() +
19+
"\" failed validation as IpDevicePath \"[adress in hex].[name]\". ");
20+
return IpDevice(unsafe_path);
21+
}
22+
23+
bool IpDevice::is_path_valid(const std::filesystem::path unsafe_path) {
24+
// Split the string at last slash
25+
int pos = unsafe_path.u8string().rfind('/');
26+
std::string assumed_device_name = unsafe_path.u8string().substr(pos + 1);
27+
28+
// Match format of hexaddr.devicename
29+
if (!std::regex_match(assumed_device_name,
30+
std::regex(R"([0-9A-Fa-f]+\..*)"))) {
31+
return false;
32+
}
33+
34+
return true;
35+
}
36+
37+
std::string IpDevice::ip_name() const {
38+
int pos = name().find('.');
39+
return name().substr(pos + 1);
40+
}
41+
42+
size_t IpDevice::addr() const {
43+
size_t pos = name().find('.');
44+
std::string addr_hex = name().substr(0, pos);
45+
46+
// convert from hex string to number
47+
std::stringstream ss;
48+
ss << std::hex << addr_hex;
49+
size_t addr = 0;
50+
ss >> addr;
51+
52+
return addr;
53+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* Utils
2+
*
3+
* Author: Pascal Bauer <[email protected]>
4+
*
5+
* SPDX-FileCopyrightText: 2023-2024 Pascal Bauer <[email protected]>
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#include <dirent.h>
10+
#include <filesystem>
11+
#include <fstream>
12+
#include <iostream>
13+
#include <villas/kernel/devices/utils.hpp>
14+
#include <villas/log.hpp>
15+
16+
void write_to_file(std::string data, const std::filesystem::path file) {
17+
villas::Log::get("Filewriter")->debug("{} > {}", data, file.u8string());
18+
std::ofstream outputFile(file.u8string());
19+
20+
if (outputFile.is_open()) {
21+
// Write to file
22+
outputFile << data;
23+
outputFile.close();
24+
} else {
25+
throw std::filesystem::filesystem_error("Cannot open outputfile",
26+
std::error_code());
27+
}
28+
}
29+
30+
std::vector<std::string> read_names_in_directory(const std::string &name) {
31+
DIR *directory = opendir(name.c_str());
32+
33+
struct dirent *dp;
34+
std::vector<std::string> names;
35+
dp = readdir(directory);
36+
while (dp != NULL) {
37+
auto name = std::string(dp->d_name);
38+
if (name != "." && name != "..") {
39+
names.push_back(name);
40+
}
41+
dp = readdir(directory);
42+
}
43+
closedir(directory);
44+
return names;
45+
}

0 commit comments

Comments
 (0)