Идентификация и исправление ошибок процессоров Intel


В данной статье, представляющей фрагменты новой книги Михаила Гука "Процессоры Pentium III, Athlon и другие" описываются некоторые свойства современных процессоров, знание которых необходимо системному, а иногда и прикладному программисту. Практическое применение этих свойств уже излагалось на сайте (см. статьи "Исправление ошибок в CPU" и "Самостоятельное исправление ошибок в CPU"), теперь немного теории.

1. Идентификация процессоров (CPUID)

Возможность программного определения типа процессора заложена в архитектуру 32-разрядных процессоров "отродясь". В любом процессоре сразу после аппаратного сброса в регистре (E)DX можно прочитать номер семейства (3 — 386, 4 — 486, 5 — Pentium, 6 — P6…), модели, типа и степпинга. Расшифровка основных полей приводится в табл. 1. Кроме перечисленных в таблице имеется поле степпинга (биты 3:0) — номер версии процессора в пределах одной модели. Информацию этого поля, к сожалению, без таблиц изготовителя не расшифровать. Поле "тип" (биты 13:12) различает процессоры OEM-версий (00), OverDrive (01) и Dual (10); значение 11 зарезервировано. Наиболее интересная информация содержится в полях "семейство" (биты 11:8) и "модель" (биты 7:3). Старшие биты (14–31) регистра EDX пока не используются (они нулевые). Процессоры 80386 имели несколько иное назначение бит: поле "семейство" совпадает, поле "модель" занимает биты 15:11, биты 7:0 отводятся под степпинг. Для младших процессоров регистр DH содержит идентификатор процессора (01 — 8086/88, 02 —80286), DL — номер модели. Поле "модель" позволяет отличать, например, Pentium MMX от "просто" Pentium 75–233 МГц или Pentium 60–66 МГц, Celeron от Pentium II или Pentium Pro. По полю "тип" можно отличить, например, процессоры OverDrive. Поле "степпинг" без таблиц не расшифровать, оно несет информацию о нюансах — например, исправлены ли те или иные ошибки, возможный диапазон частот (определяется косвенно и не точно).

Таблица 1. Коды идентификации процессоров

Тип
EDX[13:12]
Семейство
EDX[11:8]
Модель
EDX[7:4]
Процессор
00 0100 0000 Intel486DX
00 0100 0001 Intel486DX
00 0100 0010 Intel486SX
00 0100 0011 Intel487, IntelDX2, IntelDX2 OverDrive, AMD DX2 в режиме WT
00 0100 0100 IntelSXL
00 0100 0101 IntelSX2 OverDrive
00 0100 0111 IntelDX2 Enhanced в режиме WB, AMD DX2 в режиме WB
00 0100 1000 IntelDX4 OverDrive, AMD DX4 в режиме WT
00 0100 1001 AMD DX4 в режиме WB
00 0100 1110 Am5x86 в режиме WT
00 0100 1111 Am5x86 в режиме WB
01 0100 1000 IntelDX4 OverDrive
00 0101 0000 AMD K5-PR75, 90, 100
00 0101 0001 Pentium 60, 66
Pentium OverDrive для Pentium 60, 66
AMD K5-PR120, 133
00 0101 0010 Pentium 75, 90, 100, 120, 133, 150, 166, 200
AMD K5-PR166
01 0101 0010 Pentium OverDrive 75, 90, 100, 120, 133
01 0101 0011 Pentium OverDrive для 486
00 0101 0100 Pentium MMX (166, 200, 233)
01 0101 0100 Зарезервировано (OverDrive для Pentium 75, 90, 100, 120, 133)
00 0110 0001 Pentium Pro
00 0110 0011 Pentium II первого поколения (233–300 МГц)
01 0110 0011 Pentium II OverDrive
00 0110 0101 Pentium II Desсhutes (333–450 МГц), Celeron (266, 300 МГц), Xeon
00 0110 0110 Celeron 300A, 333–533
00 0110 0111 Pentium III и Pentium III Xeon
00 0110 1000 Pentium III Coppermine, Pentium III Xeon, Celeron 533A, 566, 600

Информация из (E)DX доступна только для BIOS в самом начале запуска машины (ее может считать тест POST). Поскольку BIOS ориентирован на процессоры одного поколения (семейства), проблем с различием использования регистра (E)DX не возникает. Потребность в идентификации процессора операционной системой и приложениями созревала по мере расширения диапазона функциональных возможностей и уровня производительности процессоров. Начиная с процессоров Pentium появилась новая инструкция CPUID, по которой любая программа на любом уровне привилегий в любой момент времени могла получить ту же информацию, что и BIOS после сброса, и, вдобавок, 32-битный набор флагов расширений базовой архитектуры, реализованных в данном процессоре. Полученную информацию программа может использовать, например, для выбора исполняемого кода, оптимального для данного процессора (или отказа исполнения на "недостойном" ее процессоре), а также для настройки констант программных реализаций задержек. Инструкция CPUID была реализована и в ряде поздних моделей процессоров класса 486. Формат инструкции практически безгранично расширяем, с ее помощью процессор может выдавать хоть весь свой словесный портрет (если эту возможность заложат его разработчики). Однако информация для CPUID "зашивается" в процессор на этапе изготовления кристалла, что не позволяет, например, "выпытать" у процессора его официальную тактовую частоту (она определяется позже — на этапе тестирования уже готового процессора). А эта информация была бы полезна при борьбе с пиратским разгоном (перемаркировкой) процессоров, что, в общем-то, волнует изготовителя.

Следующий шаг, уже явно нацеленный на учет и контроль, был сделан в процессоре Pentium II Xeon. Здесь имеется специальная постоянная (только для чтения) память процессорной информации PIROM (Processor Information ROM), которая хранит такие данные, как электрические спецификации ядра процессора и кэш-памяти (диапазоны частот и питающих напряжений), S-спецификацию (степпинг) и 64-битный серийный номер процессора. Кроме того, имеется энергонезависимая память Scratch EEPROM, которая предназначена для занесения системной информации поставщиком процессора (или компьютера с этим процессором) и может быть защищена от последующей записи. Для взаимодействия с PIROM и Scratch EEPROM (а также устройством термоконтроля) процессор имеет дополнительную последовательную шину SMBus (System Management Bus) — отдельный электрический интерфейс, с которым работает чипсет системной платы. Обращение к этим учетным данным получается довольно сложным — это целая процедура, привязанная к реализации чипсета, а не одна инструкция.

