PCIDriverKit

RSS for tag

Develop device drivers for Peripheral Component Interconnect accessories.

Posts under PCIDriverKit tag

26 Posts

Post

Replies

Boosts

Views

Activity

How to setup DriverKit Timer Event with OSAction Callback Binding
Hello Everyone, I'm encountering an issue while setting up a timer event in DriverKit and would appreciate any guidance. Here's my current implementation: void DRV_MAIN_CLASS_NAME::SetupEventTimer() { // 1. Create dispatch queue kern_return_t ret = IODispatchQueue::Create("TimerQueue", 0, 0, &ivars->dispatchQueue); if (ret != kIOReturnSuccess) { LogErr("Failed to create dispatch queue: 0x%x", ret); return; } // 2. Create timer source ret = IOTimerDispatchSource::Create(ivars->dispatchQueue, &ivars->dispatchSource); if (ret != kIOReturnSuccess) { LogErr("Failed to create timer: 0x%x", ret); OSSafeReleaseNULL(ivars->dispatchQueue); return; } /*! * @brief Create an instance of OSAction. * @discussion Methods to allocate an OSAction instance are generated for each method defined in a class with * a TYPE attribute, so there should not be any need to directly call OSAction::Create(). * @param target OSObject to receive the callback. This object will be retained until the OSAction is * canceled or freed. * @param targetmsgid Generated message ID for the target method. * @param msgid Generated message ID for the method invoked by the receiver of the OSAction * to generate the callback. * @param referenceSize Size of additional state structure available to the creator of the OSAction * with GetReference. * @param action Created OSAction with +1 retain count to be released by the caller. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ // 3: Create an OSAction for the TimerOccurred method // THIS IS WHERE I NEED HELP OSAction* timerAction = nullptr; ret = OSAction::Create(this, 0, 0, 0, &timerAction); if (ret != kIOReturnSuccess) { LogErr("Failed to create OSAction: 0x%x", ret); goto cleanup; } // 4. Set handler ret = ivars->dispatchSource->SetHandler(timerAction); if (ret != kIOReturnSuccess) { LogErr("Failed to set handler: 0x%x", ret); goto cleanup; } // 5. Schedule timer (1 second) uint64_t deadline = mach_absolute_time() + NSEC_PER_SEC; ivars->dispatchSource->WakeAtTime(0, deadline, 0); cleanup: if (ret != kIOReturnSuccess) { OSSafeReleaseNULL(timerAction); OSSafeReleaseNULL(ivars->dispatchSource); OSSafeReleaseNULL(ivars->dispatchQueue); } } Problem: The code runs but the OSAction callback binding seems incorrect (Step 3). According to the OSAction documentation, I need to use the TYPE macro to properly bind the callback method. But I try to use TYPE(DRV_MAIN_CLASS_NAME::TimerOccurred) kern_return_t TimerOccurred() LOCALONLY; TYPE(TimerOccurred) kern_return_t TimerOccurred() LOCALONLY; kern_return_t TimerOccurred() TYPE(DRV_MAIN_CLASS_NAME::TimerOccurred) LOCALONLY; All results in Out-of-line definition of 'TimerOccurred' does not match any declaration in 'DRV_MAIN_CLASS_NAME' Questions: What is the correct way to declare a timer callback method using TYPE? How to get the values targetmsgid & msgid generated by Xcode? Any help would be greatly appreciated! Best Regards, Charles
6
0
358
Apr ’25
Issue Writing to BAR1 After BAR0 is Unavailable
Hello Everyone, I encountered an issue with PCI memory access in DriverKit. In my case, BAR0 is not available, but BAR1 is ready for use. Here’s the log output: !!! ERROR : Failed to get BAR0 info (error: 0xe00002f0). !!! BAR1 - MemoryIndex: 0x00000000, Size: 0x00040000, Type: 0 Issue Description When I initially wrote to BAR0 using memoryIndex = 0, it worked successfully: AME_Address_Write_32(pAMEData, pAMEData->memoryIndex, AME_HOST_INT_MASK_REGISTER, 0x0F); However, I mistakenly forgot to update memoryIndex to 1 for BAR1. Surprisingly, the write operation still succeeded. When I fixed memoryIndex = 1 for BAR1, the write operation no longer had any effect. There was no error, but the expected behavior did not occur. Relevant API (From IOPCIDevice.iig) /*! /*! * @brief Writes a 32-bit value to the PCI device's aperture at a given memory index. * @discussion This method writes a 32-bit register on the device and returns its value. * @param memoryIndex An index into the array of ranges assigned to the device. * @param offset An offset into the device's memory specified by the index. * @param data A 32-bit value to be written in host byte order. */ void MemoryWrite32(uint8_t memoryIndex, uint64_t offset, uint32_t data) LOCALONLY; Log Output: Writes to BAR0 (memoryIndex = 0) AME_Address_Write_32() called memoryIndex: 0, offset: 0x34, data: 0xf Wrote data 0xF to offset 52 AME_Address_Write_32() called memoryIndex: 0, offset: 0xa0, data: 0x1 Wrote data 0x1 to offset 160 AME_Address_Write_32() called memoryIndex: 0, offset: 0x20, data: 0xffffffff Wrote data 0xFFFFFFFF to offset 32 Writes to BAR1 (memoryIndex = 1) – No Response AME_Address_Write_32() called memoryIndex: 1, offset: 0x34, data: 0xf No confirmation log, no visible effect. Questions What should memoryIndex be set to for BAR1? The log shows "BAR1 - MemoryIndex: 0x00000000", but should I be using 1 instead? How can I verify if a write operation to BAR1 is successful? Is there a way to check if the memory region is actually writable? Should I use MemoryRead32() to confirm the written value? Any guidance would be greatly appreciated! Best Regards, Charles
3
1
122
Mar ’25
iOS support for SCSI and NVME commands.
We have a macOS application which interacts with our USB and PCI devices to perform SCSI and NVME commands on them. We use IOUSBHost, IOUSBLib and IOKitLib for USB interface and have created a custom driver to interact with PCI devices. Is there a way we can implement a similar functionality for iOS as well if we connect the cards and readers using OTG?
1
1
140
Mar ’25
Why UserInitializeTargetForID() not be invoked after UserCreateTargetForID() successfully?
Hello Everyone, I am trying to create a Fake SCSI target based on SCSIControllerDriverKit.framework and inherent from IOUserSCSIParallelInterfaceController, here is the code kern_return_t IMPL(DRV_MAIN_CLASS_NAME, Start) { ... // Programmatically create a null SCSI Target SCSIDeviceIdentifier nullTargetID = 0; // Example target ID, adjust as needed ret = UserCreateTargetForID(nullTargetID, nullptr); if (ret != kIOReturnSuccess) { Log("Failed to create Null SCSI Target for ID %llu", nullTargetID); return ret; } ... } According the document UserCreateTargetForID, after creating a TargetID successfully, the framework will call the UserInitializeTargetForID() The document said: As part of the UserCreateTargetForID call, the kernel calls several APIs like UserInitializeTargetForID which run on the default dispatch queue of the dext. But after UserCreateTargetForID created, why the UserInitializeTargetForID() not be invoked automatically? Here is the part of log show init() - Start init() - End Start() - Start Start() - try 1 times UserCreateTargetForID() - Start Allocating resources for Target ID 0 UserCreateTargetForID() - End Start() - Finished. UserInitializeController() - Start - PCI vendorID: 0x14d6, deviceID: 0x626f. - BAR0: 0x1, BAR1: 0x200004. - GetBARInfo() - BAR1 - MemoryIndex: 0, Size: 262144, Type: 0. UserInitializeController() - End UserStartController() - Start - msiInterruptIndex : 0x00000000 - interruptType info is 0x00010000 - PCI Dext interrupt final value, return status info is 0x00000000 UserStartController() - End Any assistance would be greatly appreciated! Thank you in advance for your support. Best regards, Charles
1
0
378
Mar ’25
Is DEXT Driver supporting these Networking Features?
I would like to know if macOS DEXT supports the following networking features: Tx/Rx Multiqueue, RSS, RSC, NS/ARP offload, PTP or packet timestamping and TSN. I couldn't find relevant documentation for these features in the Apple Developer Documentation. If they are supported, could you let me know which features are supported and how to find the corresponding official Apple documentation? Thanks
9
0
735
Mar ’25
The Map() of IOBufferMemoryDescriptor failure and cause the DriverKit Start() repeat
Hello Everyone, I am trying to develop a DriverKit for RAID system, using PCIDriverKit & SCSIControllerDriverKit framework. The driver can detect the Vendor ID and Device ID. But before communicating to the RAID system, I would like to simulate a virtual Volume using a memory block to talk with macOS. In the UserInitializeController(), I allocated a 512K memory for a IOBufferMemoryDescriptor* volumeBuffer, but fail to use Map() to map memory for volumeBuffer. result = ivars->volumeBuffer->Map( 0, // Options: Use default 0, // Offset: Start of the buffer ivars->volumeSize, // Length: Must not exceed buffer size 0, // Flags: Use default nullptr, // Address space: Default address space &mappedAddress // Output parameter ); Log("Memory mapped completed at address: 0x%llx", mappedAddress); // this line never run The Log for Map completed never run, just restart to run the Start() and makes this Driver re-run again and again, in the end, the driver eat out macOS's memory and system halt. Are the parameters for Map() error? or I should not put this code in UserInitializeController()? Any help is appreciated! Thanks in advance. Charles
0
0
378
Mar ’25