Практикум по ACPI

На сегодня, у многих специалистов, использование ACPI ас­со­ци­и­ру­ет­ся в пер­вую оче­редь с фун­к­ци­я­ми уп­рав­ле­ния элек­т­ро­пи­та­ни­ем и ми­ни­ми­за­ци­ей энер­­го­по­треб­ле­ния. Вмес­те с тем, дан­ная спе­ци­фи­ка­ция раз­ра­бо­та­на как аль­тер­на­ти­ва ус­та­ре­ва­ю­ще­му стан­дар­ту Plug and Play, и сфе­ры ее при­ме­не­ния зна­чи­тель­но шире.

Спецификация ACPI содержит огромное ко­ли­че­ст­во оп­ре­де­ле­ний, про­то­ко­лов и фор­ма­тов, по­э­то­му в рам­ках од­ной ста­тьи мож­но из­ло­жить толь­ко ос­нов­ные прин­ци­пы ее фун­к­ци­о­ни­ро­ва­ния. Для по­дроб­но­го изу­че­ния во­про­са ре­ко­мен­ду­ется об­ра­тить­ся к до­ку­мен­там [1], [2], [8]. Пред­ла­га­е­мый ма­те­ри­ал по­зи­ци­о­ни­ру­ет­ся как прак­ти­че­ский при­мер, ин­те­рес­ный для спе­ци­а­лис­тов, уже име­ющих не­ко­то­рые ба­зо­вые зна­ния в дан­ной об­лас­ти. На уров­не ас­сем­б­лер­ных ин­струк­ций и схе­мо­тех­ни­ки ма­те­рин­ской пла­ты рас­смат­ри­ва­ет­ся про­це­ду­ра про­грам­мно­го вы­клю­че­ния пи­та­ния. К статье при­ла­га­ют­ся также про­то­ко­лы руч­но­го дизассемблирования таб­лиц ACPI с под­роб­ны­ми ком­мен­та­ри­я­ми.

Как это работает?

Рассмотрим абстрактный пример. Пусть для выполнения заданного действия не­об­ходимо записать в регистр по ад­ре­су X данные Y. При использовании под­хо­да, основанного на вызове сервисных процедур BIOS, в выполняемом блоке BIOS будет размещена процедура, которая осуществляет указанную запись. Задача опе­ра­ци­онной системы — просто вызвать эту процедуру. В данном случае, осо­бен­нос­ти реализации конкретного чипсета, если таковые имеются, скрыты вну­три BIOS и не являются заботой разработчика ОС

Второй вариант — ОС не обращается к BIOS и выполняет указанную запись са­мо­стоятельно. В этом случае, драй­вер на­пря­мую вза­и­мо­дей­ст­ву­ет с ре­гист­ра­ми чипсета, распознает и эффективно использует его возможности. Но рас­пла­та за это — усложнение и ограниченная совместимость. Как известно, под каж­дый чип­сет нужен свой драйвер.

Разработчикам ACPI удалось придумать третий вариант. Численные значения X и Y, отражающие особенности ре­а­ли­за­ции конкретной платформы, хра­нят­ся в спе­ци­аль­ных таблицах, которые генерирует BIOS при старте и размещает в опе­ра­тив­ной памяти. Для этого, как правило, используется последний мегабайт верх­ней памяти. Опе­ра­ци­он­ная сис­те­ма находит и считывает эти параметры. Про­це­ду­ра записи в регистр по адресу X данных Y является частью ОС, а не BIOS, но параметры X и Y предоставляет BIOS посредством таблиц ACPI.

Какие преимущества это дает? Таблицы ACPI, в отличие от сервисных про­це­дур BIOS, не содержат вы­пол­ня­е­мо­го ко­да, поэтому независимо от архитектуры про­цессора и режима его работы, можно использовать одни и те же таблицы. Что­бы оце­нить это преимущество, вспомним о неудобствах, связанных с тем, что большинство функций BIOS могут быть вызваны только в реальном режиме про­цес­со­ра (Real Mode). Функции, доступные в защищенном режиме (Pro­tect­ed Mo­­de) должны иметь несколько точек входа (для Real Mode, Protected Mode 16, Pro­tect­ed Mode 32).

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

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

Таблицы и структуры ACPI

