1{\rtf1\ansi\ansicpg1252\cocoartf1187
2{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Monaco;}
3{\colortbl;\red255\green255\blue255;}
4\margl1440\margr1440\vieww23820\viewh24400\viewkind0
5\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
6
7\f0\b\fs30 \cf0 PCI Pause\
8\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ri-746\pardirnatural
9
10\b0\fs24 \cf0 \
11\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
12\cf0 This document assumes familiarity with the OS X power management APIs.\
13\
14Drivers using an IOPCIDevice as a provider, where the IOPCIDevice is hot pluggable, are expected to be compatible with new support for relocating PCI resources after driver ::start(). This support will be indicated with a property similar to kIOPCITunnelCompatibleKey, kIOPCIPauseCompatibleKey. Boolean true for supported.\
15\
16
17\f1\fs20 #define kIOPCIPauseCompatibleKey        "IOPCIPauseCompatible"\
18
19\f0\fs24 \
20The system will relocate resources for a running driver only:\
21\
22- if the device is already in a state other than kIOPCIDeviceOnState, or\
23\
24- after placing the device into the new power state kIOPCIDevicePausedState, with the standard power management APIs. This means the driver can implement state changes synchronously or asynchronously.\
25\
26- the new IOPCIDevice power states are as below (no existing power state has changed, so the new state is out of order). Drivers should use only the capability bits of power states, rather than the state order. The new paused state has capability bit 
27\f1\fs20 kIOPMConfigRetained.
28\f0\fs24 \
29\
30
31\f1\fs20 enum \{\
32    kIOPCIDevicePowerStateCount = 4,\
33    kIOPCIDeviceOffState        = 0,\
34    kIOPCIDeviceDozeState       = 1,\
35    kIOPCIDeviceOnState         = 2,\
36    kIOPCIDevicePausedState     = 3,\
37\};\
38
39\f0\fs24 \
40\
41- for your driver, a sample power state table should look like:\
42\
43
44\f1\fs20 enum \{\
45    kYourDriverPowerStateCount      = 4,\
46    kYourDriverPowerOffState        = 0,\
47    kYourDriverPowerDozeState       = 1,\
48    kYourDriverPowerPausedState     = 2,\
49    kYourDriverPowerOnState         = 3,\
50\};\
51
52\f0\fs24 \
53
54\f1\fs20 static const IOPMPowerState powerStates[kYourDriverPowerStateCount] = \{\
55\
56    // version, capabilityFlags, outputPowerCharacter, inputPowerRequirement, staticPower, stateOrder\
57	\{ kIOPMPowerStateVersion1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \},\
58\
59	\{ kIOPMPowerStateVersion1, 0, kIOPMSoftSleep, kIOPMSoftSleep, 0, 0, 0, 0, 0, 0, 0, 0 \},\
60\
61	\{ kIOPMPowerStateVersion1, kIOPMConfigRetained, kIOPMConfigRetained, kIOPMConfigRetained, 0, 0, 0, 0, 0, 0, 0, 0 \}\
62\
63	\{ kIOPMPowerStateVersion1, kIOPMPowerOn | kIOPMUsable, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 \},\
64\};\
65
66\f0\fs24 \
67\
68When a driver for a IOPCIDevice provider registers for power mgt it must provide its own power state definitions to indicate which of its power states will be used for any power state of the IOPCIDevice. The inputPowerRequirement field of these power states will match masks of the PCI power states outputPowerCharacter field.\
69\
70An unmodified driver will be sent to its off state during pause since the pause state does not include the kIOPMPowerOn flag. Any clients of the driver in the power mgt hierarchy will then also have to change their states to match.\
71\
72Modified drivers can support pause explicitly by adding a power state with inputPowerRequirement kIOPMConfigRetained which will get selected by power mgt in the pause state. The outputPowerCharacter of the drivers new power state will then dictate what the drivers power mgt clients will see. Depending on this flag, clients of your driver may or may not change states.\
73\
74The driver pause state should be designed to be entered/exited as quickly as possible to avoid disrupting service. Since the hardware remains powered, running all of the same code as the regular kIOPCIDeviceOff/OnState transition is discouraged since it will be slower.\
75\
76
77\b\fs26 What happens during pause?\
78
79\b0\fs24 \
80The device is assumed to be quiesced due to the pause state. It should not:\
81\
82- be accessed by any code using memory mapped, I/O or config space transactions\
83- be generating any interrupt, MSI or pin based\
84- be generating any DMA \
85- be the target of any DMA\
86\
87This would also be true of the non-kIOPCIDeviceOnState power states so the driver state should be very similar. Since the system state is not S3, the hardware will not receive the PCI broadcast messages such as PME_turn_off.\
88\
89
90\b During pause reconfiguration, the following may be changed:\
91
92\b0 \
93- device BAR registers\
94\
95- the devices bus number\
96\
97- registry properties reflecting these values ("ranges", "assigned-addresses", "reg")\
98\
99- device MSI block values for address and value, but not the number of MSIs allocated\
100\
101
102\b \
103\
104The following will not change:\
105
106\b0 \
107- the PCI power management configuration block registers of the device (ie. the device will not be put into runtime D3).\
108\
109- the virtual map addresses of BARs. Mappings created by the driver with IOPCIDevice::mapDeviceMemoryWithRegister/Index() for MMIO access to hardware, are remapped with the same virtual address & the new physical address\
110\
111- any other configuration registers\
112\
113- any BAR resource present at pause must be reallocated (ie. a device can't lose resources \
114across reconfiguration)\
115\
116- the registry hierarchy of the device\
117\
118- the number or kind of interrupt assignments (ie. shared or MSI interrupts)\
119\
120The majority of drivers have few to no dependencies on the items above being changed. If they do, while entering the kIOPCIDeviceOnState (from any other state), these dependencies should be updated to the current configuration of the device.\
121}