127 lines
3.5 KiB
C
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;
|
|
}
|