summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/pci.c45
-rw-r--r--sys/include/dev/pci/pci.h1
2 files changed, 46 insertions, 0 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index f681431..57133bf 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -74,6 +74,33 @@ pci_cam_read(const struct pci_device *dev, uint32_t offset)
#endif
}
+/*
+ * Write to device's legacy PCI CAM space
+ *
+ * @dev: Device to write to.
+ * @offset: Offset to write at.
+ *
+ * XXX: Do not use directly!
+ */
+static void
+pci_cam_write(const struct pci_device *dev, uint32_t offset, uint32_t value)
+{
+#if defined(__x86_64__)
+ uint32_t address;
+
+ address = __BIT(31) |
+ (offset & ~3) |
+ (dev->func << 8) |
+ (dev->slot << 11) |
+ (dev->bus << 16);
+
+ outl(0xCF8, address);
+ outb(0xCFC, value);
+#else
+ panic("Invalid arch (%s())\n", __func__);
+#endif
+}
+
static bool
pci_device_exists(uint8_t bus, uint8_t slot, uint8_t func)
{
@@ -167,6 +194,24 @@ pci_readl(struct pci_device *dev, uint32_t offset)
__builtin_unreachable();
}
+/*
+ * Write to PCI(e) configuration space.
+ *
+ * @dev: Device to write to.
+ * @offset: Offset to write at.
+ */
+void
+pci_writel(struct pci_device *dev, uint32_t offset, uint32_t val)
+{
+ if (access_method == PCI_ACCESS_CAM) {
+ pci_cam_write(dev, offset, val);
+ return;
+ }
+
+ panic("Invalid access method (%s())\n", __func__);
+ __builtin_unreachable();
+}
+
struct pci_device *
pci_get_device(struct pci_lookup lookup, uint16_t lookup_type)
{
diff --git a/sys/include/dev/pci/pci.h b/sys/include/dev/pci/pci.h
index c17a08e..fbbbeab 100644
--- a/sys/include/dev/pci/pci.h
+++ b/sys/include/dev/pci/pci.h
@@ -65,6 +65,7 @@ struct pci_device {
int pci_init(void);
uint32_t pci_readl(struct pci_device *dev, uint32_t offset);
+void pci_writel(struct pci_device *dev, uint32_t offset, uint32_t val);
struct pci_device *pci_get_device(struct pci_lookup lookup, uint16_t lookup_type);
#endif /* !_DEV_PCI_H_ */