diff options
author | Liav A <liavalb@gmail.com> | 2021-05-27 22:03:26 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-29 20:53:59 +0200 |
commit | 1baa05d6b22916c4cfdf9834dec554dd685e8a09 (patch) | |
tree | 433894366774b38041a6c21f37a270e275ab9d4f | |
parent | 0259781402ddc2b7693d348db668156a49b2bd72 (diff) | |
download | serenity-1baa05d6b22916c4cfdf9834dec554dd685e8a09.zip |
Kernel/SysFS: Add PCI exposed folder
-rw-r--r-- | Kernel/FileSystem/SysFS.cpp | 2 | ||||
-rw-r--r-- | Kernel/PCI/Access.cpp | 88 | ||||
-rw-r--r-- | Kernel/PCI/Access.h | 40 | ||||
-rw-r--r-- | Kernel/PCI/Initializer.cpp | 2 |
4 files changed, 128 insertions, 4 deletions
diff --git a/Kernel/FileSystem/SysFS.cpp b/Kernel/FileSystem/SysFS.cpp index 09cb9ec78d..23d189868a 100644 --- a/Kernel/FileSystem/SysFS.cpp +++ b/Kernel/FileSystem/SysFS.cpp @@ -13,7 +13,6 @@ namespace Kernel { -static InodeIndex s_next_inode_index; static AK::Singleton<SystemRegistrar> s_the; SystemRegistrar& SystemRegistrar::the() @@ -24,7 +23,6 @@ SystemRegistrar& SystemRegistrar::the() UNMAP_AFTER_INIT void SystemRegistrar::initialize() { VERIFY(!s_the.is_initialized()); - s_next_inode_index = 0; s_the.ensure_instance(); } diff --git a/Kernel/PCI/Access.cpp b/Kernel/PCI/Access.cpp index 54ddb65d38..0796dd0233 100644 --- a/Kernel/PCI/Access.cpp +++ b/Kernel/PCI/Access.cpp @@ -368,5 +368,93 @@ void Capability::write32(u32 field, u32 value) PCI::write32(m_address, m_ptr + field, value); } +UNMAP_AFTER_INIT NonnullRefPtr<ExposedDeviceFolder> ExposedDeviceFolder::create(const SystemExposedFolder& parent_folder, Address address) +{ + return adopt_ref(*new (nothrow) ExposedDeviceFolder(parent_folder, address)); +} + +UNMAP_AFTER_INIT ExposedDeviceFolder::ExposedDeviceFolder(const SystemExposedFolder& parent_folder, Address address) + : SystemExposedFolder(String::formatted("{:04x}:{:04x}:{:02x}.{}", address.seg(), address.bus(), address.device(), address.function()), parent_folder) +{ + m_components.append(ExposedAttribute::create("vendor", *this, PCI_VENDOR_ID, 2)); + m_components.append(ExposedAttribute::create("device_id", *this, PCI_DEVICE_ID, 2)); + m_components.append(ExposedAttribute::create("class", *this, PCI_CLASS, 1)); + m_components.append(ExposedAttribute::create("subclass", *this, PCI_SUBCLASS, 1)); + m_components.append(ExposedAttribute::create("revision", *this, PCI_REVISION_ID, 1)); + m_components.append(ExposedAttribute::create("progif", *this, PCI_PROG_IF, 1)); + m_components.append(ExposedAttribute::create("subsystem_vendor", *this, PCI_SUBSYSTEM_VENDOR_ID, 2)); + m_components.append(ExposedAttribute::create("subsystem_id", *this, PCI_SUBSYSTEM_ID, 2)); +} + +UNMAP_AFTER_INIT void BusExposedFolder::initialize() +{ + auto pci_folder = adopt_ref(*new (nothrow) BusExposedFolder()); + SystemRegistrar::the().register_new_component(pci_folder); +} + +UNMAP_AFTER_INIT BusExposedFolder::BusExposedFolder() + : SystemExposedFolder("pci", SystemRegistrar::the().root_folder()) +{ + PCI::enumerate([&](const Address& address, ID) { + auto pci_device = PCI::ExposedDeviceFolder::create(*this, address); + m_components.append(pci_device); + }); +} + +NonnullRefPtr<ExposedAttribute> ExposedAttribute::create(String name, const ExposedDeviceFolder& device, size_t offset, size_t field_bytes_width) +{ + return adopt_ref(*new (nothrow) ExposedAttribute(name, device, offset, field_bytes_width)); +} + +ExposedAttribute::ExposedAttribute(String name, const ExposedDeviceFolder& device, size_t offset, size_t field_bytes_width) + : SystemExposedComponent(name) + , m_device(device) + , m_offset(offset) + , m_field_bytes_width(field_bytes_width) +{ +} + +KResultOr<size_t> ExposedAttribute::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription*) const +{ + auto blob = try_to_generate_buffer(); + if (!blob) + return KResult(EFAULT); + + if ((size_t)offset >= blob->size()) + return KSuccess; + + ssize_t nread = min(static_cast<off_t>(blob->size() - offset), static_cast<off_t>(count)); + if (!buffer.write(blob->data() + offset, nread)) + return KResult(EFAULT); + return nread; +} + +size_t ExposedAttribute::size() const +{ + auto buffer = try_to_generate_buffer(); + if (!buffer) + return 0; + return buffer->size(); +} + +OwnPtr<KBuffer> ExposedAttribute::try_to_generate_buffer() const +{ + String value; + switch (m_field_bytes_width) { + case 1: + value = String::formatted("0x{:x}", PCI::read8(m_device->address(), m_offset)); + break; + case 2: + value = String::formatted("0x{:x}", PCI::read16(m_device->address(), m_offset)); + break; + case 4: + value = String::formatted("0x{:x}", PCI::read32(m_device->address(), m_offset)); + break; + default: + VERIFY_NOT_REACHED(); + } + + return KBuffer::try_create_with_bytes(value.substring_view(0).bytes()); +} } } diff --git a/Kernel/PCI/Access.h b/Kernel/PCI/Access.h index d2c12695c2..3b42db6fd7 100644 --- a/Kernel/PCI/Access.h +++ b/Kernel/PCI/Access.h @@ -9,11 +9,47 @@ #include <AK/Bitmap.h> #include <AK/String.h> #include <AK/Vector.h> +#include <Kernel/FileSystem/SysFS.h> #include <Kernel/PCI/Definitions.h> -namespace Kernel { +namespace Kernel::PCI { -class PCI::Access { +class BusExposedFolder final : public SystemExposedFolder { +public: + static void initialize(); + +private: + BusExposedFolder(); +}; + +class ExposedDeviceFolder final : public SystemExposedFolder { +public: + static NonnullRefPtr<ExposedDeviceFolder> create(const SystemExposedFolder&, Address); + const Address& address() const { return m_address; } + +private: + ExposedDeviceFolder(const SystemExposedFolder&, Address); + + Address m_address; +}; + +class ExposedAttribute : public SystemExposedComponent { +public: + static NonnullRefPtr<ExposedAttribute> create(String name, const ExposedDeviceFolder& device, size_t offset, size_t field_bytes_width); + + virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const override; + virtual ~ExposedAttribute() {}; + virtual size_t size() const override; + +protected: + virtual OwnPtr<KBuffer> try_to_generate_buffer() const; + ExposedAttribute(String name, const ExposedDeviceFolder& device, size_t offset, size_t field_bytes_width); + NonnullRefPtr<ExposedDeviceFolder> m_device; + size_t m_offset; + size_t m_field_bytes_width; +}; + +class Access { public: void enumerate(Function<void(Address, ID)>&) const; diff --git a/Kernel/PCI/Initializer.cpp b/Kernel/PCI/Initializer.cpp index f4074e90ce..338c6cfc81 100644 --- a/Kernel/PCI/Initializer.cpp +++ b/Kernel/PCI/Initializer.cpp @@ -51,6 +51,8 @@ UNMAP_AFTER_INIT void initialize() VERIFY_NOT_REACHED(); } + PCI::BusExposedFolder::initialize(); + PCI::enumerate([&](const Address& address, ID id) { dmesgln("{} {}", address, id); }); |