Поделиться через


Синхронизация прерываний для драйверов контроллера GPIO

Драйверы контроллера GPIO могут вызывать методы GPIO_CLX_AcquireInterruptLock и GPIO_CLX_ReleaseInterruptLock для получения и освобождения блокировок прерываний, которые реализуются внутренним расширением платформы GPIO (GpioClx). Код драйвера, который выполняется в IRQL = PASSIVE_LEVEL может вызывать эти методы для синхронизации с подпрограммой службы прерываний (ISR) в GpioClx. GpioClx выделяет отдельную блокировку прерываний для каждой банки контактов в контроллере GPIO.

Если аппаратные регистры контроллера GPIO сопоставлены с памятью, ISR в GpioClx вызывает определенные функции обратного вызова событий, реализованные драйвером, в DIRQL; GpioClx вызывает остальные функции обратного вызова в PASSIVE_LEVEL. Функция обратного вызова пассивного уровня, которая обращается к банку регистров, может потребоваться использовать блокировку прерываний для синхронизации с функциями обратного вызова, которые выполняются в DIRQL и обращаются к тем же регистрам.

Например, функции обратного вызова пассивного уровня CLIENT_EnableInterrupt и CLIENT_DisableInterrupt изменяют параметры оборудования, которые влияют на работу других подпрограмм обратного вызова, связанных с прерыванием, которые выполняются в DIRQL. Функции CLIENT_EnableInterrupt и CLIENT_DisableInterrupt обычно используют блокировки прерываний банка для синхронизации доступа к регистрации.

GpioClx автоматически сериализует обратные вызовы, связанные с прерываниями и вводом-выводом, которые происходят в DIRQL. GpioClx получает блокировку прерывания для целевого банка перед вызовом функции обратного вызова в DIRQL и снимает блокировку после возврата функции. Функция обратного вызова, вызываемая в DIRQL, является ошибкой, чтобы попытаться повторно получить блокировку прерывания банка путем вызова GPIO_CLX_AcquireInterruptLock.

Аналогичным образом GpioClx автоматически сериализует обратные вызовы, происходящие в PASSIVE_LEVEL. GpioClx внутренне реализует блокировку ожидания для каждого банка. GpioClx получает блокировку ожидания для целевого банка перед вызовом функции обратного вызова в PASSIVE_LEVEL и снимает блокировку при возвращении функции. Для контроллера GPIO, сопоставленного в памяти, GpioClx управляет блокировками ожидания банка от имени драйвера, но не позволяет драйверу явно получать и освобождать блокировки.

Однако для контроллера GPIO, не сопоставленного в памяти, GPIO_CLX_AcquireInterruptLock и GPIO_CLX_ReleaseInterruptLock получить и освободить блокировку ожидания вместо блокировки прерывания. GpioClx реализует отдельную блокировку ожидания для каждой банки контактов в контроллере GPIO. Так как регистры не сопоставлены с памятью, все функции обратного вызова, связанные с прерываниями и вводом-выводом, вызываются в PASSIVE_LEVEL поэтому они могут использовать запросы ввода-вывода для доступа к регистрам через последовательную шину, например I²C. GpioClx получает блокировку ожидания для целевого банка перед вызовом одной из этих функций обратного вызова и снимает блокировку после возврата функции.

Функция обратного вызова контроллера, не сопоставленного с памятью, пытается повторно получить блокировку ожидания банка путем вызова GPIO_CLX_AcquireInterruptLock. Однако код драйвера пассивного уровня за пределами функций обратного вызова может вызывать методы GPIO_CLX_XxxInterruptLock для синхронизации с функциями обратного вызова. Так как GpioClx вызывает все функции обратного вызова, связанные с прерыванием и вводом-выводом, на PASSIVE_LEVEL, блокировки ожидания банка фактически занимают место блокировки прерываний банка для контроллеров, не сопоставленных в памяти.

Другим вариантом для контроллера, не сопоставленного с памятью, является реализация драйвера контроллера набора блокировок ожидания. Эти блокировки ожидания могут позволить подпрограммам обратного вызова выполнять более детализированную блокировку и разблокировку общих ресурсов, чем это возможно при использовании блокировок ожидания, реализованных GpioClx.

Во время вызова подпрограммы обратного вызова CLIENT_QueryControllerBasicInformation драйвер контроллера GPIO сообщает GpioClx, сопоставлены ли регистры контроллера с памятью. Дополнительные сведения см. в описании флага MemoryMappedController в CLIENT_CONTROLLER_BASIC_INFORMATION.

Дополнительные сведения о блокировках прерываний и ожидания см. в разделе Использование блокировок платформы.

В следующих таблицах содержатся более подробные сведения о том, какие функции обратного вызова вызываются в DIRQL, а не в PASSIVE_LEVEL, если регистры сопоставлены с памятью. В примечаниях, приведенных в таблицах, объясняется, когда функции обратного вызова пассивного уровня должны использовать блокировки прерываний.

