Add PCI Enumeration to boot output
This commit is contained in:
parent
73b51c851d
commit
4c9108bc87
|
@ -16,16 +16,14 @@
|
||||||
#define PCI_CONFIG_ADDRESS 0xCF8
|
#define PCI_CONFIG_ADDRESS 0xCF8
|
||||||
#define PCI_CONFIG_DATA 0xCFC
|
#define PCI_CONFIG_DATA 0xCFC
|
||||||
|
|
||||||
extern pci_dev_t** pci_root_devices;
|
|
||||||
extern pci_entry_t* pci_map;
|
|
||||||
|
|
||||||
int pci_init_early();
|
const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_t progif);
|
||||||
|
|
||||||
const char* pci_get_name(uint8_t devclass, uint8_t subclass, uint8_t progif);
|
const char* PCIGetClassName(uint8_t devclass);
|
||||||
|
|
||||||
int pci_enumerate_devices(pci_dev_t* root);
|
void PCIEnumerate();
|
||||||
|
|
||||||
int pci_get_config(uint16_t seg, uint8_t bus, uint8_t slot, uint8_t function, void** config);
|
uint32_t PCIReadConfig(uint8_t bus, uint8_t slot, uint8_t function, uint8_t offset);
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
uint8_t io_space : 1; // Device can respond to I/O access
|
uint8_t io_space : 1; // Device can respond to I/O access
|
||||||
|
@ -171,3 +169,5 @@ typedef struct {
|
||||||
} pci_entry_t;
|
} pci_entry_t;
|
||||||
|
|
||||||
|
|
||||||
|
extern pci_dev_t** pci_root_devices;
|
||||||
|
extern pci_entry_t* pci_map;
|
|
@ -32,6 +32,8 @@ void _start(void) {
|
||||||
SetupIDT();
|
SetupIDT();
|
||||||
InitInterrupts();
|
InitInterrupts();
|
||||||
|
|
||||||
|
PCIEnumerate();
|
||||||
|
|
||||||
InitMemoryManager();
|
InitMemoryManager();
|
||||||
MemoryTest();
|
MemoryTest();
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,12 @@ void ListMemoryMap() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialPrintf("[ mem 0x%p-0x%p] %s\r\n", MMapEnt_Ptr(MapEntry), MMapEnt_Ptr(MapEntry) + MMapEnt_Size(MapEntry), EntryType);
|
size_t entry_from = MMapEnt_Ptr(MapEntry);
|
||||||
|
size_t entry_to = MMapEnt_Ptr(MapEntry) + MMapEnt_Size(MapEntry);
|
||||||
|
|
||||||
|
|
||||||
|
if(entry_from != 0 && entry_to != 0)
|
||||||
|
SerialPrintf("[ mem 0x%p-0x%p] %s\r\n", entry_from, entry_to, EntryType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <chroma.h>
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
*** Team Kitty, 2020 ***
|
*** Team Kitty, 2020 ***
|
||||||
|
@ -15,12 +15,17 @@
|
||||||
pci_dev_t** pci_root_devices = NULL;
|
pci_dev_t** pci_root_devices = NULL;
|
||||||
pci_entry_t* pci_map = NULL;
|
pci_entry_t* pci_map = NULL;
|
||||||
|
|
||||||
|
//static uint32_t PCIReadConfig(uint8_t bus, uint8_t slot, uint8_t function, uint8_t offset);
|
||||||
|
|
||||||
|
//static const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_t progif);
|
||||||
|
|
||||||
|
//static const char* PCIGetClassName(uint8_t devclass);
|
||||||
|
|
||||||
void PCIEnumerate() {
|
void PCIEnumerate() {
|
||||||
|
|
||||||
uint8_t bus = 0, device = 0, function = 0;
|
uint8_t bus = 0, device = 0, function = 0;
|
||||||
|
|
||||||
uint32_t register;
|
uint32_t registerData;
|
||||||
|
|
||||||
uint16_t device_id, vendor_id;
|
uint16_t device_id, vendor_id;
|
||||||
|
|
||||||
|
@ -28,23 +33,23 @@ void PCIEnumerate() {
|
||||||
|
|
||||||
SerialPrintf("Started PCI Enumeration.");
|
SerialPrintf("Started PCI Enumeration.");
|
||||||
|
|
||||||
SerialPrintf("\nPCI Scan result:");
|
SerialPrintf("\nPCI Scan result:\n");
|
||||||
for (bus = 0; bus <= 255; bus++) {
|
do {
|
||||||
for (device = 0; device <= 31; device++) {
|
for (device = 0; device <= 31; device++) {
|
||||||
for(function = 0; function <= 7; function++) {
|
for(function = 0; function <= 7; function++) {
|
||||||
uint32_t temp = PCIReadConfig(bus, device, 0, 0xC); // Read BIST/Header/Latency/Cache Line register
|
registerData = PCIReadConfig(bus, device, 0, 0xC); // Read BIST/Header/Latency/Cache Line register
|
||||||
uint8_t header = (uint8_t) ((temp & 0x00FF0000) >> 24); // Header is lower byte of upper word, so mask it off and shift it down
|
uint8_t header = (uint8_t) ((registerData & 0x00FF0000) >> 24); // Header is lower byte of upper word, so mask it off and shift it down
|
||||||
uint8_t multifunction_bit = header & 0x80; // The multifunction bit is the highest bit of the header
|
uint8_t multifunction_bit = header & 0x80; // The multifunction bit is the highest bit of the header
|
||||||
|
|
||||||
temp = PCIReadConfig(bus, device, function, 0); // Read the Vendor/Device ID register
|
registerData = PCIReadConfig(bus, device, function, 0); // Read the Vendor/Device ID register
|
||||||
uint16_t vendor_id = (uint16_t) temp & 0x0000FFFF; // Vendor ID is bottom word
|
vendor_id = (uint16_t) registerData & 0x0000FFFF; // Vendor ID is bottom word
|
||||||
uint16_t device_id = (uint16_t) temp >> 16; // Device ID is top word
|
device_id = (uint16_t) (registerData & 0xFFFF0000) >> 16; // Device ID is top word
|
||||||
|
|
||||||
temp = PCIReadConfig(bus, device, function, 8); // Read the Device Info register
|
registerData = PCIReadConfig(bus, device, function, 8); // Read the Device Info register
|
||||||
uint8_t device_class = (uint16_t) temp >> 24; // Device class is top byte, so shift them down
|
class_code = (uint16_t) registerData >> 24; // Device class is top byte, so shift them down
|
||||||
uint8_t device_subclass = (uint16_t) (temp >> 16) & 0x00FF; // Device subclass is same as header - lower byte of higher word. Shift down and mask just like before.
|
subclass_code = (uint16_t) (registerData >> 16) & 0x00FF; // Device subclass is same as header - lower byte of higher word. Shift down and mask just like before.
|
||||||
uint8_t device_progif = (uint16_t) temp & 0x0000FF00 >> 8; // Device Programming Interface is higher byte of lower word, so mask and shift
|
uint8_t device_progif = (uint16_t) registerData & 0x0000FF00 >> 8; // Device Programming Interface is higher byte of lower word, so mask and shift
|
||||||
uint8_t device_revision = (uint16_t) temp & 0x000000FF; // Device revision is lower byte of whole double word. Just mask it.
|
uint8_t device_revision = (uint16_t) registerData & 0x000000FF; // Device revision is lower byte of whole double word. Just mask it.
|
||||||
|
|
||||||
|
|
||||||
/* 0xFFFF is not a valid Vendor ID. This serves as a sanity check.
|
/* 0xFFFF is not a valid Vendor ID. This serves as a sanity check.
|
||||||
|
@ -52,7 +57,7 @@ void PCIEnumerate() {
|
||||||
*/
|
*/
|
||||||
if(vendor_id != 0xFFFF) {
|
if(vendor_id != 0xFFFF) {
|
||||||
SerialPrintf("\n\t%x:%x:\n\t\tVendor: %x\n\t\tDevice: %x", bus, device, vendor_id, device_id);
|
SerialPrintf("\n\t%x:%x:\n\t\tVendor: %x\n\t\tDevice: %x", bus, device, vendor_id, device_id);
|
||||||
SerialPrintf("\n\t\tClass: %s\n\t\tDevice Type: %s\n\t\tRevision: %s", PCIGetClassName(device_class), PCIGetDeviceName_Subclass(device_class, device_subclass, device_progif), device_revision);
|
SerialPrintf("\n\t\tClass: %s\n\t\tDevice Type: %s\n\t\tRevision: %d\n", PCIGetClassName(class_code), PCIGetDeviceName_Subclass(class_code, subclass_code, device_progif), device_revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the PCI Device header tells us that this is not a multifunction device,
|
/* If the PCI Device header tells us that this is not a multifunction device,
|
||||||
|
@ -65,7 +70,7 @@ void PCIEnumerate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
} while (++bus);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -156,7 +161,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x80: return "Other";
|
case 0x80: return "Other";
|
||||||
default: "Unknown Mass Storage Controller";
|
default: return "Unknown Mass Storage Controller";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +177,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
case 0x07: return "Infiniband Controller";
|
case 0x07: return "Infiniband Controller";
|
||||||
case 0x08: return "Fabric Controller";
|
case 0x08: return "Fabric Controller";
|
||||||
case 0x80: return "Other";
|
case 0x80: return "Other";
|
||||||
default: "Unknown Network Controller";
|
default: return "Unknown Network Controller";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +194,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
case 0x01: return "XGA Controller";
|
case 0x01: return "XGA Controller";
|
||||||
case 0x02: return "3D Controller (Not VGA-Compatible)";
|
case 0x02: return "3D Controller (Not VGA-Compatible)";
|
||||||
case 0x80: return "Other";
|
case 0x80: return "Other";
|
||||||
default: "Unknown Display Controller";
|
default: return "Unknown Display Controller";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +293,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
case 0x02: return "EISA-Compatible PIC";
|
case 0x02: return "EISA-Compatible PIC";
|
||||||
case 0x03: return "I/O APIC Interrupt Controller";
|
case 0x03: return "I/O APIC Interrupt Controller";
|
||||||
case 0x04: return "I/O(x) APIC Interrupt Controller";
|
case 0x04: return "I/O(x) APIC Interrupt Controller";
|
||||||
default: "PIC";
|
default: return "PIC";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +302,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
case 0x00: return "Generic 8237-Compatible DMA Controller";
|
case 0x00: return "Generic 8237-Compatible DMA Controller";
|
||||||
case 0x01: return "ISA-Compatible DMA Controller";
|
case 0x01: return "ISA-Compatible DMA Controller";
|
||||||
case 0x02: return "EISA-Compatible DMA Controller";
|
case 0x02: return "EISA-Compatible DMA Controller";
|
||||||
default: "DMA Controller";
|
default: return "DMA Controller";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +312,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
case 0x01: return "ISA-Compatible Timer";
|
case 0x01: return "ISA-Compatible Timer";
|
||||||
case 0x02: return "EISA-Compatible Timer";
|
case 0x02: return "EISA-Compatible Timer";
|
||||||
case 0x03: return "HPET Timer";
|
case 0x03: return "HPET Timer";
|
||||||
default: "Timer";
|
default: return "Timer";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +320,7 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
switch(progif) {
|
switch(progif) {
|
||||||
case 0x00: return "Generic RTC Controller";
|
case 0x00: return "Generic RTC Controller";
|
||||||
case 0x01: return "ISA-Compatible RTC Controller";
|
case 0x01: return "ISA-Compatible RTC Controller";
|
||||||
default: "RTC Controller";
|
default: return "RTC Controller";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,6 +485,8 @@ const char* PCIGetDeviceName_Subclass(uint8_t devclass, uint8_t subclass, uint8_
|
||||||
case 0xFF: return "Unassigned Class";
|
case 0xFF: return "Unassigned Class";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "Invalid Device!";
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* PCIGetClassName(uint8_t devclass) {
|
const char* PCIGetClassName(uint8_t devclass) {
|
||||||
|
@ -509,5 +516,8 @@ const char* PCIGetClassName(uint8_t devclass) {
|
||||||
case 0x40: return "Co-Processor";
|
case 0x40: return "Co-Processor";
|
||||||
case 0x41: return "Reserved";
|
case 0x41: return "Reserved";
|
||||||
case 0xFF: return "Unassigned Class";
|
case 0xFF: return "Unassigned Class";
|
||||||
|
default: return "Unknown Category";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "Invalid device!";
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user