summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Yao <ryao@gentoo.org>2014-10-19 23:13:05 -0400
committerMartin Mares <mj@ucw.cz>2014-11-01 16:38:37 +0100
commit7cb1afbe8d058688fc20c689edd3f5bb6243b28f (patch)
treeb94360242900fa6e6489dd2dd2b2d9a154ef133d
parent033a6ecbf532ec97f7622a2af2ed4dd03111627e (diff)
downloadpciutils-7cb1afbe8d058688fc20c689edd3f5bb6243b28f.tar.gz
Import initial Darwin Support from Apple
Apple published a patch that adds Darwin support to pciutils. It is not complete, but it does not appear to cause a build failure on other platforms. For the sake of attribution purposes, it is being kept separate from additional changes to make pciutils build properly on Darwin. https://www.opensource.apple.com/source/IOPCIFamily/IOPCIFamily-224.92.1/tools/pciutils3.2.0.patch.c This patch differs slightly from Apple's original patch by omitting the Makefile.rej that Apple had incorrectly included in the patch that it placed on its server. Signed-off-by: Richard Yao <ryao@gentoo.org>
-rw-r--r--lib/Makefile4
-rwxr-xr-xlib/configure8
-rw-r--r--lib/darwin-device.c220
-rw-r--r--lib/init.c5
-rw-r--r--lib/internal.h2
-rw-r--r--lib/pci.h3
6 files changed, 240 insertions, 2 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 1eb06a5..7bab161 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -42,6 +42,10 @@ ifdef PCI_HAVE_PM_NBSD_LIBPCI
OBJS += nbsd-libpci
endif
+ifdef PCI_HAVE_PM_DARWIN_DEVICE
+OBJS += darwin-device
+endif
+
all: $(PCILIB) $(PCILIBPC)
ifeq ($(SHARED),no)
diff --git a/lib/configure b/lib/configure
index 27388bc..e000079 100755
--- a/lib/configure
+++ b/lib/configure
@@ -100,6 +100,14 @@ case $sys in
echo >>$c '#define PCI_PATH_OBSD_DEVICE "/dev/pci"'
LIBRESOLV=
;;
+
+ darwin)
+ echo_n " darwin-device"
+ echo >>$c '#define PCI_HAVE_PM_DARWIN_DEVICE'
+ echo >>$m 'WITH_LIBS+=-lresolv -framework CoreFoundation -framework IOKit'
+ echo >>$c '#define PCI_HAVE_64BIT_ADDRESS'
+ LIBRESOLV=
+ ;;
aix)
echo_n " aix-device"
echo >>$c '#define PCI_HAVE_PM_AIX_DEVICE'
diff --git a/lib/darwin-device.c b/lib/darwin-device.c
new file mode 100644
index 0000000..e6e091d
--- /dev/null
+++ b/lib/darwin-device.c
@@ -0,0 +1,220 @@
+/*
+ * The PCI Library -- FreeBSD /dev/pci access
+ *
+ * Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
+ * Updated in 2003 by Samy Al Bahra <samy@kerneled.com>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "internal.h"
+
+#include <mach/mach_error.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOKitKeys.h>
+
+
+enum {
+ kACPIMethodAddressSpaceRead = 0,
+ kACPIMethodAddressSpaceWrite = 1,
+ kACPIMethodDebuggerCommand = 2,
+ kACPIMethodCount
+};
+
+#pragma pack(1)
+
+typedef UInt32 IOACPIAddressSpaceID;
+
+enum {
+ kIOACPIAddressSpaceIDSystemMemory = 0,
+ kIOACPIAddressSpaceIDSystemIO = 1,
+ kIOACPIAddressSpaceIDPCIConfiguration = 2,
+ kIOACPIAddressSpaceIDEmbeddedController = 3,
+ kIOACPIAddressSpaceIDSMBus = 4
+};
+
+/*
+ * 64-bit ACPI address
+ */
+union IOACPIAddress {
+ UInt64 addr64;
+ struct {
+ unsigned int offset :16;
+ unsigned int function :3;
+ unsigned int device :5;
+ unsigned int bus :8;
+ unsigned int segment :16;
+ unsigned int reserved :16;
+ } pci;
+};
+typedef union IOACPIAddress IOACPIAddress;
+
+#pragma pack()
+
+struct AddressSpaceParam {
+ UInt64 value;
+ UInt32 spaceID;
+ IOACPIAddress address;
+ UInt32 bitWidth;
+ UInt32 bitOffset;
+ UInt32 options;
+};
+typedef struct AddressSpaceParam AddressSpaceParam;
+
+
+static void
+darwin_config(struct pci_access *a UNUSED)
+{
+}
+
+static int
+darwin_detect(struct pci_access *a)
+{
+ io_registry_entry_t service;
+ io_connect_t connect;
+ kern_return_t status;
+
+ service = IOServiceGetMatchingService(kIOMasterPortDefault,
+ IOServiceMatching("AppleACPIPlatformExpert"));
+ if (service)
+ {
+ status = IOServiceOpen(service, mach_task_self(), 0, &connect);
+ IOObjectRelease(service);
+ }
+
+ if (!service || (kIOReturnSuccess != status))
+ {
+ a->warning("Cannot open AppleACPIPlatformExpert (add boot arg debug=0x144 & run as root)");
+ return 0;
+ }
+ a->debug("...using AppleACPIPlatformExpert");
+ a->fd = connect;
+ return 1;
+}
+
+static void
+darwin_init(struct pci_access *a UNUSED)
+{
+}
+
+static void
+darwin_cleanup(struct pci_access *a UNUSED)
+{
+}
+
+static int
+darwin_read(struct pci_dev *d, int pos, byte *buf, int len)
+{
+ if (!(len == 1 || len == 2 || len == 4))
+ return pci_generic_block_read(d, pos, buf, len);
+
+ AddressSpaceParam param;
+ kern_return_t status;
+
+ param.spaceID = kIOACPIAddressSpaceIDPCIConfiguration;
+ param.bitWidth = len * 8;
+ param.bitOffset = 0;
+ param.options = 0;
+
+ param.address.pci.offset = pos;
+ param.address.pci.function = d->func;
+ param.address.pci.device = d->dev;
+ param.address.pci.bus = d->bus;
+ param.address.pci.segment = d->domain;
+ param.address.pci.reserved = 0;
+ param.value = -1ULL;
+
+ size_t outSize = sizeof(param);
+ status = IOConnectCallStructMethod(d->access->fd, kACPIMethodAddressSpaceRead,
+ &param, sizeof(param),
+ &param, &outSize);
+ if ((kIOReturnSuccess != status))
+ {
+ d->access->error("darwin_read: kACPIMethodAddressSpaceRead failed: %s",
+ mach_error_string(status));
+ }
+
+ switch (len)
+ {
+ case 1:
+ buf[0] = (u8) param.value;
+ break;
+ case 2:
+ ((u16 *) buf)[0] = cpu_to_le16((u16) param.value);
+ break;
+ case 4:
+ ((u32 *) buf)[0] = cpu_to_le32((u32) param.value);
+ break;
+ }
+ return 1;
+}
+
+static int
+darwin_write(struct pci_dev *d, int pos, byte *buf, int len)
+{
+ if (!(len == 1 || len == 2 || len == 4))
+ return pci_generic_block_write(d, pos, buf, len);
+
+ AddressSpaceParam param;
+ kern_return_t status;
+
+ param.spaceID = kIOACPIAddressSpaceIDPCIConfiguration;
+ param.bitWidth = len * 8;
+ param.bitOffset = 0;
+ param.options = 0;
+
+ param.address.pci.offset = pos;
+ param.address.pci.function = d->func;
+ param.address.pci.device = d->dev;
+ param.address.pci.bus = d->bus;
+ param.address.pci.segment = d->domain;
+ param.address.pci.reserved = 0;
+ switch (len)
+ {
+ case 1:
+ param.value = buf[0];
+ break;
+ case 2:
+ param.value = le16_to_cpu(((u16 *) buf)[0]);
+ break;
+ case 4:
+ param.value = le32_to_cpu(((u32 *) buf)[0]);
+ break;
+ }
+
+ size_t outSize = 0;
+ status = IOConnectCallStructMethod(d->access->fd, kACPIMethodAddressSpaceWrite,
+ &param, sizeof(param),
+ NULL, &outSize);
+ if ((kIOReturnSuccess != status))
+ {
+ d->access->error("darwin_read: kACPIMethodAddressSpaceWrite failed: %s",
+ mach_error_string(status));
+ }
+
+ return 1;
+}
+
+struct pci_methods pm_darwin_device = {
+ "darwin-device",
+ "Darwin device",
+ darwin_config,
+ darwin_detect,
+ darwin_init,
+ darwin_cleanup,
+ pci_generic_scan,
+ pci_generic_fill_info,
+ darwin_read,
+ darwin_write,
+ NULL, /* read_vpd */
+ NULL, /* dev_init */
+ NULL /* dev_cleanup */
+};
diff --git a/lib/init.c b/lib/init.c
index 103dc3a..04d8638 100644
--- a/lib/init.c
+++ b/lib/init.c
@@ -57,6 +57,11 @@ static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = {
#else
NULL,
#endif
+#ifdef PCI_HAVE_PM_DARWIN_DEVICE
+ &pm_darwin_device,
+#else
+ NULL,
+#endif
};
void *
diff --git a/lib/internal.h b/lib/internal.h
index 9718be6..6045948 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -69,4 +69,4 @@ void pci_free_caps(struct pci_dev *);
extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
- pm_dump, pm_linux_sysfs;
+ pm_dump, pm_linux_sysfs, pm_darwin_device;
diff --git a/lib/pci.h b/lib/pci.h
index f31419d..0670b18 100644
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -39,7 +39,8 @@ enum pci_access_type {
PCI_ACCESS_AIX_DEVICE, /* /dev/pci0, /dev/bus0, etc. */
PCI_ACCESS_NBSD_LIBPCI, /* NetBSD libpci */
PCI_ACCESS_OBSD_DEVICE, /* OpenBSD /dev/pci */
- PCI_ACCESS_DUMP, /* Dump file */
+ PCI_ACCESS_DUMP, /* Dump file */
+ PCI_ACCESS_DARWIN, /* Darwin */
PCI_ACCESS_MAX
};