feature (PCI): implemented basic PCI enumerating

This commit is contained in:
antifallobst 2023-04-25 17:13:09 +02:00
parent a904ffaaad
commit da46a78219
9 changed files with 157 additions and 16 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
build
cmake-build-debug
noxos.log
*.img # For test disk images

View File

@ -26,8 +26,6 @@ typedef struct {
uint64_t address;
} __attribute__((packed)) acpi_gas_T;
extern acpi_sdt_header_T *g_mcfg_table;
void acpi_init (boot_info_T* boot_info);
acpi_sdt_header_T* acpi_find_table (acpi_sdt_header_T* xsdt, string_t table_id);

23
inc/drivers/acpi/mcfg.h Normal file
View File

@ -0,0 +1,23 @@
// This file is part of noxos and licensed under the MIT open source license
#ifndef NOXOS_MCFG_H
#define NOXOS_MCFG_H
#include "drivers/acpi/acpi.h"
typedef struct {
acpi_sdt_header_T header;
uint64_t reserved;
} __attribute__((packed)) acpi_mcfg_T;
typedef struct {
uint64_t base;
uint16_t pci_segment_group;
uint8_t pci_start_bus;
uint8_t pci_end_bus;
uint32_t reserved;
} __attribute__((packed)) acpi_mcfg_device_config_T;
extern acpi_mcfg_T* g_acpi_table_mcfg;
#endif //NOXOS_MCFG_H

View File

@ -1,7 +1,48 @@
// This file is part of noxos and licensed under the MIT open source license
#ifndef NOXOS_PCI_H
#define NOXOS_PCI_H
#include "utils/stdtypes.h"
#include "utils/string.h"
typedef struct {
uint16_t vendor_id;
uint16_t device_id;
uint16_t command_reg;
uint16_t status_reg;
uint8_t revision_id;
uint8_t progif; // Programming Interface Byte
uint8_t subclass;
uint8_t main_class;
uint8_t cache_line_size;
uint8_t latency_timer;
uint8_t header_type;
uint8_t bist; // Built-in Self-Test
} __attribute__((packed)) pci_device_header_T;
#endif
typedef struct {
pci_device_header_T header;
uint32_t bar0;
uint32_t bar1;
uint32_t bar2;
uint32_t bar3;
uint32_t bar4;
uint32_t bar5;
uint32_t cardbus_cis_pointer;
uint16_t subsystem_vendor_id;
uint16_t subsystem_id;
uint32_t expansion_rom_base_address;
uint8_t capabilities;
uint8_t reserved[7];
uint8_t interrupt_line;
uint8_t interrupt_pin;
uint8_t min_grant;
uint8_t max_latency;
} __attribute__((packed)) pci_header_0_T;
void pci_init ();
string_t pci_get_vendor_string (uint16_t vendor_id);
string_t pci_get_device_string (uint16_t device_id);
#endif // NOXOS_PCI_H

9
run.sh
View File