Для поддержки контактов GPIO, настроенных в качестве входных данных прерывания, драйвер контроллера GPIO реализует набор функций обратного вызова событий для управления запросами прерываний через эти контакты. В следующей таблице средний столбец указывает irQL, в котором вызываются функции, если аппаратные регистры контроллера GPIO сопоставлены с памятью. Самый правый столбец указывает irQL, по которому вызываются функции, если регистры не сопоставлены с памятью и должны быть доступны через последовательную шину.

Функция обратного вызова IRQL, если память сопоставлена (MemoryMappedController = 1) IRQL при последовательном доступе (MemoryMappedController = 0)

CLIENT_EnableInterrupt

CLIENT_DisableInterrupt

PASSIVE_LEVEL

(См. примечание 1.)

PASSIVE_LEVEL

(См. примечание 2.)

CLIENT_ClearActiveInterrupts

CLIENT_MaskInterrupts

CLIENT_QueryActiveInterrupts

CLIENT_QueryEnabledInterrupts

CLIENT_ReconfigureInterrupt

CLIENT_UnmaskInterrupt

DIRQL

(См. примечание 3.)

PASSIVE_LEVEL

(См. примечание 4.)

CLIENT_PreProcessControllerInterrupt

DIRQL

(См. примечание 5.)

DIRQL

(См. примечание 6.)

Примечания

  1. GpioClx не получает блокировку прерывания банка перед вызовом этой функции обратного вызова. Функция обратного вызова может при необходимости получить блокировку прерывания банка для синхронизации доступа к регистрам, которые совместно используются с функциями обратного вызова, которые выполняются в DIRQL.

  2. GpioClx сериализует вызов этой функции обратного вызова с другими функциями обратного вызова, связанными с прерываниями и вводом-выводом, которые вызываются на PASSIVE_LEVEL. Таким образом, функция обратного вызова не должна пытаться получить блокировку ожидания банка.

  3. GpioClx получает блокировку прерывания банка перед вызовом этой функции обратного вызова и снимает блокировку после возврата функции. Таким образом, функция обратного вызова не должна пытаться получить блокировку прерывания банка.

  4. GpioClx сериализует вызов этой функции обратного вызова с другими функциями обратного вызова, связанными с прерываниями и вводом-выводом, которые вызываются на PASSIVE_LEVEL. Таким образом, функция обратного вызова не должна пытаться получить блокировку ожидания банка.

  5. GpioClx получает блокировку прерывания банка перед вызовом этой функции обратного вызова и снимает блокировку после возврата функции. Таким образом, функция обратного вызова не должна пытаться получить блокировку прерывания банка.

  6. GpioClx не получает блокировку прерывания банка перед вызовом этой функции обратного вызова. Драйвер контроллера GPIO отвечает за предоставление любой синхронизации, которая может потребоваться.

Для поддержки контактов GPIO, настроенных в качестве контактов ввода-вывода данных, драйвер контроллера GPIO реализует набор функций обратного вызова событий для управления операциями ввода-вывода с помощью этих контактов. В следующей таблице средний столбец указывает irQL, в котором вызываются функции, если аппаратные регистры контроллера GPIO сопоставлены с памятью. Самый правый столбец указывает irQL, по которому вызываются функции, если регистры не сопоставлены с памятью и должны быть доступны через последовательную шину.

Функция обратного вызова IRQL, если память сопоставлена (MemoryMappedController = 1) IRQL при последовательном доступе (MemoryMappedController = 0)

CLIENT_ConnectIoPins

CLIENT_DisconnectIoPins

PASSIVE_LEVEL

(См. примечание 1.)

PASSIVE_LEVEL

(См. примечание 2.)

CLIENT_ReadGpioPins

CLIENT_ReadGpioPinsUsingMask

CLIENT_WriteGpioPins

CLIENT_WriteGpioPinsUsingMask

DIRQL

(См. примечание 3.)

PASSIVE_LEVEL

(См. примечание 4.)

Примечания

  1. GpioClx не получает блокировку прерывания банка перед вызовом этой функции обратного вызова. Функция обратного вызова может получить блокировку прерывания, если это необходимо, для синхронизации доступа к регистрам, которые совместно используются с функциями обратного вызова, выполняемыми в DIRQL.

  2. GpioClx сериализует вызов этой функции обратного вызова с другими функциями обратного вызова, связанными с прерываниями и вводом-выводом, которые вызываются на PASSIVE_LEVEL. Таким образом, функция обратного вызова не должна пытаться получить блокировку ожидания банка.

  3. GpioClx получает блокировку прерывания банка перед вызовом этой функции обратного вызова и снимает блокировку после возврата функции. Таким образом, функция обратного вызова не должна пытаться получить блокировку прерывания банка.

  4. GpioClx сериализует вызов этой функции обратного вызова с другими функциями обратного вызова, связанными с прерываниями и вводом-выводом, которые вызываются на PASSIVE_LEVEL. Таким образом, функция обратного вызова не должна пытаться получить блокировку ожидания банка.

