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("ls", program_ls);
|
||||||
register_command("cat", program_cat);
|
register_command("cat", program_cat);
|
||||||
register_command("bmp", program_bmp);
|
register_command("bmp", program_bmp);
|
||||||
|
register_command("lspci", program_lspci);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,3 +50,4 @@ void panic()
|
|||||||
{
|
{
|
||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "../drivers/ata.h"
|
#include "../drivers/ata.h"
|
||||||
#include "../drivers/rtc.h"
|
#include "../drivers/rtc.h"
|
||||||
#include "../kernel/io.h"
|
#include "../kernel/io.h"
|
||||||
|
#include "../drivers/pci.h"
|
||||||
|
|
||||||
// Print a rainbow colorful text for testing
|
// Print a rainbow colorful text for testing
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ void program_uptime()
|
|||||||
|
|
||||||
void program_help()
|
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
|
// Panic
|
||||||
@@ -143,3 +144,10 @@ void program_reboot()
|
|||||||
|
|
||||||
while (1) asm volatile("hlt");
|
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_cat();
|
||||||
|
|
||||||
void program_bmp();
|
void program_bmp();
|
||||||
|
void program_lspci();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user