[PATCH libpciaccess] OpenBSD: Implement map_legacy and legacy_io

Mark Kettenis mark.kettenis at xs4all.nl
Sat Dec 31 11:50:28 PST 2011


> From: Jeremy Huddleston <jeremyhu at apple.com>
> Date: Sat, 31 Dec 2011 10:28:11 -0500
> 
> There is a logic error in the preprocessing which seems to assume
> that PCI_MAGIC_IO_RANGE is defined iff !(i386 || x86_64).

Wouldn't call this a logic error, but yes, OpenBSD/i386 and
OpenBSD/amd64 will not define PCI_MAGIC_IO_RANGE.

> I would prefer the preprocessor checks be a bit more robust... perhaps
> following this template for pci_device_openbsd_open_legacy_io:
> 
> #if defined(__i386__)
> ...
> #elif defined(__x86_64__)
> ...
> #elif defined(PCI_MAGIC_IO_RANGE)
> ...
> #else
> #error "Unsupported Platform"
> #endif

Fair enough.  The double return is a bit bogus even though GCC doesn't
seem to whine about it.  The #error would be inappropriate though
since it is ok for open_legacy_io to fail on OpenBSD/sparc64 and
OpenBSD/macppc where legacy io isn't necessary for the drivers that
matter.  Here's a new diff.  I'll probably push this somewhere next
week.


Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
Reviewed-by: Matthieu Herrb <matthieu.herrb at laas.fr>
Tested-by: Matthieu Herrb <matthieu.herrb at laas.fr>
---
 src/openbsd_pci.c       |  153 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/pciaccess_private.h |    1 +
 2 files changed, 152 insertions(+), 2 deletions(-)

diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
index 219aba7..14e976d 100644
--- a/src/openbsd_pci.c
+++ b/src/openbsd_pci.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Mark Kettenis
+ * Copyright (c) 2008, 2011 Mark Kettenis
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -394,6 +394,141 @@ pci_device_openbsd_probe(struct pci_device *device)
 	return 0;
 }
 
+#if defined(__i386__) || defined(__amd64__)
+#include <machine/sysarch.h>
+#include <machine/pio.h>
+#endif
+
+static struct pci_io_handle *
+pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
+    struct pci_device *dev, pciaddr_t base, pciaddr_t size)
+{
+#if defined(__i386__)
+	struct i386_iopl_args ia;
+
+	ia.iopl = 1;
+	if (sysarch(I386_IOPL, &ia))
+		return NULL;
+
+	ret->base = base;
+	ret->size = size;
+	return ret;
+#elif defined(__amd64__)
+	struct amd64_iopl_args ia;
+
+	ia.iopl = 1;
+	if (sysarch(AMD64_IOPL, &ia))
+		return NULL;
+
+	ret->base = base;
+	ret->size = size;
+	return ret;
+#elif defined(PCI_MAGIC_IO_RANGE)
+	ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+	    aperturefd, PCI_MAGIC_IO_RANGE + base);
+	if (ret->memory == MAP_FAILED)
+		return NULL;
+
+	ret->base = base;
+	ret->size = size;
+	return ret;
+#else
+	return NULL;
+#endif
+}
+
+static uint32_t
+pci_device_openbsd_read32(struct pci_io_handle *handle, uint32_t reg)
+{
+#if defined(__i386__) || defined(__amd64__)
+	return inl(handle->base + reg);
+#else
+	return *(uint32_t *)((uintptr_t)handle->memory + reg);
+#endif
+}
+
+static uint16_t
+pci_device_openbsd_read16(struct pci_io_handle *handle, uint32_t reg)
+{
+#if defined(__i386__) || defined(__amd64__)
+	return inw(handle->base + reg);
+#else
+	return *(uint16_t *)((uintptr_t)handle->memory + reg);
+#endif
+}
+
+static uint8_t
+pci_device_openbsd_read8(struct pci_io_handle *handle, uint32_t reg)
+{
+#if defined(__i386__) || defined(__amd64__)
+	return inb(handle->base + reg);
+#else
+	return *(uint8_t *)((uintptr_t)handle->memory + reg);
+#endif
+}
+
+static void
+pci_device_openbsd_write32(struct pci_io_handle *handle, uint32_t reg,
+    uint32_t data)
+{
+#if defined(__i386__) || defined(__amd64__)
+	outl(handle->base + reg, data);
+#else
+	*(uint16_t *)((uintptr_t)handle->memory + reg) = data;
+#endif
+}
+
+static void
+pci_device_openbsd_write16(struct pci_io_handle *handle, uint32_t reg,
+    uint16_t data)
+{
+#if defined(__i386__) || defined(__amd64__)
+	outw(handle->base + reg, data);
+#else
+	*(uint8_t *)((uintptr_t)handle->memory + reg) = data;
+#endif
+}
+
+static void
+pci_device_openbsd_write8(struct pci_io_handle *handle, uint32_t reg,
+    uint8_t data)
+{
+#if defined(__i386__) || defined(__amd64__)
+	outb(handle->base + reg, data);
+#else
+	*(uint32_t *)((uintptr_t)handle->memory + reg) = data;
+#endif
+}
+
+static int
+pci_device_openbsd_map_legacy(struct pci_device *dev, pciaddr_t base,
+    pciaddr_t size, unsigned map_flags, void **addr)
+{
+	struct pci_device_mapping map;
+	int err;
+
+	map.base = base;
+	map.size = size;
+	map.flags = map_flags;
+	map.memory = NULL;
+	err = pci_device_openbsd_map_range(dev, &map);
+	*addr = map.memory;
+
+	return err;
+}
+
+static int
+pci_device_openbsd_unmap_legacy(struct pci_device *dev, void *addr,
+    pciaddr_t size)
+{
+	struct pci_device_mapping map;
+
+	map.memory = addr;
+	map.size = size;
+	map.flags = 0;
+	return pci_device_openbsd_unmap_range(dev, &map);
+}
+
 static const struct pci_system_methods openbsd_pci_methods = {
 	pci_system_openbsd_destroy,
 	NULL,
@@ -403,7 +538,21 @@ static const struct pci_system_methods openbsd_pci_methods = {
 	pci_device_openbsd_unmap_range,
 	pci_device_openbsd_read,
 	pci_device_openbsd_write,
-	pci_fill_capabilities_generic
+	pci_fill_capabilities_generic,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	pci_device_openbsd_open_legacy_io,
+	NULL,
+	pci_device_openbsd_read32,
+	pci_device_openbsd_read16,
+	pci_device_openbsd_read8,
+	pci_device_openbsd_write32,
+	pci_device_openbsd_write16,
+	pci_device_openbsd_write8,
+	pci_device_openbsd_map_legacy,
+	pci_device_openbsd_unmap_legacy
 };
 
 int
diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index 1653b8b..32f8a75 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -94,6 +94,7 @@ struct pci_device_mapping {
 struct pci_io_handle {
     pciaddr_t base;
     pciaddr_t size;
+    void *memory;
     int fd;
 };
 
-- 
1.7.6



More information about the xorg-devel mailing list