]> mj.ucw.cz Git - pciutils.git/commitdiff
Import initial Darwin Support from Apple
authorRichard Yao <ryao@gentoo.org>
Mon, 20 Oct 2014 03:13:05 +0000 (23:13 -0400)
committerMartin Mares <mj@ucw.cz>
Sat, 1 Nov 2014 15:38:37 +0000 (16:38 +0100)
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>
lib/Makefile
lib/configure
lib/darwin-device.c [new file with mode: 0644]
lib/init.c
lib/internal.h
lib/pci.h

index 1eb06a566fc90d1d23564cdff14460571bdd61f6..7bab161934bbd716027b82e1b80960dc3329f1ec 100644 (file)
@@ -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)
index 27388bc15b5e99f0d550e5bec30f861fa2b97115..e00007926b60ff97f8a3842f19f02568056e08fb 100755 (executable)
@@ -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 (file)
index 0000000..e6e091d
--- /dev/null
@@ -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 */
+};
index 103dc3afd89907e1bf228380e560a44716e4f0e7..04d8638a64ce7569c742d7d8067c13ce0de7b3ff 100644 (file)
@@ -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 *
index 9718be610680ce2fc9afa675de70a8054611bb3a..6045948656af30bf2a4716dc16f5c4565fb88685 100644 (file)
@@ -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;
index f31419d2a0a045c9fee7f26cf76d4ed98c228495..0670b18167ffdaf331a7d91d6a07c01ac5a4f829 100644 (file)
--- 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
 };