2 * The PCI Library -- FreeBSD /dev/pci access
4 * Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
5 * Updated in 2003 by Samy Al Bahra <samy@kerneled.com>
7 * Can be freely distributed and used under the terms of the GNU GPL.
19 #include <mach/mach_error.h>
20 #include <CoreFoundation/CoreFoundation.h>
21 #include <IOKit/IOKitLib.h>
22 #include <IOKit/IOKitKeys.h>
26 kACPIMethodAddressSpaceRead = 0,
27 kACPIMethodAddressSpaceWrite = 1,
28 kACPIMethodDebuggerCommand = 2,
34 typedef UInt32 IOACPIAddressSpaceID;
37 kIOACPIAddressSpaceIDSystemMemory = 0,
38 kIOACPIAddressSpaceIDSystemIO = 1,
39 kIOACPIAddressSpaceIDPCIConfiguration = 2,
40 kIOACPIAddressSpaceIDEmbeddedController = 3,
41 kIOACPIAddressSpaceIDSMBus = 4
50 unsigned int offset :16;
51 unsigned int function :3;
52 unsigned int device :5;
54 unsigned int segment :16;
55 unsigned int reserved :16;
58 typedef union IOACPIAddress IOACPIAddress;
62 struct AddressSpaceParam {
65 IOACPIAddress address;
70 typedef struct AddressSpaceParam AddressSpaceParam;
74 darwin_config(struct pci_access *a UNUSED)
79 darwin_detect(struct pci_access *a)
81 io_registry_entry_t service;
85 service = IOServiceGetMatchingService(kIOMasterPortDefault,
86 IOServiceMatching("AppleACPIPlatformExpert"));
89 status = IOServiceOpen(service, mach_task_self(), 0, &connect);
90 IOObjectRelease(service);
93 if (!service || (kIOReturnSuccess != status))
95 a->warning("Cannot open AppleACPIPlatformExpert (add boot arg debug=0x144 & run as root)");
98 a->debug("...using AppleACPIPlatformExpert");
104 darwin_init(struct pci_access *a UNUSED)
109 darwin_cleanup(struct pci_access *a UNUSED)
114 darwin_read(struct pci_dev *d, int pos, byte *buf, int len)
116 if (!(len == 1 || len == 2 || len == 4))
117 return pci_generic_block_read(d, pos, buf, len);
119 AddressSpaceParam param;
120 kern_return_t status;
122 param.spaceID = kIOACPIAddressSpaceIDPCIConfiguration;
123 param.bitWidth = len * 8;
127 param.address.pci.offset = pos;
128 param.address.pci.function = d->func;
129 param.address.pci.device = d->dev;
130 param.address.pci.bus = d->bus;
131 param.address.pci.segment = d->domain;
132 param.address.pci.reserved = 0;
135 size_t outSize = sizeof(param);
136 status = IOConnectCallStructMethod(d->access->fd, kACPIMethodAddressSpaceRead,
137 ¶m, sizeof(param),
139 if ((kIOReturnSuccess != status))
141 d->access->error("darwin_read: kACPIMethodAddressSpaceRead failed: %s",
142 mach_error_string(status));
148 buf[0] = (u8) param.value;
151 ((u16 *) buf)[0] = cpu_to_le16((u16) param.value);
154 ((u32 *) buf)[0] = cpu_to_le32((u32) param.value);
161 darwin_write(struct pci_dev *d, int pos, byte *buf, int len)
163 if (!(len == 1 || len == 2 || len == 4))
164 return pci_generic_block_write(d, pos, buf, len);
166 AddressSpaceParam param;
167 kern_return_t status;
169 param.spaceID = kIOACPIAddressSpaceIDPCIConfiguration;
170 param.bitWidth = len * 8;
174 param.address.pci.offset = pos;
175 param.address.pci.function = d->func;
176 param.address.pci.device = d->dev;
177 param.address.pci.bus = d->bus;
178 param.address.pci.segment = d->domain;
179 param.address.pci.reserved = 0;
183 param.value = buf[0];
186 param.value = le16_to_cpu(((u16 *) buf)[0]);
189 param.value = le32_to_cpu(((u32 *) buf)[0]);
194 status = IOConnectCallStructMethod(d->access->fd, kACPIMethodAddressSpaceWrite,
195 ¶m, sizeof(param),
197 if ((kIOReturnSuccess != status))
199 d->access->error("darwin_read: kACPIMethodAddressSpaceWrite failed: %s",
200 mach_error_string(status));
206 struct pci_methods pm_darwin_device = {
214 pci_generic_fill_info,
219 NULL /* dev_cleanup */