feature (PCI): implemented a BASIC pci device manager

This commit is contained in:
antifallobst 2023-04-25 23:03:03 +02:00
parent f8b70e4469
commit 203a8c2049
3 changed files with 84 additions and 19 deletions

View File

@ -230,8 +230,25 @@ typedef struct {
uint8_t max_latency;
} __attribute__((packed)) pci_header_0_T;
void pci_init ();
string_t pci_get_subclass_string (pci_class_E class, uint8_t subclass);
string_t pci_get_vendor_string (uint16_t vendor_id);
typedef struct pci_device_T pci_device_T;
struct pci_device_T {
pci_device_header_T* header;
pci_device_T* prev;
pci_device_T* next;
};
typedef struct {
pci_device_T* devices;
} pci_manager_T;
void pci_init ();
void pci_manager_add_device (pci_device_header_T* header);
void pci_manager_remove_device (pci_device_T* device);
pci_device_T* pci_manager_find_device (pci_class_E class, uint8_t subclass, uint8_t progif);
void pci_manager_dump_devices ();
string_t pci_get_subclass_string (pci_class_E class, uint8_t subclass);
string_t pci_get_vendor_string (uint16_t vendor_id);
#endif // NOXOS_PCI_H

View File

@ -60,20 +60,7 @@ void kmain(boot_info_T boot_info) {
log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n");
vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.elf");
void* buffer = memory_allocate(node->size);
vfs_file_read(node, 0, node->size, buffer);
elf_executable_T* exec = elf_executable_create(buffer);
pid_t process = process_spawn(PROCESS_KERNEL, "test 1", exec, buffer);
void* func = (void*)symbol_resolve_from_name(scheduler_get_process(process)->executable->symbols,
scheduler_get_process(process)->executable->num_symbols,
"_start")->address + MEM_REGION_PROCESS_EXEC;
thread_start(thread_spawn(process, func));
scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0);
pci_device_T* ahci_controller = pci_manager_find_device(PCI_CLASS_MASS_STORAGE_CONTROLLER, PCI_SUBCLASS_SERIAL_ATA_CONTROLLER, 1);
CORE_HALT_FOREVER
}

View File

@ -5,6 +5,9 @@
#include "drivers/acpi/mcfg.h"
#include "mm/page_map.h"
#include "utils/logger.h"
#include "utils/memory.h"
pci_manager_T* g_pci_manager;
string_t pci_get_subclass_string(pci_class_E class, uint8_t subclass) {
switch (class) {
@ -248,8 +251,7 @@ void pci_enumerate_function(void* device_address, uint8_t function) {
pci_device_header_T* device_header = (pci_device_header_T*)function_address;
if (device_header->device_id == 0 || device_header->device_id == 0xFFFF) return;
log(LOG_DEBUG, "<PCI> Found %s - %s - %xw:%xw", pci_get_subclass_string(device_header->main_class, device_header->subclass),
pci_get_vendor_string(device_header->vendor_id), device_header->vendor_id, device_header->device_id);
pci_manager_add_device(device_header);
}
void pci_enumerate_device(void* bus_address, uint8_t device) {
@ -277,6 +279,11 @@ void pci_enumerate_bus(void* base, uint8_t bus) {
}
void pci_init() {
g_pci_manager = memory_allocate(sizeof(pci_manager_T));
g_pci_manager->devices = NULL;
// enumerate devices
uint32_t num_configs = (g_acpi_table_mcfg->header.length - sizeof(acpi_mcfg_T)) / sizeof(acpi_mcfg_device_config_T);
acpi_mcfg_device_config_T* configs = (acpi_mcfg_device_config_T*)(&g_acpi_table_mcfg[1]);
@ -287,4 +294,58 @@ void pci_init() {
pci_enumerate_bus((void*)config->base, bus);
}
}
pci_manager_dump_devices();
}
void pci_manager_add_device(pci_device_header_T* header) {
pci_device_T* device = memory_allocate(sizeof(pci_device_T));
device->header = header;
// link in front of list
device->prev = NULL;
device->next = g_pci_manager->devices;
g_pci_manager->devices = device;
if (device->next != NULL) {
device->next->prev = device;
}
}
void pci_manager_remove_device(pci_device_T* device) {
if (device->prev != NULL) {
device->prev->next = device->next;
}
if (device->next != NULL) {
device->next->prev = device->prev;
}
memory_free(device);
}
pci_device_T* pci_manager_find_device(pci_class_E class, uint8_t subclass, uint8_t progif) {
pci_device_T* device = g_pci_manager->devices;
while (device != NULL) {
if (device->header->main_class != class || device->header->subclass != subclass || device->header->progif != progif) {
device = device->next;
continue;
}
return device;
}
log(LOG_WARNING, "<PCI> %s with progif 0x%xb not found!", pci_get_subclass_string(class, subclass), progif);
return NULL;
}
void pci_manager_dump_devices() {
log(LOG_DEBUG, "<PCI> Devices:");
pci_device_T* device = g_pci_manager->devices;
while (device != NULL) {
log(LOG_DEBUG, " %s - %s - %xw:%xw",
pci_get_subclass_string(device->header->main_class, device->header->subclass),
pci_get_vendor_string(device->header->vendor_id), device->header->vendor_id, device->header->device_id);
device = device->next;
}
}