feature (PCI): implemented basic PCI enumerating
This commit is contained in:
parent
a904ffaaad
commit
da46a78219
|
@ -1,4 +1,3 @@
|
|||
build
|
||||
cmake-build-debug
|
||||
noxos.log
|
||||
*.img # For test disk images
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
9
run.sh
|
@ -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 |=====>"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue