Как-то при разработке UEFI мне посчастливилось разбираться с таблицами описания системы в исходниках ASL (ACPI Source Language). Тема оказалась не тривиальная и моего багажа в несколько лет опыта, достаточно плотной embedded-разработки, не хватало для полного понимания работы подсистемы ACPI (Advanced Configuration and Power Interface). Поэтому пришлось исследовать доступные материалы на тему.

В процессе поиска информации заметил, что очень мало русскоязычных статей на эту тему – а если и есть, то они в основном рассказывают о том, как включить какое-то оборудование на раннем этапе загрузки системы, а не дают понимания, как это устроено. Поэтому решил попробовать написать об устройстве ACPI, тем более что тема достаточно сложная для понимания – одна лишь спецификация ACPI занимает более 1200 страниц (на момент написания статьи). А некоторые даже и не знают о её существовании.

Цель данной статьи – приоткрыть занавес в интересный и местами удивительный мир подсистемы ACPI, так как она работает практически во всех современных устройствах, от ПК до умных часов. Основной материал буду черпать из спецификация ACPI, переводя её основные моменты и дополняя их.

История ACPI

ACPI был разработан в середине 1990-х годов в результате сотрудничества компаний Intel, Microsoft, Toshiba, HP и Phoenix. До появления ACPI операционные системы (ОС) в основном использовали интерфейсы BIOS (базовой системы ввода-вывода) для управления питанием, а также для обнаружения и настройки устройств.

При таком подходе к управлению питанием ОС напрямую обращалась к системному BIOS. BIOS также использовался для обнаружения системных устройств и загрузки драйверов на основе проверки ввода-вывода (I/O) и подбора подходящего драйвера для соответствующего устройства (plug and play). Расположение устройств также могло быть жестко запрограммировано в BIOS, поскольку сама платформа не поддерживала перечисление. Эти решения были проблематичными по трем ключевым причинам:

  1. На поведение приложений ОС могли негативно влиять настроенные в BIOS параметры управления питанием, из-за чего системы могли переходить в спящий режим во время показа презент��ций или в любое другое неудобное время.

  2. Интерфейс управления питанием был проприетарным в каждой системе. Это требовало от разработчиков знания того, как настраивать управление питанием в каждой отдельной системе.

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

Итак, ACPI был разработан для решения этих и других проблем.

Что такое ACPI

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

Основная цель стандартной системы ACPI и набора аппаратных регистров — обеспечить управление питанием и настройку системы без вызова встроенного ПО (прошивки) из ОС. ACPI служит интерфейсом между ОС и системным встроенным ПО, как показано на схеме.

Основные цели ACPI

ACPI является ключевым элементом в настройке и управлении питанием, ориентированным на ОС (Operating System-directed configuration and Power Management / OSPM).

Основными целями ACPI и OSPM являются:

  1. Обеспечение возможности реализации функций конфигурации материнской платы и управления питанием во всех компьютерных системах (настольные, мобильные, рабочие и серверные компьютеры).

  2. Добавление функциональности и надёжности системы управления питанием. Унификация алгоритмов управления питанием в ОС уменьшит количество конфликтов между прошивкой и ОС и повысит надёжность.

  3. Облегчение и ускорение внедрения системы управления энергопотреблением в масштабах всей отрасли. OSPM и ACPI сокращают избыточные инвестиции в управление питанием во всей отрасли, поскольку эти инвестиции и функции будут объединены в ОС.

  4. Создание надежного интерфейса для настройки устройств материнской платы.

Для их достижения необходимо перенести управление питанием в ОС и использовать абстрактный интерфейс (ACPI) между ОС и аппаратным обеспечением. Поскольку ACPI является абстрактным интерфейсом, ОС может развиваться отдельно от аппаратного обеспечения, а аппаратное обеспечение — отдельно от ОС.

Интересно, что ACPI обеспечивает поддержку плавного перехода от устаревшего оборудования к оборудованию ACPI и позволяет использовать оба механизма на одном компьютере по мере необходимости.

Архитектура ACPI

Важно понимать, что несмотря на то, что ACPI касается как программного, так и аппаратного обеспечения и определяет, как они должны работать, это вовсе не спецификация ПО и не спецификация аппаратного обеспечения. ACPI — это спецификация интерфейса, состоящая из программных и аппаратных элементов.

В ACPI есть три компонента, работающих во время выполнения:

Таблицы описания системы ACPI (ACPI System Description Tables)

Описывают интерфейсы аппаратного обеспечения. В таблицах ACPI, содержащих «блоки определений», может использоваться псевдокод, интерпретация которого выполняется ОС. То есть OSPM содержит и использует интерпретатор, который выполняет процедуры, закодированные на языке псевдокода и хранящиеся в таблицах ACPI, содержащих «блоки определений».

Регистры ACPI

Ограниченная часть аппаратного интерфейса, описанная (по крайней мере, в части расположения) в таблицах описания системы ACPI.

Прошивка платформы ACPI

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

Таблицы описания системы ACPI, описывающие аппаратное обеспечение конкретной платформы, лежат в основе реализации ACPI, а роль прошивки ACPI заключается, в основном, в предоставлении таблиц ACPI (а не собственного API инструкций).

Функциональные области ACPI

Далее разберём, какие функции выполняет ACPI.

1. Управление питанием системы

ACPI определяет механизмы перевода компьютера в целом в спящий режим и вывода его из спящего режима. Он также предоставляет общий механизм для пробуждения компьютера любым устройством.

2. Управление питанием устройств

Таблицы ACPI описывают устройства материнской платы, их состояния питания, плоскости питания, к которым ��одключены устройства, а также элементы управления для перевода устройств в различные состояния питания. Это позволяет ОС переводить устройства в режимы пониженного энергопотребления в зависимости от использования приложений.

3. Управление энергопотреблением процессора

Пока ОС простаивает, но не переходит в спящий режим, она использует команды, описанные в ACPI, для перевода процессоров в режим пониженного энергопотребления.

4. Управление производительностью устройства и процессора

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

5. Конфигурация / Plug and Play

ACPI предоставляет информацию, используемую для перечисления и настройки устройств материнской платы. Эта информация структурирована иерархически, поэтому при таких событиях, как подключение и отключение, ОС точно знает, какие устройства затронуты этим событием.

6. Системные события

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

7. Управление температурным режимом

Поскольку ОС контролирует энергопотребление и производительность устройств и процессоров, ACPI также отвечает за управление температурным режимом системы.

8. Контроллер SMBus

ACPI определяет стандартный аппаратный и программный интерфейс связи между драйвером шины ОС и контроллером SMBus.

Структуры данных ACPI

ACPI определяет два типа структур данных, которые совместно используются прошивкой и ОС через подсистему ACPI:

  • Data Tables (Таблицы данных)

  • Definition Blocks (Блоки определений)

Эти структуры данных являются основным механизмом взаимодействия между прошивкой и ОС. В таблицах данных хранятся необработанные данные, которые используются драйверами устройств.

Интерпретатор AML

Блоки определений состоят из байт-кода, который выполняется интерпретатором AML. AML (ACPI Machine Language) — это язык, обрабатываемый интерпретатором AML – см. рисунок ниже.

Интерпретатор AML выполняет следующую последовательность действий:

  1. Извлекает байт-код из блоков определений в виде перечисляемых объектов. Этот набор перечисляемых объектов образует конструкцию ОС, называемую пространством имён ACPI (ACPI namespace).

  2. Вычисляет значения объектов из пространства имён ACPI, чтобы байт-код мог получать доступ к определённым адресным пространствам (системная память, ввод-вывод, конфигурация PCI и многое другое) и выполнять операции, необходимые приложениям.

  3. Взаимодействует с системным оборудованием для выполнения необходимых операций.

 ACPI Source Language 

Байт-код блока определения компилируется из языка ACPI Source Language (ASL), используемого для определения объектов ACPI и написания методов управления. Компилятор ASL преобразует исходный код ASL в AML байт-код, как показано на следующем рисунке.

 Пространство имён ACPI

