BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 53a772a74dcbec1afdda913da790696f3c78bc4b / kernel / pci / pci.c

// Related

Nucleus

Barry ACPI DSDT + PCI 53a772a (3 years, 3 months ago)
diff --git a/kernel/pci/pci.c b/kernel/pci/pci.c
new file mode 100644
index 0000000..408aeb8
--- /dev/null
+++ b/kernel/pci/pci.c
@@ -0,0 +1,86 @@
+/*
+ *
+ */
+
+#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);
+	}
+}