@ -1,11 +1,10 @@
#!/bin/bash
# This file is part of noxos and licensed under the MIT open source license
EMUFLAGS="-no-reboot -m 256M -cdrom build/noxos.iso -chardev stdio,id=log,logfile=noxos.log -serial chardev:log -drive id=disk,file=test_disk.img,if=none \
-device ahci,id=disk \
-device ide-hd,drive=disk
"
EMUFLAGS="-no-reboot -machine q35 -cpu qemu64 -m 256M \
-drive file=build/noxos.iso,id=disk \
-drive file=fat:rw:ramdisk \
-chardev stdio,id=log,logfile=noxos.log -serial chardev:log"
emulate_bios() {
echo "<=====| Emulating |=====>"

View File

@ -13,6 +13,7 @@
#include "drivers/graphics/renderer.h"
#include "drivers/fs/vfs.h"
#include "drivers/acpi/acpi.h"
#include "drivers/pci.h"
//#include "drivers/ps2/keyboard.h"
#include "proc/scheduler.h"
@ -43,6 +44,8 @@ void kernel_init(boot_info_T* boot_info) {
acpi_init(boot_info);
pci_init();
// ps2_keyboard_init();
scheduler_init(boot_info);

View File

@ -3,12 +3,13 @@
#include "drivers/acpi/acpi.h"
#include "drivers/acpi/rsdp.h"
#include "drivers/acpi/fadt.h"
#include "drivers/acpi/mcfg.h"
#include "utils/logger.h"
#include "utils/memory.h"
#include "utils/panic.h"
acpi_sdt_header_T *g_mcfg_table;
acpi_fadt_T* g_acpi_table_fadt;
acpi_mcfg_T* g_acpi_table_mcfg;
void acpi_init(boot_info_T* boot_info) {
log(LOG_INFO, "Initializing ACPI - RSDP: 0x%x", boot_info->rsdp);
@ -27,12 +28,21 @@ void acpi_init(boot_info_T* boot_info) {
if (!rsdp_descriptor_v2_verify(boot_info->rsdp)) {
log(LOG_WARNING, "<ACPI> RSDP header verification failed");
}
g_acpi_table_fadt = (acpi_fadt_T*)acpi_find_table((acpi_sdt_header_T*)((rsdp_descriptor_v2_T*)boot_info->rsdp)->xsdt_address, "FACP");
acpi_sdt_header_T* xsdt = ((rsdp_descriptor_v2_T*)boot_info->rsdp)->xsdt_address;
g_acpi_table_fadt = (acpi_fadt_T*)acpi_find_table(xsdt, "FACP");
if (g_acpi_table_fadt == NULL) {
panic(NULL, "<ACPI> FADT table not found");
}
log(LOG_INFO, "<ACPI> found FADT at address 0x%x", g_acpi_table_fadt);
g_acpi_table_mcfg = (acpi_mcfg_T*)acpi_find_table(xsdt, "MCFG");
if (g_acpi_table_mcfg == NULL) {
panic(NULL, "<ACPI> MCFG table not found");
}
log(LOG_INFO, "<ACPI> found MCFG at address 0x%x", g_acpi_table_mcfg);
break;
}
default: {
@ -40,8 +50,6 @@ void acpi_init(boot_info_T* boot_info) {
break;
}
}
g_mcfg_table = acpi_find_table((acpi_sdt_header_T*)((rsdp_descriptor_v2_T*)boot_info->rsdp)->xsdt_address, "MCFG");
}
acpi_sdt_header_T* acpi_find_table(acpi_sdt_header_T* xsdt, string_t table_id) {
@ -54,6 +62,6 @@ acpi_sdt_header_T* acpi_find_table(acpi_sdt_header_T* xsdt, string_t table_id) {
if (!memory_compare(sdt->signature, (void*)table_id, 4)) continue;
return sdt;
}
log(LOG_WARNING, "<ACPI> table '%.4' not found (no matching xsdt entry)");
log(LOG_WARNING, "<ACPI> table '%.4s' not found (no matching xsdt entry)", table_id);
return NULL;
}

View File

@ -1,3 +1,72 @@
#include <drivers/pci.h>
// This file is part of noxos and licensed under the MIT open source license
#include "drivers/pci.h"
#include "drivers/acpi/acpi.h"
#include "drivers/acpi/mcfg.h"
#include "mm/page_map.h"
#include "utils/logger.h"
string_t pci_get_vendor_string(uint16_t vendor_id) {
switch (vendor_id) {
case 0x1234: return "QEMU";
case 0x8086: return "Intel";
default: return "Unknown";
}
}
string_t pci_get_device_string(uint16_t device_id) {
switch (device_id) {
case 0x1111: return "Bochs Graphics Adaptor";
case 0x29C0: return "Express DRAM Controller";
default: return "Unknown";
}
}
void pci_enumerate_function(void* device_address, uint8_t function) {
void* function_address = (void*)((uint64_t)device_address + (function << 12));
page_map_map_memory(g_kernel_page_map, function_address, function_address, PM_FLAG_READ_WRITE);
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, " Vendor ID: 0x%xw - %s", device_header->vendor_id, pci_get_vendor_string(device_header->vendor_id));
log(LOG_DEBUG, " Device ID: 0x%xw - %s", device_header->device_id, pci_get_device_string(device_header->device_id));
log(LOG_DEBUG, "<PCI> Found device CLASS[0x%xb] SUBCLASS[0x%xb] PROGIF[0x%xb]", device_header->main_class, device_header->subclass, device_header->progif);
}
void pci_enumerate_device(void* bus_address, uint8_t device) {
void* device_address = (void*)((uint64_t)bus_address + (device << 15));
page_map_map_memory(g_kernel_page_map, device_address, device_address, PM_FLAG_READ_WRITE);
pci_device_header_T* device_header = (pci_device_header_T*)device_address;
if (device_header->device_id == 0 || device_header->device_id == 0xFFFF) return;
for (uint8_t function = 0; function < 8; function++) {
pci_enumerate_function(device_address, function);
}
}
void pci_enumerate_bus(void* base, uint8_t bus) {
void* bus_address = (void*)((uint64_t)base + (bus << 20));
page_map_map_memory(g_kernel_page_map, bus_address, bus_address, PM_FLAG_READ_WRITE);
pci_device_header_T* device_header = (pci_device_header_T*)bus_address;
if (device_header->device_id == 0 || device_header->device_id == 0xFFFF) return;
for (uint8_t device = 0; device < 32; device++) {
pci_enumerate_device(bus_address, device);
}
}
void pci_init() {
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]);
for (uint32_t i = 0; i < num_configs; i++) {
acpi_mcfg_device_config_T* config = &configs[i];
for (uint8_t bus = config->pci_start_bus; bus < config->pci_end_bus; bus++) {
pci_enumerate_bus((void*)config->base, bus);
}
}
}

View File

@ -57,6 +57,7 @@ void page_map_map_memory(page_map_T* page_map, void* virtual_address, void* phys
page_map_T* page_table = page_map_request_entry(page_directory, page_table_index);
uint64_t* page = &page_table->entries[page_index];
*page = 0;
page_map_entry_set_address(page, (void*)((uint64_t)physical_address >> 12));
page_map_entry_set_flags(page, PM_FLAG_PRESENT | flags);
}