lindows/lcrash/driver/sysbus.c
2024-04-22 07:58:33 -04:00

127 lines
3.5 KiB
C

#include <lcrash/driver/sysbus.h>
#include <lcrash/debug/debug.h>
#include <lcrash/mm/kmalloc.h>
struct SysbusDeviceDescription* SysbusRootDeviceDescription = 0;
struct SysbusDevice* SysbusRootDevice = 0;
/**
* Create a new device description
*/
struct SysbusDeviceDescription* SysbusCreateDeviceDescriptionInternal() {
struct SysbusDeviceDescription* Description = KernelHeapAlloc(sizeof(struct SysbusDeviceDescription), 1, 0);
Description->DeviceName = 0;
Description->Instances = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 1, 0);
Description->InstanceCount = 0;
Description->InstanceSlots = 4;
Description->CreateDevice = 0;
Description->DeleteDevice = 0;
Description->GetCapability = 0;
return Description;
}
/**
* Attach a device to another device
*/
void SysbusAttachChildDeviceInternal(struct SysbusDevice* Parent, struct SysbusDevice* Child) {
// See if we need to grow the list
if (Parent->ChildCount >= Parent->ChildSlots) {
struct SysbusDevice** NewList = KernelHeapAlloc(sizeof(struct SysbusDevice*) * Parent->ChildSlots * 2, 1, 0);
for (int i = 0; i < Parent->ChildCount; i++) {
NewList[i] = Parent->Children[i];
}
KernelHeapFree(Parent->Children);
Parent->Children = NewList;
Parent->ChildSlots *= 2;
}
// Add the child
Parent->Children[Parent->ChildCount++] = Child;
return;
}
/**
* Create a new device
*
* \param Description device description
* \param Parent parent device
* \param DeviceData device specific data
* \param IsRootDevice device has no parent
*/
struct SysbusDevice* SysbusCreateDeviceInternal(
struct SysbusDeviceDescription* Description,
struct SysbusDevice* Parent,
void* DeviceData,
bool IsRootDevice
) {
struct SysbusDevice* Device = KernelHeapAlloc(sizeof(struct SysbusDevice), 1, 0);
Device->DeviceDescription = Description;
Device->DeviceName = 0;
Device->DeviceData = 0;
Device->Parent = Parent;
Device->Children = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 1, 0);
Device->ChildCount = 0;
Device->ChildSlots = 4;
// Attach to parent
if (Parent != NULL) SysbusAttachChildDeviceInternal(Parent, Device);
// See if we need to grow the instance list
if (Description->InstanceCount >= Description->InstanceSlots) {
struct SysbusDevice** NewList = KernelHeapAlloc(sizeof(struct SysbusDevice*) * Description->InstanceSlots * 2, 1, 0);
for (int i = 0; i < Description->InstanceCount; i++) {
NewList[i] = Description->Instances[i];
}
KernelHeapFree(Description->Instances);
Description->Instances = NewList;
Description->InstanceSlots *= 2;
}
// Add us as an instance
Description->Instances[Description->InstanceCount++] = Device;
return Device;
}
struct SysbusDeviceDescription* SysbusCreateDeviceDescription() {
return SysbusCreateDeviceDescriptionInternal();
}
void SysbusDeleteDeviceDescription(struct SysbusDeviceDescription* Description) {
Panic("todo");
}
struct SysbusDevice* SysbusCreateDevice(
struct SysbusDeviceDescription* Description,
struct SysbusDevice* Parent,
void* Data
) {
return SysbusCreateDeviceInternal(Description, Parent, Data, false);
}
void SysbusDeleteDevice(struct SysbusDevice* Device) {
Panic("todo");
}
void SysbusInitialize() {
// Create the sysbus root
SysbusRootDeviceDescription = SysbusCreateDeviceDescriptionInternal();
SysbusRootDeviceDescription->DeviceName = "Lcrash System Bus";
SysbusRootDevice = SysbusCreateDeviceInternal(
SysbusRootDeviceDescription,
NULL,
NULL,
true
);
SysbusRootDevice->DeviceName = "Lcrash System Bus";
return;
}