Add: PCI driver, lspci
This commit is contained in:
105
src/drivers/pci.c
Normal file
105
src/drivers/pci.c
Normal file
@@ -0,0 +1,105 @@
|
||||
// PCI bus driver implementation
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pci.h"
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
static inline void outl(uint16_t port, uint32_t value)
|
||||
{
|
||||
__asm__ volatile ("outl %0, %1" : : "a"(value), "Nd"(port));
|
||||
}
|
||||
|
||||
static inline uint32_t inl(uint16_t port)
|
||||
{
|
||||
uint32_t ret;
|
||||
__asm__ volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pci_write_config_address(uint32_t address)
|
||||
{
|
||||
outl(PCI_CONFIG_ADDRESS, address);
|
||||
}
|
||||
|
||||
uint32_t pci_read_config_data()
|
||||
{
|
||||
return inl(PCI_CONFIG_DATA);
|
||||
}
|
||||
|
||||
uint32_t pci_config_address(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
|
||||
{
|
||||
return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
|
||||
}
|
||||
|
||||
uint32_t pci_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
|
||||
{
|
||||
uint32_t address = pci_config_address(bus, device, function, offset);
|
||||
pci_write_config_address(address);
|
||||
return pci_read_config_data();
|
||||
}
|
||||
|
||||
pci_device_t pci_get_device(uint8_t bus, uint8_t device, uint8_t function)
|
||||
{
|
||||
pci_device_t dev;
|
||||
|
||||
uint32_t reg0 = pci_read(bus, device, function, 0x00); // Vendor ID, Device ID
|
||||
uint32_t reg2 = pci_read(bus, device, function, 0x08); // Class, Subclass, Prog IF, Revision
|
||||
|
||||
dev.vendor_id = reg0 & 0xFFFF;
|
||||
dev.device_id = (reg0 >> 16) & 0xFFFF;
|
||||
dev.class_code = (reg2 >> 24) & 0xFF;
|
||||
dev.subclass = (reg2 >> 16) & 0xFF;
|
||||
dev.prog_if = (reg2 >> 8) & 0xFF;
|
||||
dev.revision_id = reg2 & 0xFF;
|
||||
dev.bus = bus;
|
||||
dev.device = device;
|
||||
dev.function = function;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
void scan_pci_bus()
|
||||
{
|
||||
for (uint16_t bus = 0; bus < 256; bus++) {
|
||||
for (uint8_t device = 0; device < 32; device++) {
|
||||
for (uint8_t function = 0; function < 8; function++) {
|
||||
pci_device_t dev = pci_get_device(bus, device, function);
|
||||
|
||||
if (dev.vendor_id != 0xFFFF) {
|
||||
|
||||
char* vendor_string;
|
||||
switch(dev.vendor_id)
|
||||
{
|
||||
case 0x8086:
|
||||
vendor_string = "Intel Corporation";
|
||||
break;
|
||||
case 0x1234:
|
||||
vendor_string = "Brain Actuated Technologies";
|
||||
break;
|
||||
default:
|
||||
vendor_string = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
char* device_string;
|
||||
switch(dev.device_id)
|
||||
{
|
||||
case 0x1237:
|
||||
device_string = "440FX - 82441FX PMC";
|
||||
break;
|
||||
default:
|
||||
device_string = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
printf("PCI Device found: Bus %u, Device %u, Function %u, Vendor ID: 0x%x (%s), Device ID: 0x%x (%s), Class: 0x%x\n",
|
||||
dev.bus, dev.device, dev.function, dev.vendor_id, vendor_string, dev.device_id, device_string, dev.class_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
src/drivers/pci.h
Normal file
29
src/drivers/pci.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// PCI bus driver implementation header
|
||||
// Author: xamidev
|
||||
// Licensed under the Unlicense. See the repo below.
|
||||
// https://github.com/xamidev/blankos
|
||||
|
||||
#ifndef PCI_H
|
||||
#define PCI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PCI_CONFIG_ADDRESS 0xCF8
|
||||
#define PCI_CONFIG_DATA 0xCFC
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t vendor_id;
|
||||
uint16_t device_id;
|
||||
uint8_t class_code;
|
||||
uint8_t subclass;
|
||||
uint8_t prog_if;
|
||||
uint8_t revision_id;
|
||||
uint8_t bus;
|
||||
uint8_t device;
|
||||
uint8_t function;
|
||||
} pci_device_t;
|
||||
|
||||
void scan_pci_bus();
|
||||
|
||||
#endif
|
||||
@@ -143,6 +143,7 @@ void shell_install()
|
||||
register_command("ls", program_ls);
|
||||
register_command("cat", program_cat);
|
||||
register_command("bmp", program_bmp);
|
||||
register_command("lspci", program_lspci);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
@@ -50,3 +50,4 @@ void panic()
|
||||
{
|
||||
for (;;);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "../drivers/ata.h"
|
||||
#include "../drivers/rtc.h"
|
||||
#include "../kernel/io.h"
|
||||
#include "../drivers/pci.h"
|
||||
|
||||
// Print a rainbow colorful text for testing
|
||||
|
||||
@@ -73,7 +74,7 @@ void program_uptime()
|
||||
|
||||
void program_help()
|
||||
{
|
||||
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\n");
|
||||
printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\t lspci\n");
|
||||
}
|
||||
|
||||
// Panic
|
||||
@@ -143,3 +144,10 @@ void program_reboot()
|
||||
|
||||
while (1) asm volatile("hlt");
|
||||
}
|
||||
|
||||
// List PCI buses and devices
|
||||
|
||||
void program_lspci()
|
||||
{
|
||||
scan_pci_bus();
|
||||
}
|
||||
|
||||
@@ -39,5 +39,6 @@ void program_ls();
|
||||
void program_cat();
|
||||
|
||||
void program_bmp();
|
||||
void program_lspci();
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user