И, наконец, в Intel решили соединить всеобщий учет (и контроль) с простотой доступа: в процессор Pentium III ввели расширение инструкции CPUID, по которому легко можно получить 64-битный уникальный идентификатор данного процессора. Идентификатор процессора, по замыслу Intel, должен стать дополнительным средством аутентификации в сети Internet (и других сетях), наряду с именем пользователя и паролем, вводимыми вручную. Однако, если имя и пароль можно сменить в любое время, идентификатор присваивается навечно и принудительно, хотя имеется возможность запретить процессору сообщать свой идентификатор. Вот эта всеобщая инвентаризованность и вызвала бурю обсуждений прав на частную жизнь пользователей нового процессора. После жарких споров фирма Intel "идя навстречу пожеланиям трудящихся" постановила, что по умолчанию выдача идентификатора запрещена, а разрешается только с ведома пользователя. Как подчеркивает Intel, идентификатор сообщается пассивно, то есть компьютер с новым процессором, ОС и броузером не кричит на весь мир "я — номер такой-то!". Это естественно, поскольку для идентификации процессор должен исполнить фрагмент программного кода, в котором вызывается инструкция CPUID и интерпретируются ее результаты.

Для управления выдачей идентификатора в модельно-специфическом регистре BBL_CR_CTL (MSR 119h) выделяется запрещающий бит (бит 21). Он может быть установлен в "1" программно — с помощью инструкции обращения к MSR, и тогда по инструкции CPUID будет доступна только традиционная информация. Заметим, что инструкции обращения к MSR обычно привилегированы, т. е. могут выполняться только на уровне привилегий ядра ОС. По аппаратному сбросу процессора (и только так!) бит обнуляется, и полная идентификация разрешается. Декларированное "отключение по умолчанию" возлагается на ОС, и для Windows предлагается специальная утилита, опрашивающая значение бита MSR и управляющая его установкой, а также сообщающая прочитанный (по возможности) идентификатор. Для использования ОС, отличных от Windows, Intel рекомендует разработчикам BIOS включать фрагмент кода аналогичного назначения в BIOS Setup (здесь любое переключение будет требовать перезагрузки).

Основная информация о процессоре предоставляется по инструкции CPUID, доступность которой определяется через бит 21 (ID) регистра EFLAGS. По инструкции CPUID(0) можно определить производителя процессора и возможности данной инструкции. Вызов CPUID(1) сообщает сигнатуру процессора — тип, семейство, модель и степинг (табл. 1), а также список расширений архитектуры (табл. 2). Как видно из таблицы 1, одному и тому же сочетанию типа, семейства и модели может соответствовать несколько типов процессоров — например, Pentium II и Pentium II Xeon по ним неразличимы. Эти процессоры различаются элементами системы кэширования, и их можно распознать по дескрипторам (табл. 3), сообщаемым по CPUID(2). И, наконец, серийный номер процессора, если это позволено (см. ниже), можно узнать по CPUID(3). Серийный номер появился с процессорами Pentium III (он был введен еще в кристалл Celeron модели 6, но на конечном этапе производства эту возможность отключали).

Заметим, что здесь нигде в явном виде не фигурирует тактовая частота процессора — для каждой модели и степинга выпускаются процессоры с некоторым диапазоном тактовых частот, а конкретное значение обозначается на корпусе после отбраковочных испытаний. В процессорах Xeon "официальная" тактовая частота заносится в энергонезависимую память конфигурации, откуда может быть считана по интерфейсу SMBus. Доступ к этой памяти осуществляется по процедурам, определяемым чипсетом системной платы, но не по одной определенной инструкции процессора. Возможно, тактовую частоту можно определить и по серийному номеру процессора, но пока на это нет официальных указаний.

Идентификация процессора требуется на разных уровнях ПО. Первым делом идентификацию выполняет BIOS — для того, чтобы сообщить о найденных процессорах пользователю и выполнить необходимые настройки под конкретную модель и степинг процессора. Для процессоров 6-го поколения эта информация позволяет определить, какими ошибками (erratum) страдает данный процессор и какими "заплатками" эти ошибки нейтрализуются. Нейтрализация ошибок может выполняться как с помощью модификации микрокода процессора (update microcode, см. п. 2), так и специфическими фрагментами программного кода для обработчиков прерываний и исключений. Эти "заплатки" могут входить как в операционные системы, так и в BIOS. Если конкретный процессор "не знаком" для BIOS или ОС, "заплатки" для него не будут загружены и возможны различные неожиданности при работе. В этом случае стоит позаботиться об обновлении BIOS (для флэш-BIOS это технически несложно) или приобретении загружаемых "заплат" для ОС.

В зависимости от обнаруженного процессора, ОС может использовать те или иные варианты реализации своих функций. ОС защищенного режима (а теперь иными практически и не пользуются) разрешает или запрещает те или иные архитектурные расширения (в основном записью в регистр CR4). Прикладным программам остается только согласиться с предлагаемым набором свойств процессора или отказаться от работы. Прикладные программы могут получать информацию о процессоре по инструкции CPUID при любом уровне привилегий, а привилегированные программы (PL=0) могут пользоваться и данными CR4.

Рассмотрим возможности идентификации процессоров разных поколений. Программам, загружаемым операционной системой, да и самой ОС информация о процессоре из регистра EDX недоступна (аппаратный сброс был слишком давно). Задача идентификации осложняется тем, что поколение процессора заранее неизвестно. Когда появился процессор 80286, его (и все последующие) отличали от 8086/88 по значениям, сохраняемым в стеке инструкцией PUSH SP: первые процессоры сначала декрементировали указатель стека, а потом его сохраняли. Для идентификации процессоров, начиная еще с 16-разрядных, рекомендуется анализ значения регистра флагов, сохраненного по инструкции PUSHF после попытки его изменения. Приведем параметры регистра флагов в том порядке, в каком их анализируют при идентификации типа:

  • у процессоров 8086/88 биты 12–15 всегда установлены — попытка их сброса не удается;
  • у 80286 в реальном режиме биты 12–15 всегда сброшены;
  • у 32-разрядных процессоров в реальном режиме бит 15 всегда сброшен, а биты с 12–14 хранят последнее загруженное в них значение. В защищенном режиме бит 15 всегда сброшен, а бит 14 хранит последнее загруженное в него значение (биты 12, 13 можно изменить только при IOPL=0).

Для 32-разрядных процессоров анализируется EFLAG:

  • бит 18 доступен, начиная с процессоров 486, — у 80386 его невозможно изменить;
  • биты 19 (VIF) и 20 (VIP) у процессоров, не поддерживающих расширения виртуального режима (VME) всегда нулевые;
  • бит 21 (ID) определяет возможность использования инструкции CPUID. Признаком доступности инструкции является возможность программного изменения значения этого бита.

Для определения присутствия сопроцессора выполняют инструкцию FNINIT, после чего исполняют инструкцию FNSTENV и проверяют корректность образа сопроцессора, сохраненного в памяти. Тип сопроцессора обычно определяется типом CPU, кроме процессора 80386, который может работать как с 80287, так и с 80387. Их различить можно по способу представления + и – : у 287 они одинаковы, у 387 — различны.

