BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / 366395f052aa08364bd7e309662860dd94d8ed99 / kernel / pci / pci.c

// Related

Nucleus

Barry ACPI DSDT + PCI 53a772a (3 years, 3 months ago)
/*
 *
 */

#include <stdint.h>
#include <io.h>
#include "pci.h"

const uint16_t CONFIG_ADDRESS = 0xCF8;
const uint16_t CONFIG_DATA = 0xCFC;

/* Make a PCI Address */
static inline uint32_t
make_pci_address(int bus, int dev, int func, int off)
{
	return (1 << 31) | (bus << 16) | (dev << 11) | (func << 8) |
	       (off & 0xFC);
}

/* Read PCI config byte */
uint8_t
pci_read_byte(int bus, int dev, int func, int off)
{
	outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off));
	return inb(CONFIG_DATA + (off & 3));
}

/* Read PCI config word */
uint16_t
pci_read_word(int bus, int dev, int func, int off)
{
	outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off));
	return inw(CONFIG_DATA + (off & 2));
}

/* Read PCI config dword */
uint32_t
pci_read_dword(int bus, int dev, int func, int off)
{
	outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off));
	return inl(CONFIG_DATA);
}

/* Write PCI config byte */
void
pci_write_byte(int bus, int dev, int func, int off, uint8_t value)
{
	outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off));
	outb(CONFIG_DATA + (off & 3), value);
}

/* Write PCI config word */
void
pci_write_word(int bus, int dev, int func, int off, uint16_t value)
{
	outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off));
	outw(CONFIG_DATA + (off & 2), value);
}

/* Write PCI config dword */
void
pci_write_dword(int bus, int dev, int func, int off, uint32_t value)
{
	outl(CONFIG_ADDRESS, make_pci_address(bus, dev, func, off));
	outl(CONFIG_DATA, value);
}

/* Scan for PCI devices */
void
init_pci(void)
{
	uint16_t bus, slot, func;
	uint16_t vendor, device;
	uint8_t class, subclass;
	uint32_t dev;
	/* This is one massive iteration */
	for (bus = 0; bus < 256; bus++)
	for (slot = 0; slot < 32; slot++)
	for (func = 0; func < 8; func++)
	if ((vendor = pci_read_word(bus, slot, func, 0)) != 0xFFFF) {
		device = pci_read_word(bus, slot, func, 2);
		/* do something */
//		kprintf("PCI(%d,%d,%d) = %#.4x:%#.4x",
//		        bus, slot, func, vendor, device);
	}
}