2#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
5#include "pedigree/kernel/BootstrapInfo.h"
6#include "pedigree/kernel/machine/Device.h"
7#include "pedigree/kernel/machine/Disk.h"
8#include "pedigree/kernel/utilities/utility.h"
10#include "DevFs-block.h"
13#include "modules/system/network-stack/NetworkStack.h"
14#include "modules/system/vfs/Symlink.h"
15#include "modules/system/vfs/VFS.h"
18class AttributeFile final :
public File {
22 :
File(name, 0, 0, 0, inode, filesystem, contents.length(), parent), m_Contents(contents) {
28 uint64_t
readBytewise(uint64_t offset, uint64_t size, uintptr_t buffer,
bool)
override {
29 if (offset >= m_Contents.length())
31 size = min(size, m_Contents.length() - offset);
32 MemoryCopy(
reinterpret_cast<void*
>(buffer), m_Contents.cstr() + offset, size);
35 uint64_t
writeBytewise(uint64_t, uint64_t, uintptr_t,
bool)
override {
38 size_t getSize()
override {
39 return m_Contents.length();
49class SysFsLink final :
public Symlink {
53 :
Symlink(name, 0, 0, 0, inode, filesystem, target.length(), parent) {
55 setPermissions(FILE_UR | FILE_UW | FILE_UX | FILE_GR | FILE_GW | FILE_GX | FILE_OR | FILE_OW |
60struct NetworkSnapshot {
61 struct netif*
interface = nullptr;
67 unsigned macLength = 0;
71void snapshotNetwork(
void* context) {
72 auto& snapshot = *
static_cast<NetworkSnapshot*
>(context);
73 auto*
interface = snapshot.interface;
74 MemoryCopy(snapshot.name, interface->name,
sizeof(snapshot.name));
75 snapshot.number = interface->num;
76 snapshot.mtu = interface->mtu;
79 snapshot.macLength = min(
static_cast<unsigned>(interface->hwaddr_len),
80 static_cast<unsigned>(
sizeof(snapshot.mac)));
81 MemoryCopy(snapshot.mac, interface->hwaddr, snapshot.macLength);
90 ERROR(
"SysFs: root directory did not get cleaned up");
94 static String label(
"sysfs");
102 parent->addEntry(result->getName(), result);
107 auto* file =
new AttributeFile(
String(name), allocateInode(),
this, parent, contents);
109 parent->addEntry(file->getName(), file);
113 auto* link =
new SysFsLink(
String(name), allocateInode(),
this, parent, target);
115 parent->addEntry(link->getName(), link);
121 const uint16_t vendor = device->getPciVendorId();
122 if (!vendor || vendor == 0xffff)
125 name.Format(
"0000:%02x:%02x.%x", device->getPciBusPosition(), device->getPciDevicePosition(),
126 device->getPciFunctionNumber());
127 auto* entry = directory(devices, name.cstr());
131 value.Format(
"0x%04x\n", vendor);
132 attribute(entry,
"vendor", value);
133 value.Format(
"0x%04x\n", device->getPciDeviceId());
134 attribute(entry,
"device", value);
135 value.Format(
"0x%02x%02x%02x\n", device->getPciClassCode(), device->getPciSubclassCode(),
136 device->getPciProgInterface());
137 attribute(entry,
"class", value);
138 value.Format(
"%lu\n", device->getInterruptNumber());
139 attribute(entry,
"irq", value);
141 for (
auto* address : device->addresses()) {
142 const uintptr_t end =
143 address->m_Size ? address->m_Address + address->m_Size - 1 : address->m_Address;
145 line.Format(
"0x%016lx 0x%016lx 0x%016lx\n", address->m_Address, end,
146 address->m_IsIoSpace ? 1UL : 0UL);
149 attribute(entry,
"resource", resources);
152 auto callback = pedigree_std::make_callable(add);
160 auto* disk =
static_cast<Disk*
>(device);
161 const uint32_t
id = disk->endpointId();
165 name.Format(
"disk%u",
id);
166 auto* entry = directory(devices, name.cstr());
170 value.Format(
"%u:%u\n", PosixBlock::PhysicalMajor,
id);
171 attribute(entry,
"dev", value);
172 value.Format(
"%lu\n", disk->getSize() / 512);
173 attribute(entry,
"size", value);
174 attribute(entry,
"removable",
String(
"0\n"));
177 auto callback = pedigree_std::make_callable(add);
182 auto* stack = NetworkStack::instanceIfAvailable();
185 for (
size_t index = 0;; ++index) {
187 if (!stack->acquireDevice(index, device))
189 NetworkSnapshot snapshot;
190 snapshot.interface = device.interface();
194 name.Format(
"%c%c%u", snapshot.name[0], snapshot.name[1], snapshot.number);
195 auto* entry = directory(devices, name.cstr());
199 for (
unsigned i = 0; i < snapshot.macLength; ++i) {
201 octet.Format(
"%s%02x", i ?
":" :
"", snapshot.mac[i]);
205 attribute(entry,
"address", value);
206 value.Format(
"%u\n", snapshot.mtu);
207 attribute(entry,
"mtu", value);
208 attribute(entry,
"operstate",
String(snapshot.up && snapshot.link ?
"up\n" :
"down\n"));
220 auto* classDirectory = directory(m_Root,
"class");
221 auto* block = classDirectory ? directory(classDirectory,
"block") :
nullptr;
222 auto* network = classDirectory ? directory(classDirectory,
"net") :
nullptr;
223 auto* input = classDirectory ? directory(classDirectory,
"input") :
nullptr;
224 auto* graphics = classDirectory ? directory(classDirectory,
"graphics") :
nullptr;
225 auto* framebuffer = graphics ? directory(graphics,
"fb0") :
nullptr;
226 auto* framebufferDevice = framebuffer ? directory(framebuffer,
"device") :
nullptr;
227 auto* bus = directory(m_Root,
"bus");
228 auto* pci = bus ? directory(bus,
"pci") :
nullptr;
229 auto* pciDevices = pci ? directory(pci,
"devices") :
nullptr;
230 auto* platform = bus ? directory(bus,
"platform") :
nullptr;
231 auto* firmware = directory(m_Root,
"firmware");
232 if (!block || !network || !input || !framebufferDevice || !pciDevices || !platform || !firmware) {
236 auto* keyboard = directory(input,
"event0");
237 auto* keyboardDevice = keyboard ? directory(keyboard,
"device") :
nullptr;
238 auto* pointer = directory(input,
"event1");
239 auto* pointerDevice = pointer ? directory(pointer,
"device") :
nullptr;
240 if (!keyboardDevice || !pointerDevice) {
243 attribute(keyboard,
"dev",
String(
"13:64\n"));
244 attribute(keyboardDevice,
"name",
String(
"Pedigree keyboard\n"));
245 attribute(pointer,
"dev",
String(
"13:65\n"));
246 attribute(pointerDevice,
"name",
String(
"Pedigree pointer\n"));
248 symlink(framebufferDevice,
"subsystem",
String(
"/sys/bus/platform"));
250 addBlockDevices(block);
251 addNetworkDevices(network);
252 addPciDevices(pciDevices);
253 if (g_pBootstrapInfo && g_pBootstrapInfo->isUefi() && !directory(firmware,
"efi"))
static void foreach(Callback callback, Device *root=0)
@ Disk
A disk device - a block device in UNIX terms.
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual bool isBytewise() const
void setGidOnly(size_t gid)
void setPermissionsOnly(uint32_t perms)
void setUidOnly(size_t uid)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
bool initialise(Disk *) override
const String & getVolumeLabel() const override
void trackFile(File *pFile)
Track a File object that exists. It is necessary to keep track of File objects, or at least those tha...
#define netif_is_up(netif)
#define netif_is_link_up(netif)
#define NETIF_MAX_HWADDR_LEN
err_t tcpip_callback_wait(tcpip_callback_fn function, void *ctx)