[lcrash] ADD: System bus subsystem
This commit is contained in:
parent
5f750e66d6
commit
516329d25c
@ -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
128
lcrash/driver/sysbus.c
Normal 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;
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user