Операционная система, или программа, желающая воспользоваться ин­тер­фей­сом ACPI, сначала должна выполнить его детектирование и определить расположение таблиц. Для этого, в области адресов выполняемого блока BIOS (E0000h-FFFFFh) необходимо найти структуру RSDP (Root System Description Poin­t­er). Структура имеет размер 36 байт, может быть расположена в про­из­воль­ном месте внутри указанного 128-Кбайтного блока и обнаруживается по пос­ле­до­ва­тель­нос­ти символов «RSD PTR». Если структура не обнаружена или ее кон­троль­ная сумма неверна, де­тек­ти­ру­ю­щая программа делает вывод, что ACPI не под­дер­жи­вается. Если структура обнаружена и имеет правильную кон­т­роль­ную сум­му, из нее считывается 32-битный адрес таблицы RSDT (Root System De­scrip­tion Table), содержащей ка­та­лог таб­лиц ACPI. В реализациях ACPI версии 2.0 и выше, доступен также 64-битный адрес таблицы XSDT (Extended System De­scrip­tion Table). Функции этой таблицы, такие же, как у таблицы RSDT, но за счет использования 64-битных указателей, таблица XSDT, а также таблицы, на которые она ссылается, могут быть расположены выше 4 Гб.

Ниже перечислены основные таблицы ACPI, полная номенклатура таблиц приведена в [1].

Таблица FADT (Fixed ACPI Description Table) содержит набор параметров, опи­сы­ва­ю­щих платформу и чипсет. ОС ис­поль­зу­ет эти параметры при вза­и­мо­дей­ствии с оборудованием. Таблица FADT форматирована, то есть назначение каж­до­го поля определяется его адресом внутри таблицы. Здесь содержатся кон­стан­ты, характеризующие платформу, адреса структур в оперативной памяти, ис­поль­зу­е­мых для взаимодействия BIOS и ОС, адреса регистров чипсета, ис­поль­зу­е­мых для передачи заданных команд (регистры управления) и опроса текущего состояния (регистры статуса), номера линий запросов на прерывание, ис­поль­зу­е­мых для оповещения ОС о заданных событиях в подсистеме ACPI и другая информация.

Структура FACS (Firmware ACPI Control Structure) используется для управления переходом в спящий режим и вы­хо­дом из него. Она содержит век­тор для передачи управления на процедуру, запускаемую при выходе из спя­ще­го ре­жи­ма. Также здесь находится 32-битная сигнатура оборудования или Hardware Signature, используемая для кон­т­ро­ля из­ме­не­ний конфигурации, про­и­зо­шед­ших за время нахождения системы в спящем режиме, например удаления или под­клю­че­ния каких-либо устройств. Это переменная, вычисляемая как функция от текущей кон­фи­гу­ра­ции обо­ру­до­ва­ния. По­сле выхода из спящего режима, зна­че­ние этой переменной вычисляется повторно и срав­ни­ва­ет­ся с об­раз­цом, хра­ня­щим­ся в структуре FACS.

Таблица DSDT (Differentiated System Description Table) является самой сложной. Она содержит описание методов вы­пол­не­ния типовых системных опе­ра­ций (например, считывание температуры процессора или изменение номера ли­нии запроса на прерывание, используемой заданным устройством), ин­фор­ма­цию об устройствах, шинах, всех сис­тем­ных объектах и методах взаимодействия с ними. Декларации системных устройств (объекты System Plug and Play Nodes), также продублированы в этой таблице, при этом номенклатура описанных устройств существенно расширена. Таблица DSDT, в отличие от FADT, не фор­ма­ти­ро­ва­на, то есть доступ к заданной записи осуществляется не по фик­си­ро­ван­но­му адресу, а последовательным сканированием и детектированием требуемой записи. Исходный код таблицы DSDT пишется программистом на языке ASL (ACPI Source Language), который преобразуется компилятором в код AML (ACPI Machine Language). Интерпретатор языка AML, входящий в состав операционной системы, обеспечивающий обработку DSDT, обычно называется виртуальной машиной ACPI.

Таблицы SSDT (Secondary System Description Table) используются как модули расширения таблицы DSDT. В системе мо­жет присутствовать несколько таблиц SSDT. Мотивация применения таблиц SSDT состоит в том, что отдельные пор­ции AML кода (например, выбираемые в зависимости от типа установленного про­цес­со­ра или состояния опций BIOS Setup) удобно выделить в виде отдельных таблиц, а не размещать в главной таблице DSDT.