Инструкция CPUID, доступная, начиная с Pentium и некоторых моделей 486, вызывается с параметром, указанным в регистре EAX. Значение EAX при вызове CPUID, указанные в скобках, определяет функцию вызова:

  • CPUID(0) — в регистре EAX возвращается максимально допустимое значение параметра вызова; в регистрах EBX, EDX и ECX процессор возвращает символьную строку, специфичную для производителя. Символы строки размещаются в регистрах в указанном порядке, начиная с младших байт. Процессоры Intel возвращают строку "GenuineIntel":
  • EBX=756E6547h — "Genu", символ "G" в регистре BL,
  • EDX=49656E69h — "ineI", символ "i" в регистре DL,
  • ECX=6C65746Eh — "ntel", символ "n" в регистре CL.

Процессоры AMD возвращают строку "AuthenticAMD" (EBX=68747541h, ECX=444D4163h, EDX=69746E65h).

  • CPUID(1) — в младшем слове регистра EAX процессор возвращает код идентификации (табл. 1) он же сигнатура процессора и старший элемент 96-битного серийного номера. Это же значение содержится в регистре DX после аппаратного сброса:
  • EAX[3:0] — степпинг;
  • EAX[7:4] — модель;
  • EAX[11:8] — семейство;
  • EAX[13:12] — тип;
  • EAX[31:14] — зарезервировано (0);
  • Регистры EBX=0, ECX=0 (резерв).
  • Регистр EDX содержит список имеющихся расширений базовой архитектуры — отображает регистр свойств (Feature Flags register). Назначение бит регистра приведено в табл. 2.
  • CPUID(2) — в регистрах EAX, EBX, ECX, EDX возвращаются параметры конфигурации процессора. Младшие 8 бит EAX сообщают, сколько раз нужно подряд вызвать инструкцию (с EAX=2) для получения полной информации о процессоре. Остальные байты регистра EAX и других регистров содержат дескрипторы отдельных узлов, которые расшифровываются по специальным таблицам. Признаком использования каждого из регистров EAX, EBX, ECX, EDX является нуль в его бите 31.

Вызов CPUID(2) появился с процессорами 6-го поколения. Пока что по нему сообщаются только дескрипторы элементов кэширования (табл. 3). Например, для Pentium Pro по CPUID(2) возвращается EAX=03020101h, EBX=0, ECX=0, EDX=06040A42h. Это означает, что вызов нужно делать однократно (AL=1); TLB инструкций для страниц 4К имеет 32 вхождения (01h), для страниц 4М — 2 вхождения; TLB данных для страниц 4К на 64 вхождения (03h), для страниц 4М — на 8 вхождений (04h); первичный кэш инструкций — 8К (06h), данных — 8К (0Ah); вторичный кэш 256К (42h).

  • CPUID(3) — получение младших 64 бит серийного номера процессора (Intel Processor Serial Number), доступно начиная с Pentium III (семейство 6, модель 7 и старше).
  • EDX — средние 32 бита идентификатора;
  • ECX — младшие 32 бита идентификатора.