Чтобы настроить контроллер GPIO для выполнения операций ввода-вывода и прерываний, драйвер контроллера GPIO реализует набор функций обратного вызова событий для инициализации контроллера. В следующей таблице средний столбец указывает IRQL, в котором вызываются функции, если аппаратные регистры контроллера GPIO сопоставлены в памяти. Крайний правый столбец указывает irQL, в котором вызываются функции, если регистры не сопоставлены с памятью и должны быть доступны через последовательную шину.

Функция обратного вызова IRQL, если память сопоставлена (MemoryMappedController = 1) IRQL при последовательном доступе (MemoryMappedController = 0)

CLIENT_PrepareController

CLIENT_ReleaseController

CLIENT_StartController

CLIENT_StopController

CLIENT_QueryControllerBasicInformation

CLIENT_QuerySetControllerInformation

PASSIVE_LEVEL

(См. примечание 1.)

PASSIVE_LEVEL

(См. примечание 2.)

Примечания

  1. Когда GpioClx вызывает любую из этих функций обратного вызова, блокировки прерываний банка недоступны. Таким образом, эти функции обратного вызова не должны пытаться получить блокировку прерывания банка.

  2. Блокировки ожидания банка GpioClx недоступны при вызове этих функций обратного вызова. Таким образом, драйвер не должен пытаться получить блокировку ожидания банка для синхронизации с этими функциями обратного вызова.

Чтобы контроллер GPIO мог изменять состояния питания устройства, драйвер контроллера GPIO реализует набор функций обратного вызова событий для сохранения и восстановления параметров оборудования во время этих изменений. В следующей таблице средний столбец указывает IRQL, в котором вызываются функции, если аппаратные регистры контроллера GPIO сопоставлены в памяти. Крайний правый столбец указывает irQL, в котором вызываются функции, если регистры не сопоставлены с памятью и должны быть доступны через последовательную шину.

Функция обратного вызова IRQL, если память сопоставлена (MemoryMappedController = 1) IRQL при последовательном доступе (MemoryMappedController = 0)

CLIENT_RestoreBankHardwareContext

CLIENT_SaveBankHardwareContext

DIRQL или HIGH_LEVEL

(См. примечания.)

Не поддерживается.

Примечания

  • Для обычных переходов F-состояния. Функции обратного вызова сохранения и восстановления вызываются с блокировкой прерываний банка, удерживаемой GpioClx в DIRQL. Таким образом, ни функция обратного вызова не должна пытаться получить блокировку прерываний банка.
  • Для критических переходов F-состояния. Обратные вызовы сохранения и восстановления вызываются при вызове подключаемого модуля подсистемы питания (PEP) для сохранения и восстановления состояния GPIO. Функции обратного вызова сохранения и восстановления вызываются в HIGH_LEVEL в контексте последнего процессора для перехода в режим бездействия, что происходит в конце последовательности перехода с глубоким бездействующей платформой. Таким образом, ни функция обратного вызова не должна пытаться получить блокировку прерываний банка.

Дополнительные сведения о F-состояниях см. в разделе Управление питанием на уровне компонентов. Дополнительные сведения о PEP см. в разделе PoFxPowerControl.

Другие функции обратного вызова

Чтобы контроллер GPIO поддерживал операции, связанные с контроллером, драйвер контроллера GPIO реализует функцию обратного вызова события CLIENT_ControllerSpecificFunction . В следующей таблице средний столбец указывает IRQL, в котором вызывается функция, если аппаратные регистры контроллера GPIO сопоставлены в памяти. Крайний правый столбец указывает irQL, в котором вызывается функция, если регистры не сопоставлены с памятью и должны быть доступны через последовательную шину.

Функция обратного вызова IRQL, если память сопоставлена (MemoryMappedController = 1) IRQL при последовательном доступе (MemoryMappedController = 0)

CLIENT_ControllerSpecificFunction

PASSIVE_LEVEL

(См. примечание 1.)

PASSIVE_LEVEL

(См. примечание 2.)

Примечания

  1. GpioClx не получает блокировку прерываний банка перед вызовом этой функции обратного вызова. Функция обратного вызова может получить блокировку прерываний банка, если это необходимо, для синхронизации доступа к регистрам, которые совместно используются с функциями обратного вызова, выполняемыми в DIRQL.

  2. GpioClx сериализует вызов этой функции обратного вызова с другими функциями обратного вызова, связанными с прерываниями и вводом-выводом, которые вызываются на PASSIVE_LEVEL. Таким образом, функция обратного вызова не должна пытаться получить блокировку ожидания банка.