Таблица MADT (Multiple APIC Description Table) используется для ин­фор­ми­ро­ва­ния операционной системы о ло­ги­че­ских и фи­зи­че­ских процессорах и контроллерах прерываний I/O APIC (Input-Output Advanced Programmable Interrupt Controller). Подобно старой таблице MPT (Multiprocessing Table), расположенной в выполняемом блоке BIOS, таблица MADT содержит по­сле­довательность информационных структур, описывающих процессоры, кон­трол­ле­ры пре­ры­ва­ний, а также соответствие между номерами линий запросов на прерывание и входами кон­т­рол­ле­ров пре­ры­ва­ний. Заметим, что в большинстве сис­тем, использующих технологию Hyper Threading, в таблице MPT де­кла­ри­ро­ва­ны только физические процессоры или ядра, а в таблице MADT перечислены все логические процессоры. Это дает операционной системе дополнительную возможность для распознавания типа мультипроцессорной системы.

Первые 36 байт каждой таблицы образуют заголовок, назначение полей ко­то­ро­го одинаково для всех таблиц. Далее следует основной блок, это ин­фор­ма­ция, структура которой определяется типом таблицы. Полная но­мен­кла­ту­ра и де­таль­ное описание всех таблиц и структур, а также формат указателя RSDP приводится в [1].

Протоколы дизассемблирования таблиц ACPI

В прилагаемом каталоге DISASM содержатся протоколы ручного диз­ас­сем­блирования некоторых таблиц ACPI и их фрагментов с детальными ком­мен­та­ри­ями (текстовые файлы в кодировке DOS). Разумеется, существует возможность для автоматизированного выполнения этой задачи, например, дизассемблер фирмы Phoenix Technologies — AD.EXE (ACPI Dump). Вместе с тем, для получения некоторых сведений, необходимых для написания собственной вир­ту­аль­ной ма­шины ACPI и других исследовательских работ, автор посчитал уместным «коп­нуть глубже», несмотря на оче­вид­ную тру­до­ем­кость данного подхода.

Примечание. В комментариях к дизассемблированным таблицам ACPI, ис­поль­зу­ют­ся ссылки на страницы и пункты документов, указанных в файле README.TXT. Для того чтобы ссылки оставались верными, необходимо ис­поль­зо­вать именно те версии документов, которые указаны. Например, вместо до­ступ­ной на сегодня спецификации ACPI 3.0 (документ [1]), во время вы­пол­не­ния дан­ных работ использовалась спецификация ACPI 2.0.

Описание работы программы

Как и в ранее опубликованных статьях данного цикла, в целях монопольного и бес­пре­пятственного взаимодействия программы с оборудованием, автор при­ме­нил древнюю технологию отладки под DOS. Аргументация такого шага и ре­ко­мен­да­ции по организации рабочего места приведены в ранее опу­бли­ко­ван­ной статье «64-битный режим под DOS: исследовательская работа №1».

В качестве примера взаимодействия с оборудованием посредством ин­тер­фей­са ACPI, рассмотрена процедура про­грам­мно­го выключения питания ком­пью­те­ра (для систем с блоком питания ATX).

Предлагаемый пример является полуфабрикатом, и совместим не со всеми ре­а­ли­зациями таблиц DSDT. Те­ку­щая вер­сия программы способна на­хо­дить объ­екты _S5, только в таких реализациях, где указанные объекты рас­по­ло­же­ны в на­ча­ле таблицы DSDT. Для универсального решения такой задачи, необходима пол­но­ценная реализация вир­ту­аль­ной машины ACPI, так как чтобы добраться до объекта _S5, потребуется интерпретировать AML код, рас­по­ло­женный до тре­бу­е­мо­го объекта. В случае несовместимости выдается со­об­ще­ние In­com­pa­tible version of AML code.

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

Прилагаемый каталог WORK содержит следующие файлы:

ACPI

 

Рассмотрим выполнение основного модуля. Нумерация пунктов данного описания соответствует нумерации пунктов комментариев в исходном тексте - файле WORK\atx_off.asm.

  1. Устанавливаем адрес стека.
  2. Выводим сообщение о начале выполнения программы.
  3. Проверяем режим работы процессора. Данная программа требует Real Mode, так как взаимодействует с оборудованием. Если процессор в Protected Mode, выходим с сообщением об ошибке.
  4. Разрешаем адресную линию A20 и включаем Big Real Mode. Эти действия необходимы, так как таблицы ACPI расположены выше 1 MB.
  5. Детектируем поддержку ACPI. Подпрограмма Scan_ACPI_RSDP сканирует 128-Кбайтный блок E0000h-FFFFFh на предмет обнаружения сигнатуры - последовательности символов «RSD PTR», с которой начинается структура RSDP. Если сигнатура найдена и контрольная сумма RSDP верна, из RSDP считывается 32-битный адрес таблицы RSDT, содержащей каталог таблиц ACPI. Иначе, выходим с сообщением об ошибке. Далее, используя подпрограмму Get_ACPI_Table, находим таблицу FADT по сигнатуре "FACP". Из таблицы FADT, по фиксированным адресам считываем адреса портов для регистров управления контроллера Power Management: PM1a_CNT_BLK и PM1b_CNT_BLK (Power Management Control Blocks). Использование этих регистров описано в пункте 7. Сохраняем прочитанные значения.
  6. Используя подпрограмму Get_ACPI_Table, находим таблицу DSDT по сигнатуре «DSDT». Используя подпрограмму Scan_AML_Name, находим в таблице DSDT декларацию объекта NAME содержащего имя _S5. Этот объект содержит значения S5a_Value, S5b_Value, использование которых описано в пункте 7. Сохраняем значения, полученные при интерпретации содержимого объекта.

