diff --git a/.gitignore b/.gitignore index df8d2ff..dd6d270 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build cmake-build-debug -noxos.log \ No newline at end of file +noxos.log +*.img # For test disk images diff --git a/inc/drivers/pci.h b/inc/drivers/pci.h index d8c5d59..b52dfb2 100644 --- a/inc/drivers/pci.h +++ b/inc/drivers/pci.h @@ -205,11 +205,12 @@ typedef enum { typedef struct { - + pci_class_T pci_class; + uint16_t pci_subclass; } pci_device_T; +extern pci_device_T *g_pci_devices; - -void pci_init(acpi_sdt_header_T *xsdt); +void pci_init(boot_info_T* boot_info); #endif diff --git a/inc/utils/io.h b/inc/utils/io.h index d8d1c8d..40b8b72 100644 --- a/inc/utils/io.h +++ b/inc/utils/io.h @@ -8,6 +8,8 @@ // sends one byte to a port void io_out_byte (uint16_t port, uint8_t data); uint8_t io_in_byte (uint16_t port); +void io_out_word (uint16_t port, uint32_t data); +uint32_t io_in_word (uint16_t port); void io_wait (); #endif //NOX_IO_H diff --git a/src/boot/kmain.c b/src/boot/kmain.c index 9799a00..4bc52ba 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -42,6 +42,8 @@ void kernel_init(boot_info_T* boot_info) { vfs_init(boot_info); acpi_init(boot_info); + pci_init(boot_info); + // ps2_keyboard_init(); diff --git a/src/drivers/acpi/acpi.c b/src/drivers/acpi/acpi.c index ae2ef97..ca7eaa8 100644 --- a/src/drivers/acpi/acpi.c +++ b/src/drivers/acpi/acpi.c @@ -41,7 +41,7 @@ void acpi_init(boot_info_T* boot_info) { } } - g_mcfg_table = acpi_find_table(rsdp, "MCFG"); + 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,7 +54,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, " table '%.4' not found (no matching xsdt entry)"); return NULL; } \ No newline at end of file diff --git a/src/drivers/pci.c b/src/drivers/pci.c index e1bb31b..d80690d 100644 --- a/src/drivers/pci.c +++ b/src/drivers/pci.c @@ -1,46 +1,123 @@ #include -typedef struct { - uint64_t config_base_address; - uint16_t segment_group_number; - uint8_t min_pci_bus_number; - uint8_t max_pci_bus_number; - uint32_t reserved; -} __attribute__((packed)) pci_mcfg_table_entry_T; +#include -typedef struct{ - uint16_t device_index; +#define PCI_CONFIG_ADDRESS 0xCF8 +#define PCI_CONFIG_DATA 0xCFC + +typedef struct { + uint16_t device_id; uint16_t vendor_id; - uint16_t status; - uint16_t command; - uint8_t class_code; + uint16_t status_reg; + uint16_t command_reg; + uint8_t main_class; uint8_t subclass; - uint8_t prog_info_struct; + uint8_t progif; // Programming Interface Byte uint8_t revision_id; - uint8_t bist; + uint8_t bist; // Built-in Self-Test uint8_t header_type; uint8_t latency_timer; uint8_t cache_line_size; -} __attribute__((packed)) pci_config_space; +} __attribute__((packed)) pci_internal_device_T; -pci_device_T *g_pci_devices; +typedef struct { + uint16_t device_id; + uint16_t vendor_id; + uint16_t status_reg; + uint16_t command_reg; + uint8_t main_class; + uint8_t subclass; + uint8_t progif; // Programming Interface Byte + uint8_t revision_id; + uint8_t bist; // Built-in Self-Test + uint8_t header_type; + uint8_t latency_timer; + uint8_t cache_line_size; + + 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_id; + uint16_t subsystem_vendor_id; + uint32_t expansion_rom_base_address; + uint8_t reserved1[3]; + uint8_t capabilities; + uint8_t reserved2[4]; + uint8_t max_latency; + uint8_t min_grant; + uint8_t interrupt_pin; + uint8_t interrupt_line; +} __attribute__((packed)) pci_internal_default_header_t; -pci_device_T pci_decode_device(void *config_space) { +pci_device_T *g_pci_devices = NULL; +uint32_t pci_read_config_word(uint8_t bus, uint8_t slot, uint8_t function, uint8_t offset) { + + uint32_t bus32 = bus; + uint32_t slot32 = slot; + uint32_t function32 = function; + uint32_t offset32 = offset; + + uint32_t address = 0x80000000 | bus32 << 16 | slot32 << 11 | function32 << 8 | offset32; + + io_out_word(PCI_CONFIG_ADDRESS, address); + //uint32_t raw = io_in_word(PCI_CONFIG_DATA); + uint32_t raw = 0; + raw |= ((uint32_t) io_in_byte(PCI_CONFIG_DATA)) << 24; + raw |= ((uint32_t) io_in_byte(PCI_CONFIG_DATA)) << 16; + raw |= ((uint32_t) io_in_byte(PCI_CONFIG_DATA)) << 8; + raw |= ((uint32_t) io_in_byte(PCI_CONFIG_DATA)); + uint32_t processed = (raw >> 24) | ((raw >> 8) & 0x00ff0000) | (raw << 8 & 0x0000ff00) | (raw << 24); + //return processed; + return raw; } -void pci_init(acpi_sdt_header_T *xsdt) { +pci_internal_default_header_t pci_read_internal_default_header(uint8_t bus, uint8_t slot, uint8_t function) { + pci_internal_default_header_t header; + uint32_t *header32 = (void *) &header; + uint32_t word_index = 0; + while(word_index < 16) { + header32[word_index] = pci_read_config_word(bus, slot, function, sizeof(pci_internal_device_T) + word_index*4); + ++word_index; + } + return header; +} + +void pci_init(boot_info_T* boot_info) { - uint32_t num_devices = (g_mcfg_table->length - 44); // Table data length in bytes - if(num_devices == 0) return; - num_devices /= 16; // Each entry is 16 bytes long; get the number of entries from the number of bytes. - - pci_mcfg_table_entry_T *entries = g_mcfg_table + 44; - g_pci_devices = memory_allocate(sizeof(pci_mcfg_table_entry_T) * num_devices); - - uint32_t device_index = 0; - while(device_index < num_devices) { - pci_decode_device(&entries[device_index]); - ++device_index; + // g_pci_devices = memory_allocate(sizeof(pci_device_T) * 256); + uint16_t bus_index = 0; + while(bus_index < 256) { + uint16_t slot_index = 0; + while(slot_index < 256) { + uint32_t first_config_word = pci_read_config_word(bus_index, slot_index, 0, 0); + if(first_config_word == 0xffffffff) { + break; + } + log(LOG_DEBUG, "Header Byte: %d", (pci_read_config_word(bus_index, slot_index, 0, 4) & 0x00ff0000) >> 16); + pci_internal_default_header_t header = pci_read_internal_default_header(bus_index, slot_index, 0); + uint32_t *header32 = &header; + // log(LOG_DEBUG, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", + log(LOG_DEBUG, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", + header32[0], header32[1], header32[2], header32[3], + header32[4], header32[5], header32[6], header32[7], + header32[8], header32[9], header32[10], header32[11], + header32[12], header32[13], header32[14], header32[15] + ); + log(LOG_DEBUG, "This is the real data:\nmain_class: %d\nsubclass: %d\n", header.main_class, header.subclass); + log(LOG_DEBUG, "First header part 16-bits: %x %x", (header32[2] >> 24) & 0xff, (header32[2] >> 16) & 0xff); + /* + if(header.main_class == PCI_CLASS_MASS_STORAGE_CONTROLLER) { + log(LOG_DEBUG, "Mass Storage Controller found!"); + if(header.subclass == PCI_SUBCLASS_SERIAL_ATA_CONTROLLER) log(LOG_DEBUG, "Found the SATA controller!"); + } + */ + ++slot_index; + } + ++bus_index; } } diff --git a/src/utils/io.c b/src/utils/io.c index e872e95..3dfe5df 100644 --- a/src/utils/io.c +++ b/src/utils/io.c @@ -12,6 +12,16 @@ uint8_t io_in_byte(uint16_t port) { return data; } +void io_out_word(uint16_t port, uint32_t data) { + asm volatile ("outl %0, %1" : : "a"(data), "Nd"(port)); +} + +uint32_t io_in_word(uint16_t port) { + uint32_t data; + asm volatile ("inl %1, %0" : "=a"(data) : "Nd"(port)); + return data; +} + void io_wait() { io_out_byte(0x80, 0); -} \ No newline at end of file +}