#pragma once /** * The lcrash system bus is a root device which manages all other associated devices, and handles bookkeeping for other subsystems (e.g. classifying devices) * The system bus supports device names to aid debuggers, however these names are otherwise meaningless and pointers to structures should be used instead * * Example device tree: * /SYSBUS * /PCI * /PCI0000:00:00.0 * $ETHERNET * /PCI0000:00:00.1 * $FRAMEBUF * $TEXTBUF * /ACPI:0 * $BATTERY * /ACPI:1 * $SERIAL * /COM:0 * $SERIAL * /COM:1 * $SERIAL * * Device capabilities provide a way for devices to expose functionality without writing device specific code, a capability is defined by the following structure * struct SysbusDeviceCapability { * // Name of the device capability * const char* CapabilityName; * }; * * Devices types are defined by the following structure: * struct SysbusDeviceDescription { * // Name of the device type * const char* DeviceName; * * // == Instance Management == * // List of device instances * struct SysbusDevice** Instances; * * // Device initialization code, returns 0 if ok * int (*CreateDevice)(struct SysbusDevice* Device, void* Data); * * // Cleanup code for before a device is deleted, returns 0 if ok * int (*DeleteDevice)(struct SysbusDevice* Device); * * // == Capablities == * // Returns a capability specific structure if a capability is present, otherwise returns NULL * void* (*GetCapability)(struct SysbusDevice* Device, struct SysbusDeviceCapability* Capability); * }; * * Devices are stored in the following structure: * struct SysbusDevice { * // Pointer to the device type structure * const struct SysbusDeviceDescription* DeviceDescription; * * // Name of the device * const char* DeviceName; * * // Device specific data * void* DeviceData; * * // Child devices * struct SysbusDevice** Children; * }; * * Drivers can define a new device type by calling `struct SysbusDeviceDescription* SysbusCreateDeviceDescription()` which * Allocates and returns a device description structure * * Drivers must free device types with `void SysbusDeleteDeviceDescription(struct SysbusDeviceDescription* DESCRIPTION)` which * Deletes a DESCRIPTION's instances * Deallocates a device DESCRIPTION structure * * Drivers can create a new device by calling `struct SysbusDevice* SysbusCreateDevice(struct SysbusDeviceDescription* DESCRIPTION, void* DATA)` which * DEVICE = Allocate a device structure * Initializes it by calling DESCRIPTION::CreateDevice(DEVICE, DATA) * if ok then * Adds the DEVICE to the DESCRIPTION's instance list * Returns the DEVICE * otherwise returns NULL * * Drivers must free devices with `void SysbusDeleteDevice(struct SysbusDevice* DEVICE)` which * Uninitializes the DEVICE by calling DEVICE::DeviceDescription::DeleteDevice(DEVICE) * Removes the DEVICE from the DEVICE::DeviceDescription's instance list * Deallocates the DEVICE */