summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2021-05-27 22:03:26 +0300
committerAndreas Kling <kling@serenityos.org>2021-06-29 20:53:59 +0200
commit1baa05d6b22916c4cfdf9834dec554dd685e8a09 (patch)
tree433894366774b38041a6c21f37a270e275ab9d4f /Kernel
parent0259781402ddc2b7693d348db668156a49b2bd72 (diff)
downloadserenity-1baa05d6b22916c4cfdf9834dec554dd685e8a09.zip
Kernel/SysFS: Add PCI exposed folder
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/SysFS.cpp2
-rw-r--r--Kernel/PCI/Access.cpp88
-rw-r--r--Kernel/PCI/Access.h40
-rw-r--r--Kernel/PCI/Initializer.cpp2
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);
});