Browse Source

lowl-pci: Autodetect build-time support for UIO and/or VFIO during configure

Luke Dashjr 12 years ago
parent
commit
fa18061369
2 changed files with 80 additions and 20 deletions
  1. 37 1
      configure.ac
  2. 43 19
      lowl-pci.c

+ 37 - 1
configure.ac

@@ -220,6 +220,36 @@ AC_CHECK_DECL([HASH_ITER],[
 ])
 ])
 
 
 
 
+lowl_pci=no
+if test "x$ac_cv_header_sys_mman_h" = "xyes"; then
+	AC_ARG_WITH([uio],
+		[AC_HELP_STRING([--with-uio],[Compile support for PCI devices via Linux UIO interface (default enabled)])],
+		[uio=$withval],
+		[uio=yes])
+	AC_ARG_WITH([vfio],
+		[AC_HELP_STRING([--with-vfio],[Compile support for PCI devices via Linux VFIO interface (default enabled)])],
+		[vfio=$enableval],
+		[vfio=auto])
+	if test "x$vfio" != "xno"; then
+		AC_CHECK_HEADER([linux/vfio.h],[
+			vfio=yes
+		],[
+			if test "x$vfio" = "xyes"; then
+				AC_MSG_ERROR([Unable to find linux/vfio.h])
+			elif test "x$uio" = "xyes"; then
+				AC_MSG_WARN([linux/vfio.h not found; PCI device support will require UIO (and root access)])
+			else
+				AC_MSG_WARN([linux/vfio.h not found; PCI device support will not be available])
+			fi
+			vfio=no
+		])
+	fi
+	if test "x$vfio$uio" != xnono; then
+		lowl_pci=yes
+	fi
+fi
+
+
 driverlist="$driverlist cpu/cpumining"
 driverlist="$driverlist cpu/cpumining"
 cpumining="no"
 cpumining="no"
 
 