Как было описано ранее пространство имён ACPI состоит и перечисляемых объектов, которые были описаны в таблицах описания системы. Основными объектами пространства имен ACPI являются:

  1. System bus (SB) – системная шина, является корнем перечисления для устройств ACPI.

  2. Устройства (Devices), которые можно перечислить на других шинах, например, устройства PCI или USB, обычно не перечисляются в пространстве имён. Вместо этого их собственные шины перечисляют устройства и загружают их драйверы. Однако все перечисляемые шины имеют метод кодирования, который позволяет ACPI кодировать адреса устройств на конкретной шине, чтобы их можно было найти в ACPI, даже несмотря на то, что ACPI обычно не загружает драйверы для этих устройств.

Инициализация ACPI

Сначала необходимо разобраться в основных таблицах описаний системы ACPI:

  • XSDT – eXtended Root System Description Table или расширенная таблица описания корневой системы.

  • FADT – Fixed ACPI Description Table или фиксированная таблица описания ACPI.

  • DSDT – Differentiated System Description Table или дифференцированная таблица описания системы

  • SSDT – Secondary System Description Tables или вторичная таблица описания системы

Лучший способ понять, как работает ACPI, — рассмотреть процесс инициализации в хронологическом порядке.

  1. В момент включения системы пользователем встроенное ПО завершает настройку, инициализацию и самотестирование.

  2. Затем встроенное ПО использует информацию, полученную во время инициализации, для обновления ACPI таблиц в соответствии с различными конфигурациями платформы и данными интерфейса питания, прежде чем передать управление загрузчику. XSDT - это первая таблица, используемая подсистемой ACPI. Она содержит адреса большинства других таблиц ACPI в системе. XSDT указывает на FADT, а также на другие основные таблицы, которые ОС обрабатывает во время инициализации.

  3. После инициализации ОС FADT направляет подсистему ACPI в DSDT, которая является началом пространства имён, поскольку это первая таблица, содержащая блок определений.

  4. Затем подсистема ACPI обрабатывает DSDT и начинает формировать пространство имён на основе блоков определения ACPI.

  5. XSDT также указывает на SSDT и добавляет их в пространство имён.

  6. После того, как ОС сформирует пространство имён на основе таблиц ACPI, она начнёт обходить пространство имён и загружать драйверы устройств для всех устройств, которые она обнаружит в пространстве имён.

Модель времени выполнения

После запуска системы, ACPI взаимодействует с ОС для обработки любых событий ACPI, возникающих в результате прерывания. Это прерывание вызывает события ACPI одним из двух основных способов: фиксированными событиями и событиями общего назначения (General Purpose Events или GPE).

  • Фиксированные события — это события ACPI, которые имеют заранее опреде��ённое значение в спецификации ACPI. К таким фиксированным событиям относятся, например, нажатие кнопки питания или переполнение таймера ACPI. Эти события обрабатываются непосредственно обработчиками ОС.

  • GPE — это события ACPI, которые не предусмотрены спецификацией ACPI. Эти события обычно обрабатываются с помощью методов управления, которые являются объектами в пространстве имён и могут получать доступ к системному оборудованию.

Заключение

ACPI лучше всего можно описать как набор концепций и интерфейсов, которые реализуются для формирования подсистемы в рамках ОС хоста. Таблицы ACPI, обработчики, интерпретатор, пространство имён, события и т.д. вместе образуют эту реализацию ACPI, создавая ее подсистему. В этом смысле ACPI — это интерфейс между системным оборудованием/прошивкой и ОС, а также приложениями ОС для настройки и управления питанием. Это даёт различным ОС стандартизированный способ поддержки и настройки управления питанием, производительностью, энергопотреблением, температурным режимом.

Как показывает практика, благодаря применению ACPI производителям железа и ПО стало легче создавать новое, не изобретая велосипедов и костылей.

Надеюсь, что этой статьёй мне получилось немного приоткрыть читателю дверь в мир ACPI. В следующих статьях планирую описать аппаратную модель и модель программирования ПО ACPI.