[Voltage ID]
В жж своем писала уже это сегодня, но т.к. не все читают чужие жж как логическое продолжение отпишу и тут. Я так подумала, что буду потихоньку приводить в нормальный вид свой кодес с измерением температуры и делать что-то более-менее приличное, конечно, в образовательных целях. В планах привести сорс в нормальный удобочитаемый вид и выложить для всеобщего пользования.
Ясное дело, что чисто температуру мерить довольно скушно, вот я и подумала по ходу дела прикрутить измерение текущего напряжения питания процессора, к тому же, что делается это довольно-таки просто. Для того, чтобы узнать текущий Voltage ID (а затем переверсти его в значение напряжения) нам потребуется доступ к так называемому FIDVID_STATUS register, машинно-зависимому регистру с адресом 0xС0010042.
Его формат. Нас интересует 6-битовое поле CurrVID во втором двойном слове. Таблица соответсвия этих 6-битов и значения напряжения приведена ниже.
Сначала проверяем с помощью функции 8000_0007 CPUID доступность этой [VID] опции (функции CPUID можно глянуть в CPUID Specification от AMD, ссылки на скачку я давала в предыдущем посте амдэшных мануалов).
Код:
_asm{
//проверяем доступность опции
// Advanced Power Management Information
mov eax,80000007h
cpuid
// 2 бит в edx - VID: Voltage Id control
bts edx,2
// cf == 1?
jnb ext
mov isVID,TRUE
ext:
}
Я думаю, что есть народ тут, который с асмом не дружит. Ну так вот, поясняю насчет многострадальной инструкции bts. Инструкции bts/btr полюбились мне еще в 2007 году, тогда кажись я постила 23 способа получения единицы в регистре (тема вроде такая была) и меня интересовали разные извратные способы, тогда-то я и познакомилась с этой инструкцией. Первый ее операнд - это источник, в котором мы проверяем бит с номером, хранящимся во втором операнде. То есть проверяем второй бит от нуля в edx. флаг CF устанавливается значением этого бита. Сам бит потом устанавливается в 1, но нам это уже не важно. jсс, проверяющие флаг CF - это jb и jnb. второй происходит, если этот бит 0. вот такие дела. Теперь, думаю, все ясно и непосвященному.
В драйвере, после проверок пишем
Код:
// получаем напряжение
if(isVID){
_asm{
mov ecx,0c0010042h
rdmsr
and edx,111111b
mov uVID,edx
}
buf[2] = uVID;
KdPrint(("VID %X",uVID));
}else buf[2]=0xFFFFFFFF;
Из таблицы соответствия была выведена формула для напряжения
opart - часть до запятой, tpart - после запятой.
Код:
DWORD opart,tpart;
if(tmp[2]<0x20){
tmp[2]=1550-tmp[2]*25;
opart = tmp[2]/1000;
tpart = tmp[2]-1000;
}else{
tmp[2]=7750 - (tmp[2]-0x1F)*25;
opart = 0;
tpart = tmp[2];
}
wsprintf(core,L"%d.%dv",opart,tpart);
Как-то так.
---
Если есть ошибки - неточности в моих рассуждениях буду рада указанию на них, т.к. в общем-то тестирования достаточного не было и какой-то момент могла упустить. Кароче, велкам в jabber и пм, если что.
---------
Ах да, речь, идет, конечно об амд, насчет как это у интелов я хз, пока в их манах не смотрела этого