On the NUC (and many other desktop systems), there is no EC and then OSX falls back to using the GPE. By querying the ACPI tables, OSX can get a list of all possible event sources corresponding to a single GPE. It then does a series of filtering actions. First, it removes duplicates (any device that shows up both as an ACPI device and a PCI device). Then, for each PCI device, it queries the PMCS register to look at PM_Status. PM_Status is set to 1 by hardware when PME# is asserted (remember, this signal is what wakes up PCH, which wakes up the processor). Here's the confusing part: when you write a 1 back to PMCS.PM_Status by the processor, it clears PM_Status. This allows OS designers to read PMCS once, then write the same value back which clears it. Then it will only be set again by the next PME# and prevent any race condition. OSX looks for any PCI device corresponding to the GPE that has PM_Status set to 1. (It will not clear it, but instead much later in the wakeup process, the IOPCIDevice driver will clear it.) Finally the list of potential wake sources is created from the filtered set: any PCI power management capable device with PM_Status set, any PCI devices without power management, and then any non-PCI devices. For each potential wake source, a device property acpi-wake-type
is queried (such as user, timer, networking, etc). Then out of all the potential wake sources, the wake type with the highest priority (for example any user triggered wakeup takes priority over stuff like battery notifications or timers) becomes the Wake Type
written to IOPMrootDomain for XNU to act upon.