#include #include #include 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; }