Skip to content

Commit b9e6468

Browse files
add devices and driver
Signed-off-by: IgnoreWarnings <[email protected]>
1 parent f25e1dd commit b9e6468

File tree

8 files changed

+288
-0
lines changed

8 files changed

+288
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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/fpga/devices/driver.hpp>
14+
#include <villas/fpga/devices/utils.hpp>
15+
16+
class Device {
17+
private:
18+
static constexpr char PROBE_DEFAULT[] = "/sys/bus/platform/drivers_probe";
19+
static constexpr char OVERRIDE_DEFAULT[] = "driver_override";
20+
21+
public:
22+
const std::filesystem::path path;
23+
const std::filesystem::path probe_path;
24+
const std::filesystem::path override_path;
25+
26+
public:
27+
Device(const std::filesystem::path path)
28+
: Device(path, std::filesystem::path(PROBE_DEFAULT),
29+
path / std::filesystem::path(OVERRIDE_DEFAULT)){};
30+
Device(const std::filesystem::path path,
31+
const std::filesystem::path probe_path,
32+
const std::filesystem::path override_path)
33+
: path(path), probe_path(probe_path), override_path(override_path){};
34+
35+
std::string name() const {
36+
size_t pos = path.u8string().rfind('/');
37+
return path.u8string().substr(pos + 1);
38+
}
39+
40+
std::optional<Driver> driver() const {
41+
std::filesystem::path driver_symlink =
42+
this->path / std::filesystem::path("driver");
43+
44+
if (!std::filesystem::is_symlink(driver_symlink))
45+
return std::nullopt;
46+
47+
std::filesystem::path driver_path =
48+
std::filesystem::canonical(driver_symlink);
49+
return Driver(driver_path);
50+
};
51+
52+
void probe() const { write_to_file(this->name(), this->probe_path); };
53+
};
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/fpga/devices/device.hpp>
13+
14+
class IpDevice : public Device {
15+
public:
16+
static IpDevice from(const std::filesystem::path unsafe_path);
17+
static bool is_path_valid(const std::filesystem::path unsafe_path);
18+
19+
private:
20+
IpDevice(const std::filesystem::path valid_path) : Device(valid_path){};
21+
22+
public:
23+
std::string ip_name() const;
24+
size_t addr() const;
25+
int iommu_group() const;
26+
};
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);

fpga/lib/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ set(SOURCES
1313
utils.cpp
1414
dma.cpp
1515

16+
devices/driver.cpp
17+
devices/ip_device.cpp
18+
devices/utils.cpp
19+
1620
ips/aurora_xilinx.cpp
1721
ips/aurora.cpp
1822
ips/bram.cpp

fpga/lib/devices/driver.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/fpga/devices/ip_device.hpp>
10+
#include <villas/fpga/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.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+
};

fpga/lib/devices/ip_device.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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/fpga/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+
}
54+
55+
int IpDevice::iommu_group() const {
56+
std::filesystem::path symlink =
57+
std::filesystem::path(this->path.u8string() + "/iommu_group");
58+
59+
std::filesystem::path link;
60+
link = std::filesystem::read_symlink(symlink);
61+
62+
std::string delimiter = "iommu_groups/";
63+
int pos = link.u8string().find(delimiter);
64+
int iommu_group = std::stoi(link.u8string().substr(pos + delimiter.length()));
65+
return iommu_group;
66+
}

fpga/lib/devices/utils.cpp

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/fpga/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)