Полный идентификатор имеет длину 96 бит. Старшие 32 бита — код идентификации процессора, возращаемый в EAX по CPUID(1). Доступность вызова определяется по биту PN регистра свойств (после CPUID(1) бит EDX.18=1). После аппаратного сброса у процессоров, поддерживающих сообщение идентификатора, этот вызов разрешен. Запретить сообщение идентификатора до следующего аппаратного сброса можно установкой в единицу бита 21 регистра. Фрагмент программы на ассемблере для запрета сообщения номера приведен ниже. После запрета бит PN обнуляется. Снова разрешить сообщение номера программно невозможно, повторное разрешение возможно только через аппаратный сброс (по сигналу RESET, но не INIT#).

MOV ECX, 119h

RDMSR ;загрузка значения MSR в EDX:EAX

OR EAX, 0020 0000h ;модификация бита 21

WRMSR ;запись в MSR

Вызовы инструкций CPUID с EAX>3 (в пределах разрешенного значения, сообщенного процессором при вызове CPUID(0) зарезервированы для будущих применений.

Фирма AMD расширила вызовы CPUID. Для проверки наличия расширений вызывается CPUID с EAX=8000_0000h. При наличии расширений в EAX результатом будет число, большее 8000_0000h, — максимальный параметр расширенного вызова. Вызовом EAX=8000_0001h можно определить специфические расширения архитектуры от AMD. Например, поддержка 3DNow! определяется по установленному биту 31 регистра EDX.

Таблица 2. Назначение флагов расширения архитектуры

Бит Название Назначение
0 FPU Floating Poin Unit — наличие математического сопроцессора
1 VME Virtual-8086 Mode Enhancements — расширение режима V86 (виртуализация флага прерываний)
2 DE Debugging Extensions — расширение отладки (возможность остановки по обращению к портам)
3 PSE Page Size Extension — возможность применения размера страницы в 4 Мбайт
4 TSC Time Stamp Counter — наличие счетчика меток реального времени
5 MSR Model Specific Register — поддержка модельно-специфических регистров в стиле Pentium (инструкции RDMSR, WRMSR)
6 PAE Physical Address Extension — возможность расширения физического адреса до 36 бит
7 MCE Machine Check Exception — поддержка исключения машинного контроля #MC
8 CX8 Поддержка инструкции CMPXCHG8B
9 APIC Наличие встроенного программно-доступного контроллера прерываний APIC
10 Зарезервировано
11 SEP SYSENTER Present — поддержка инструкций быстрых системных вызовов SYSENTER и SYSEXIT
12 MTRR Memory Type Range Registers — наличие регистра управления кэшированием MTRRcap
13 PGE Page Global Enable — поддержка бит глобальности в элементах каталога и таблиц страниц, а также бита PGE в регистре CR4
14 MCA Machine Check Architecture — поддержка архитектуры машинного контроля
15 CMOV Conditional Move — поддержка инструкций условной пересылки CMOVcc, а если есть FPU, то и инструкций FCMOVCC и FCOMI
16 PAT Page Attribute Table — поддержка таблиц атрибутов страниц (PAT)
17 PSE-36 36-bit Page Size Extension — возможность использования 36-битной физической адресации для страниц в 4 Мб
18 PN Processor Number — поддержка сообщения 96-битного серийного номера по инструкции CPUID(3)
18–22 Зарезервировано
23 MMX Поддержка MMX
24 FXSR Fast floating point save and restore — поддержка инструкций быстрого сохранения и восстановления контекста FPU (инструкций FXSAVE и FXRSTOR). Указывает и на доступность индикатора использования этих инструкций операционной системой (CR4.OSFXSR)
25 XMM Наличие блока XMM (поддержка новых инструкций расширения SSE)
24…31 Зарезервировано

Таблица 3. Дескрипторы элементов кэширования

00h Нулевой дескриптор (в неиспользуемых байтах)
01h TLB инструкций: страницы 4К, 4WSA, 32 вхождения
02h TLB инструкций: страницы 4М, FA, 2 вхождения
03h TLB данных: страницы 4К, 4WSA, 64 вхождения
04h TLB данных: страницы 4М, 4WSA, 8 вхождений
06h Кэш инструкций (L1): 8К, 4WSA, размер строки 32 байта
08h Кэш инструкций (L1): 16К, 4WSA, размер строки 32 байта
0Ah Кэш данных (L1): 8К, 2WSA, размер строки 32 байта
0Ch Кэш данных (L1): 16К, 2WSA, размер строки 32 байта
40h Нет вторичного кэша
41h Вторичный кэш 128К, 4WSA, размер строки 32 байта
42h Вторичный кэш 256К, 4WSA, размер строки 32 байта
43h Вторичный кэш 512К, 4WSA, размер строки 32 байта
44h Вторичный кэш 1М, 4WSA, размер строки 32 байта
45h Вторичный кэш 2М, 4WSA, размер строки 32 байта

где:

  • 4WSA — четырехканальный наборно-ассоциативный кэш
  • FA — полностью ассоциативный кэш

2. Обновление микрокода

Фирма Intel постоянно модернизирует свои процессоры, и даже в пределах одной модели процессоры разного времени выпуска различаются степпингом. Для процессоров каждого степпинга известны свои ошибки (errata) и методы их исправления. Микроархитектура P6 позволяет исправлять эти ошибки путем загрузки в процессор блока "заплаток", являющегося, очевидно, набором фрагментов микропрограмм. Обновление микрокода (Microcode Update) должно выполняться во время инициализации процессора после аппаратного сброса (по сигналу RESET#), загруженный микрокод действует только до следующего аппаратного сброса (инициализация сигналом INIT# на загруженное обновление не влияет). Фирма Intel отвечает за корректность поведения своих процессоров только при загруженных "заплатках" и для каждого степпинга выпускает специальный блок данных (в виде файла). Таким образом, процессор определенного степпинга рассматривается как комплект из собственно процессора и "заплаток". Заплатки фирма помещает на своем сайте, правда доступ к ним запаролирован. Пароли сообщаются официальны дилерам, так что за свежими "заплатками" следует обращаться именно к ним. Если дилер не способен предоставить "заплатки" (или сообщить пароль), то можно усомниться в его легальности. Загрузка актуальных заплаток организуется в процессор в два этапа: требуемый образ должен быть "зашит в BIOS" изготовителем компьютера или пользователем; на этапе инициализации компьютера BIOS организует загрузку микрокода в процессор. Если BIOS не поддерживает процессор требуемого степпинга, то следует обновить либо всю BIOS, либо только область с микрокодами. Вопросы обновления BIOS выходят за рамки данной статьи (см. книгу "Аппаратные средства IBM PC. Энциклопедия"), здесь рассматривается только процессорная сторона данного вопроса.

"Заплатки" поставляются в виде блоков данных размером 2048 байт, никакого исполняемого кода они не содержат. Формат блока приведен на рис.1.

Блок состоит из 48-байтного заголовка (номер версии заголовка указывается в самом его начале) и собственно данных обновления (2000 байт). Целостность всего блока контролируется контрольной суммой — сумма всех 512 двойных слов блока должна быть нулевой. Поле версии обновления позволяет определить, загружено ли данное обновление в процессор (см. ниже). Блок обновления приемлем только для процессора, имеющего тот же идентификатор (тип, семейство, модель, степпинг), сообщаемый по CPUID(1), что и указан в заголовке блока. Младшие биты в слове Processor Flags определяют, к каким "платформам" применимо данное обновление. Идентификатор платформы процессора считывается из MSR BBL_CR_OVRD (адрес 17h), где он кодируется битами [52:50]. Блок применим, если флаг (P0…P7), соответствующий его идентификатору платформы, будет единичным (блок может подходить к процессорам с разными идентификаторами платформы). Обновление должно загружаться загрузчиком, версия которого соответствует прописанной в заголовке. Загрузчик версии 1 (другие пока не описаны) записывает линейный адрес данных в MSR 79h. Для этого в регистр EAX заносится линейный адрес начала данных обновления (адрес блока +48), EDX=0, ECX=79h, и выполняется инструкция WRMSR. Микрокод должен обновляться до инициализации контроллера вторичного кэша. Данные обновления не должны пересекать границу сегмента (требований к выравниванию нет); если включена страничная переадресация, данные, естественно, должны быть доступны. Программа-загрузчик версии 00000001h на языке Ассемблер приведена ниже. Подразумевается, что блок обновления находится в сегменте кода со смещением Update.

;Обновление микрокода

mov ecx,79h ;в ECX заносится номер MSR

xor eax,eax ;обнуление EAX

xor ebx,ebx ;обнуление EBX

mov ax,cs ;формирование

shl eax,4 ;линейного

mov bx,offset Update ;адреса

add eax,ebx ;блока обновления в EAX

add eax,48d ;указатель на начало данных обновления

xor edx,edx ;обнуление EDX

WRMSR ;запуск обновления микрокода

Обновление может выполняться многократно без каких-либо побочных эффектов. Успешность и версию произведенного обновления можно проверить программно, не изменяя состояния обновления (см. программу ниже). Процессор с загруженным обновлением по инструкции CPUID(1) кроме возврата результата, описанного в п.1, записывает сигнатуру (значение версии обновления) в MSR 08Bh (если обновление не производилось, содержимое MSR не меняется). Для проверки загруженной версии обновления предварительно обнуляют MSR 08Bh (инструкцией WRMSR), затем выполняют CPUID(1) и читают MSR 08Bh (инструкцией RDMSR).

;определение сигнатуры загруженного обновления

mov ecx,08Bh ;номер MSR

xor eax,eax ;обнуление EAX

xor edx,edx ;обнуление EDX

WRMSR ;загрузка "0" в MSR 8Bh

mov eax,1

CPUID ;идентификация процессора CPUID(1)

mov ecx,08Bh ;номер MSR

RDMSR ;чтение сигнатуры обновления в EDX:EAX

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



Подробнее о процессорах можно будет узнать из книги "Процессоры Pentium III, Athlon и другие", которую вскоре выпустит издательство "Питер". С содержанием книги можно ознакомиться на сайте, где имеется информация по всем книгам Михаила Гука; там же находятся статьи по аппаратным средствам компьютеров.




Дополнительно

Идентификация и исправление ошибок процессоров Intel

Идентификация и исправление ошибок процессоров Intel

В данной статье, представляющей фрагменты новой книги Михаила Гука "Процессоры Pentium III, Athlon и другие" описываются некоторые свойства современных процессоров, знание которых необходимо системному, а иногда и прикладному программисту. Практическое применение этих свойств уже излагалось на сайте (см. статьи "Исправление ошибок в CPU" и "Самостоятельное исправление ошибок в CPU"), теперь немного теории.

1. Идентификация процессоров (CPUID)

Возможность программного определения типа процессора заложена в архитектуру 32-разрядных процессоров "отродясь". В любом процессоре сразу после аппаратного сброса в регистре (E)DX можно прочитать номер семейства (3 — 386, 4 — 486, 5 — Pentium, 6 — P6…), модели, типа и степпинга. Расшифровка основных полей приводится в табл. 1. Кроме перечисленных в таблице имеется поле степпинга (биты 3:0) — номер версии процессора в пределах одной модели. Информацию этого поля, к сожалению, без таблиц изготовителя не расшифровать. Поле "тип" (биты 13:12) различает процессоры OEM-версий (00), OverDrive (01) и Dual (10); значение 11 зарезервировано. Наиболее интересная информация содержится в полях "семейство" (биты 11:8) и "модель" (биты 7:3). Старшие биты (14–31) регистра EDX пока не используются (они нулевые). Процессоры 80386 имели несколько иное назначение бит: поле "семейство" совпадает, поле "модель" занимает биты 15:11, биты 7:0 отводятся под степпинг. Для младших процессоров регистр DH содержит идентификатор процессора (01 — 8086/88, 02 —80286), DL — номер модели. Поле "модель" позволяет отличать, например, Pentium MMX от "просто" Pentium 75–233 МГц или Pentium 60–66 МГц, Celeron от Pentium II или Pentium Pro. По полю "тип" можно отличить, например, процессоры OverDrive. Поле "степпинг" без таблиц не расшифровать, оно несет информацию о нюансах — например, исправлены ли те или иные ошибки, возможный диапазон частот (определяется косвенно и не точно).

Таблица 1. Коды идентификации процессоров

Тип
EDX[13:12]
Семейство
EDX[11:8]
Модель
EDX[7:4]
Процессор
00 0100 0000 Intel486DX
00 0100 0001 Intel486DX
00 0100 0010 Intel486SX
00 0100 0011 Intel487, IntelDX2, IntelDX2 OverDrive, AMD DX2 в режиме WT
00 0100 0100 IntelSXL
00 0100 0101 IntelSX2 OverDrive
00 0100 0111 IntelDX2 Enhanced в режиме WB, AMD DX2 в режиме WB
00 0100 1000 IntelDX4 OverDrive, AMD DX4 в режиме WT
00 0100 1001 AMD DX4 в режиме WB
00 0100 1110 Am5x86 в режиме WT
00 0100 1111 Am5x86 в режиме WB
01 0100 1000 IntelDX4 OverDrive
00 0101 0000 AMD K5-PR75, 90, 100
00 0101 0001 Pentium 60, 66
Pentium OverDrive для Pentium 60, 66
AMD K5-PR120, 133
00 0101 0010 Pentium 75, 90, 100, 120, 133, 150, 166, 200
AMD K5-PR166
01 0101 0010 Pentium OverDrive 75, 90, 100, 120, 133
01 0101 0011 Pentium OverDrive для 486
00 0101 0100 Pentium MMX (166, 200, 233)
01 0101 0100 Зарезервировано (OverDrive для Pentium 75, 90, 100, 120, 133)
00 0110 0001 Pentium Pro
00 0110 0011 Pentium II первого поколения (233–300 МГц)
01 0110 0011 Pentium II OverDrive
00 0110 0101 Pentium II Desсhutes (333–450 МГц), Celeron (266, 300 МГц), Xeon
00 0110 0110 Celeron 300A, 333–533
00 0110 0111 Pentium III и Pentium III Xeon
00 0110 1000 Pentium III Coppermine, Pentium III Xeon, Celeron 533A, 566, 600

Информация из (E)DX доступна только для BIOS в самом начале запуска машины (ее может считать тест POST). Поскольку BIOS ориентирован на процессоры одного поколения (семейства), проблем с различием использования регистра (E)DX не возникает. Потребность в идентификации процессора операционной системой и приложениями созревала по мере расширения диапазона функциональных возможностей и уровня производительности процессоров. Начиная с процессоров Pentium появилась новая инструкция CPUID, по которой любая программа на любом уровне привилегий в любой момент времени могла получить ту же информацию, что и BIOS после сброса, и, вдобавок, 32-битный набор флагов расширений базовой архитектуры, реализованных в данном процессоре. Полученную информацию программа может использовать, например, для выбора исполняемого кода, оптимального для данного процессора (или отказа исполнения на "недостойном" ее процессоре), а также для настройки констант программных реализаций задержек. Инструкция CPUID была реализована и в ряде поздних моделей процессоров класса 486. Формат инструкции практически безгранично расширяем, с ее помощью процессор может выдавать хоть весь свой словесный портрет (если эту возможность заложат его разработчики). Однако информация для CPUID "зашивается" в процессор на этапе изготовления кристалла, что не позволяет, например, "выпытать" у процессора его официальную тактовую частоту (она определяется позже — на этапе тестирования уже готового процессора). А эта информация была бы полезна при борьбе с пиратским разгоном (перемаркировкой) процессоров, что, в общем-то, волнует изготовителя.

Следующий шаг, уже явно нацеленный на учет и контроль, был сделан в процессоре Pentium II Xeon. Здесь имеется специальная постоянная (только для чтения) память процессорной информации PIROM (Processor Information ROM), которая хранит такие данные, как электрические спецификации ядра процессора и кэш-памяти (диапазоны частот и питающих напряжений), S-спецификацию (степпинг) и 64-битный серийный номер процессора. Кроме того, имеется энергонезависимая память Scratch EEPROM, которая предназначена для занесения системной информации поставщиком процессора (или компьютера с этим процессором) и может быть защищена от последующей записи. Для взаимодействия с PIROM и Scratch EEPROM (а также устройством термоконтроля) процессор имеет дополнительную последовательную шину SMBus (System Management Bus) — отдельный электрический интерфейс, с которым работает чипсет системной платы. Обращение к этим учетным данным получается довольно сложным — это целая процедура, привязанная к реализации чипсета, а не одна инструкция.

И, наконец, в Intel решили соединить всеобщий учет (и контроль) с простотой доступа: в процессор Pentium III ввели расширение инструкции CPUID, по которому легко можно получить 64-битный уникальный идентификатор данного процессора. Идентификатор процессора, по замыслу Intel, должен стать дополнительным средством аутентификации в сети Internet (и других сетях), наряду с именем пользователя и паролем, вводимыми вручную. Однако, если имя и пароль можно сменить в любое время, идентификатор присваивается навечно и принудительно, хотя имеется возможность запретить процессору сообщать свой идентификатор. Вот эта всеобщая инвентаризованность и вызвала бурю обсуждений прав на частную жизнь пользователей нового процессора. После жарких споров фирма Intel "идя навстречу пожеланиям трудящихся" постановила, что по умолчанию выдача идентификатора запрещена, а разрешается только с ведома пользователя. Как подчеркивает Intel, идентификатор сообщается пассивно, то есть компьютер с новым процессором, ОС и броузером не кричит на весь мир "я — номер такой-то!". Это естественно, поскольку для идентификации процессор должен исполнить фрагмент программного кода, в котором вызывается инструкция CPUID и интерпретируются ее результаты.

Для управления выдачей идентификатора в модельно-специфическом регистре BBL_CR_CTL (MSR 119h) выделяется запрещающий бит (бит 21). Он может быть установлен в "1" программно — с помощью инструкции обращения к MSR, и тогда по инструкции CPUID будет доступна только традиционная информация. Заметим, что инструкции обращения к MSR обычно привилегированы, т. е. могут выполняться только на уровне привилегий ядра ОС. По аппаратному сбросу процессора (и только так!) бит обнуляется, и полная идентификация разрешается. Декларированное "отключение по умолчанию" возлагается на ОС, и для Windows предлагается специальная утилита, опрашивающая значение бита MSR и управляющая его установкой, а также сообщающая прочитанный (по возможности) идентификатор. Для использования ОС, отличных от Windows, Intel рекомендует разработчикам BIOS включать фрагмент кода аналогичного назначения в BIOS Setup (здесь любое переключение будет требовать перезагрузки).

Основная информация о процессоре предоставляется по инструкции CPUID, доступность которой определяется через бит 21 (ID) регистра EFLAGS. По инструкции CPUID(0) можно определить производителя процессора и возможности данной инструкции. Вызов CPUID(1) сообщает сигнатуру процессора — тип, семейство, модель и степинг (табл. 1), а также список расширений архитектуры (табл. 2). Как видно из таблицы 1, одному и тому же сочетанию типа, семейства и модели может соответствовать несколько типов процессоров — например, Pentium II и Pentium II Xeon по ним неразличимы. Эти процессоры различаются элементами системы кэширования, и их можно распознать по дескрипторам (табл. 3), сообщаемым по CPUID(2). И, наконец, серийный номер процессора, если это позволено (см. ниже), можно узнать по CPUID(3). Серийный номер появился с процессорами Pentium III (он был введен еще в кристалл Celeron модели 6, но на конечном этапе производства эту возможность отключали).

Заметим, что здесь нигде в явном виде не фигурирует тактовая частота процессора — для каждой модели и степинга выпускаются процессоры с некоторым диапазоном тактовых частот, а конкретное значение обозначается на корпусе после отбраковочных испытаний. В процессорах Xeon "официальная" тактовая частота заносится в энергонезависимую память конфигурации, откуда может быть считана по интерфейсу SMBus. Доступ к этой памяти осуществляется по процедурам, определяемым чипсетом системной платы, но не по одной определенной инструкции процессора. Возможно, тактовую частоту можно определить и по серийному номеру процессора, но пока на это нет официальных указаний.

Идентификация процессора требуется на разных уровнях ПО. Первым делом идентификацию выполняет BIOS — для того, чтобы сообщить о найденных процессорах пользователю и выполнить необходимые настройки под конкретную модель и степинг процессора. Для процессоров 6-го поколения эта информация позволяет определить, какими ошибками (erratum) страдает данный процессор и какими "заплатками" эти ошибки нейтрализуются. Нейтрализация ошибок может выполняться как с помощью модификации микрокода процессора (update microcode, см. п. 2), так и специфическими фрагментами программного кода для обработчиков прерываний и исключений. Эти "заплатки" могут входить как в операционные системы, так и в BIOS. Если конкретный процессор "не знаком" для BIOS или ОС, "заплатки" для него не будут загружены и возможны различные неожиданности при работе. В этом случае стоит позаботиться об обновлении BIOS (для флэш-BIOS это технически несложно) или приобретении загружаемых "заплат" для ОС.

В зависимости от обнаруженного процессора, ОС может использовать те или иные варианты реализации своих функций. ОС защищенного режима (а теперь иными практически и не пользуются) разрешает или запрещает те или иные архитектурные расширения (в основном записью в регистр CR4). Прикладным программам остается только согласиться с предлагаемым набором свойств процессора или отказаться от работы. Прикладные программы могут получать информацию о процессоре по инструкции CPUID при любом уровне привилегий, а привилегированные программы (PL=0) могут пользоваться и данными CR4.

Рассмотрим возможности идентификации процессоров разных поколений. Программам, загружаемым операционной системой, да и самой ОС информация о процессоре из регистра EDX недоступна (аппаратный сброс был слишком давно). Задача идентификации осложняется тем, что поколение процессора заранее неизвестно. Когда появился процессор 80286, его (и все последующие) отличали от 8086/88 по значениям, сохраняемым в стеке инструкцией PUSH SP: первые процессоры сначала декрементировали указатель стека, а потом его сохраняли. Для идентификации процессоров, начиная еще с 16-разрядных, рекомендуется анализ значения регистра флагов, сохраненного по инструкции PUSHF после попытки его изменения. Приведем параметры регистра флагов в том порядке, в каком их анализируют при идентификации типа:

  • у процессоров 8086/88 биты 12–15 всегда установлены — попытка их сброса не удается;
  • у 80286 в реальном режиме биты 12–15 всегда сброшены;
  • у 32-разрядных процессоров в реальном режиме бит 15 всегда сброшен, а биты с 12–14 хранят последнее загруженное в них значение. В защищенном режиме бит 15 всегда сброшен, а бит 14 хранит последнее загруженное в него значение (биты 12, 13 можно изменить только при IOPL=0).

Для 32-разрядных процессоров анализируется EFLAG:

  • бит 18 доступен, начиная с процессоров 486, — у 80386 его невозможно изменить;
  • биты 19 (VIF) и 20 (VIP) у процессоров, не поддерживающих расширения виртуального режима (VME) всегда нулевые;
  • бит 21 (ID) определяет возможность использования инструкции CPUID. Признаком доступности инструкции является возможность программного изменения значения этого бита.

Для определения присутствия сопроцессора выполняют инструкцию FNINIT, после чего исполняют инструкцию FNSTENV и проверяют корректность образа сопроцессора, сохраненного в памяти. Тип сопроцессора обычно определяется типом CPU, кроме процессора 80386, который может работать как с 80287, так и с 80387. Их различить можно по способу представления + и – : у 287 они одинаковы, у 387 — различны.

Инструкция CPUID, доступная, начиная с Pentium и некоторых моделей 486, вызывается с параметром, указанным в регистре EAX. Значение EAX при вызове CPUID, указанные в скобках, определяет функцию вызова:

  • CPUID(0) — в регистре EAX возвращается максимально допустимое значение параметра вызова; в регистрах EBX, EDX и ECX процессор возвращает символьную строку, специфичную для производителя. Символы строки размещаются в регистрах в указанном порядке, начиная с младших байт. Процессоры Intel возвращают строку "GenuineIntel":
  • EBX=756E6547h — "Genu", символ "G" в регистре BL,
  • EDX=49656E69h — "ineI", символ "i" в регистре DL,
  • ECX=6C65746Eh — "ntel", символ "n" в регистре CL.

Процессоры AMD возвращают строку "AuthenticAMD" (EBX=68747541h, ECX=444D4163h, EDX=69746E65h).

  • CPUID(1) — в младшем слове регистра EAX процессор возвращает код идентификации (табл. 1) он же сигнатура процессора и старший элемент 96-битного серийного номера. Это же значение содержится в регистре DX после аппаратного сброса:
  • EAX[3:0] — степпинг;
  • EAX[7:4] — модель;
  • EAX[11:8] — семейство;
  • EAX[13:12] — тип;
  • EAX[31:14] — зарезервировано (0);
  • Регистры EBX=0, ECX=0 (резерв).
  • Регистр EDX содержит список имеющихся расширений базовой архитектуры — отображает регистр свойств (Feature Flags register). Назначение бит регистра приведено в табл. 2.
  • CPUID(2) — в регистрах EAX, EBX, ECX, EDX возвращаются параметры конфигурации процессора. Младшие 8 бит EAX сообщают, сколько раз нужно подряд вызвать инструкцию (с EAX=2) для получения полной информации о процессоре. Остальные байты регистра EAX и других регистров содержат дескрипторы отдельных узлов, которые расшифровываются по специальным таблицам. Признаком использования каждого из регистров EAX, EBX, ECX, EDX является нуль в его бите 31.

Вызов CPUID(2) появился с процессорами 6-го поколения. Пока что по нему сообщаются только дескрипторы элементов кэширования (табл. 3). Например, для Pentium Pro по CPUID(2) возвращается EAX=03020101h, EBX=0, ECX=0, EDX=06040A42h. Это означает, что вызов нужно делать однократно (AL=1); TLB инструкций для страниц 4К имеет 32 вхождения (01h), для страниц 4М — 2 вхождения; TLB данных для страниц 4К на 64 вхождения (03h), для страниц 4М — на 8 вхождений (04h); первичный кэш инструкций — 8К (06h), данных — 8К (0Ah); вторичный кэш 256К (42h).

  • CPUID(3) — получение младших 64 бит серийного номера процессора (Intel Processor Serial Number), доступно начиная с Pentium III (семейство 6, модель 7 и старше).
  • EDX — средние 32 бита идентификатора;
  • ECX — младшие 32 бита идентификатора.

Полный идентификатор имеет длину 96 бит. Старшие 32 бита — код идентификации процессора, возращаемый в EAX по CPUID(1). Доступность вызова определяется по биту PN регистра свойств (после CPUID(1) бит EDX.18=1). После аппаратного сброса у процессоров, поддерживающих сообщение идентификатора, этот вызов разрешен. Запретить сообщение идентификатора до следующего аппаратного сброса можно установкой в единицу бита 21 регистра. Фрагмент программы на ассемблере для запрета сообщения номера приведен ниже. После запрета бит PN обнуляется. Снова разрешить сообщение номера программно невозможно, повторное разрешение возможно только через аппаратный сброс (по сигналу RESET, но не INIT#).

MOV ECX, 119h

RDMSR ;загрузка значения MSR в EDX:EAX

OR EAX, 0020 0000h ;модификация бита 21

WRMSR ;запись в MSR

Вызовы инструкций CPUID с EAX>3 (в пределах разрешенного значения, сообщенного процессором при вызове CPUID(0) зарезервированы для будущих применений.

Фирма AMD расширила вызовы CPUID. Для проверки наличия расширений вызывается CPUID с EAX=8000_0000h. При наличии расширений в EAX результатом будет число, большее 8000_0000h, — максимальный параметр расширенного вызова. Вызовом EAX=8000_0001h можно определить специфические расширения архитектуры от AMD. Например, поддержка 3DNow! определяется по установленному биту 31 регистра EDX.

Таблица 2. Назначение флагов расширения архитектуры

Бит Название Назначение
0 FPU Floating Poin Unit — наличие математического сопроцессора
1 VME Virtual-8086 Mode Enhancements — расширение режима V86 (виртуализация флага прерываний)
2 DE Debugging Extensions — расширение отладки (возможность остановки по обращению к портам)
3 PSE Page Size Extension — возможность применения размера страницы в 4 Мбайт
4 TSC Time Stamp Counter — наличие счетчика меток реального времени
5 MSR Model Specific Register — поддержка модельно-специфических регистров в стиле Pentium (инструкции RDMSR, WRMSR)
6 PAE Physical Address Extension — возможность расширения физического адреса до 36 бит
7 MCE Machine Check Exception — поддержка исключения машинного контроля #MC
8 CX8 Поддержка инструкции CMPXCHG8B
9 APIC Наличие встроенного программно-доступного контроллера прерываний APIC
10 Зарезервировано
11 SEP SYSENTER Present — поддержка инструкций быстрых системных вызовов SYSENTER и SYSEXIT
12 MTRR Memory Type Range Registers — наличие регистра управления кэшированием MTRRcap
13 PGE Page Global Enable — поддержка бит глобальности в элементах каталога и таблиц страниц, а также бита PGE в регистре CR4
14 MCA Machine Check Architecture — поддержка архитектуры машинного контроля
15 CMOV Conditional Move — поддержка инструкций условной пересылки CMOVcc, а если есть FPU, то и инструкций FCMOVCC и FCOMI
16 PAT Page Attribute Table — поддержка таблиц атрибутов страниц (PAT)
17 PSE-36 36-bit Page Size Extension — возможность использования 36-битной физической адресации для страниц в 4 Мб
18 PN Processor Number — поддержка сообщения 96-битного серийного номера по инструкции CPUID(3)
18–22 Зарезервировано
23 MMX Поддержка MMX
24 FXSR Fast floating point save and restore — поддержка инструкций быстрого сохранения и восстановления контекста FPU (инструкций FXSAVE и FXRSTOR). Указывает и на доступность индикатора использования этих инструкций операционной системой (CR4.OSFXSR)
25 XMM Наличие блока XMM (поддержка новых инструкций расширения SSE)
24…31 Зарезервировано

Таблица 3. Дескрипторы элементов кэширования

00h Нулевой дескриптор (в неиспользуемых байтах)
01h TLB инструкций: страницы 4К, 4WSA, 32 вхождения
02h TLB инструкций: страницы 4М, FA, 2 вхождения
03h TLB данных: страницы 4К, 4WSA, 64 вхождения
04h TLB данных: страницы 4М, 4WSA, 8 вхождений
06h Кэш инструкций (L1): 8К, 4WSA, размер строки 32 байта
08h Кэш инструкций (L1): 16К, 4WSA, размер строки 32 байта
0Ah Кэш данных (L1): 8К, 2WSA, размер строки 32 байта
0Ch Кэш данных (L1): 16К, 2WSA, размер строки 32 байта
40h Нет вторичного кэша
41h Вторичный кэш 128К, 4WSA, размер строки 32 байта
42h Вторичный кэш 256К, 4WSA, размер строки 32 байта
43h Вторичный кэш 512К, 4WSA, размер строки 32 байта
44h Вторичный кэш 1М, 4WSA, размер строки 32 байта
45h Вторичный кэш 2М, 4WSA, размер строки 32 байта

где:

  • 4WSA — четырехканальный наборно-ассоциативный кэш
  • FA — полностью ассоциативный кэш

2. Обновление микрокода

Фирма Intel постоянно модернизирует свои процессоры, и даже в пределах одной модели процессоры разного времени выпуска различаются степпингом. Для процессоров каждого степпинга известны свои ошибки (errata) и методы их исправления. Микроархитектура P6 позволяет исправлять эти ошибки путем загрузки в процессор блока "заплаток", являющегося, очевидно, набором фрагментов микропрограмм. Обновление микрокода (Microcode Update) должно выполняться во время инициализации процессора после аппаратного сброса (по сигналу RESET#), загруженный микрокод действует только до следующего аппаратного сброса (инициализация сигналом INIT# на загруженное обновление не влияет). Фирма Intel отвечает за корректность поведения своих процессоров только при загруженных "заплатках" и для каждого степпинга выпускает специальный блок данных (в виде файла). Таким образом, процессор определенного степпинга рассматривается как комплект из собственно процессора и "заплаток". Заплатки фирма помещает на своем сайте, правда доступ к ним запаролирован. Пароли сообщаются официальны дилерам, так что за свежими "заплатками" следует обращаться именно к ним. Если дилер не способен предоставить "заплатки" (или сообщить пароль), то можно усомниться в его легальности. Загрузка актуальных заплаток организуется в процессор в два этапа: требуемый образ должен быть "зашит в BIOS" изготовителем компьютера или пользователем; на этапе инициализации компьютера BIOS организует загрузку микрокода в процессор. Если BIOS не поддерживает процессор требуемого степпинга, то следует обновить либо всю BIOS, либо только область с микрокодами. Вопросы обновления BIOS выходят за рамки данной статьи (см. книгу "Аппаратные средства IBM PC. Энциклопедия"), здесь рассматривается только процессорная сторона данного вопроса.

"Заплатки" поставляются в виде блоков данных размером 2048 байт, никакого исполняемого кода они не содержат. Формат блока приведен на рис.1.

Блок состоит из 48-байтного заголовка (номер версии заголовка указывается в самом его начале) и собственно данных обновления (2000 байт). Целостность всего блока контролируется контрольной суммой — сумма всех 512 двойных слов блока должна быть нулевой. Поле версии обновления позволяет определить, загружено ли данное обновление в процессор (см. ниже). Блок обновления приемлем только для процессора, имеющего тот же идентификатор (тип, семейство, модель, степпинг), сообщаемый по CPUID(1), что и указан в заголовке блока. Младшие биты в слове Processor Flags определяют, к каким "платформам" применимо данное обновление. Идентификатор платформы процессора считывается из MSR BBL_CR_OVRD (адрес 17h), где он кодируется битами [52:50]. Блок применим, если флаг (P0…P7), соответствующий его идентификатору платформы, будет единичным (блок может подходить к процессорам с разными идентификаторами платформы). Обновление должно загружаться загрузчиком, версия которого соответствует прописанной в заголовке. Загрузчик версии 1 (другие пока не описаны) записывает линейный адрес данных в MSR 79h. Для этого в регистр EAX заносится линейный адрес начала данных обновления (адрес блока +48), EDX=0, ECX=79h, и выполняется инструкция WRMSR. Микрокод должен обновляться до инициализации контроллера вторичного кэша. Данные обновления не должны пересекать границу сегмента (требований к выравниванию нет); если включена страничная переадресация, данные, естественно, должны быть доступны. Программа-загрузчик версии 00000001h на языке Ассемблер приведена ниже. Подразумевается, что блок обновления находится в сегменте кода со смещением Update.

;Обновление микрокода

mov ecx,79h ;в ECX заносится номер MSR

xor eax,eax ;обнуление EAX

xor ebx,ebx ;обнуление EBX

mov ax,cs ;формирование

shl eax,4 ;линейного

mov bx,offset Update ;адреса

add eax,ebx ;блока обновления в EAX

add eax,48d ;указатель на начало данных обновления

xor edx,edx ;обнуление EDX

WRMSR ;запуск обновления микрокода

Обновление может выполняться многократно без каких-либо побочных эффектов. Успешность и версию произведенного обновления можно проверить программно, не изменяя состояния обновления (см. программу ниже). Процессор с загруженным обновлением по инструкции CPUID(1) кроме возврата результата, описанного в п.1, записывает сигнатуру (значение версии обновления) в MSR 08Bh (если обновление не производилось, содержимое MSR не меняется). Для проверки загруженной версии обновления предварительно обнуляют MSR 08Bh (инструкцией WRMSR), затем выполняют CPUID(1) и читают MSR 08Bh (инструкцией RDMSR).

;определение сигнатуры загруженного обновления

mov ecx,08Bh ;номер MSR

xor eax,eax ;обнуление EAX

xor edx,edx ;обнуление EDX

WRMSR ;загрузка "0" в MSR 8Bh

mov eax,1

CPUID ;идентификация процессора CPUID(1)

mov ecx,08Bh ;номер MSR

RDMSR ;чтение сигнатуры обновления в EDX:EAX

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



Подробнее о процессорах можно будет узнать из книги "Процессоры Pentium III, Athlon и другие", которую вскоре выпустит издательство "Питер". С содержанием книги можно ознакомиться на сайте, где имеется информация по всем книгам Михаила Гука; там же находятся статьи по аппаратным средствам компьютеров.