Working with Thunderbolt Technology

This chapter provides guidelines for working with the Thunderbolt technology. Keep these guidelines in mind when creating compatible devices.

Discovering Thunderbolt Devices

System software is used to discover Thunderbolt devices and to determine when a new Thunderbolt device has been attached. The software discovers all DisplayPort and PCI devices, and creates Thunderbolt paths to those devices using any available resources. Once the paths are created, the applicable OS driver(s) are notified to the presence of the devices.

In the case of DisplayPort, graphics drivers may light up the screen. The screen is only lit up based on the capabilities of the GPU.

In the case of PCI, the I/O PCI family (IOPCIFamily) within the I/O Kit is responsible for enumerating the PCI bridge in the controller chip and any downstream bridges or devices.

Using PCI Resources Wisely

PCI resources (bus numbers, memory apertures) are scarce and programmers and device manufacturers should do their best to present the true requirements of the device.

For example, consider a PCI device that has multiple functions, where only function 0 will be used in the application. PCI functions other than function 0 should be hidden from the OS if possible, by returning 0xFFFFFFFF for a Configuration Read at offset 0 for that function. Another example is a device that requires only 2 KB of aperture for Memory Mapped I/O (MMIO) space, but instead reports 64 KB of aperture during enumeration. These devices should report accurate aperture values.

I/O space cannot be counted on when designing for the Thunderbolt interface. PCI limitations require an I/O space allocation of 4 KB per PCI Bridge, and the total system-wide I/O space is only 64 KB. Therefore, use MMIO instead of relying on I/O space allocations for devices. Using MMIO allows the operating system to load the device driver, even if I/O space could not be properly allocated for the device.

Tolerating PCI Latency

Devices on a Thunderbolt bus exhibit higher latency than devices on internal slots—about 1.5 microseconds of round-trip latency per hop. This means that putting a device at the end of a Thunderbolt chain can add up to 9 microseconds of round-trip latency. Most devices and drivers handle this additional communication latency with no particular difficulty. In some cases, however, your driver or device firmware must be tweaked to tolerate that latency.

For example:

And so on. The details are highly dependent on the driver.

Using a Registered Vendor ID

Each Thunderbolt device must have a Device ROM (DROM) that contains information about the vendor and the device, as well as a 64-bit UID, which uniquely identifies the device. Each vendor must have a registered vendor ID with the Thunderbolt naming authority (Intel).

Enabling PCI Device Drivers for Thunderbolt Operation

To declare support for Thunderbolt technology, the following key must be added to each of the personalities in your driver’s Info.plist file.

Listing 2-1  PCI Driver Key (Thunderbolt Operation)

<key>IOPCITunnelCompatible</key>
<true/>

You must include the key in the IOKitPersonalities section of the Info.plist file or the IOPCIFamily will not load the drivers for Thunderbolt connected PCI devices. This opt-in key protects consumers against older drivers that have not yet been updated to support Thunderbolt technology. This method also makes it easy for third party developers, who have properly updated their driver, to signify they have done so. (See example driver Listing 2-2.)

An example driver that includes this key in one of its personalities is AppleAHCIPort.kext, which is shown in the PCI Driver Personality (Thunderbolt Key Set).

Listing 2-2  PCI Driver Personality (Thunderbolt Key Set)

<key>GenericAHCI</key>
<dict>
         <key>CFBundleIdentifier</key>
         <string>com.apple.driver.AppleAHCIPort</string>
         <key>Chipset Name</key>
         <string>AHCI Standard Controller</string>
         <key>IOClass</key>
         <string>AppleAHCI</string>
         <key>IOPCIClassMatch</key>
         <string>0x01060100&0xffffff00</string>
         <key>IOProbeScore</key>
         <integer>800</integer>
         <key>IOProviderClass</key>
         <string>IOPCIDevice</string>
         <key>Vendor Name</key>
         <string>Unknown</string>
         key>IOPCITunnelCompatible/key>
         <true/>
</dict>

Verifying Thunderbolt Connections in PCI Devices

PCI device drivers can determine if a Thunderbolt device is connected by recursively searching over parents in the I/O Registry for the key IOPCITunnelled. (See code example Listing 2-3 .)

Listing 2-3  Verifying Thunderbolt Connections

#include < IOKit/pci/IOPCIDevice.h>
bool tb = false;
if ( getProperty ( kIOPCITunnelledKey, gIOServicePlane, kIORegistryIterateRecursively | kIORegistryIterateParents ) )
     tb = true;

Additionally, PCI device drivers that present storage to the operating system must ensure the “Physical Interconnect Location” key is set to indicate that the device is externally connected. (See physical interconnect location key example Listing 2-4 .)

Listing 2-4  PCI Driver: External Storage Key Set

setProperty ( kIOPropertyPhysicalInterconnectLocationKey,
kIOPropertyExternalKey );