2 * The PCI Library -- Darwin kIOACPI access
4 * Copyright (c) 2013 Apple, Inc.
6 * Can be freely distributed and used under the terms of the GNU GPL.
18 #include <mach/mach_error.h>
19 #include <CoreFoundation/CoreFoundation.h>
20 #include <IOKit/IOKitLib.h>
21 #include <IOKit/IOKitKeys.h>
24 kACPIMethodAddressSpaceRead = 0,
25 kACPIMethodAddressSpaceWrite = 1,
26 kACPIMethodDebuggerCommand = 2,
32 typedef UInt32 IOACPIAddressSpaceID;
35 kIOACPIAddressSpaceIDSystemMemory = 0,
36 kIOACPIAddressSpaceIDSystemIO = 1,
37 kIOACPIAddressSpaceIDPCIConfiguration = 2,
38 kIOACPIAddressSpaceIDEmbeddedController = 3,
39 kIOACPIAddressSpaceIDSMBus = 4
48 unsigned int offset :16;
49 unsigned int function :3;
50 unsigned int device :5;
52 unsigned int segment :16;
53 unsigned int reserved :16;
56 typedef union IOACPIAddress IOACPIAddress;
60 struct AddressSpaceParam {
63 IOACPIAddress address;
68 typedef struct AddressSpaceParam AddressSpaceParam;
71 darwin_config(struct pci_access *a UNUSED)
76 darwin_detect(struct pci_access *a)
78 io_registry_entry_t service;
82 service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleACPIPlatformExpert"));
85 status = IOServiceOpen(service, mach_task_self(), 0, &connect);
86 IOObjectRelease(service);
89 if (!service || (kIOReturnSuccess != status))
91 a->warning("Cannot open AppleACPIPlatformExpert (add boot arg debug=0x144 & run as root)");
94 a->debug("...using AppleACPIPlatformExpert");
100 darwin_init(struct pci_access *a UNUSED)
105 darwin_cleanup(struct pci_access *a UNUSED)
110 darwin_read(struct pci_dev *d, int pos, byte *buf, int len)
112 if (!(len == 1 || len == 2 || len == 4))
113 return pci_generic_block_read(d, pos, buf, len);
115 AddressSpaceParam param;
116 kern_return_t status;
118 param.spaceID = kIOACPIAddressSpaceIDPCIConfiguration;
119 param.bitWidth = len * 8;
123 param.address.pci.offset = pos;
124 param.address.pci.function = d->func;
125 param.address.pci.device = d->dev;
126 param.address.pci.bus = d->bus;
127 param.address.pci.segment = d->domain;
128 param.address.pci.reserved = 0;
131 size_t outSize = sizeof(param);
132 status = IOConnectCallStructMethod(d->access->fd, kACPIMethodAddressSpaceRead,
133 ¶m, sizeof(param),
135 if ((kIOReturnSuccess != status))
136 d->access->error("darwin_read: kACPIMethodAddressSpaceRead failed: %s", mach_error_string(status));
141 buf[0] = (u8) param.value;
144 ((u16 *) buf)[0] = cpu_to_le16((u16) param.value);
147 ((u32 *) buf)[0] = cpu_to_le32((u32) param.value);
154 darwin_write(struct pci_dev *d, int pos, byte *buf, int len)
156 if (!(len == 1 || len == 2 || len == 4))
157 return pci_generic_block_write(d, pos, buf, len);
159 AddressSpaceParam param;
160 kern_return_t status;
162 param.spaceID = kIOACPIAddressSpaceIDPCIConfiguration;
163 param.bitWidth = len * 8;
167 param.address.pci.offset = pos;
168 param.address.pci.function = d->func;
169 param.address.pci.device = d->dev;
170 param.address.pci.bus = d->bus;
171 param.address.pci.segment = d->domain;
172 param.address.pci.reserved = 0;
177 param.value = buf[0];
180 param.value = le16_to_cpu(((u16 *) buf)[0]);
183 param.value = le32_to_cpu(((u32 *) buf)[0]);
188 status = IOConnectCallStructMethod(d->access->fd, kACPIMethodAddressSpaceWrite,
189 ¶m, sizeof(param),
191 if ((kIOReturnSuccess != status))
192 d->access->error("darwin_read: kACPIMethodAddressSpaceWrite failed: %s", mach_error_string(status));
197 struct pci_methods pm_darwin_device = {
205 pci_generic_fill_info,
210 NULL /* dev_cleanup */