BarryServer : Git

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

// Related

Nucleus

Barry System headers (remove libc dependency) 18495cf (3 years, 2 months ago)
/*
 * This file controls the PCI interface.  It contains utility functions for
 * accessing PCI configuration space.  It scans all devices connected to the
 * system and tries to initialise them.
 */

#include <stdint.h>
#include <nucleus/io.h>
#include <nucleus/pci.h>

/* PCI Configuration Ports */
enum PCIConfigPort {
	CONFIG_ADDRESS = 0xCF8,
	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, dev, func;
	/* This is one massive iteration */
	for (bus = 0; bus < 256; bus++)
	for (dev = 0; dev < 32; dev++)
	for (func = 0; func < 8; func++)
	if (pci_read_word(bus, dev, func, 0) != 0xFFFF)
		init_pci_device(bus, dev, func);
}