diff --git a/common/include/villas/kernel/devices/platform_device.hpp b/common/include/villas/kernel/devices/platform_device.hpp new file mode 100644 index 000000000..4cef2ceb4 --- /dev/null +++ b/common/include/villas/kernel/devices/platform_device.hpp @@ -0,0 +1,52 @@ +/* Platform Device + * + * Author: Pascal Bauer + * + * SPDX-FileCopyrightText: 2023-2024 Pascal Bauer + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include + +namespace villas { +namespace kernel { +namespace devices { + +class PlatformDevice : public Device { +private: + static constexpr char PROBE_DEFAULT[] = "/sys/bus/platform/drivers_probe"; + static constexpr char OVERRIDE_DEFAULT[] = "driver_override"; + +private: + const std::filesystem::path m_path; + const std::filesystem::path m_probe_path; + const std::filesystem::path m_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) + : m_path(path), m_probe_path(probe_path), + m_override_path(override_path){}; + + // Implement device interface + std::optional> driver() const override; + std::optional iommu_group() const override; + std::string name() const override; + std::filesystem::path override_path() const override; + std::filesystem::path path() const override; + void probe() const override; +}; + +} // namespace devices +} // namespace kernel +} // namespace villas \ No newline at end of file diff --git a/common/lib/kernel/devices/platform_device.cpp b/common/lib/kernel/devices/platform_device.cpp new file mode 100644 index 000000000..28b6c4796 --- /dev/null +++ b/common/lib/kernel/devices/platform_device.cpp @@ -0,0 +1,54 @@ +/* Platform Device + * + * Author: Pascal Bauer + * + * SPDX-FileCopyrightText: 2023-2024 Pascal Bauer + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +using villas::kernel::devices::Driver, villas::kernel::devices::GenericDriver; +using villas::kernel::devices::PlatformDevice; +using villas::kernel::devices::utils::write_to_file; + +std::optional> PlatformDevice::driver() const { + std::filesystem::path driver_symlink = + this->m_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 std::make_optional(std::make_unique(driver_path)); +} + +std::optional PlatformDevice::iommu_group() const { + std::filesystem::path symlink = + std::filesystem::path(this->m_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 std::make_optional(iommu_group); +} + +std::filesystem::path PlatformDevice::path() const { return this->m_path; }; + +void PlatformDevice::probe() const { + write_to_file(this->name(), this->m_probe_path); +} + +std::filesystem::path PlatformDevice::override_path() const { + return this->m_override_path; +} + +std::string PlatformDevice::name() const { + size_t pos = this->m_path.u8string().rfind('/'); + return this->m_path.u8string().substr(pos + 1); +} \ No newline at end of file