From 2cd12fd9b3d00b959c159fc9fc2590a3887d0ac9 Mon Sep 17 00:00:00 2001 From: Darcy Liu Date: Mon, 25 Feb 2013 23:49:32 +0800 Subject: [PATCH] add AppleSamplePCI --- AppleSamplePCI.zip | Bin 0 -> 43485 bytes AppleSamplePCI/AppleSamplePCI.cpp | 429 +++++++ AppleSamplePCI/AppleSamplePCI.h | 109 ++ .../AppleSamplePCI.xcodeproj/project.pbxproj | 1027 +++++++++++++++++ AppleSamplePCI/AppleSamplePCIAvailability.h | 93 ++ AppleSamplePCI/AppleSamplePCIClient.c | 316 +++++ AppleSamplePCI/AppleSamplePCIShared.h | 108 ++ AppleSamplePCI/AppleSamplePCIUserClient.cpp | 478 ++++++++ AppleSamplePCI/AppleSamplePCIUserClient.h | 114 ++ AppleSamplePCI/Info-AppleSamplePCI.plist | 78 ++ AppleSamplePCI/Info-AppleSamplePCI_10_4.plist | 67 ++ AppleSamplePCI/readme.txt | 13 + 12 files changed, 2832 insertions(+) create mode 100644 AppleSamplePCI.zip create mode 100644 AppleSamplePCI/AppleSamplePCI.cpp create mode 100644 AppleSamplePCI/AppleSamplePCI.h create mode 100644 AppleSamplePCI/AppleSamplePCI.xcodeproj/project.pbxproj create mode 100644 AppleSamplePCI/AppleSamplePCIAvailability.h create mode 100644 AppleSamplePCI/AppleSamplePCIClient.c create mode 100644 AppleSamplePCI/AppleSamplePCIShared.h create mode 100644 AppleSamplePCI/AppleSamplePCIUserClient.cpp create mode 100644 AppleSamplePCI/AppleSamplePCIUserClient.h create mode 100644 AppleSamplePCI/Info-AppleSamplePCI.plist create mode 100644 AppleSamplePCI/Info-AppleSamplePCI_10_4.plist create mode 100644 AppleSamplePCI/readme.txt diff --git a/AppleSamplePCI.zip b/AppleSamplePCI.zip new file mode 100644 index 0000000000000000000000000000000000000000..14e5e8de5070afc11df202aed978a0f2e2b6f660 GIT binary patch literal 43485 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 +#include + +#if IOMEMORYDESCRIPTOR_SUPPORTS_DMACOMMAND +#include +#endif + +#include "AppleSamplePCI.h" +#include +#include + +/* + * Define the metaclass information that is used for runtime + * typechecking of IOKit objects. We're a subclass of IOService, + * but usually we would subclass from a family class. + */ + +#define super IOService + +/* + * even though we are defining the convenience macro super for the superclass, you must use the actual class name + * in the OS*MetaClass macros. Note that the class name is different when supporting PowerPC on 10.4. + */ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +OSDefineMetaClassAndStructors( com_YourCompany_driver_SamplePCI_10_4, IOService ) +#else +OSDefineMetaClassAndStructors( com_YourCompany_driver_SamplePCI, IOService ) +#endif + +// This function will be called when the user process calls IORegistryEntrySetCFProperties on +// this driver. You can add your custom functionality to this function. +IOReturn SamplePCIClassName::setProperties(OSObject* properties) +{ + OSDictionary* dict; + OSNumber* number; + + dict = OSDynamicCast(OSDictionary, properties); + if (!dict) { + return kIOReturnBadArgument; + } + // we're adding the property to the registry here + number = OSDynamicCast(OSNumber, dict->getObject(kMyDisplayValueKey)); + if (number) { + uint32_t value = number->unsigned32BitValue(); + + IOLog("%s[%p]::%s(%p) got value %u\n", getName(), this, __FUNCTION__, properties, value); + updateRegistry(value); + return kIOReturnSuccess; + } + else { + return super::setProperties(properties); + } + +} + +// updateRegistry does the actual I/O Registry update. +// It is important to note that we work on a copy of the section of the I/O Registry +// until the actual reinsertion into the I/O Registry. +// The setProperty call is serialized for us and is the only safe way to +// handle this. +void SamplePCIClassName::updateRegistry(UInt32 value) +{ + // Directly changing a collection in the I/O Registry is not supported as it is not protected against + // multiple writers. So expose a copy and work on that instead. + OSDictionary* dict = OSDynamicCast(OSDictionary, copyProperty(kMyDisplayParametersKey)); + + OSDictionary* copyDict = (OSDictionary *) dict->copyCollection(); + + if (copyDict != NULL) { + OSDictionary* copyBrightnessDict = OSDynamicCast(OSDictionary, copyDict->getObject(kMyDisplayBrightnessKey)); + + if (copyBrightnessDict != NULL) { + OSNumber* num = OSDynamicCast(OSNumber, copyBrightnessDict->getObject(kMyDisplayValueKey)); + if (num != NULL) { + num->setValue(value); + + // setProperty correctly serializes I/O Registry updates for our protection. + setProperty(kMyDisplayParametersKey, copyDict); + } + } + + copyDict->release(); + } +} + + +bool SamplePCIClassName::start( IOService* provider ) +{ + IOMemoryDescriptor * mem; + IOMemoryMap * map; + + IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider); + + if (!super::start( provider )) + return false; + + /* + * Our provider class is specified in the driver property table + * as IOPCIDevice, so the provider must be of that class. + * The assert is just to make absolutely sure for debugging. + */ + + assert( OSDynamicCast( IOPCIDevice, provider )); + fPCIDevice = (IOPCIDevice *) provider; + + /* + * Enable memory response from the card + */ + fPCIDevice->setMemoryEnable( true ); + + /* + * Log some info about the device + */ + + /* Print all the device's memory ranges */ + for ( uint32_t index = 0; index < fPCIDevice->getDeviceMemoryCount(); index++ ) { + + mem = fPCIDevice->getDeviceMemoryWithIndex( index ); + assert( mem ); + IOLog("Range[%d] " PhysAddr_FORMAT ":" ByteCount_FORMAT "\n", index, + mem->getPhysicalAddress(), mem->getLength()); + } + + /* look up a range based on its config space base address register */ + mem = fPCIDevice->getDeviceMemoryWithRegister( + kIOPCIConfigBaseAddress0 ); + if ( mem ) + IOLog("Range@0x%x " PhysAddr_FORMAT ":" ByteCount_FORMAT "\n", kIOPCIConfigBaseAddress0, + mem->getPhysicalAddress(), mem->getLength()); + + /* Map a range based on its config space base address register, + * This is how the driver gets access to its memory-mapped registers. + * The getVirtualAddress() method returns a kernel virtual address + * for the register mapping */ + + map = fPCIDevice->mapDeviceMemoryWithRegister( + kIOPCIConfigBaseAddress0 ); + if ( map ) { + IOLog("Range@0x%x (" PhysAddr_FORMAT ") mapped to kernel virtual address " VirtAddr_FORMAT "\n", + kIOPCIConfigBaseAddress0, + map->getPhysicalAddress(), + map->getVirtualAddress() + ); + + /* Release the map object, and the mapping itself */ + map->release(); + } + + /* Read a config space register */ + IOLog("Config register@0x%x = " UInt32_FORMAT "\n", kIOPCIConfigCommand, + fPCIDevice->configRead32(kIOPCIConfigCommand) ); + + // Construct a memory descriptor for a buffer below the 4Gb physical line & + // so addressable by 32-bit DMA. This could be used for a + // DMA program buffer, for example. + + IOBufferMemoryDescriptor * bmd = +#if defined(__ppc__) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) + IOBufferMemoryDescriptor::withOptions(kIOMemoryPhysicallyContiguous, 64 * 1024, page_size); +#else + IOBufferMemoryDescriptor::inTaskWithPhysicalMask( + // task to hold the memory + kernel_task, + // options + kIOMemoryPhysicallyContiguous, + // size + 64*1024, + // physicalMask - 32 bit addressable and page aligned + 0x00000000FFFFF000ULL); +#endif + + if (bmd) { + generateDMAAddresses(bmd); + } else { + IOLog("IOBufferMemoryDescriptor::inTaskWithPhysicalMask failed\n"); + } + fLowMemory = bmd; + + /* Publish ourselves so clients can find us */ + registerService(); + + return true; +} + +/* + * We'll come here when the device goes away, or the driver is unloaded. + */ + +void SamplePCIClassName::stop( IOService* provider ) +{ + IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider); + super::stop( provider ); +} + +/* + * Method to supply an IOMemoryDescriptor for the user client to map into + * the client process. This sample just supplies all of the hardware memory + * associated with the PCI device's Base Address Register 0. + * In a real driver mapping hardware memory would only ever be used in some + * limited high performance scenarios where the device range can be safely + * accessed by client code with compromising system stability. + */ + +IOMemoryDescriptor * SamplePCIClassName::copyGlobalMemory( void ) +{ + IOMemoryDescriptor* memory; + + memory = fPCIDevice->getDeviceMemoryWithRegister( kIOPCIConfigBaseAddress0 ); + if( memory) + memory->retain(); + + return memory; +} + +#if defined(__ppc__) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) +IOReturn SamplePCIClassName::generateDMAAddresses( IOMemoryDescriptor* memDesc ) +{ + // Get the physical segment list. These could be used to generate a scatter gather + // list for hardware. + + // This is the old getPhysicalSegment() loop calling IOMemoryDescriptor. + // It will fail (panic) on systems with physical memory above the 4GiB line. + + IOByteCount offset = 0; + IOPhysicalAddress physicalAddr; + IOPhysicalLength segmentLength; + uint32_t index = 0; + + while ((physicalAddr = memDesc->getPhysicalSegment(offset, &segmentLength))) { + IOLog("Physical segment(%u) " PhysAddr_FORMAT ":" ByteCount_FORMAT "\n", index, physicalAddr, segmentLength); + offset += segmentLength; + index++; + } + + return kIOReturnSuccess; +} +#else +IOReturn SamplePCIClassName::generateDMAAddresses( IOMemoryDescriptor* memDesc ) +{ + // Get the physical segment list. These could be used to generate a scatter gather + // list for hardware. + + IODMACommand* cmd; + IOReturn err = kIOReturnSuccess; + + // 64 bit physical address generation using IODMACommand + do + { + cmd = IODMACommand::withSpecification( + // outSegFunc - Host endian since we read the address data with the cpu + // and 64 bit wide quantities + kIODMACommandOutputHost64, + // numAddressBits + 64, + // maxSegmentSize - zero for unrestricted physically contiguous chunks + 0, + // mappingOptions - kMapped for DMA addresses + IODMACommand::kMapped, + // maxTransferSize - no restriction + 0, + // alignment - no restriction + 1 ); + if (!cmd) + { + IOLog("IODMACommand::withSpecification failed\n"); + break; + } + + // Point at the memory descriptor and use the auto prepare option + // to prepare the entire range + err = cmd->setMemoryDescriptor(memDesc); + if (kIOReturnSuccess != err) + { + IOLog("setMemoryDescriptor failed (0x%08x)\n", err); + break; + } + + UInt64 offset = 0; + while ((kIOReturnSuccess == err) && (offset < memDesc->getLength())) + { + // use the 64 bit variant to match outSegFunc + IODMACommand::Segment64 segments[1]; + UInt32 numSeg = 1; + + // use the 64 bit variant to match outSegFunc + err = cmd->gen64IOVMSegments(&offset, &segments[0], &numSeg); + IOLog("gen64IOVMSegments(%x) addr 0x%016llx, len %llu, nsegs " UInt32_FORMAT "\n", + err, segments[0].fIOVMAddr, segments[0].fLength, numSeg); + } + + // if we had a DMA controller, kick off the DMA here + + // when the DMA has completed, + + // clear the memory descriptor and use the auto complete option + // to complete the transaction + err = cmd->clearMemoryDescriptor(); + if (kIOReturnSuccess != err) + { + IOLog("clearMemoryDescriptor failed (0x%08x)\n", err); + } + } + while (false); + if (cmd) + cmd->release(); + // end 64 bit loop + + + // 32 bit physical address generation using IODMACommand + // any memory above 4GiB in the memory descriptor will be bounce-buffered + // to memory below the 4GiB line on machines without remapping HW support + do + { + cmd = IODMACommand::withSpecification( + // outSegFunc - Host endian since we read the address data with the cpu + // and 32 bit wide quantities + kIODMACommandOutputHost32, + // numAddressBits + 32, + // maxSegmentSize - zero for unrestricted physically contiguous chunks + 0, + // mappingOptions - kMapped for DMA addresses + IODMACommand::kMapped, + // maxTransferSize - no restriction + 0, + // alignment - no restriction + 1 ); + if (!cmd) + { + IOLog("IODMACommand::withSpecification failed\n"); + break; + } + + // point at the memory descriptor and use the auto prepare option + // to prepare the entire range + err = cmd->setMemoryDescriptor(memDesc); + if (kIOReturnSuccess != err) + { + IOLog("setMemoryDescriptor failed (0x%08x)\n", err); + break; + } + + UInt64 offset = 0; + while ((kIOReturnSuccess == err) && (offset < memDesc->getLength())) + { + // use the 32 bit variant to match outSegFunc + IODMACommand::Segment32 segments[1]; + UInt32 numSeg = 1; + + // use the 32 bit variant to match outSegFunc + err = cmd->gen32IOVMSegments(&offset, &segments[0], &numSeg); + IOLog("gen32IOVMSegments(%x) addr " UInt32_x_FORMAT ", len " UInt32_FORMAT ", nsegs " UInt32_FORMAT "\n", + err, segments[0].fIOVMAddr, segments[0].fLength, numSeg); + } + + // if we had a DMA controller, kick off the DMA here + + // when the DMA has completed, + + // clear the memory descriptor and use the auto complete option + // to complete the transaction + err = cmd->clearMemoryDescriptor(); + if (kIOReturnSuccess != err) + { + IOLog("clearMemoryDescriptor failed (0x%08x)\n", err); + } + } + while (false); + if (cmd) + cmd->release(); + // end 32 bit loop + + return (err); +} +#endif \ No newline at end of file diff --git a/AppleSamplePCI/AppleSamplePCI.h b/AppleSamplePCI/AppleSamplePCI.h new file mode 100644 index 00000000..a71bcc27 --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCI.h @@ -0,0 +1,109 @@ +// +// File: AppleSamplePCI.h +// +// Abstract: Sample PCI device driver +// +// Version: 2.0 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") +// in consideration of your agreement to the following terms, and your use, +// installation, modification or redistribution of this Apple software +// constitutes acceptance of these terms. If you do not agree with these +// terms, please do not use, install, modify or redistribute this Apple +// software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non - exclusive +// license, under Apple's copyrights in this original Apple software ( the +// "Apple Software" ), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and / or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following text +// and disclaimers in all such redistributions of the Apple Software. Neither +// the name, trademarks, service marks or logos of Apple Inc. may be used to +// endorse or promote products derived from the Apple Software without specific +// prior written permission from Apple. Except as expressly stated in this +// notice, no other rights or licenses, express or implied, are granted by +// Apple herein, including but not limited to any patent rights that may be +// infringed by your derivative works or by other works in which the Apple +// Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION +// ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION +// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER +// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR +// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright ( C ) 2008 Apple Inc. All Rights Reserved. +// + +#include +#include "AppleSamplePCIAvailability.h" +#include "AppleSamplePCIShared.h" + +#if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || !defined(MAC_OS_X_VERSION_10_4) +#error Missing definition of availability macros +#endif + +// Handy IOLog/printf format strings for dealing with types that have a different +// length on LP64. +#if __LP64__ +#define UInt32_FORMAT "%u" +#define UInt32_x_FORMAT "0x%08x" +#define PhysAddr_FORMAT "0x%016llx" +#define PhysLen_FORMAT "%llu" +#define VirtAddr_FORMAT "0x%016llx" +#define ByteCount_FORMAT "%llu" +#else +#define UInt32_FORMAT "%lu" +#define UInt32_x_FORMAT "0x%08lx" +#define PhysAddr_FORMAT "0x%08lx" +#define PhysLen_FORMAT UInt32_FORMAT +#define VirtAddr_FORMAT "0x%08x" +#define ByteCount_FORMAT UInt32_FORMAT +#endif + +// Forward declarations +class IOPCIDevice; +class IOMemoryDescriptor; + +class SamplePCIClassName : public IOService +{ + /* + * Declare the metaclass information that is used for runtime + * typechecking of I/O Kit objects. Note that the class name is different when targeting PowerPC on 10.4 + * because that support has to be built as a separate kext. This is because we have to use + * older 32-bit-only KPIs for that platform. + */ + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + OSDeclareDefaultStructors( com_YourCompany_driver_SamplePCI_10_4 ); +#else + OSDeclareDefaultStructors( com_YourCompany_driver_SamplePCI ); +#endif + +private: + IOPCIDevice* fPCIDevice; + IOMemoryDescriptor* fLowMemory; + +public: + /* IOService overrides */ + virtual bool start(IOService* provider); + virtual void stop(IOService* provider); + virtual IOReturn setProperties(OSObject* properties); + + /* Other methods */ + IOMemoryDescriptor* copyGlobalMemory(void); + IOReturn generateDMAAddresses(IOMemoryDescriptor* memDesc); + void updateRegistry(UInt32 value); +}; + + diff --git a/AppleSamplePCI/AppleSamplePCI.xcodeproj/project.pbxproj b/AppleSamplePCI/AppleSamplePCI.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8bd5a42b --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCI.xcodeproj/project.pbxproj @@ -0,0 +1,1027 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 181FB5220DF8573500F31406 /* AppleSamplePCIAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 181FB5210DF8573500F31406 /* AppleSamplePCIAvailability.h */; }; + 181FB5230DF8573500F31406 /* AppleSamplePCIAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 181FB5210DF8573500F31406 /* AppleSamplePCIAvailability.h */; }; + 185AD87D0DEF441000958A72 /* AppleSamplePCI.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A224C3EFF42367911CA2CB7 /* AppleSamplePCI.h */; }; + 185AD87E0DEF441000958A72 /* AppleSamplePCIShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 02DCC5CA0060199D11CA2A5F /* AppleSamplePCIShared.h */; }; + 185AD8810DEF441000958A72 /* AppleSamplePCI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A224C3FFF42367911CA2CB7 /* AppleSamplePCI.cpp */; settings = {ATTRIBUTES = (); }; }; + 185AD8820DEF441000958A72 /* AppleSamplePCIUserClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 014E0F880060136E11CA2A5F /* AppleSamplePCIUserClient.cpp */; }; + 185AD92B0DEF7A6800958A72 /* AppleSamplePCIUserClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 185AD92A0DEF7A6800958A72 /* AppleSamplePCIUserClient.h */; }; + 185AD92C0DEF7A6800958A72 /* AppleSamplePCIUserClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 185AD92A0DEF7A6800958A72 /* AppleSamplePCIUserClient.h */; }; + 187E14EC0DFA0831006054D0 /* AppleSamplePCIClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */; }; + 187E14EE0DFA0831006054D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */; }; + 187E14EF0DFA0831006054D0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690C0DD12A04004CBF5F /* IOKit.framework */; }; + 187E14F90DFA0860006054D0 /* AppleSamplePCIClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */; }; + 187E14FB0DFA0860006054D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */; }; + 187E14FC0DFA0860006054D0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690C0DD12A04004CBF5F /* IOKit.framework */; }; + 187E15060DFA0884006054D0 /* AppleSamplePCIClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */; }; + 187E15080DFA0884006054D0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */; }; + 187E15090DFA0884006054D0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690C0DD12A04004CBF5F /* IOKit.framework */; }; + 69156DC50DE722660032D6B1 /* AppleSamplePCIClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */; }; + 69156DC70DE722660032D6B1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */; }; + 69156DC80DE722660032D6B1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690C0DD12A04004CBF5F /* IOKit.framework */; }; + A6AB002F0AA3B2AC00401E96 /* AppleSamplePCI.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A224C3EFF42367911CA2CB7 /* AppleSamplePCI.h */; }; + A6AB00300AA3B2AC00401E96 /* AppleSamplePCIShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 02DCC5CA0060199D11CA2A5F /* AppleSamplePCIShared.h */; }; + A6AB00330AA3B2AC00401E96 /* AppleSamplePCI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A224C3FFF42367911CA2CB7 /* AppleSamplePCI.cpp */; settings = {ATTRIBUTES = (); }; }; + A6AB00340AA3B2AC00401E96 /* AppleSamplePCIUserClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 014E0F880060136E11CA2A5F /* AppleSamplePCIUserClient.cpp */; }; + BF6536EF0E018B6500EF1DF5 /* AppleSamplePCIClient.c in Sources */ = {isa = PBXBuildFile; fileRef = 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */; }; + BF6536F10E018B6500EF1DF5 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */; }; + BF6536F20E018B6500EF1DF5 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6948690C0DD12A04004CBF5F /* IOKit.framework */; }; + BF65379F0E01B3DF00EF1DF5 /* AppleSamplePCI_10_4.kext in CopyFiles */ = {isa = PBXBuildFile; fileRef = 185AD88A0DEF441000958A72 /* AppleSamplePCI_10_4.kext */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + BF6536F80E018C3500EF1DF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 089C1669FE841209C02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 187E14F70DFA0860006054D0; + remoteInfo = AppleSamplePCIClient_i386; + }; + BF65370A0E019CCF00EF1DF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 089C1669FE841209C02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A6AB002C0AA3B2AC00401E96; + remoteInfo = AppleSamplePCI; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + BF65378C0E01B2E700EF1DF5 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = AppleSamplePCI.kext/Contents/PlugIns; + dstSubfolderSpec = 16; + files = ( + BF65379F0E01B3DF00EF1DF5 /* AppleSamplePCI_10_4.kext in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 014E0F880060136E11CA2A5F /* AppleSamplePCIUserClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AppleSamplePCIUserClient.cpp; sourceTree = ""; }; + 02DCC5CA0060199D11CA2A5F /* AppleSamplePCIShared.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppleSamplePCIShared.h; sourceTree = ""; }; + 181FB5210DF8573500F31406 /* AppleSamplePCIAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleSamplePCIAvailability.h; sourceTree = ""; }; + 185AD88A0DEF441000958A72 /* AppleSamplePCI_10_4.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppleSamplePCI_10_4.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 185AD8CA0DEF4F4400958A72 /* Info-AppleSamplePCI_10_4.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-AppleSamplePCI_10_4.plist"; sourceTree = ""; }; + 185AD92A0DEF7A6800958A72 /* AppleSamplePCIUserClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleSamplePCIUserClient.h; sourceTree = ""; }; + 187E14F30DFA0831006054D0 /* AppleSamplePCIClient_x86_64 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AppleSamplePCIClient_x86_64; sourceTree = BUILT_PRODUCTS_DIR; }; + 187E15000DFA0860006054D0 /* AppleSamplePCIClient_i386 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AppleSamplePCIClient_i386; sourceTree = BUILT_PRODUCTS_DIR; }; + 187E150D0DFA0884006054D0 /* AppleSamplePCIClient_ppc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AppleSamplePCIClient_ppc; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A224C3EFF42367911CA2CB7 /* AppleSamplePCI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppleSamplePCI.h; sourceTree = ""; }; + 1A224C3FFF42367911CA2CB7 /* AppleSamplePCI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AppleSamplePCI.cpp; sourceTree = ""; }; + 69156DB90DE721DE0032D6B1 /* Kernel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kernel.framework; path = /System/Library/Frameworks/Kernel.framework; sourceTree = ""; }; + 69156DCD0DE722660032D6B1 /* AppleSamplePCIClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AppleSamplePCIClient; sourceTree = BUILT_PRODUCTS_DIR; }; + 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = AppleSamplePCIClient.c; sourceTree = ""; }; + 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; + 6948690C0DD12A04004CBF5F /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + A6AB003C0AA3B2AC00401E96 /* Info-AppleSamplePCI.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-AppleSamplePCI.plist"; sourceTree = ""; }; + A6AB003D0AA3B2AC00401E96 /* AppleSamplePCI.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppleSamplePCI.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + BF6536F60E018B6500EF1DF5 /* AppleSamplePCIClient_ppc64 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AppleSamplePCIClient_ppc64; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 185AD8830DEF441000958A72 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 187E14ED0DFA0831006054D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 187E14EE0DFA0831006054D0 /* CoreFoundation.framework in Frameworks */, + 187E14EF0DFA0831006054D0 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 187E14FA0DFA0860006054D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 187E14FB0DFA0860006054D0 /* CoreFoundation.framework in Frameworks */, + 187E14FC0DFA0860006054D0 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 187E15070DFA0884006054D0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 187E15080DFA0884006054D0 /* CoreFoundation.framework in Frameworks */, + 187E15090DFA0884006054D0 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 69156DC60DE722660032D6B1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 69156DC70DE722660032D6B1 /* CoreFoundation.framework in Frameworks */, + 69156DC80DE722660032D6B1 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A6AB00350AA3B2AC00401E96 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF6536F00E018B6500EF1DF5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BF6536F10E018B6500EF1DF5 /* CoreFoundation.framework in Frameworks */, + BF6536F20E018B6500EF1DF5 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* AppleSamplePCI */ = { + isa = PBXGroup; + children = ( + 247142CAFF3F8F9811CA285C /* Source */, + 184A321E0DF0B65A00BC208A /* Frameworks */, + 089C167CFE841241C02AAC07 /* Resources */, + 19C28FB6FE9D52B211CA2CBB /* Products */, + 69156DB90DE721DE0032D6B1 /* Kernel.framework */, + ); + name = AppleSamplePCI; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + A6AB003C0AA3B2AC00401E96 /* Info-AppleSamplePCI.plist */, + 185AD8CA0DEF4F4400958A72 /* Info-AppleSamplePCI_10_4.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 184A321E0DF0B65A00BC208A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6948690B0DD12A04004CBF5F /* CoreFoundation.framework */, + 6948690C0DD12A04004CBF5F /* IOKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 19C28FB6FE9D52B211CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + A6AB003D0AA3B2AC00401E96 /* AppleSamplePCI.kext */, + 69156DCD0DE722660032D6B1 /* AppleSamplePCIClient */, + 185AD88A0DEF441000958A72 /* AppleSamplePCI_10_4.kext */, + 187E14F30DFA0831006054D0 /* AppleSamplePCIClient_x86_64 */, + 187E15000DFA0860006054D0 /* AppleSamplePCIClient_i386 */, + 187E150D0DFA0884006054D0 /* AppleSamplePCIClient_ppc */, + BF6536F60E018B6500EF1DF5 /* AppleSamplePCIClient_ppc64 */, + ); + name = Products; + sourceTree = ""; + }; + 247142CAFF3F8F9811CA285C /* Source */ = { + isa = PBXGroup; + children = ( + 1A224C3EFF42367911CA2CB7 /* AppleSamplePCI.h */, + 1A224C3FFF42367911CA2CB7 /* AppleSamplePCI.cpp */, + 185AD92A0DEF7A6800958A72 /* AppleSamplePCIUserClient.h */, + 014E0F880060136E11CA2A5F /* AppleSamplePCIUserClient.cpp */, + 181FB5210DF8573500F31406 /* AppleSamplePCIAvailability.h */, + 02DCC5CA0060199D11CA2A5F /* AppleSamplePCIShared.h */, + 694869070DD129DB004CBF5F /* AppleSamplePCIClient.c */, + ); + name = Source; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 185AD87C0DEF441000958A72 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 185AD87D0DEF441000958A72 /* AppleSamplePCI.h in Headers */, + 185AD87E0DEF441000958A72 /* AppleSamplePCIShared.h in Headers */, + 185AD92B0DEF7A6800958A72 /* AppleSamplePCIUserClient.h in Headers */, + 181FB5220DF8573500F31406 /* AppleSamplePCIAvailability.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A6AB002E0AA3B2AC00401E96 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A6AB002F0AA3B2AC00401E96 /* AppleSamplePCI.h in Headers */, + A6AB00300AA3B2AC00401E96 /* AppleSamplePCIShared.h in Headers */, + 185AD92C0DEF7A6800958A72 /* AppleSamplePCIUserClient.h in Headers */, + 181FB5230DF8573500F31406 /* AppleSamplePCIAvailability.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 185AD87A0DEF441000958A72 /* AppleSamplePCI_10.4 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 185AD8860DEF441000958A72 /* Build configuration list for PBXNativeTarget "AppleSamplePCI_10.4" */; + buildPhases = ( + 185AD87C0DEF441000958A72 /* Headers */, + 185AD87F0DEF441000958A72 /* Resources */, + 185AD8800DEF441000958A72 /* Sources */, + 185AD8830DEF441000958A72 /* Frameworks */, + 185AD8840DEF441000958A72 /* Rez */, + BF65378C0E01B2E700EF1DF5 /* CopyFiles */, + ); + buildRules = ( + ); + comments = "Builds ppc architecture using MacOSX10.3.9 SDK and GCC 3.3.\nInstalls into main kext's PlugIns directory."; + dependencies = ( + BF65370B0E019CCF00EF1DF5 /* PBXTargetDependency */, + ); + name = AppleSamplePCI_10.4; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = AppleSamplePCI; + productReference = 185AD88A0DEF441000958A72 /* AppleSamplePCI_10_4.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; + 187E14EA0DFA0831006054D0 /* AppleSamplePCIClient_x86_64 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 187E14F00DFA0831006054D0 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_x86_64" */; + buildPhases = ( + 187E14EB0DFA0831006054D0 /* Sources */, + 187E14ED0DFA0831006054D0 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppleSamplePCIClient_x86_64; + productName = AppleSamplePCIUserClient; + productReference = 187E14F30DFA0831006054D0 /* AppleSamplePCIClient_x86_64 */; + productType = "com.apple.product-type.tool"; + }; + 187E14F70DFA0860006054D0 /* AppleSamplePCIClient_i386 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 187E14FD0DFA0860006054D0 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_i386" */; + buildPhases = ( + 187E14F80DFA0860006054D0 /* Sources */, + 187E14FA0DFA0860006054D0 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppleSamplePCIClient_i386; + productName = AppleSamplePCIUserClient; + productReference = 187E15000DFA0860006054D0 /* AppleSamplePCIClient_i386 */; + productType = "com.apple.product-type.tool"; + }; + 187E15040DFA0884006054D0 /* AppleSamplePCIClient_ppc */ = { + isa = PBXNativeTarget; + buildConfigurationList = 187E150A0DFA0884006054D0 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_ppc" */; + buildPhases = ( + 187E15050DFA0884006054D0 /* Sources */, + 187E15070DFA0884006054D0 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppleSamplePCIClient_ppc; + productName = AppleSamplePCIUserClient; + productReference = 187E150D0DFA0884006054D0 /* AppleSamplePCIClient_ppc */; + productType = "com.apple.product-type.tool"; + }; + 69156DC30DE722660032D6B1 /* AppleSamplePCIClient */ = { + isa = PBXNativeTarget; + buildConfigurationList = 69156DC90DE722660032D6B1 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient" */; + buildPhases = ( + 69156DC40DE722660032D6B1 /* Sources */, + 69156DC60DE722660032D6B1 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + BF6536F90E018C3500EF1DF5 /* PBXTargetDependency */, + ); + name = AppleSamplePCIClient; + productName = AppleSamplePCIUserClient; + productReference = 69156DCD0DE722660032D6B1 /* AppleSamplePCIClient */; + productType = "com.apple.product-type.tool"; + }; + A6AB002C0AA3B2AC00401E96 /* AppleSamplePCI */ = { + isa = PBXNativeTarget; + buildConfigurationList = A6AB00380AA3B2AC00401E96 /* Build configuration list for PBXNativeTarget "AppleSamplePCI" */; + buildPhases = ( + A6AB002E0AA3B2AC00401E96 /* Headers */, + A6AB00310AA3B2AC00401E96 /* Resources */, + A6AB00320AA3B2AC00401E96 /* Sources */, + A6AB00350AA3B2AC00401E96 /* Frameworks */, + A6AB00360AA3B2AC00401E96 /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppleSamplePCI; + productInstallPath = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + productName = AppleSamplePCI; + productReference = A6AB003D0AA3B2AC00401E96 /* AppleSamplePCI.kext */; + productType = "com.apple.product-type.kernel-extension.iokit"; + }; + BF6536ED0E018B6500EF1DF5 /* AppleSamplePCIClient_ppc64 */ = { + isa = PBXNativeTarget; + buildConfigurationList = BF6536F30E018B6500EF1DF5 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_ppc64" */; + buildPhases = ( + BF6536EE0E018B6500EF1DF5 /* Sources */, + BF6536F00E018B6500EF1DF5 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppleSamplePCIClient_ppc64; + productName = AppleSamplePCIUserClient; + productReference = BF6536F60E018B6500EF1DF5 /* AppleSamplePCIClient_ppc64 */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = A65146A00A50ADC4006021BE /* Build configuration list for PBXProject "AppleSamplePCI" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* AppleSamplePCI */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A6AB002C0AA3B2AC00401E96 /* AppleSamplePCI */, + 185AD87A0DEF441000958A72 /* AppleSamplePCI_10.4 */, + 69156DC30DE722660032D6B1 /* AppleSamplePCIClient */, + 187E14F70DFA0860006054D0 /* AppleSamplePCIClient_i386 */, + 187E14EA0DFA0831006054D0 /* AppleSamplePCIClient_x86_64 */, + 187E15040DFA0884006054D0 /* AppleSamplePCIClient_ppc */, + BF6536ED0E018B6500EF1DF5 /* AppleSamplePCIClient_ppc64 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 185AD87F0DEF441000958A72 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A6AB00310AA3B2AC00401E96 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 185AD8840DEF441000958A72 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A6AB00360AA3B2AC00401E96 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 185AD8800DEF441000958A72 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 185AD8810DEF441000958A72 /* AppleSamplePCI.cpp in Sources */, + 185AD8820DEF441000958A72 /* AppleSamplePCIUserClient.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 187E14EB0DFA0831006054D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 187E14EC0DFA0831006054D0 /* AppleSamplePCIClient.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 187E14F80DFA0860006054D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 187E14F90DFA0860006054D0 /* AppleSamplePCIClient.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 187E15050DFA0884006054D0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 187E15060DFA0884006054D0 /* AppleSamplePCIClient.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 69156DC40DE722660032D6B1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 69156DC50DE722660032D6B1 /* AppleSamplePCIClient.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A6AB00320AA3B2AC00401E96 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A6AB00330AA3B2AC00401E96 /* AppleSamplePCI.cpp in Sources */, + A6AB00340AA3B2AC00401E96 /* AppleSamplePCIUserClient.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF6536EE0E018B6500EF1DF5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF6536EF0E018B6500EF1DF5 /* AppleSamplePCIClient.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + BF6536F90E018C3500EF1DF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 187E14F70DFA0860006054D0 /* AppleSamplePCIClient_i386 */; + targetProxy = BF6536F80E018C3500EF1DF5 /* PBXContainerItemProxy */; + }; + BF65370B0E019CCF00EF1DF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A6AB002C0AA3B2AC00401E96 /* AppleSamplePCI */; + targetProxy = BF65370A0E019CCF00EF1DF5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 185AD8870DEF441000958A72 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = 4.0; + HEADER_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/Headers", + ); + INFOPLIST_FILE = "Info-AppleSamplePCI_10_4.plist"; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = "a-w,u+w,a+rX"; + INSTALL_OWNER = root; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + KERNEL_MODULE = YES; + LIBRARY_SEARCH_PATHS = ""; + MODULE_IOKIT = YES; + MODULE_NAME = com.YourCompany.driver.SamplePCI_10_4; + MODULE_VERSION = 2.0.0d1; + ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = AppleSamplePCI_10_4; + SDKROOT = macosx10.4; + SECTORDER_FLAGS = ""; + VALID_ARCHS = "ppc i386"; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + 185AD8880DEF441000958A72 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = 4.0; + HEADER_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/Headers", + ); + INFOPLIST_FILE = "Info-AppleSamplePCI_10_4.plist"; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = "a-w,u+w,a+rX"; + INSTALL_OWNER = root; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + KERNEL_MODULE = YES; + LIBRARY_SEARCH_PATHS = ""; + MODULE_IOKIT = YES; + MODULE_NAME = com.YourCompany.driver.SamplePCI_10_4; + MODULE_VERSION = 2.0.0d1; + ONLY_ACTIVE_ARCH = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = AppleSamplePCI_10_4; + SDKROOT = macosx10.4; + SECTORDER_FLAGS = ""; + VALID_ARCHS = "ppc i386"; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; + 187E14F10DFA0831006054D0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = x86_64; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_OPTIMIZATION_LEVEL = 0; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_x86_64; + SDKROOT = macosx10.6; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Debug; + }; + 187E14F20DFA0831006054D0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = x86_64; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_x86_64; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Release; + }; + 187E14FE0DFA0860006054D0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = i386; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_OPTIMIZATION_LEVEL = 0; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_i386; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Debug; + }; + 187E14FF0DFA0860006054D0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = i386; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_i386; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Release; + }; + 187E150B0DFA0884006054D0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ppc; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_OPTIMIZATION_LEVEL = 0; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_ppc; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Debug; + }; + 187E150C0DFA0884006054D0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ppc; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_ppc; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Release; + }; + 69156DCA0DE722660032D6B1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + x86_64, + ppc64, + ); + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_OPTIMIZATION_LEVEL = 0; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Debug; + }; + 69156DCB0DE722660032D6B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + x86_64, + ppc64, + ); + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Release; + }; + A65146A10A50ADC4006021BE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + SDKROOT = macosx10.6; + WARNING_CFLAGS = ( + "-Wall", + "-Wshorten-64-to-32", + ); + }; + name = Debug; + }; + A65146A20A50ADC4006021BE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + SDKROOT = macosx10.6; + WARNING_CFLAGS = ( + "-Wall", + "-Wshorten-64-to-32", + ); + }; + name = Release; + }; + A6AB00390AA3B2AC00401E96 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = ""; + "GCC_VERSION[sdk=macosx10.5]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=x86_64]" = ""; + HEADER_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/Headers", + ); + INFOPLIST_FILE = "Info-AppleSamplePCI.plist"; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = "a-w,u+w,a+rX"; + INSTALL_OWNER = root; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + KERNEL_MODULE = YES; + LIBRARY_SEARCH_PATHS = ""; + "MACOSX_DEPLOYMENT_TARGET[sdk=macosx10.5]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[sdk=macosx10.6][arch=x86_64]" = 10.6; + MODULE_IOKIT = YES; + MODULE_NAME = com.YourCompany.driver.SamplePCI; + MODULE_VERSION = 2.0.0d1; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = AppleSamplePCI; + SDKROOT = macosx10.6; + "SDKROOT[arch=i386]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.5; + "SDKROOT[arch=x86_64]" = macosx10.6; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + A6AB003A0AA3B2AC00401E96 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = ""; + "GCC_VERSION[sdk=macosx10.5]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=x86_64]" = ""; + HEADER_SEARCH_PATHS = ( + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/PrivateHeaders", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/Kernel.framework/Headers", + ); + INFOPLIST_FILE = "Info-AppleSamplePCI.plist"; + INSTALL_GROUP = wheel; + INSTALL_MODE_FLAG = "a-w,u+w,a+rX"; + INSTALL_OWNER = root; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Extensions"; + KERNEL_MODULE = YES; + LIBRARY_SEARCH_PATHS = ""; + "MACOSX_DEPLOYMENT_TARGET[sdk=macosx10.5]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[sdk=macosx10.6][arch=x86_64]" = 10.6; + MODULE_IOKIT = YES; + MODULE_NAME = com.YourCompany.driver.SamplePCI; + MODULE_VERSION = 2.0.0d1; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = AppleSamplePCI; + SDKROOT = macosx10.6; + "SDKROOT[arch=i386]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.5; + "SDKROOT[arch=x86_64]" = macosx10.6; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; + BF6536F40E018B6500EF1DF5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ppc64; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_OPTIMIZATION_LEVEL = 0; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_ppc64; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Debug; + }; + BF6536F50E018B6500EF1DF5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ppc64; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + "GCC_VERSION[sdk=macosx10.4][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.5][arch=*]" = 4.0; + "GCC_VERSION[sdk=macosx10.6][arch=*]" = ""; + INSTALL_PATH = /usr/local/bin; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + PREBINDING = NO; + PRODUCT_NAME = AppleSamplePCIClient_ppc64; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc64]" = macosx10.5; + "SDKROOT[arch=ppc]" = macosx10.4; + "SDKROOT[arch=x86_64]" = macosx10.5; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 185AD8860DEF441000958A72 /* Build configuration list for PBXNativeTarget "AppleSamplePCI_10.4" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 185AD8870DEF441000958A72 /* Debug */, + 185AD8880DEF441000958A72 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 187E14F00DFA0831006054D0 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_x86_64" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 187E14F10DFA0831006054D0 /* Debug */, + 187E14F20DFA0831006054D0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 187E14FD0DFA0860006054D0 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_i386" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 187E14FE0DFA0860006054D0 /* Debug */, + 187E14FF0DFA0860006054D0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 187E150A0DFA0884006054D0 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_ppc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 187E150B0DFA0884006054D0 /* Debug */, + 187E150C0DFA0884006054D0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 69156DC90DE722660032D6B1 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 69156DCA0DE722660032D6B1 /* Debug */, + 69156DCB0DE722660032D6B1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + A65146A00A50ADC4006021BE /* Build configuration list for PBXProject "AppleSamplePCI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A65146A10A50ADC4006021BE /* Debug */, + A65146A20A50ADC4006021BE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + A6AB00380AA3B2AC00401E96 /* Build configuration list for PBXNativeTarget "AppleSamplePCI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A6AB00390AA3B2AC00401E96 /* Debug */, + A6AB003A0AA3B2AC00401E96 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + BF6536F30E018B6500EF1DF5 /* Build configuration list for PBXNativeTarget "AppleSamplePCIClient_ppc64" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BF6536F40E018B6500EF1DF5 /* Debug */, + BF6536F50E018B6500EF1DF5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/AppleSamplePCI/AppleSamplePCIAvailability.h b/AppleSamplePCI/AppleSamplePCIAvailability.h new file mode 100644 index 00000000..1509a383 --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCIAvailability.h @@ -0,0 +1,93 @@ +// +// File: AppleSamplePCIAvailability.h +// +// Abstract: Subset of AvailabilityMacros.h for pre-10.5 kernel builds. +// +// The availability macros are useful for conditionally compiling code targeting +// specific versions of Mac OS X. But these macros aren't available to kernel code +// prior to Mac OS X 10.5. Code targeting 10.5 and later should use AvailabilityMacros.h +// instead of this file. Code targeting 10.6 and later should use Availability.h +// instead of this file. +// +// Version: 1.0 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") +// in consideration of your agreement to the following terms, and your use, +// installation, modification or redistribution of this Apple software +// constitutes acceptance of these terms. If you do not agree with these +// terms, please do not use, install, modify or redistribute this Apple +// software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non - exclusive +// license, under Apple's copyrights in this original Apple software ( the +// "Apple Software" ), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and / or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following text +// and disclaimers in all such redistributions of the Apple Software. Neither +// the name, trademarks, service marks or logos of Apple Inc. may be used to +// endorse or promote products derived from the Apple Software without specific +// prior written permission from Apple. Except as expressly stated in this +// notice, no other rights or licenses, express or implied, are granted by +// Apple herein, including but not limited to any patent rights that may be +// infringed by your derivative works or by other works in which the Apple +// Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION +// ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION +// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER +// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR +// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright ( C ) 2008 Apple Inc. All Rights Reserved. +// + + +/* + * Set up standard Mac OS X versions + */ +#define MAC_OS_X_VERSION_10_0 1000 +#define MAC_OS_X_VERSION_10_1 1010 +#define MAC_OS_X_VERSION_10_2 1020 +#define MAC_OS_X_VERSION_10_3 1030 +#define MAC_OS_X_VERSION_10_4 1040 +#define MAC_OS_X_VERSION_10_5 1050 +#define MAC_OS_X_VERSION_10_6 1060 + + +/* + * If min OS not specified, assume 10.1 for ppc and 10.4 for all others + * Note: gcc driver may set _ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED_ based on MACOSX_DEPLOYMENT_TARGET environment variable + */ +#ifndef MAC_OS_X_VERSION_MIN_REQUIRED +#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#if (__i386__ || __x86_64__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < MAC_OS_X_VERSION_10_4) +#warning Building for Intel with Mac OS X Deployment Target < 10.4 is invalid. +#elif __ppc64__ && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < MAC_OS_X_VERSION_10_4) +#warning Building for ppc64 with Mac OS X Deployment Target < 10.4 is invalid. +#endif +#define MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +#else +#if __ppc64__ || __i386__ || __x86_64__ +#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_4 +#else +#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_1 +#endif +#endif +#endif + +/* + * Error on bad values + */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_0 +#error MAC_OS_X_VERSION_MIN_REQUIRED must be >= MAC_OS_X_VERSION_10_0 +#endif diff --git a/AppleSamplePCI/AppleSamplePCIClient.c b/AppleSamplePCI/AppleSamplePCIClient.c new file mode 100644 index 00000000..135139be --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCIClient.c @@ -0,0 +1,316 @@ +// +// File: AppleSamplePCIClient.c +// +// Abstract: Userland Application that accesses the user client routines of our AppleSamplePCI kext +// is ifdef'd to reflect different methods appropriate for different OS versions. +// +// Version: 2.0 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") +// in consideration of your agreement to the following terms, and your use, +// installation, modification or redistribution of this Apple software +// constitutes acceptance of these terms. If you do not agree with these +// terms, please do not use, install, modify or redistribute this Apple +// software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non - exclusive +// license, under Apple's copyrights in this original Apple software ( the +// "Apple Software" ), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and / or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following text +// and disclaimers in all such redistributions of the Apple Software. Neither +// the name, trademarks, service marks or logos of Apple Inc. may be used to +// endorse or promote products derived from the Apple Software without specific +// prior written permission from Apple. Except as expressly stated in this +// notice, no other rights or licenses, express or implied, are granted by +// Apple herein, including but not limited to any patent rights that may be +// infringed by your derivative works or by other works in which the Apple +// Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION +// ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION +// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER +// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR +// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright ( C ) 2008 Apple Inc. All Rights Reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AppleSamplePCIShared.h" + +void TestProperties( io_service_t service ); +void TestUserClient( io_service_t service ); +void TestSharedMemory( io_connect_t connect ); + +#define arrayCnt(var) (sizeof(var) / sizeof(var[0])) + +void TestProperties( io_service_t service ) +{ + CFMutableDictionaryRef properties; + CFStringRef cfStr; + kern_return_t kr; + CFMutableDictionaryRef dictRef; + CFNumberRef numberRef; + SInt32 constant24 = 24; + + // Create a dictionary to pass to our driver. This dictionary has the key "value" + // and the value an integer in constant24. + printf("Testing sending properties to the driver.\n"); + + dictRef = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &constant24); + CFDictionarySetValue(dictRef, CFSTR("value"), numberRef); + CFRelease(numberRef); + + // This is the function that results in ::setProperties() being called in our + // kernel driver. The dictionary we created is passed to the driver here. + kr = IORegistryEntrySetCFProperties(service, dictRef); + if (KERN_SUCCESS != kr) { + fprintf(stderr, "IORegistryEntrySetCFProperties returned 0x%08x.\n", kr); + } else { + printf("Property setting test succeeded.\n"); + } + + // print the value of kIONameMatchedKey property, as an example of + // getting properties from the registry. Property based access + // doesn't require a user client connection. + // grab a copy of the properties + printf("Testing fetching driver's properties from the I/O Registry.\n"); + + kr = IORegistryEntryCreateCFProperties( service, &properties, + kCFAllocatorDefault, kNilOptions ); + assert( KERN_SUCCESS == kr ); + + // finding the name we matched on + cfStr = CFDictionaryGetValue( properties, CFSTR(kIONameMatchedKey) ); + if ( cfStr) { + const char* c = NULL; + char* buffer = NULL; + c = CFStringGetCStringPtr(cfStr, kCFStringEncodingMacRoman); + if (!c) { + CFIndex bufferSize = CFStringGetLength(cfStr) + 1; + buffer = malloc(bufferSize); + if (buffer) { + if (CFStringGetCString(cfStr, buffer, bufferSize, kCFStringEncodingMacRoman)) + c = buffer; + } + } + if (c) + printf("Driver matched on name \"%s\"\n", c); + if (buffer) + free(buffer); + } + CFRelease( properties ); + + printf("Property fetching test completed.\n"); +} + +void TestUserClient( io_service_t service ) +{ + kern_return_t kr; + io_connect_t connect; + size_t structureOutputSize; + SampleStructForMethod2 method2Param; + SampleResultsForMethod2 method2Results; + uint32_t varStructParam[3] = { 1, 2, 3 }; + IOByteCount bigBufferLen; + uint32_t * bigBuffer; + + // connecting to driver + kr = IOServiceOpen( service, mach_task_self(), kSamplePCIConnectType, &connect ); + assert( KERN_SUCCESS == kr ); + + // test a simple struct in/out method + structureOutputSize = sizeof(varStructParam); + + // here's how to properly ifdef forward... +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + kr = IOConnectMethodStructureIStructureO( connect, kSampleMethod1, + sizeof(varStructParam), /* structureInputSize */ + &structureOutputSize, /* structureOutputSize */ + &varStructParam, /* inputStructure */ + &varStructParam); /* ouputStructure */ +#else + kr = IOConnectCallStructMethod( connect, kSampleMethod1, + // inputStructure + &varStructParam, sizeof(varStructParam), + // ouputStructure + &varStructParam, &structureOutputSize ); +#endif + + assert( KERN_SUCCESS == kr ); + printf("kSampleMethod1 results 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "\n", + varStructParam[0], varStructParam[1], varStructParam[2]); + + // test shared memory + TestSharedMemory( connect ); + + // test method with out of line memory. + // Use anonymous mmap to ensure we get a single VM object. + bigBufferLen = 0x4321; + bigBuffer = (uint32_t *) mmap(NULL, bigBufferLen, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); + if (bigBuffer == MAP_FAILED) { + perror("mmap() call error:"); + return; + } + + printf("buffer is created @ %p\n", bigBuffer); + + strcpy( (char *) (bigBuffer + (32 / 4)), "some out of line data"); + + method2Param.parameter1 = 0x12345678; + method2Param.data_pointer = (uintptr_t) bigBuffer; + method2Param.data_length = bigBufferLen; + + structureOutputSize = sizeof(method2Results); + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + kr = IOConnectMethodStructureIStructureO( connect, kSampleMethod2, + sizeof(method2Param), /* structureInputSize */ + &structureOutputSize, /* structureOutputSize */ + &method2Param, /* inputStructure */ + &method2Results); /* ouputStructure */ +#else + kr = IOConnectCallStructMethod( connect, kSampleMethod2, + // inputStructure + &method2Param, sizeof(method2Param), + // ouputStructure + &method2Results, &structureOutputSize ); +#endif + + assert( KERN_SUCCESS == kr ); + printf("kSampleMethod2 result 0x%" PRIx64 "\n", method2Results.results1); + + munmap( bigBuffer, bigBufferLen ); +} +// when using shared memory you need to decide and manage the endianess and word length issues +// remember that if you expect to support mixed endiness (i.e. Rosetta) you probably will want to +// be using shared memory in a PPC way even on Intel machines. Why? Can you rewrite the old PPC +// app to understand Intel endianess and word length? No :-( +// +// An alternative for shared memory for a high speed streaming data queue would be IOStream Family. + +void TestSharedMemory( io_connect_t connect ) +{ + kern_return_t kr; + SampleSharedMemory * shared; + +#if __LP64__ + mach_vm_address_t addr; + mach_vm_size_t size; +#else + vm_address_t addr; + vm_size_t size; +#endif + + kr = IOConnectMapMemory( connect, kSamplePCIMemoryType1, + mach_task_self(), &addr, &size, + kIOMapAnywhere | kIOMapDefaultCache ); + assert( KERN_SUCCESS == kr ); + assert( size == sizeof( SampleSharedMemory )); + + shared = (SampleSharedMemory *) addr; + + printf("From SampleSharedMemory: %08" PRIx32 ", %08" PRIx32 ", %08" PRIx32 ", \"%s\"\n", + shared->field1, shared->field2, shared->field3, shared->string); + + strcpy( shared->string, "some other data" ); +} + + +int main( int argc, char * argv[] ) +{ + io_iterator_t iter; + io_service_t service; + kern_return_t kr; + bool driverFound = false; + + // Look up the object we wish to open. This example uses simple class + // matching (IOServiceMatching()) to look up the object that is the + // SamplePCI driver class instantiated by the kext. + + // Because older versions of Mac OS X had no weak-linking support in the kernel, the only way to + // support mutually-exclusive KPIs is to provide separate kexts. This in turn means that the + // separate kexts must have their own unique CFBundleIdentifiers and I/O Kit class names. + // + // This sample shows how to do this in the AppleSamplePCI and AppleSamplePCI_10.4 Xcode targets. + // + // From the userland perspective, a process must look for any of the class names it is prepared to talk + // to. + + kr = IOServiceGetMatchingServices( kIOMasterPortDefault, + IOServiceMatching( kSamplePCIClassName ), &iter); + assert( KERN_SUCCESS == kr ); + + for( ; + (service = IOIteratorNext(iter)); + IOObjectRelease(service)) { + io_string_t path; + kr = IORegistryEntryGetPath(service, kIOServicePlane, path); + assert( KERN_SUCCESS == kr ); + + driverFound = true; + printf("Found a device of class "kSamplePCIClassName": %s\n", path); + + // Test getting and setting properties + TestProperties( service ); + + // Test the user client + TestUserClient( service ); + } + IOObjectRelease(iter); + + kr = IOServiceGetMatchingServices( kIOMasterPortDefault, + IOServiceMatching( kSamplePCIClassName_10_4 ), &iter); + assert( KERN_SUCCESS == kr ); + + for( ; + (service = IOIteratorNext(iter)); + IOObjectRelease(service)) { + io_string_t path; + kr = IORegistryEntryGetPath(service, kIOServicePlane, path); + assert( KERN_SUCCESS == kr ); + + driverFound = true; + printf("Found a device of class "kSamplePCIClassName_10_4": %s\n", path); + + // Test getting and setting properties + TestProperties( service ); + + // Test the user client + TestUserClient( service ); + } + IOObjectRelease(iter); + + if (driverFound == false) { + fprintf(stderr, "No matching drivers found.\n"); + } + + return EXIT_SUCCESS; +} + diff --git a/AppleSamplePCI/AppleSamplePCIShared.h b/AppleSamplePCI/AppleSamplePCIShared.h new file mode 100644 index 00000000..ac1aae88 --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCIShared.h @@ -0,0 +1,108 @@ +// +// File: AppleSamplePCIShared.h +// +// Abstract: Shared header that defines the data structures we can use to +// communicate between our kext and our userland client> +// +// Version: 2.0 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") +// in consideration of your agreement to the following terms, and your use, +// installation, modification or redistribution of this Apple software +// constitutes acceptance of these terms. If you do not agree with these +// terms, please do not use, install, modify or redistribute this Apple +// software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non - exclusive +// license, under Apple's copyrights in this original Apple software ( the +// "Apple Software" ), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and / or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following text +// and disclaimers in all such redistributions of the Apple Software. Neither +// the name, trademarks, service marks or logos of Apple Inc. may be used to +// endorse or promote products derived from the Apple Software without specific +// prior written permission from Apple. Except as expressly stated in this +// notice, no other rights or licenses, express or implied, are granted by +// Apple herein, including but not limited to any patent rights that may be +// infringed by your derivative works or by other works in which the Apple +// Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION +// ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION +// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER +// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR +// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright ( C ) 2008 Apple Inc. All Rights Reserved. +// + +// Have to be careful regarding the alignment of structures since +// this file is shared between 32 bit kernel code and 32 or 64 bit +// user level code. +// See http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting/index.html + +// Structures in this file are aligned naturally by ordering any 64 bit quantities first. +// #pragma pack could also be used to force alignment + +enum { + kSampleMethod1 = 0, + kSampleMethod2 = 1, + kSampleMethod3 = 2, + kSampleNumMethods +}; + +// To avoid invisible compiler padding, align fields on 64-bit boundaries when possible +// and make the whole structure's size a multiple of 64 bits. +typedef struct SampleStructForMethod2 { + uint64_t data_pointer; // Use C99 types to ensure desired size without unexpected truncation of 64-bit quantities. + uint64_t data_length; + uint32_t parameter1; + uint32_t __pad; +} SampleStructForMethod2; + +typedef struct SampleResultsForMethod2 { + uint64_t results1; +} SampleResultsForMethod2; + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#define SamplePCIClassName com_YourCompany_driver_SamplePCI_10_4 +#else +#define SamplePCIClassName com_YourCompany_driver_SamplePCI +#endif + +#define kSamplePCIClassName "com_YourCompany_driver_SamplePCI" +#define kSamplePCIClassName_10_4 "com_YourCompany_driver_SamplePCI_10_4" + +// types for IOServiceOpen() +enum { + kSamplePCIConnectType = 23 +}; + +// types for IOConnectMapMemory() +enum { + kSamplePCIMemoryType1 = 100, + kSamplePCIMemoryType2 = 101, +}; + +// memory structure to be shared between the kernel and userland. +typedef struct SampleSharedMemory { + uint32_t field1; + uint32_t field2; + uint32_t field3; + char string[100]; +} SampleSharedMemory; + +#define kMyDisplayBrightnessKey "brightness" +#define kMyDisplayParametersKey "DisplayParameters" +#define kMyDisplayValueKey "value" +#define kMyPropertyKey "MyProperty" \ No newline at end of file diff --git a/AppleSamplePCI/AppleSamplePCIUserClient.cpp b/AppleSamplePCI/AppleSamplePCIUserClient.cpp new file mode 100644 index 00000000..fa9f9980 --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCIUserClient.cpp @@ -0,0 +1,478 @@ +// +// File: AppleSamplePCIUserClient.cpp +// +// Abstract: User client interface between userland and sample kernel PCI driver +// +// Version: 2.0 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") +// in consideration of your agreement to the following terms, and your use, +// installation, modification or redistribution of this Apple software +// constitutes acceptance of these terms. If you do not agree with these +// terms, please do not use, install, modify or redistribute this Apple +// software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non - exclusive +// license, under Apple's copyrights in this original Apple software ( the +// "Apple Software" ), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and / or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following text +// and disclaimers in all such redistributions of the Apple Software. Neither +// the name, trademarks, service marks or logos of Apple Inc. may be used to +// endorse or promote products derived from the Apple Software without specific +// prior written permission from Apple. Except as expressly stated in this +// notice, no other rights or licenses, express or implied, are granted by +// Apple herein, including but not limited to any patent rights that may be +// infringed by your derivative works or by other works in which the Apple +// Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION +// ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION +// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER +// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR +// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright ( C ) 2008 Apple Inc. All Rights Reserved. +// +/* + * AppleSamplePCIUserClient implementation. + * This class represents the user client object for the driver, which + * will be instantiated by I/O Kit to represent a connection to the client + * process, in response to the client's call to IOServiceOpen(). + * It will be destroyed when the connection is closed or the client + * abnormally terminates, so it should track all the resources allocated + * to the client. + */ + +#include "AppleSamplePCIUserClient.h" +#include +#include +#include +#include +#include +#include + +/* + * Define the metaclass information that is used for runtime + * typechecking of IOKit objects. We're a subclass of IOUserClient. + */ + +#define super IOUserClient +/* + * Even though we are defining the convenient macro super for the superclass you must use the actual class name + * in the OS*MetaClass macros. Note that the class name is different when supporting PowerPC on 10.4. + */ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +OSDefineMetaClassAndStructors(com_YourCompany_driver_SamplePCIUserClient_10_4, IOUserClient); +#else +OSDefineMetaClassAndStructors(com_YourCompany_driver_SamplePCIUserClient, IOUserClient); +#endif + +/* + * The following constant was added in the 10.5 SDK. + */ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +enum { + kIOUCVariableStructureSize = 0xffffffff +}; +#endif + +/* + * Since this sample uses the IOUserClientClass property in its Info.plist, the SamplePCIUserClient + * is created automatically in response to IOServiceOpen(). More complex applications + * might have several kinds of clients each with a different IOUserClient subclass, + * with different enumerated types. In that case the SamplePCI class must implement + * the newUserClient() method (see IOService.h headerdoc). + */ + +bool SamplePCIUserClientClassName::initWithTask(task_t owningTask, void* securityID, + UInt32 type, OSDictionary* properties) +{ + bool success; + + success = super::initWithTask(owningTask, securityID, type, properties); + + // Can't call getName() until init() has been called. + IOLog("%s[%p]::%s(type = " UInt32_FORMAT ")\n", getName(), this, __FUNCTION__, type); + + if (success) { + // This code will do the right thing on both PowerPC- and Intel-based systems because the cross-endian + // property will never be set on PowerPC-based Macs. + fCrossEndian = false; + if (properties != NULL && properties->getObject(kIOUserClientCrossEndianKey)) { + // A connection to this user client is being opened by a user process running using Rosetta. + + // Indicate that this user client can handle being called from cross-endian user processes by + // setting its IOUserClientCrossEndianCompatible property in the I/O Registry. + if (setProperty(kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue)) { + fCrossEndian = true; + IOLog("%s[%p]::%s(): fCrossEndian = true\n", getName(), this, __FUNCTION__); + } + } + } + + fTask = owningTask; + fDriver = NULL; + + return success; +} + +/* + * driver initialization after the matching has completed... + */ +bool SamplePCIUserClientClassName::start(IOService* provider) +{ + IOLog("%s[%p]::%s(provider = %p)\n", getName(), this, __FUNCTION__, provider); + + if (!super::start(provider)) + return false; + + /* + * Our provider should be a SamplePCI object. Verify that before proceeding. + */ + + assert(OSDynamicCast(SamplePCIClassName, provider)); + fDriver = (SamplePCIClassName*) provider; + + /* + * Set up some memory to be shared between this user client instance and its + * client process. The client will call in to map this memory, and I/O Kit + * will call clientMemoryForType to obtain this memory descriptor. + */ + + fClientSharedMemory = IOBufferMemoryDescriptor::withOptions(kIOMemoryKernelUserShared, sizeof(SampleSharedMemory)); + if (!fClientSharedMemory) + return false; + + fClientShared = (SampleSharedMemory *) fClientSharedMemory->getBytesNoCopy(); + + fClientShared->field1 = 0x11111111; // same in all endianesses... + fClientShared->field2 = 0x22222222; // ditto + fClientShared->field3 = 0x33333333; // ditto + + if (fCrossEndian) { + // Swap the fields so the user process sees the proper endianness + fClientShared->field1 = OSSwapInt32(fClientShared->field1); + fClientShared->field2 = OSSwapInt32(fClientShared->field2); + fClientShared->field3 = OSSwapInt32(fClientShared->field3); + } + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + // strlcpy() doesn't exist in the MacOSX10.4u SDK. + (void)strncpy(fClientShared->string, "some data", sizeof(fClientShared->string) - 1); + fClientShared->string[sizeof(fClientShared->string) - 1] = '\0'; +#else + (void) strlcpy(fClientShared->string, "some data", sizeof(fClientShared->string)); +#endif + fOpenCount = 1; + + return true; +} + + +/* + * Kill ourselves off if the client closes its connection or the client dies. + */ + +IOReturn SamplePCIUserClientClassName::clientClose(void) +{ + IOLog("%s[%p]::%s()\n", getName(), this, __FUNCTION__); + + if( !isInactive()) + terminate(); + + return kIOReturnSuccess; +} + +/* + * stop will be called during the termination process, and should free all resources + * associated with this client. + */ +void SamplePCIUserClientClassName::stop(IOService* provider) +{ + IOLog("%s[%p]::%s(provider = %p)\n", getName(), this, __FUNCTION__, provider); + + if (fClientSharedMemory) { + fClientSharedMemory->release(); + fClientSharedMemory = 0; + } + + super::stop(provider); +} + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +/* + * Look up the external methods - supply a description of the parameters + * available to be called + * + * This is the old way which only supports 32-bit user processes. + */ +IOExternalMethod* SamplePCIUserClientClassName::getTargetAndMethodForIndex(IOService** targetP, UInt32 index) +{ + static const IOExternalMethod methodDescs[kSampleNumMethods] = { + + { NULL, (IOMethod) &SamplePCIUserClientClassName::method1, + kIOUCStructIStructO, kIOUCVariableStructureSize, kIOUCVariableStructureSize }, + + { NULL, (IOMethod) &SamplePCIUserClientClassName::method2, + kIOUCStructIStructO, sizeof(SampleStructForMethod2), sizeof(SampleResultsForMethod2) }, + }; + + IOLog("%s[%p]::%s(index = "UInt32_FORMAT")\n", getName(), this, __FUNCTION__, index); + + *targetP = this; + if (index < kSampleNumMethods) + return (IOExternalMethod*) &methodDescs[index]; + else + return NULL; +} +#else +// defining and selecting our external user client methods +IOReturn SamplePCIUserClientClassName::externalMethod( + uint32_t selector, IOExternalMethodArguments* arguments, + IOExternalMethodDispatch * dispatch, OSObject * target, void * reference ) +{ + IOReturn result; + + if (fDriver == NULL || isInactive()) { + // Return an error if we don't have a provider. This could happen if the user process + // called either method without calling IOServiceOpen first. Or, the user client could be + // in the process of being terminated and is thus inactive. + result = kIOReturnNotAttached; + } + else if (!fDriver->isOpen(this)) { + // Return an error if we do not have the driver open. This could happen if the user process + // did not call openUserClient before calling this function. + result = kIOReturnNotOpen; + } + + IOReturn err; + IOLog("The Leopard and later way to route external methods\n"); + switch (selector) + { + case kSampleMethod1: + err = method1( (UInt32 *) arguments->structureInput, + (UInt32 *) arguments->structureOutput, + arguments->structureInputSize, (IOByteCount *) &arguments->structureOutputSize ); + break; + + case kSampleMethod2: + err = method2( (SampleStructForMethod2 *) arguments->structureInput, + (SampleResultsForMethod2 *) arguments->structureOutput, + arguments->structureInputSize, (IOByteCount *) &arguments->structureOutputSize ); + break; + + default: + err = kIOReturnBadArgument; + break; + } + + IOLog("externalMethod(%d) 0x%x", selector, err); + + return (err); +} +#endif + +/* + * Implement each of the external methods described above. + */ + +IOReturn SamplePCIUserClientClassName::method1( + UInt32 * dataIn, UInt32 * dataOut, + IOByteCount inputSize, IOByteCount * outputSize ) +{ + IOReturn ret; + IOItemCount count; + + IOLog("SamplePCIUserClient::method1("); + + if (*outputSize < inputSize) + return( kIOReturnNoSpace ); + + count = inputSize / sizeof( UInt32 ); + for (UInt32 i = 0; i < count; i++ ) { + // Client app is running using Rosetta + if (fCrossEndian) { + dataIn[i] = OSSwapInt32(dataIn[i]); + } + IOLog("" UInt32_x_FORMAT ", ", dataIn[i]); + dataOut[i] = dataIn[i] ^ 0xffffffff; + // Rosetta again + if (fCrossEndian) { + dataOut[i] = OSSwapInt32(dataOut[i]); + } + + } + + ret = kIOReturnSuccess; + IOLog(")\n"); + *outputSize = count * sizeof( UInt32 ); + + return( ret ); +} + +IOReturn SamplePCIUserClientClassName::method2( SampleStructForMethod2 * structIn, + SampleResultsForMethod2 * structOut, + IOByteCount inputSize, IOByteCount * outputSize ) + +{ + IOReturn err; + IOMemoryDescriptor * memDesc = 0; + UInt32 param1 = structIn->parameter1; + + uint64_t clientAddr = structIn->data_pointer; + uint64_t size = structIn->data_length; + + // Rosetta + if (fCrossEndian) { + param1 = OSSwapInt32(param1); + } + + IOLog("SamplePCIUserClient::method2(" UInt32_x_FORMAT ")\n", param1); + IOLog( "fClientShared->string == \"%s\"\n", fClientShared->string ); + + structOut->results1 = 0x87654321; + // Rosetta + if (fCrossEndian) { + structOut->results1 = OSSwapInt64(structOut->results1); + clientAddr = OSSwapInt64(clientAddr); + size = OSSwapInt64(size); + } + + do + { + +#if defined(__ppc__) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) + // construct a memory descriptor for the out of line client memory + // old 32 bit API - this will fail and log a backtrace if the task is 64 bit + IOLog("The Pre-Leopard way to construct a memory descriptor\n"); + memDesc = IOMemoryDescriptor::withAddress( (vm_address_t) clientAddr, (IOByteCount) size, kIODirectionNone, fTask ); + if (memDesc == NULL) { + IOLog("IOMemoryDescriptor::withAddress failed\n"); + err = kIOReturnVMError; + continue; + } +#else + // 64 bit API - works on all tasks, whether 64 bit or 32 bit + IOLog("The Leopard and later way to construct a memory descriptor\n"); + memDesc = IOMemoryDescriptor::withAddressRange( clientAddr, size, kIODirectionNone, fTask ); + if (memDesc == NULL) { + IOLog("IOMemoryDescriptor::withAddresswithAddressRange failed\n"); + err = kIOReturnVMError; + continue; + } +#endif + // Wire it and make sure we can write it + err = memDesc->prepare( kIODirectionOutIn ); + if (kIOReturnSuccess != err) { + IOLog("IOMemoryDescriptor::prepare failed(0x%08x)\n", err); + continue; + } + + // Generate a DMA list for the client memory + err = fDriver->generateDMAAddresses(memDesc); + + // Other methods to access client memory: + + // readBytes/writeBytes allow programmed I/O to/from an offset in the buffer + char pioBuffer[ 200 ]; + memDesc->readBytes(32, &pioBuffer, sizeof(pioBuffer)); + IOLog("readBytes: \"%s\"\n", pioBuffer); + + // map() will create a mapping in the kernel address space. + IOMemoryMap* memMap = memDesc->map(); + if (memMap) { + char* address = (char *) memMap->getVirtualAddress(); + IOLog("kernel mapped: \"%s\"\n", address + 32); + memMap->release(); + } else { + IOLog("memDesc map(kernel) failed\n"); + } + + // this map() will create a mapping in the users (the client of this IOUserClient) address space. +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + memMap = memDesc->map(fTask, 0, kIOMapAnywhere); +#else + memMap = memDesc->createMappingInTask(fTask, 0, kIOMapAnywhere); +#endif + if (memMap) { +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + IOLog("The pre-Leopard way to construct a memory descriptor\n"); + // old 32 bit API - this will truncate and log a backtrace if the task is 64 bit + IOVirtualAddress address32 = memMap->getVirtualAddress(); + IOLog("user32 mapped: " VirtAddr_FORMAT "\n", address32); +#else + IOLog("The Leopard and later way to construct a memory descriptor\n"); + // new 64 bit API - same for 32 bit and 64 bit client tasks + mach_vm_address_t address64 = memMap->getAddress(); + IOLog("user64 mapped: 0x%016llx\n", address64); + memMap->release(); +#endif + } else { + IOLog("memDesc map(user) failed\n"); + } + + // Done with the I/O now. + memDesc->complete( kIODirectionOutIn ); + + } while ( false ); + + if (memDesc) + memDesc->release(); + + return err; +} + +/* + * Shared memory support. Supply a IOMemoryDescriptor instance to describe + * each of the kinds of shared memory available to be mapped into the client + * process with this user client. + */ + +IOReturn SamplePCIUserClientClassName::clientMemoryForType( + UInt32 type, + IOOptionBits* options, + IOMemoryDescriptor** memory ) +{ + // Return a memory descriptor reference for some memory a client has requested + // be mapped into its address space. + + IOReturn ret; + + IOLog("SamplePCIUserClient::clientMemoryForType(" UInt32_FORMAT ")\n", type); + + switch( type ) { + + case kSamplePCIMemoryType1: + // give the client access to some shared data structure + // (shared between this object and the client) + fClientSharedMemory->retain(); + *memory = fClientSharedMemory; + ret = kIOReturnSuccess; + break; + + case kSamplePCIMemoryType2: + // Give the client access to some of the card's memory + // (all clients get the same) + *memory = fDriver->copyGlobalMemory(); + ret = kIOReturnSuccess; + break; + + default: + ret = kIOReturnBadArgument; + break; + } + + return ret; +} + diff --git a/AppleSamplePCI/AppleSamplePCIUserClient.h b/AppleSamplePCI/AppleSamplePCIUserClient.h new file mode 100644 index 00000000..b27f0653 --- /dev/null +++ b/AppleSamplePCI/AppleSamplePCIUserClient.h @@ -0,0 +1,114 @@ +// +// File: AppleSamplePCIUserClient.h +// +// Abstract: User client interface between userland and sample kernel PCI driver +// +// Version: 2.0 +// +// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") +// in consideration of your agreement to the following terms, and your use, +// installation, modification or redistribution of this Apple software +// constitutes acceptance of these terms. If you do not agree with these +// terms, please do not use, install, modify or redistribute this Apple +// software. +// +// In consideration of your agreement to abide by the following terms, and +// subject to these terms, Apple grants you a personal, non - exclusive +// license, under Apple's copyrights in this original Apple software ( the +// "Apple Software" ), to use, reproduce, modify and redistribute the Apple +// Software, with or without modifications, in source and / or binary forms; +// provided that if you redistribute the Apple Software in its entirety and +// without modifications, you must retain this notice and the following text +// and disclaimers in all such redistributions of the Apple Software. Neither +// the name, trademarks, service marks or logos of Apple Inc. may be used to +// endorse or promote products derived from the Apple Software without specific +// prior written permission from Apple. Except as expressly stated in this +// notice, no other rights or licenses, express or implied, are granted by +// Apple herein, including but not limited to any patent rights that may be +// infringed by your derivative works or by other works in which the Apple +// Software may be incorporated. +// +// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO +// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED +// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION +// ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +// +// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR +// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION +// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER +// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR +// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright ( C ) 2008 Apple Inc. All Rights Reserved. +// + +#include +#include "AppleSamplePCI.h" + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#define SamplePCIUserClientClassName com_YourCompany_driver_SamplePCIUserClient_10_4 +#else +#define SamplePCIUserClientClassName com_YourCompany_driver_SamplePCIUserClient +#endif + +// Forward declarations +class IOBufferMemoryDescriptor; + +class SamplePCIUserClientClassName : public IOUserClient +{ + /* + * Declare the metaclass information that is used for runtime + * typechecking of IOKit objects. Note that the class name is different when supporting PowerPC on 10.4. + */ + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + OSDeclareDefaultStructors( com_YourCompany_driver_SamplePCIUserClient_10_4 ); +#else + OSDeclareDefaultStructors( com_YourCompany_driver_SamplePCIUserClient ); +#endif + +private: + SamplePCIClassName* fDriver; + IOBufferMemoryDescriptor* fClientSharedMemory; + SampleSharedMemory* fClientShared; + task_t fTask; + int32_t fOpenCount; + bool fCrossEndian; + +public: + /* IOService overrides */ + virtual bool start(IOService* provider); + virtual void stop(IOService* provider); + + /* IOUserClient overrides */ + virtual bool initWithTask(task_t owningTask, void* securityID, + UInt32 type, OSDictionary* properties); + + virtual IOReturn clientClose(void); + +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 + /* Old user client API - only supports access from 32-bit user processes. */ + virtual IOExternalMethod* getTargetAndMethodForIndex(IOService** targetP, UInt32 index); +#else + /* New user client API for supporting access from both 32-bit and 64-bit user processes. */ + virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments* arguments, + IOExternalMethodDispatch* dispatch, OSObject* target, void* reference); +#endif + + virtual IOReturn clientMemoryForType(UInt32 type, + IOOptionBits* options, + IOMemoryDescriptor** memory); + + /* External methods */ + virtual IOReturn method1(UInt32* dataIn, UInt32* dataOut, + IOByteCount inputCount, IOByteCount* outputCount); + + virtual IOReturn method2(SampleStructForMethod2* structIn, + SampleResultsForMethod2* structOut, + IOByteCount inputSize, IOByteCount* outputSize); + +}; + diff --git a/AppleSamplePCI/Info-AppleSamplePCI.plist b/AppleSamplePCI/Info-AppleSamplePCI.plist new file mode 100644 index 00000000..b0b76ce6 --- /dev/null +++ b/AppleSamplePCI/Info-AppleSamplePCI.plist @@ -0,0 +1,78 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + AppleSamplePCI + CFBundleIconFile + + CFBundleIdentifier + com.YourCompany.driver.SamplePCI + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleVersion + 2.0.0d1 + IOKitPersonalities + + Matching + + CFBundleIdentifier + com.YourCompany.driver.SamplePCI + IOClass + com_YourCompany_driver_SamplePCI + IOMatchCategory + com_YourCompany_driver_SamplePCI + IONameMatch + + ATY* + NVDA* + display + + IOProviderClass + IOPCIDevice + IOUserClientClass + com_YourCompany_driver_SamplePCIUserClient + DisplayParameters + + brightness + + max + 127 + min + 0 + value + 120 + + + + + OSBundleLibraries + + com.apple.iokit.IOPCIFamily + 1.0.0b1 + com.apple.kpi.iokit + 9.0.0 + com.apple.kpi.libkern + 9.0.0 + com.apple.kpi.mach + 9.0.0 + + OSBundleLibraries_x86_64 + + com.apple.iokit.IOPCIFamily + 2.5 + com.apple.kpi.iokit + 10.0.0d1 + com.apple.kpi.libkern + 10.0.0d1 + com.apple.kpi.mach + 10.0.0d1 + + + diff --git a/AppleSamplePCI/Info-AppleSamplePCI_10_4.plist b/AppleSamplePCI/Info-AppleSamplePCI_10_4.plist new file mode 100644 index 00000000..a0bb305f --- /dev/null +++ b/AppleSamplePCI/Info-AppleSamplePCI_10_4.plist @@ -0,0 +1,67 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + AppleSamplePCI_10_4 + CFBundleIconFile + + CFBundleIdentifier + com.YourCompany.driver.SamplePCI_10_4 + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + KEXT + CFBundleSignature + ???? + CFBundleVersion + 2.0.0d1 + IOKitPersonalities + + Matching + + CFBundleIdentifier + com.YourCompany.driver.SamplePCI_10_4 + IOClass + com_YourCompany_driver_SamplePCI_10_4 + IOMatchCategory + com_YourCompany_driver_SamplePCI_10_4 + IONameMatch + + ATY* + NVDA* + display + + IOProviderClass + IOPCIDevice + IOUserClientClass + com_YourCompany_driver_SamplePCIUserClient_10_4 + DisplayParameters + + brightness + + max + 127 + min + 0 + value + 120 + + + + + OSBundleLibraries + + com.apple.iokit.IOPCIFamily + 1.0.0 + com.apple.kpi.iokit + 8.0.0 + com.apple.kpi.libkern + 8.0.0 + com.apple.kpi.mach + 8.0.0 + + + diff --git a/AppleSamplePCI/readme.txt b/AppleSamplePCI/readme.txt new file mode 100644 index 00000000..a8ad0caf --- /dev/null +++ b/AppleSamplePCI/readme.txt @@ -0,0 +1,13 @@ +AppleSamplePCI is a simple driver example that shows how to build a single deliverable that will function on all Macintosh systems from Mac OS X 10.4 through Snow Leopard. It matches on the IOPCIFamily, specifically on the graphics card(s) found in all Macintosh computers. + +It demonstrates the use of I/O Registry Properties to set and retrieve settings properties to your driver. Additionally, it shows how to handle PowerPC applications running on Intel-based systems calling your driver using Rosetta. Finally, it addresses the new 64-bit kernel (K64) world by demonstrating which APIs to use on Leopard and beyond. + +The sample produces two kexts and a test tool. One kext targets the i386 and ppc architectures for Mac OS X 10.4 only. This is where you'll encounter the most differences between architectures. + +The second kext targets i386 and ppc on Leopard and later, and x86_64 (K64) on Snow Leopard. + +During the build process, the first kext is copied into the Contents/PlugIns directory of the second kext. This shows how a single kext bundle can be shipped which contains related sub-kexts. The kext loading daemon (kextd) searches one level deep inside kext bundles for sub-kexts. + +The test tool is built four-way universal for i386, x86_64, ppc, and ppc64 architectures. The 64-bit architectures are supported only on Leopard and beyond as that is where user client support for 64-bit processes was added. + +The project also builds the test tool as four separate single-architecture binaries. This is only to make it easier to test running binaries for specific architectures to see the results. \ No newline at end of file