Стандартное для ACPI имя переменной _S5, используемой в процедуре выключения питания, обусловлено тем, что дежурный режим, при котором на блок питания ATX подается напряжение сети, но система выключена (блок питания выдает только напряжение +5V Standby и сигнал PS_ON=1) классифицируется спецификацией ACPI как состояние S5=Soft-Off.

  1. Выполняем запись заданных значений в заданные порты, что приводит к выключению питания (переводу сигнала PS_ON в состояние логической «1»). Предварительно выводим дамп значений, полученных на шагах 5 и 6. Считываем порт PM1a_CNT_BLK, в прочитанном значении, бит 13 (Sleep Enable) устанавливаем в «1», биты 12-10 (поле Sleep Type) устанавливаем в состояние, равное содержимому объекта S5a_Value, остальные биты не изменяем. Значение, с модифицированными битами 13-10 записываем обратно в порт PM1a_CNT_BLK. Считываем порт PM1b_CNT_BLK, в прочитанном значении, бит 13 (Sleep Enable) устанавливаем в «1», биты 12-10 (поле Sleep Type) устанавливаем в состояние, равное содержимому объекта S5b_Value, остальные биты не изменяем. Значение, с модифицированными битами 13-10 записываем обратно в порт PM1b_CNT_BLK. После задержки, связанной с прохождением сигналов через Power Management контроллер, питание должно выключиться. Запрещаем прерывания и останавливаем процессор. В типовой платформе, инструкции CLI и HLT, расположенные после процедуры записи регистров, успеют выполниться до выключения питания, так как существует задержка срабатывания контроллера Power Management и инерционность блока питания. Вместе с тем, вариант, при котором питание выключится раньше, также допускается.

Использование двух портов управления PM1a_CNT_BLK и PM1b_CNT_BLK обусловлено тем, что спецификация ACPI поддерживает описание нетипичных платформ, у которых для выключения питания требуется выполнить запись в два порта, имеющие различные адреса и физически расположенные в разных микросхемах (Северном и Южном мостах чипсета). В типичной платформе такая возможность избыточна, так как для рассматриваемого действия достаточно записи в один порт, расположенный в составе Южного моста чипсета. При этом переменная PM1a_CNT_BLK содержит адрес этого порта, а переменная PM1b_CNT_BLK содержит нуль, что соответствует отсутствию порта. Программа, вы­пол­ня­ю­щая запись значений в указанные регистры, пропускает операцию записи, если адрес нулевой.

  1. Сюда передается управление, если требуется аварийное завершение программы после того, как разрешена линия A20 и включен режим Big Real Mode. Восстанавливаем состояние линии A20, выключаем режим Big Real Mode и переходим к пункту 9 для выхода из программы.
  2. Выход из программы с генерацией сообщения об ошибке.

Управление блоком питания ATX

Рассмотрим процессы, происходящие при выполнении вышеописанной программы, на уровне принципиальной элек­т­ри­че­ской схемы. Разумеется, в каждой материнской плате, в зависимости от модели чипсета, микросхемы MIO (Multi Input/Output) и других факторов, рассматриваемый узел реализован по-своему.

Плата ASUS P5GPL-X SE с набором системной логики Intel 915PL и микросхемой SIO-контроллера Winbond W83627EHG

 

Для определенности возьмем частный случай - материнские платы, использующие Южный мост Intel ICH6, опи­сан­ный в [6] (это платы на чипсетах Intel 915 и 925) и микросхему MIO Winbond W83627THF, описанную в [12].

Расположение выводов корпуса микросхемы SuperIO Winbond W83627THF