@@ -374,7 +404,7 @@ AC_ARG_ENABLE([bitforce],
 if test "x$bitforce" = xyes; then
 if test "x$bitforce" = xyes; then
 	AC_DEFINE([USE_BITFORCE], [1], [Defined to 1 if BitForce support is wanted])
 	AC_DEFINE([USE_BITFORCE], [1], [Defined to 1 if BitForce support is wanted])
 	driverlist="$driverlist bitforce:uio/ac_cv_header_sys_mman_h"
 	driverlist="$driverlist bitforce:uio/ac_cv_header_sys_mman_h"
-	if test "x$ac_cv_header_sys_mman_h" = "xyes"; then
+	if test "x$lowl_pci" = "xyes"; then
 		need_lowl_pci=yes
 		need_lowl_pci=yes
 	fi
 	fi
 	need_lowl_vcom=yes
 	need_lowl_vcom=yes
@@ -989,6 +1019,12 @@ fi
 if test x$need_lowl_pci = xyes; then
 if test x$need_lowl_pci = xyes; then
 	AC_DEFINE([NEED_BFG_LOWL_PCI], [1], [Defined to 1 if lowlevel PCI drivers are being used])
 	AC_DEFINE([NEED_BFG_LOWL_PCI], [1], [Defined to 1 if lowlevel PCI drivers are being used])
 	need_lowlevel=yes
 	need_lowlevel=yes
+	if test x$uio = xyes; then
+		AC_DEFINE([USE_UIO], [1], [Defined to 1 if lowlevel PCI drivers should support UIO])
+	fi
+	if test x$vfio = xyes; then
+		AC_DEFINE([USE_VFIO], [1], [Defined to 1 if lowlevel PCI drivers should support VFIO])
+	fi
 fi
 fi
 
 
 if test x$need_lowl_usb = xyes; then
 if test x$need_lowl_usb = xyes; then

+ 43 - 19
lowl-pci.c

@@ -9,7 +9,13 @@
 
 
 #include "config.h"
 #include "config.h"
 
 
+#if defined(USE_VFIO) || defined(USE_UIO)
+#	define USE_LOWL_PCI_MMAP
+#	define USE_LOWL_PCI_DATA_WRAPPERS
+#endif
+
 #include <stdbool.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
@@ -22,10 +28,14 @@
 
 
 #include <utlist.h>
 #include <utlist.h>
 
 
+#ifdef USE_VFIO
 #include <linux/vfio.h>
 #include <linux/vfio.h>
 #include <sys/ioctl.h>
 #include <sys/ioctl.h>
+#endif
 
 
+#ifdef USE_LOWL_PCI_MMAP
 #include <sys/mman.h>
 #include <sys/mman.h>
+#endif
 
 
 #include "logging.h"
 #include "logging.h"
 #include "lowlevel.h"
 #include "lowlevel.h"
@@ -87,12 +97,17 @@ struct lowl_pci_interface {
 struct lowl_pci_handle {
 struct lowl_pci_handle {
 	const char *path;
 	const char *path;
 	const struct lowl_pci_interface *lpi;
 	const struct lowl_pci_interface *lpi;
+#ifdef USE_VFIO
 	int fd[3];
 	int fd[3];
-	uint32_t *bar[6];
 	off_t baroff[6];
 	off_t baroff[6];
+#endif
+#ifdef USE_LOWL_PCI_MMAP
+	uint32_t *bar[6];
 	size_t barsz[6];
 	size_t barsz[6];
+#endif
 };
 };
 
 
+#ifdef USE_LOWL_PCI_MMAP
 static
 static
 void lowl_pci_close_mmap(struct lowl_pci_handle * const lph)
 void lowl_pci_close_mmap(struct lowl_pci_handle * const lph)
 {
 {
@@ -117,6 +132,24 @@ bool lowl_pci_set_words_mmap(struct lowl_pci_handle * const lph, const uint32_t
 	return true;
 	return true;
 }
 }
 
 
+static
+int _file_mode_to_mmap_prot(const int mode)
+{
+	switch (mode)
+	{
+		case O_RDONLY:
+			return PROT_READ;
+		case O_WRONLY:
+			return PROT_WRITE;
+		case O_RDWR:
+			return PROT_READ | PROT_WRITE;
+		default:
+			return -1;
+	}
+}
+#endif
+
+#ifdef USE_LOWL_PCI_DATA_WRAPPERS
 static
 static
 const void *lowl_pci_get_data_from_words(struct lowl_pci_handle * const lph, void * const bufp, const size_t sz, const int bar, const off_t offset)
 const void *lowl_pci_get_data_from_words(struct lowl_pci_handle * const lph, void * const bufp, const size_t sz, const int bar, const off_t offset)
 {
 {
@@ -165,25 +198,11 @@ bool lowl_pci_set_data_in_words(struct lowl_pci_handle * const lph, const void *
 	}
 	}
 	return lowl_pci_set_words(lph, wdata, words, bar, offset32);
 	return lowl_pci_set_words(lph, wdata, words, bar, offset32);
 }
 }
+#endif
 
 
+#ifdef USE_UIO
 static const struct lowl_pci_interface lpi_uio;
 static const struct lowl_pci_interface lpi_uio;
 
 
-static
-int _file_mode_to_mmap_prot(const int mode)
-{
-	switch (mode)
-	{
-		case O_RDONLY:
-			return PROT_READ;
-		case O_WRONLY:
-			return PROT_WRITE;
-		case O_RDWR:
-			return PROT_READ | PROT_WRITE;
-		default:
-			return -1;
-	}
-}
-
 static
 static
 void *_uio_mmap_bar(const char * const path, const int bar, const size_t sz, const int prot)
 void *_uio_mmap_bar(const char * const path, const int bar, const size_t sz, const int prot)
 {
 {
@@ -236,8 +255,9 @@ static const struct lowl_pci_interface lpi_uio = {
 	.set_words = lowl_pci_set_words_mmap,
 	.set_words = lowl_pci_set_words_mmap,
 	.set_data  = lowl_pci_set_data_in_words,
 	.set_data  = lowl_pci_set_data_in_words,
 };
 };
+#endif
 
 
-
+#ifdef USE_VFIO
 static const struct lowl_pci_interface lpi_vfio;
 static const struct lowl_pci_interface lpi_vfio;
 
 
 #define _VFIO_ACCESS_BAR_PROBLEM ((void*)&lpi_vfio)
 #define _VFIO_ACCESS_BAR_PROBLEM ((void*)&lpi_vfio)
@@ -428,13 +448,17 @@ static const struct lowl_pci_interface lpi_vfio = {
 	.set_words = lowl_pci_set_words_vfio,
 	.set_words = lowl_pci_set_words_vfio,
 	.set_data  = lowl_pci_set_data_in_words,
 	.set_data  = lowl_pci_set_data_in_words,
 };
 };
-
+#endif
 
 
 struct lowl_pci_handle *lowl_pci_open(const char * const path, const struct _lowl_pci_config * const barcfgs)
 struct lowl_pci_handle *lowl_pci_open(const char * const path, const struct _lowl_pci_config * const barcfgs)
 {
 {
 	return
 	return
+#ifdef USE_VFIO
 		lpi_vfio.open(path, barcfgs) ?:
 		lpi_vfio.open(path, barcfgs) ?:
+#endif
+#ifdef USE_UIO
 		lpi_uio.open(path, barcfgs) ?:
 		lpi_uio.open(path, barcfgs) ?:
+#endif
 		false;
 		false;
 }
 }