С точки зрения идеальной корректности поиск пакета _S5_ простым линейным сканированием ничуть не лучше банального поиска подстроки _S5_ - в таблицах ACPI может быть много всяких заморочек, и нужно либо полностью создавать дерево объектов и быть готовым к выполнению методов, либо вообще не заморачиваться.
В чём проблема с декодированием PkgLength? Экономное кодирование, на первом скриншоте закодирована длина 53h, слишком большая для одного байта, но влезающая в два, на втором - длина 19h, влезающая в один байт.
Обсуждение необходимости ACPI
-
Сделаем мир лучше!
Code: Select all
;--- Interpreting AML ---
Interpret_AML: lods byte [gs:esi] ;Get Lead Byte
cmp al, 0x10 ;10h = SCOPE Operator
jne AML_1
;--- Interpreting 10h=ScopeOp ---
Skip_Pack: mov dl, [gs:esi] ;Get Package Length, byte 0
movzx ebx, dl
and dl, 11000000b
jz Skip_Package
and bl, 00001111b
mov cx, 0x104 ;Offset=1, Shifts=4
call Scan_AML_Local_0
cmp dl, 01000000b
je Skip_Package
mov cx, 0x20C ;Offset=2, Shifts=12
call Scan_AML_Local_0
cmp dl, 10000000b
je Skip_Package
mov cx, 0x314 ;Offset=3, Shifts=20
call Scan_AML_Local_0
Skip_Package: add esi, ebx
jmp Next_AML
неправильного либо кода 19h либо... либо самого декодирования.
Возможно версия ACPI таблицы старовата, вернее что то типа ACPI v.1.0, не помню...
это старенький ящик, там южник ICH2, это точно.
Так вот думаю, может он, этот байт раньше как то по другому кодировался чтоли...
мало того гугл говорит, что народ мордующийся, проблемами корявого ACPI в ноутах, часто
говорит, что дескать поправьте сами, пропачте Вашу проблему.
Сайтов таких немало и даже специалные ,т.е. специализирующихся на коллекционировании
методов исправления ACPI корявостей. Я не специально это говорю, чтобы очернить.
Я сам в шоке с массой увиденного и прочитанного.
Подумал что с ходу оседлаю ACPI, универсальность...
Похоже ляжет очередным пластом недоделок в мой "личный ящик черновиков"...
Некогда
Нужно думать.
Думать и принимать решение(е) и вообще ограничиться бы "правильным" и нужным сегментом ACPI и не лезть в дебри. Вряд ли кто подскажет. Нужен реальнй опыт на разных чипах и производителях.
Кто бы подсказал что лишнее, что нет, что в перую очередь, а что нет.
Это если делать. А делать никто не хочет.
Все хотят бесплатной халвы и чтобы именно его чипсет работал и пофиг дальше. Факт.
Ладно, дам ссылку про ноуты, может кому и на подобную неприятность откроет глаза http://habrahabr.ru/blogs/system_programming/128449/
Приятно читать у других то, за что говорил сам (SMI).
Этот огрызок кода декодирует PkgLength. Весь код по вышеприведённой ссылке не способен даже на простое линейное сканирование - малейшее отличие таблицы от той, на которую рассчитывал автор, приводит код в ступор. Скачайте уже AML-дизассемблер с http://www.acpica.org/downloads/binary_tools.php - iasl -d в пакете - и посмотрите на таблицы:
Code: Select all
/* первая таблица */
Scope (\_PR) /* про оператор Scope код знает и полностью игнорирует содержимое */
{
Processor (\_PR.CPU0, 0x00, 0x00000410, 0x06) {}
Processor (\_PR.CPU1, 0x01, 0x00000410, 0x06) {}
Processor (\_PR.CPU2, 0x02, 0x00000410, 0x06) {}
Processor (\_PR.CPU3, 0x03, 0x00000410, 0x06) {}
}
Name (\_S0, Package (0x04) /* про оператор Name код знает и ищет \_S5 */
{
0x00,
0x00,
0x00,
0x00
})
Name (\SS1, Package (0x04)
{
0x01,
0x00,
0x00,
0x00
})
Name (\_S3, Package (0x04)
{
0x05,
0x00,
0x00,
0x00
})
Name (\_S4, Package (0x04)
{
0x06,
0x00,
0x00,
0x00
})
Name (\_S5, Package (0x04) /* вот он \_S5, до него ничего неподдерживаемого нет */
{
0x07,
0x00,
0x00,
0x00
})
...
Code: Select all
/* вторая таблица */
Scope (\_PR) /* про оператор Scope код знает и полностью игнорирует содержимое */
{
Processor (\_PR.CPU0, 0x01, 0x00004010, 0x06) {}
}
OperationRegion (CM72, SystemIO, 0x72, 0x02) /* а про это код не знает и тупо вываливается */
Field (CM72, ByteAcc, NoLock, Preserve)
{
CI72, 8,
CO73, 8
}
IndexField (CI72, CO73, ByteAcc, NoLock, Preserve)
{
Offset (0x50),
SUSF, 8
}
Name (FLAG, 0x00)
Name (STAT, 0x00)
Name (\_S0, Package (0x04)
{
0x00,
0x00,
0x00,
0x00
})
And (SUSF, 0x02, STAT)
If (STAT)
{
Name (\_S3, Package (0x04)
{
0x05,
0x00,
0x00,
0x00
})
}
Else
{
Name (\_S1, Package (0x04)
{
0x01,
0x00,
0x00,
0x00
})
Name (\_S4, Package (0x04)
{
0x07,
0x00,
0x00,
0x00
})
}
Name (\_S5, Package (0x04)
{
0x07,
0x00,
0x00,
0x00
})
Сделаем мир лучше!
А как же стандарт, описание...???CleverMouse wrote:Этот огрызок кода декодирует PkgLength. Весь код по вышеприведённой ссылке не способен даже на простое линейное сканирование - малейшее отличие таблицы от той, на которую рассчитывал автор, приводит код в ступор.
Автор согласно стандарту реализовал битовую работу с PkgLength или нет?
А вроде вижу, что по стандарту.
Тогда его код вправе "прыгать" по таблице DSDT блочно, перешагивать куски таблицы, я так понимаю.
Ну естественно зная, наверное структуру таблицы. Хотя я не совсем понял, что такое PkgLength.
Length ближайшего блока, а дальше будет следующий PkgLength, наверное...
В данном примере проблемы asm код этот "недошагивает" до _S5_, длина выходит короткой, т.е. 19h типа мало.
Даже глядя на дамп, что привел видно, что фактический offset до _S5_ больше чем 19h от текущей позиции.
Вот и вываливаемся из алгоритма, как ошибка декодинга таблицы.
Либо я заблуждаюсь и в таблице "роются" по блокам, таки сигнатурно, как и делают до того.
Фигню эту и др. я скачал, только непонятно, что за псевдоязык, нафига... намутили блин,
науниверсалили так, что набекрень извилины, а вкуривать некогда, да и влом уже, если честно.
Раценка свободного времени уже не та.
Ладно, как нить потом, быть может.
С PkgLength - по стандарту. Но в стандарте PkgLength - это всего лишь один вспомогательный элемент из многих. Таблица DSDT состоит из отдельных блоков; некоторые блоки имеют переменную длину, и им нужен PkgLength, а некоторые - фиксированную, и им PkgLength не нужен. Чтобы "прыгать" по таблице DSDT, нужно знать о всех блоках.
Пример на основе второго скриншота. Длина заголовка таблицы 24h, дальше начинается AML-код. Первый байт - 0x10; в таблице из 19.3 AML Byte Stream Byte Values можно увидеть, что это ScopeOp, опкод команды Scope. Для этой команды, как можно увидеть в другом месте, дальше идёт PkgLength, определяющий длину этого блока. Дальше некоторое время идут данные самого Scope и данные внутри Scope. Следующий блок начинается с байтов 0x5B 0x80; по той же таблице это OpRegionOp, который состоит из OpRegionOp NameString RegionSpace RegionOffset RegionLen; дизассемблер показывает это как OperationRegion (CM72, SystemIO, 0x72, 0x02). Этот блок фиксированной длины, у него нет PkgLength. Кривой код пропустить этот блок не может, потому что о нём не знает - знает он только о Scope и Name.
Пример на основе второго скриншота. Длина заголовка таблицы 24h, дальше начинается AML-код. Первый байт - 0x10; в таблице из 19.3 AML Byte Stream Byte Values можно увидеть, что это ScopeOp, опкод команды Scope. Для этой команды, как можно увидеть в другом месте, дальше идёт PkgLength, определяющий длину этого блока. Дальше некоторое время идут данные самого Scope и данные внутри Scope. Следующий блок начинается с байтов 0x5B 0x80; по той же таблице это OpRegionOp, который состоит из OpRegionOp NameString RegionSpace RegionOffset RegionLen; дизассемблер показывает это как OperationRegion (CM72, SystemIO, 0x72, 0x02). Этот блок фиксированной длины, у него нет PkgLength. Кривой код пропустить этот блок не может, потому что о нём не знает - знает он только о Scope и Name.
Сделаем мир лучше!
вообще для подсчета тактов используют RDTSC у нее точноть точьно побольше будетSerge wrote:VaStaNi
Твои графики ничего не доказывают. Точность HPET 0.05%. Это +- 750 тактов для 1.5Ггц процессора. Точность 8254 ведома только Интелу. А разброс частоты у процессора ?
Ты же не хочешь сказать что у тебя в чипсете идеальный таймер и идеальный процессор в сокете ? Если хочешь точно считать такты используй таймер LAPIC. А пока все эти замеры ничего не доказывают. Ты микрометры меряешь школьной линейкой.
abcd0081
1. Таймер LAPIC и RDTSC используют общий тактовый генератор.
2. LAPIC генерирует прерывание через установленное программистом количество тактов. Следовательно независимо от стабильности тактового генератора прерывания всегда следуют через одинаковое количество тактов.
3. Прочитав значение счётчика LAPIC в обработчике прерываний и сравнив с исходным значением легко вычислить латентность обработчика в процессорных тактах.
1. Таймер LAPIC и RDTSC используют общий тактовый генератор.
2. LAPIC генерирует прерывание через установленное программистом количество тактов. Следовательно независимо от стабильности тактового генератора прерывания всегда следуют через одинаковое количество тактов.
3. Прочитав значение счётчика LAPIC в обработчике прерываний и сравнив с исходным значением легко вычислить латентность обработчика в процессорных тактах.
я имел ввиду замер тактов. например для куска кода. а не частоту вызовов прерывания.Serge wrote:abcd0081
1. Таймер LAPIC и RDTSC используют общий тактовый генератор.
2. LAPIC генерирует прерывание через установленное программистом количество тактов. Следовательно независимо от стабильности тактового генератора прерывания всегда следуют через одинаковое количество тактов.
3. Прочитав значение счётчика LAPIC в обработчике прерываний и сравнив с исходным значением легко вычислить латентность обработчика в процессорных тактах.
abcd0081
VaStaNi интересуют паузы между прерываниями. И я писал про паузы между прерываниями.
VaStaNi интересуют паузы между прерываниями. И я писал про паузы между прерываниями.
Who is online
Users browsing this forum: No registered users and 1 guest