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 */