На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Чтение содержимого SPD планок памяти
    Здравствуйте!

    Не могли б вы ли поделиться исходниками (не важно на чем написанные) для чтения содержимого SPD планок памяти?

    Очень нада!

    Заранее благодарен, Евгений
      Вот те тута Программирование SMBus на ICHx
      счастье! SMBus Device: 0x50 и 0x51 - адреса SPD нулевого и 1го сокета :)
        Пасиба, буду копать!

        Если что, не отказывайте в сотрудничестве!

        Заранее благодарен, Евгений
          Ув. VaStaNi!

          Прочитав форум, не совсем мне стало понятно, как работать с SPDbios планок памяти.

          Можно ли у Вас попросить пример кода для наглядности?

          Сам уже написал монитор для Win/Lin, который выводит показания температур, напруг и скоростей вращения вентиляторов.

          Заранее благодарен за сотрудничество!

          З.Ы.

          Вот, кстати, попытался сотворить читалку SPD:

          ExpandedWrap disabled
                  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!!!

          Что я делаю не так?
          Сообщение отредактировано: RoadStar -
            RoadStar
            Сам только что набрал код по четению SPD, в отличии от других участков программы работает более или менее стабильно.
            Так пойдем по порядку базовый адресс SMBus не верный. Определяем его через конфигурационное пространство PCI.
            ;or al, 1 - разкаментировать это бит если стоит 1 то означает четение 0 запись остальная часть это адресс ячейки EEPROM.
            Так что, нужно добавит после сторчки
            add cl, i
            еще одну
            Shl cl, 1

            Я пробовал читать из 5 порта, 7 не проверял.
            add dx, 7 ; +7 --- DATA PORT!
              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 ???
              Или я не прав?

              Заранее благодарен за ответы....
                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
                  Не катит в винде такое!

                  Я сканировал шину так:

                  ExpandedWrap disabled
                    // определяем значения смещений для пространства шины 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 читать под винду так и не получаицца!
                  Обидно!
                  Сообщение отредактировано: RoadStar -
                    RoadStar
                    Раз с PCI получается работать. То почему бы чтение SPD не должно работать? По моему все должно работать и виндоусе.
                      Постоянно выдает в конце программы 18h и хоть ты тресни!

                      Я уже не знаю, чего я делаю не так!!!

                      Уже отчаялся проста...
                        RoadStar
                        Тут, попробовал, на стареньком компьюторе. Так вот, регистр может возаврощать постоянно 18h. Лично у меня это было 07h. Но как только я попробовал другии адреса A0h-B0h, зароботало. Вернее как только я набрел на существующие устройство он вернул его данные. На не существующие выдовал последний прочитанный/записанный байт.
                          Адреса чего? Устройства на SMBus?

                          Можно попросить пример кода?
                          Так я думаю лучше будет!

                          Заранее благодарен за помощь!
                            RoadStar
                            Да адресса устройств на SMBus, под A0h-B0h я имел ввиду 50h-54h сдвинутые в лево на 1. и выставленным нуливым битом.
                            И еще я выше писал нужно добавить Shl cl, 1. Так это я перепитул адресса строчка не нужна, так как оно у нас учитывается в адрессе.
                            Код пока не дороботан, думаю нужно добавить проверку на то есть ли устройства или нет, но пока не добавил.

                            ExpandedWrap disabled
                              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;
                              У SPD на SMBUS адрес 50h.
                              Для несуществующего устройства ерунда возвращается, плюс там где-то бит статуса есть - типа успешное чтение или нет.
                              Точнее сейчас не помню.
                              Советую посмотреть исходники lmsensors - там много всего, но нужный код найти в принципе не сложно...
                                А кто нибудь писать пробовал? Так собственно все вышло, код немного подправил.
                                Добавил несколько строчек out 0EBh,al {Задержка}


                                ExpandedWrap disabled
                                  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;
                                Сообщение отредактировано: Pavia -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0558 ]   [ 15 queries used ]   [ Generated: 15.05.24, 13:11 GMT ]