Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.12.123.183] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Здравствуйте!
Не могли б вы ли поделиться исходниками (не важно на чем написанные) для чтения содержимого SPD планок памяти? Очень нада! Заранее благодарен, Евгений |
Сообщ.
#2
,
|
|
|
Вот те тута Программирование SMBus на ICHx
счастье! SMBus Device: 0x50 и 0x51 - адреса SPD нулевого и 1го сокета |
Сообщ.
#3
,
|
|
|
Пасиба, буду копать!
Если что, не отказывайте в сотрудничестве! Заранее благодарен, Евгений |
Сообщ.
#4
,
|
|
|
Ув. VaStaNi!
Прочитав форум, не совсем мне стало понятно, как работать с SPDbios планок памяти. Можно ли у Вас попросить пример кода для наглядности? Сам уже написал монитор для Win/Lin, который выводит показания температур, напруг и скоростей вращения вентиляторов. Заранее благодарен за сотрудничество! З.Ы. Вот, кстати, попытался сотворить читалку SPD: char mem_data[2048]; memset(&mem_data[0], 0, 2048); char i = 0, rez; for (i = 0; i< 128; i++) { __asm { mov dx, 500h mov cx, 0xA000 ; адрес, режим, offset add cl, i loc_E92F7: in al, dx out 0EBh, al out dx, al and al, 0BFh or al, al jnz loc_E92F7 add dx, 4 ; +4 mov al, ch ;or al, 1 out dx, al mov al, cl dec dx ; +3 out dx, al dec dx ; +2 mov al, 48h ; 74h ; = команда READ BYTE! out dx, al out 0EBh, al xor cx, cx sub dx, 2 ; = BASE loc_E931C: in al, dx out 0EBh, al test al, 4 jnz loc_E932D test al, 2 jz loc_E932B test al, 80h jnz loc_E932D loc_E932B: loop loc_E931C loc_E932D: out dx, al add dx, 7 ; +7 --- DATA PORT! in al, dx mov rez, al } mem_data[i] = rez; } Все время возвращает мне 18h!!! Что я делаю не так? |
Сообщ.
#5
,
|
|
|
RoadStar
Сам только что набрал код по четению SPD, в отличии от других участков программы работает более или менее стабильно. Так пойдем по порядку базовый адресс SMBus не верный. Определяем его через конфигурационное пространство PCI. ;or al, 1 - разкаментировать это бит если стоит 1 то означает четение 0 запись остальная часть это адресс ячейки EEPROM. Так что, нужно добавит после сторчки add cl, i еще одну Shl cl, 1 Я пробовал читать из 5 порта, 7 не проверял. add dx, 7 ; +7 --- DATA PORT! |
Сообщ.
#6
,
|
|
|
2 Pavia
Цитата базовый адресс SMBus не верный. Определяем его через конфигурационное пространство PCI. А можно поподробнее? Плиз. Про бит понял. Попробую. З.Ы. На счет базового адреса - я в SpeedFun`е смотрел: I/O properly initialized Linked ISA BUS at $0290 Linked Intel 82801EB ICH5 SMBUS at $0500 Found nVidia GeForce4 MX 480 with AGP 8X Linked nVidiaI2C0 SMBUS at $3D403E3F Linked nVidiaI2C1 SMBUS at $3D403637 Linked nVidiaI2C2 SMBUS at $3D405051 Scanning ISA BUS at $0290... Winbond W83627HF (ID=$21) found on ISA at $290 SuperIO Chip=Winbond W83627HF Scanning Intel SMBus at $0500... Scanning I2CNVidia SMBus at $3D403E3F... Scanning I2CNVidia SMBus at $3D403637... Scanning I2CNVidia SMBus at $3D405051... SMART Enabled for drive 0 Found WDC WD1200BB-00FTA0 (120,0GB) Found ACPI temperature (54,0C) End of detection Вродеж 500h ??? Или я не прав? Заранее благодарен за ответы.... |
Сообщ.
#7
,
|
|
|
RoadStar
Число 500h меня смутило, но раз SpeedFun, так определил значит так оно и есть. В большенстве случаев можно определить так. Цитата VaStaNi @ mov ax, 0xB103 ;найти mov ecx, 0x0C0500 ;класс SMBus устройства mov si, 0 int 0x1A jnc @sm1 ret @sm1: mov di, 0x20 ;номер читаемого регистра mov ax, 0xB109 ;читать WORD значение int 0x1A and cx, 0xFFFE mov dx, cx |
Сообщ.
#8
,
|
|
|
Не катит в винде такое!
Я сканировал шину так: // определяем значения смещений для пространства шины PCI #define VENDOR_ID 0x00 #define DEVICE_ID 0x02 #define CODE 0x04 #define STATUS 0x06 #define REVISION_ID 0x08 #define INTERFACE 0x09 #define SUBCLASS 0x0A #define CLASSCODE 0x0B #define CACHE_LINE_SIZE 0x0C #define LATENCY_TIMER 0x0D #define HEADER_TYPE 0x0E #define BIST 0x0F #define BASE_ADDRESS_0 0x10 #define BASE_ADDRESS_1 0x14 #define BASE_ADDRESS_2 0x18 #define BASE_ADDRESS_3 0x1C #define BASE_ADDRESS_4 0x20 #define BASE_ADDRESS_5 0x24 #define CARDBUS_POINTER 0x28 #define SUBVEN_ID 0x2C #define SUBSYSTEM_ID 0x2E #define ROM_BASE_ADDRESS 0x30 #define INTERRUPT_LINE 0x3C #define INTERRUPT_PIN 0x3D #define MIN_GNT 0x3E #define MAX_LAT 0x3F for (iBusPCI = 1; iBusPCI < 255; iBusPCI++) for ( int iDevice = 0; iDevice < 32; iDevice++ ) { for ( int iFunction = 0; iFunction < 8; iFunction++ ) { memset ( &buffer, 0, 256 ); // вычисляем номер очередного слота int iSlot = GetDeviceSlot ( iDevice, iFunction ); // проверяем поле Vendor ID для определения наличия устройства DWORD dwVendorID = 0; // получаем конфигурацию устройства dwResult = GetDevice ( iBusPCI, iSlot, VENDOR_ID ); // пишем в адресный порт параметры устройства e_outp(dwResult, 0xCF8); dwResult = 0; // читаем из порта данных идентификатор производителя dwResult = e_inp(0xCFC); // если полученное значение равно 0 или 0xFFFFFFFF, // выходим из вложенного цикла и продолжаем поиск if ( dwResult == 0x00000000 || dwResult == 0xFFFFFFFF ) continue; if(dwResultPrev==dwResult) continue; dwResultPrev=dwResult; // если устройство присутствует, читаем его параметры // из конфигурационного пространства шины PCI memset(&buffer[0], 0, sizeof(buffer)); for ( int j = 0; j < 251; j+=4 ) { // получаем конфигурацию устройства dwResult = GetDevice ( iBusPCI, iSlot, j ); // пишем в адресный порт параметры устройства e_outp( dwResult, 0xCF8 ); // получаем из порта очередной байт dwResult = e_inp ( 0xCFC + ( j&0x03 ) ); // сохраняем полученный байт в буфер memcpy(buffer+j, &dwResult, sizeof(DWORD)); } } } Во как! Потом в полученном буфере для "Intel Corporation 82801EB/ER SMBus Controller" по смещению BASE_ADDRESS_4 я вычитал 501h => значит базовый адрес = 500h А вот SPD читать под винду так и не получаицца! Обидно! |
Сообщ.
#9
,
|
|
|
RoadStar
Раз с PCI получается работать. То почему бы чтение SPD не должно работать? По моему все должно работать и виндоусе. |
Сообщ.
#10
,
|
|
|
Постоянно выдает в конце программы 18h и хоть ты тресни!
Я уже не знаю, чего я делаю не так!!! Уже отчаялся проста... |
Сообщ.
#11
,
|
|
|
RoadStar
Тут, попробовал, на стареньком компьюторе. Так вот, регистр может возаврощать постоянно 18h. Лично у меня это было 07h. Но как только я попробовал другии адреса A0h-B0h, зароботало. Вернее как только я набрел на существующие устройство он вернул его данные. На не существующие выдовал последний прочитанный/записанный байт. |
Сообщ.
#12
,
|
|
|
Адреса чего? Устройства на SMBus?
Можно попросить пример кода? Так я думаю лучше будет! Заранее благодарен за помощь! |
Сообщ.
#13
,
|
|
|
RoadStar
Да адресса устройств на SMBus, под A0h-B0h я имел ввиду 50h-54h сдвинутые в лево на 1. и выставленным нуливым битом. И еще я выше писал нужно добавить Shl cl, 1. Так это я перепитул адресса строчка не нужна, так как оно у нас учитывается в адрессе. Код пока не дороботан, думаю нужно добавить проверку на то есть ли устройства или нет, но пока не добавил. Function ReadSMBus(SMBusAddr, Addr:integer):Byte; var a:Byte; begin asm mov dx,SMBUsAddr mov cx,Addr @loc_E92F7: in al,dx {+0 Читаем регистор статуса} out 0EBh,al {Задержка} out dx,al {+0 Пишем в регистор статуса, что обнуляет его} and al,0BFh or al,al jnz @loc_E92F7 {Ждем пока контролер не осовбодиться???} add dx,4 {+4 Регистр адресса нулевой бит определяет запись или четение 1=Read 0=Write} mov al,ch or al,1 out dx,al mov al,cl dec dx {+3 Регистр команды, для EEPROM это адрес ячейки} out dx,al dec dx {+2 Регистр Host Controler регистр задает способ передачи} mov al,48h {Способ передачи с Byte Data 010b } out dx,al out 0EBh,al {Задержка} xor cx,cx sub dx,2 {+0 регистор статуса} @loc_E931C: {Порядок проверок важен!!!} in al,dx out 0EBh,al {Задержка} test al,4 {ошибоки устройства} jnz @loc_E932D test al,2 {Произошло прерывание} jz @loc_E932B test al,80 {данные пришли} jnz @loc_E932D @loc_E932B: loop @loc_E931C @loc_E932D: out dx,al {+0 Пишем в регистор статуса, что обнуляет его} add dx,5 {+5 Регистр данных Date0} in al,dx mov a,al end; ReadSMBus:=a; end; procedure SMBusINFO; var n,i:integer; b:Byte; PCI:PPCIList; Reg1:DWord; Addr:Word; begin Addr:=0; for i:=0 to PCICount do begin PCI:=PCIListNum(i); ReadPCICFGReg(PCI^.Addr+$00,Reg1); if (Reg1=$71138086) then begin ReadPCICFGReg(PCI^.Addr+$90,Reg1); Addr:=Reg1 and $FFF0;; break; end; ReadPCICFGReg(PCI^.Addr+$08,Reg1); if (Reg1 shr 24 and $FF =$0C) and ((Reg1 shr 16 and $00FF)=05) then begin ReadPCICFGReg(PCI^.Addr+$20,Reg1); Addr:=Reg1 and $FFF0; break; end; end; IF Addr=0 then Write('SMBus - not found'); n:=0; while n<>-1 do begin clrscr; WriteLn('=SMBus INFO='); WriteLn('SMBus Addr:',HexW(Addr)); WriteLn('50h - Memory SPD'); WriteLn('51h - Memory SPD'); WriteLn('52h - Memory SPD'); WriteLn('53h - Memory SPD'); Write('->'); ReadLn(n); case n of 00..127: begin for i:=0 to 255 do begin b:=ReadSMBus(addr,n*512+256+i); Write(HexB(B)); end; ReadLn; end; end; end; Write('Please enter...'); readln; end; |
Сообщ.
#14
,
|
|
|
У SPD на SMBUS адрес 50h.
Для несуществующего устройства ерунда возвращается, плюс там где-то бит статуса есть - типа успешное чтение или нет. Точнее сейчас не помню. Советую посмотреть исходники lmsensors - там много всего, но нужный код найти в принципе не сложно... |
Сообщ.
#15
,
|
|
|
А кто нибудь писать пробовал? Так собственно все вышло, код немного подправил.
Добавил несколько строчек out 0EBh,al {Задержка} procedure WriteSMBus(SMBusAddr, Addr:integer; b:Byte); var a:Byte; begin asm mov dx,SMBUsAddr mov cx,Addr @loc_E92F7: in al,dx {+0 Читаем регистор статуса} out 0EBh,al {Задержка} out dx,al {+0 Пишем в регистор статуса, что обнуляет его} and al,0BFh or al,al jnz @loc_E92F7 {Ждем пока контролер не осовбодиться???} out 0EBh,al {Задержка} mov al,b add dx,5 {+5 Регистр данных Date0} out dx,al {пишим в него} out 0EBh,al {Задержка} dec dx {+4 Регистр адресса нулевой бит определяет запись или четение 1=Read 0=Write} mov al,ch and al,0FEh {- запись} out dx,al mov al,cl dec dx {+3 Регистр команды, для EEPROM это адрес ячейки} out dx,al dec dx {+2 Регистр Host Controler регистр задает способ передачи} mov al,48h {Способ передачи с Byte Data 010b } out dx,al out 0EBh,al {Задержка} xor cx,cx sub dx,2 {+0 регистор статуса} @loc_E931C: {Порядок проверок важен!!!} in al,dx out 0EBh,al {Задержка} test al,4 {ошибоки устройства} jnz @loc_E932D test al,2 {Произошло прерывание} jz @loc_E932B test al,80 {данные пришли} jnz @loc_E932D @loc_E932B: loop @loc_E931C @loc_E932D: end; end; |