[lcrash] ADD: System bus subsystem

This commit is contained in:
xwashere 2024-04-19 13:02:34 -04:00
parent 5f750e66d6
commit 516329d25c
Signed by: XWasHere
GPG Key ID: 042F8BFA1B0EF93B
5 changed files with 238 additions and 2 deletions

View File

@ -8,7 +8,7 @@ lw_project(lcrash
enable_language(ASM) enable_language(ASM)
lw_add_executable(lcrashkern lw_add_executable(lcrashkern
SOURCES main.c cmdline.c util.c lnxboot.c math.c debug/debug.c acpi/acpi.c efi/efi.c efi/guid.c efi/memmap.c gdb/gdb.c pci/pci.c mm/phys.c mm/kmalloc.c SOURCES main.c cmdline.c util.c lnxboot.c math.c debug/debug.c acpi/acpi.c efi/efi.c efi/guid.c efi/memmap.c gdb/gdb.c pci/pci.c mm/phys.c mm/kmalloc.c driver/sysbus.c
) )
add_executable(lcrashkernld IMPORTED) add_executable(lcrashkernld IMPORTED)
set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)

128
lcrash/driver/sysbus.c Normal file
View File

@ -0,0 +1,128 @@
#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), 0);
Description->DeviceName = 0;
Description->Instances = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 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, 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), 0);
Device->DeviceDescription = Description;
Device->DeviceName = 0;
Device->DeviceData = 0;
Device->Parent = Parent;
Device->Children = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 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, 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";
Panic("Failed to initialize system bus");
return;
}

View File

@ -82,3 +82,105 @@
* Removes the DEVICE from the DEVICE::DeviceDescription's instance list * Removes the DEVICE from the DEVICE::DeviceDescription's instance list
* Deallocates the DEVICE * Deallocates the DEVICE
*/ */
#include <lcrash/types.h>
/**
* Structure that describes a specific device capablility
*/
struct SysbusDeviceCapability {
// Name of the device capability
const char* CapabilityName;
};
/**
* Structure that describes a device and allows them to hook the sysbus subsystem
*/
struct SysbusDeviceDescription {
/// Device name, this is only used for debugging
const c8* DeviceName;
/// List of device instances
/// Do not hold pointers to this list
/// Managed by the sysbus subsystem. DRIVERS, DO NOT MODIFY THIS LIST.
struct SysbusDevice** Instances;
/// Number of instances
/// Managed by the sysbus subsystem. DO NOT MODIFY THIS.
u32 InstanceCount;
/// Instance array length
/// Managed by the sysbus subsysyem. DO NOT MODIFY THIS.
/// \internal
u32 InstanceSlots;
/// Called by the sysbus subsystem when a device is created, use this to initialize a device
/// \returns 0 on success
s32 (*CreateDevice)(struct SysbusDevice*, void*);
/// Called by the sysbus subsystem when a device is deleted, use this to deinitialize a device
/// \returns 0 on success
s32 (*DeleteDevice)(struct SysbusDevice* Device);
/// Returns a capability specific structure if a capability is present, otherwise returns NULL
void* (*GetCapability)(struct SysbusDevice* Device, struct SysbusDeviceCapability* Capability);
};
/**
* Structure that describes an instace of a specific device
*/
struct SysbusDevice {
/// Pointer to the device type structure
const struct SysbusDeviceDescription* DeviceDescription;
/// Name of the device
const c8* DeviceName;
/// Device specific data
void* DeviceData;
/// Parent device
/// Managed by the sysbus subsystem. DO NOT MODIFY THIS.
struct SysbusDevice* Parent;
/// Child devices
/// Managed by the sysbus subsystem. DRIVERS, DO NOT MODIFY THIS LIST
/// Do not hold pointers to this list, it may be moved or resized as needed
struct SysbusDevice** Children;
/// Number of children
/// Managed by the sysbus subsystem. DO NOT MODIFY THIS.
u32 ChildCount;
/// Child array length
/// Managed by the sysbus subsysyem. DO NOT MODIFY THIS.
/// \internal
u32 ChildSlots;
};
/// Initialize the sysbus subsystem
void SysbusInitialize();
/**
* Create and return a sysbus device description
*/
struct SysbusDeviceDescription* SysbusCreateDeviceDescription();
/**
* Delete a sysbus device description
*/
void SysbusDeleteDeviceDescription(struct SysbusDeviceDescription* Description);
/**
* Create a new device
*/
struct SysbusDevice* SysbusCreateDevice(
struct SysbusDeviceDescription* Description,
struct SysbusDevice* Parent,
void* Data
);
/**
* Delete a device
*/
void SysbusDeleteDevice(struct SysbusDevice* Device);

View File

@ -7,6 +7,7 @@
#include <lcrash/mm/kmalloc.h> #include <lcrash/mm/kmalloc.h>
#include <lcrash/cmdline.h> #include <lcrash/cmdline.h>
#include <lcrash/debug/debug.h> #include <lcrash/debug/debug.h>
#include <lcrash/driver/sysbus.h>
#include "types.h" #include "types.h"
#include "lnxboot.h" #include "lnxboot.h"
@ -37,6 +38,9 @@ void entry64(struct boot_params* BootParams) {
// Initialize the extended debugging information block // Initialize the extended debugging information block
if (DebugInitialize()) while (1) {} if (DebugInitialize()) while (1) {}
// Initialize the system bus
SysbusInitialize();
// Initialize EFI code if we had EFI // Initialize EFI code if we had EFI
EfiInitialize(); EfiInitialize();

View File

@ -1,5 +1,7 @@
#include <lcrash/pci/pci.h> #include <lcrash/pci/pci.h>
#include <lcrash/acpi/acpi.h> #include <lcrash/acpi/acpi.h>
#include <lcrash/debug/debug.h>
bool PciIsPresent = false; bool PciIsPresent = false;
bool PciSupportsECM = false; bool PciSupportsECM = false;
@ -15,7 +17,7 @@ void PciInitialize() {
while (1) {} while (1) {}
} }
nopcie: while (1) {} nopcie: Panic("Failed to initialize PCI");
return; return;
} }