Ядро Power Management контроллера, а именно, логика, принимающая решение о включении и выключении питания находится в составе Южного моста чипсета. Здесь же расположен программно-доступный регистр PM1_CNT_BLK, ис­поль­зу­е­мый в приведенном примере для выключения питания. Обеспечение интерфейса Power Man­­a­ge­ment кон­т­рол­ле­ра с внешним миром входит в обязанности микросхемы MIO. В ее составе находится схема опроса кнопки Po­wer Switch, которая, получив сигнал от кнопки, транслирует его Power Management контроллеру (ICH6). Также в составе MIO находится формирователь сигнала PS_ON для блока питания ATX. При получении соответствующего приказа от ICH6, микросхема MIO выдает сигнал PS_ON=0, что приводит к включению блока питания.

Битовые поля, осуществляющие выбор Power Management состояния и
стробирование его установки, определенные согласно спецификации ACPI

 

Что происходит при выполнении нашей программы? Запись в регистр PM1_CNT_BLK 16-битного слова, у которого бит 13 (Sleep Enable) установлен в «1», а значение битового поля Sleep_Type соответствует ACPI-состоянию S5 (состояние Soft-Off) является приказом для ICH6 начать процедуру выключения питания. ICH6 выдает сигнал SLP_S3# (контакт с координатами T4). Он приходит на вход SLP_Sx (контакт 73) микросхемы MIO W83627THF. В результате микросхема W83627THF выдает логическую «1» на выход PWCTL# (контакт 72) и блок питания выключается. Этот вы­ход под­клю­чен к ли­нии PS_ON блока питания. В зависимости от схемотехники платы, подключение выполняется на­пря­мую или че­рез бу­фер­ный по­вто­ри­тель.

Другие примеры реализаций микросхем Южных мостов и MIO приведены в [7], [9], [10], [11], [13].

При рассмотрении работы блока питания, не следует путать сигналы PS_ON и PWR_OK. Сигнал PS_ON (Power Supply On) используется для включения блока питания ATX. Это входной сигнал для блока питания и выходной сигнал для материнской платы. При логическом «1» на этой линии, блок питания выключен (работает только дежурный источник +5V Standby, необходимый для схемы управления питанием). При логическом «0» на этой линии блок пи­та­ния вклю­чен, вы­да­ют­ся все выходные напряжения. Сигнал PWR_OK (Power OK, синоним Power Good) используется для за­пус­ка ма­те­рин­ской платы при включении питания и блокировки работы ее устройств на время переходных процессов при включении и выключении питания. Это входной сигнал для материнской платы и выходной сигнал для блока питания. Логический «0» на этой линии равносилен нажатию кнопки RESET. При этом все устройства зафиксированы в со­сто­я­нии сбро­са. При включении питания, в течение нескольких миллисекунд, сигнал PWR_OK=0, это обеспечивает за­пуск ком­пью­те­ра и препятствует выполнению каких-либо операций до стабилизации питания. При вы­клю­че­нии пи­та­ния, во вре­мя пе­ре­ход­но­го про­цес­са, сигнал PWR_OK также переходит в состояние логического «0». Во время ра­бо­че­го се­ан­са на этой ли­нии при­сут­ст­ву­ет ло­ги­че­ская «1». Подробности в [3], [4].

Источники информации

Электронные документы, доступные на сайте ACPI

  1. Advanced Configuration and Power Interface Specification. Revision 3.0

Электронные документы, доступные на сайте Intel

  1. Instantly Available Power Managed Desktop PC Design Guide. Revision 1.1
  2. ATX Specification. Version 2.03
  3. ATX / ATX12V Power Supply Design Guide. Version 1.0 (Public Release)
  4. ATX Balanced Technology Extended (BTX) Interface Specification. Version 1.0
  5. Intel I/O Controller Hub 6 (ICH6) Family Datasheet. Document Number 301473-001
  6. Intel I/O Controller Hub 7 (ICH7) Family Datasheet. Document Number 307013-002

Электронные документы, доступные на сайте AMD

  1. Open Platform Management Architecture Specification. Publication # 32200
  2. AMD-8111 HyperTransport I/O Hub Data Sheet. Publication # 24674

Электронные документы, доступные на сайте datasheetarchive.com

  1. VIA VT82C686A South Bridge Datasheet. Revision 1.54
  2. VIA VT82C686B South Bridge Datasheet. Revision 1.71

Электронные документы, доступные на сайте Winbond

  1. Winbond LPC I/O W83627THF

Электронные документы, доступные на сайте ITE

  1. IT8712F Environment Control - Low Pin Count Input/Output (EC-LPC I/O)