Вопросы по шине SMBus

Discussion in 'WASM.OS.DEVEL' started by drem1lin, Aug 21, 2010.

  1. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Здравствуйте, по работе пришлось разбираться с этой шиной и возникли некоторые вопросы.
    В ходе изучения шины у меня сложилось следующее представление о ней если я в чем-то ошибусь подправьте меня.
    Для работы используется южный мост, и перед началом работы надо понять включена ли она, для этого проверить биты в регистрах Host Configuration Register бит 0 и Chipset Configuration Registers-> Function Disable бит 3. Потом из конфигурационого пространства PCI считать значение SMBus Base и относительно него обращаться к регистрам контроллера SMBus. Но в интернете я нашел примеры только считывания SPD планок памяти, а вот примеров с другими устройствами нет. И возник вопрос как определить какие устройства еще подключены к шине, какие их адреса и как к ним обратиться. И я не понял как формируется запрос к какому либо устройству и в какие регистры что пишется. Этом вопрос вроде освещен в спецификации на шину, но не понятно(
     
  2. Protorus

    Protorus New Member

    Blog Posts:
    0
    Joined:
    Dec 30, 2009
    Messages:
    51
    Я, например, вот с этого начинал http://www.xlevel.ru/forum/YaBB.cgi?board=programming;action=display;num=1186920031
    Запомни этот ник, Pavia. Вот этот чел уж точно занет все по этой теме.
    Ищи его творения и на этом форуме тоже...
     
  3. VaStaNi

    VaStaNi Member

    Blog Posts:
    0
    Joined:
    Jun 1, 2004
    Messages:
    203
    Location:
    Ukraine
  4. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Я его творения почти все уже прочитал
     
  5. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Это я все видел)
     
  6. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    В общем для чтения SPD я написал следующую программу на C++. Только она все время выводит 26h. Почему пока не знаю... Если кому не лень проверьте код и алгоритм. Для ее рнаботы нужен драйвер ввода вывода, я использовал giveio.sys
    Code (Text):
    1. #include "stdafx.h"
    2.  
    3. #define PCI_ADR 0xCF8
    4. #define PCI_DATA 0xCFC
    5. #define RCBA_ADR 0x8000F8F0 //B00:D31:F00 offset f0h
    6. #define SMBus_REG 0x8000FB00 //B00:D31:F03 offset not const
    7.  
    8. int CheckFunctionDisableRegister();
    9. DWORD GetSMBusRegisterDataDword(int offset);
    10. DWORD GetSMBusRegisterDataByte(int offset);
    11. DWORD GetSMBusRegisterDataWord(int offset);
    12. void ClearSMBusStatusReg(int SMBusBase);
    13. DWORD ShowSMBusControllerInfo();
    14. void ReadSpd(int SMBusBase);
    15.  
    16. int inline openIO(){
    17.     HANDLE h;
    18.     h = CreateFile(L"\\\\.\\giveio", GENERIC_READ, 0, NULL,
    19.         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    20.     if(h == INVALID_HANDLE_VALUE) {
    21.         printf("Couldn't access giveio device\n");
    22.         return 1;
    23.     }
    24.     CloseHandle(h);
    25.     return 0;
    26. }
    27.  
    28.  
    29.  
    30. int _tmain(int argc, _TCHAR* argv[])
    31. {
    32.     if(openIO()) return -1;
    33.     //для южного моста ich9
    34.     //получаем базовый адрес регистров конфигурации чипсета PCI Configuration Registers (LPC I/F—D31:F0)
    35.     //для этого считываем регистр RCBA
    36.     if (CheckFunctionDisableRegister() < 0)
    37.     {
    38.         printf("SMBus host disabled\n");
    39.     }
    40.     DWORD SMBb = ShowSMBusControllerInfo();
    41.     ClearSMBusStatusReg(SMBb);
    42.     _outp(0xEB, 1);
    43.  
    44.     ReadSpd(SMBb);
    45.    
    46. }
    47.  
    48. int CheckFunctionDisableRegister()
    49. {
    50.     //получаем базовый адрес регистров конфигурации чипсета PCI Configuration Registers (LPC I/F—D31:F0)
    51.     //для этого считываем регистр RCBA
    52.     _outpd(PCI_ADR, RCBA_ADR);
    53.     int RCBARegister = _inpd(PCI_DATA);//считали RCBA
    54.     printf("RCBA register = 0x%08lX\n", RCBARegister);
    55.     if (RCBARegister & 1 == 0)
    56.     {
    57.         return -2; //When set, enables the range specified in BA to be claimed as the Root Complex Register Block.
    58.     }
    59.     _asm
    60.     {
    61.         shr RCBARegister, 14
    62.     }
    63.     printf("RCBA base address= 0x%08lX\n", RCBARegister);
    64.     RCBARegister += 0x3418; //Function disable register
    65.     //считываем FDR
    66.     DWORD FDR = _inpd(RCBARegister);
    67.     printf("FDR register = 0x%08lX\n", FDR);
    68.     if (FDR & 0x00000008 != 0)
    69.     {
    70.     //  return -3; //Выключен контроллер SMBus
    71.     }
    72.  
    73.  
    74.     return 1;
    75. }
    76.  
    77. DWORD GetSMBusRegisterDataDword(int offset)
    78. {
    79.     _outpd(PCI_ADR, SMBus_REG+offset);
    80.     return _inpd(PCI_DATA);
    81. }
    82.  
    83. DWORD GetSMBusRegisterDataWord(int offset)
    84. {
    85.     _outpd(PCI_ADR, SMBus_REG+offset);
    86.     DWORD b = _inpd(PCI_DATA);
    87.     _asm{
    88.         push eax
    89.             mov eax, b
    90.             rol eax, 16
    91.             mov b, eax
    92.             pop eax
    93.     }
    94.     return b;
    95. }
    96.  
    97. DWORD GetSMBusRegisterDataByte( int offset )
    98. {
    99.     _outpd(PCI_ADR, SMBus_REG+offset);
    100.     DWORD b = _inpd(PCI_DATA);
    101.     _asm{
    102.             push eax
    103.             mov eax, b
    104.             bswap eax
    105.             mov b, eax
    106.             pop eax
    107.     }
    108.     return b;
    109. }
    110.  
    111. DWORD ShowSMBusControllerInfo()
    112. {
    113.     DWORD data = GetSMBusRegisterDataWord(0);
    114.     printf("0x00 %08lX\n", data);
    115.     data = GetSMBusRegisterDataWord(4);
    116.     printf("0x04 %08lX\n", data);
    117.     data = GetSMBusRegisterDataByte(8);
    118.     printf("0x08 %08lX\n", data);
    119.     data = GetSMBusRegisterDataDword(0xc);
    120.     printf("0x0c %08lX\n", data);  
    121.     data = GetSMBusRegisterDataDword(0x10);
    122.     printf("0x10 %08lX\n", data);  
    123.     data = GetSMBusRegisterDataDword(0x14);
    124.     printf("0x14 %08lX\n", data);  
    125.     data = GetSMBusRegisterDataDword(0x18);
    126.     printf("0x18 %08lX\n", data);  
    127.     data = GetSMBusRegisterDataDword(0x1c);
    128.     printf("0x1c %08lX\n", data);  
    129.     data = GetSMBusRegisterDataDword(0x20);
    130.     printf("0x20 %08lX\n", data);  
    131.     data = GetSMBusRegisterDataDword(0x24);
    132.     printf("0x24 %08lX\n", data);  
    133.     data = GetSMBusRegisterDataDword(0x28);
    134.     printf("0x28 %08lX\n", data);  
    135.     data = GetSMBusRegisterDataDword(0x2c);
    136.     printf("0x2c %08lX\n", data);  
    137.     data = GetSMBusRegisterDataDword(0x30);
    138.     printf("0x30 %08lX\n", data);  
    139.     data = GetSMBusRegisterDataDword(0x34);
    140.     printf("0x34 %08lX\n", data);  
    141.     data = GetSMBusRegisterDataDword(0x38);
    142.     printf("0x38 %08lX\n", data);  
    143.     data = GetSMBusRegisterDataDword(0x3c);
    144.     printf("0x3c %08lX\n", data);  
    145.     data = GetSMBusRegisterDataByte(0x40);
    146.     printf("0x40 %08lX\n\n", data);
    147.  
    148.     DWORD SMBusBaseAddress = GetSMBusRegisterDataDword(0x20);
    149.     SMBusBaseAddress--;
    150.     printf("SMBus Base Address = 0x%08lX\n", SMBusBaseAddress);
    151.     DWORD SMBusPCICommandReg = GetSMBusRegisterDataWord(0x4);
    152.     _asm shr SMBusPCICommandReg, 16
    153.     printf("SMBus PCICommandReg = 0x%08lX\n", SMBusPCICommandReg);
    154.     DWORD SMBusHostConfigurationReg = GetSMBusRegisterDataByte(0x40);
    155.     printf("SMBus Host Configuration Register = 0x%08lX\n", SMBusHostConfigurationReg);
    156.     if (SMBusPCICommandReg & 0x1 == 0)
    157.     {
    158.         return -4;
    159.     }
    160.     if (SMBusHostConfigurationReg & 0x1 == 0)
    161.     {
    162.         return -5;
    163.     }
    164.     return SMBusBaseAddress;
    165. }
    166.  
    167. void ClearSMBusStatusReg(int SMBusBase)
    168. {
    169.     BYTE a;
    170.     do
    171.     {
    172.         a = _inp(SMBusBase);
    173.         //printf("SMBus IO Status reg = 0x%02lX\n", a);
    174.         _outp(0xEB, a);
    175.         _outp(SMBusBase, a);
    176.         _outp(0xEB, a);
    177.         a = a & 0xBF;
    178.     } while (a != 0);
    179. }
    180.  
    181. void ReadSpd(int SMBusBase)
    182. {
    183.     //цикл по модулям dimm
    184.     for(BYTE i = 0; i<4; i++)
    185.     {
    186.         printf("\nDIMM %X\n", i);
    187.         //цикл по ячейкам SPD
    188.         for (int j = 0; j< 256; j++)
    189.         {
    190.             ClearSMBusStatusReg(SMBusBase);
    191.             if (j%16 == 0)
    192.             {
    193.                 printf("\n");
    194.             }
    195.             int Reg = SMBusBase + 4;
    196.             _outp(Reg, 0xA1+i*2);
    197.             Reg--; //+3
    198.             _outp(Reg, j);
    199.             Reg--; //+2
    200.             _outp(Reg, 0x48);
    201.             Reg = SMBusBase;
    202.             //Начинаем ожидание готовности контроллера
    203.             //Порядок проверок важен?
    204.            
    205.             BYTE a=0;
    206.         /*Этот код взят из кода Pavia  _asm{
    207.                 xor cx,cx
    208.             loc_E931C:
    209.                 mov edx, SMBusBase
    210.                 in al,dx
    211.                 out 0EBh,al ;{Задержка}
    212.                 test al,4  ; {ошибоки устройства}
    213.                 jnz  loc_E932D
    214.                 test al,2  ; {Произошло прерывание}
    215.                 jz  loc_E932B
    216.                 test al,80  ;{данные пришли}
    217.                 jnz  loc_E932D
    218.             loc_E932B:
    219.                 loop loc_E931C
    220.             loc_E932D:
    221.                 out dx,al   ;{+0 Пишем в регистор статуса, что обнуляет его}
    222.                 add dx,5    ;{+5 Регистр данных Date0}
    223.                 in al,dx
    224.                 mov a,al
    225.             }
    226.             printf("%02lX ", a);*/
    227.            
    228.            
    229.            
    230.             BYTE Status;
    231.             do
    232.             {
    233.                 _outp(0xEB, 1);
    234.                 Status = _inp(Reg);
    235.                 _outp(0xEB, 1);
    236.                 /*if((Status & 4) != 0)
    237.                 {
    238.                     printf("bit DEV_ERR\n");
    239.                     printf("Status reg: 0x%02lX\n\n", Status);
    240.                     break;
    241.                 }
    242.                 if((Status & 2) != 1)
    243.                 {
    244.                     printf("bit INTR error\n");
    245.                     printf("Status reg: 0x%02lX\n\n", Status);
    246.                     break;
    247.                 }*/
    248.                
    249.             } while (Status & 0x80 != 0x80);
    250.         /*  if((Status & 2) != 1)
    251.             {
    252.                 break;
    253.             }*/
    254.             BYTE data = _inp(SMBusBase + 5);
    255.             printf("%02lX ", data);
    256.         }
    257.         _getch();
    258.     }
    259. }
     
  7. VaStaNi

    VaStaNi Member

    Blog Posts:
    0
    Joined:
    Jun 1, 2004
    Messages:
    203
    Location:
    Ukraine
    ну раз все видел, тогда посмотри еще раз и разбери по полочкам модулёк с метки
    @ICH_SetCmdSMBus: до RET
    при этом DataSheet на твой ICH строго обязателен...
     
  8. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    У меня этих даташитов, как ...)))) Как нибудь можно сравнить то, что возвращает прога с истинным значением? просто я вернул 256 байт и они похожи на правду, но несколько значений там смущают. Мне бы сравнить с неразобранной эталонной SPD, а как ее получить не знаю....
     
  9. VaStaNi

    VaStaNi Member

    Blog Posts:
    0
    Joined:
    Jun 1, 2004
    Messages:
    203
    Location:
    Ukraine
    drem1lin
    Сэр, Вы меня удивляете до невозможности, её Богу!
    А что гугла нет?
    Чем НЕ устраивает дока по SPD структуре и тот же SpeedFAN?
    или CPU-Z? или EVEREST? или SiSoftware Sandra или HWinFO?
    Да в конце концов давно существует DocMemory SPD Reader 1.4????
    Тем более, что он "в точку тот" ибо:
    "Limitations: Currently only supports only Intel and SiS DDR chips."
    Что ссылку дать? Ну вот тут
    ftp://majorgeeks.mirror.internode.on.net/memory/spdreaderv1_4.exe
    http://www.hwinfo.com/download32.html#
    http://www.hwinfo.com/files/hw32_358.zip
    http://www.overclockers.com/ctspd-memory-readout-utility/
    Чем НЕ устраивает приведенный РАБОЧИЙ исходник? НЕ тем языком писаный?
     
  10. Protorus

    Protorus New Member

    Blog Posts:
    0
    Joined:
    Dec 30, 2009
    Messages:
    51
    Я вот что хочу уточнить, может ты заодно и подскажешь..
    У тебя там приведен вариант кода от Pavia, он отличается от того на который я давал ссылку, вплане определения момента правильного приема данных контроллером от устройства по шине I2C.
    Так вот какой по твоему более правильный?
    И еще в коде Pavia этот момент определяется так (что вроде как не верно)
    Code (Text):
    1. test al,80  ;{данные пришли}
    2. jnz  loc_E932D
    У тебя как то так
    Code (Text):
    1. while (Status & 0x80 != 0x80);
    А вообще я код на сях чуть хуже воспринимаю чем на asm.
     
  11. Protorus

    Protorus New Member

    Blog Posts:
    0
    Joined:
    Dec 30, 2009
    Messages:
    51
    Если не против я задам в твоем топике вопрос?
    Дело в том что у меня BIOS запрещает контроллер SMB перед загрузкой ОС и
    следовательно код для "голой" системы не работает, для Win все нормально.
    У тебя в функции CheckFunctionDisableRegister() это как раз проверяется.
    Так вот, что будет страшного если в этой функции в регистре FDR (Function disable register) очищать бит 7?
     
  12. VaStaNi

    VaStaNi Member

    Blog Posts:
    0
    Joined:
    Jun 1, 2004
    Messages:
    203
    Location:
    Ukraine
    Protorus,
    это тот, который проверен для конкретного чипсета южного моста.
    Только детальная сверка даташитов, например ICH4, 6, 7, 9, 10, и конкретно в данном аспекте битов регистра
    "HST_STS—Host Status Register" помогут точно сделать вывод, что более... даже не то чтобы правильно, а что более совместимо, универсально для разных чипсетов, а значит и машин.
    Конкретный бит 7 это "Byte Done Status" и мой беглый взгляд на даташиты ICH6 и ICH10 существенных различий не замечает...
    Если так беспокоит программная реализация ожидания готовности, то вот мой дизасменный код одного из интеловских биосов по данному поводу:
    Code (Text):
    1.        .............
    2.                 xor     cx, cx
    3.                 mov     dx, 500h
    4. loc_E931C:
    5.                 in      al, dx
    6.                 out     0EBh, al
    7.                 test    al, 4
    8.                 jnz     loc_E932D
    9.                 test    al, 2
    10.                 jz      loc_E932B
    11.                 test    al, 80h
    12.                 jnz     loc_E932D
    13. loc_E932B:
    14.                 loop    loc_E931C
    15. loc_E932D:
    16.                 out     dx, al
    17.                 mov     dx, 507h
    18.                 in      al, dx        ; СОБСТВЕННО ЧТЕНИЕ ПРИНЯТОГО БАЙТА!
    19.                 pop     cx
    20.                 ret
    а вот пример этого же места из некоторых сорцов биоса, которые уже несколько лет гуляют в нете и может быть даже на этом форуме ссылка была...
    Точно знаю, что это AWARD, так вот это дело:
    Code (Text):
    1. Chk_SMBus_READY:
    2.                 mov     dx, SMBus_Port + 0
    3.                 clc
    4.                 mov     cx, 0x100
    5. Chk_I2c_OK:
    6.                 in      al, dx           ;get status
    7.                 NEWIODELAY
    8.                 or      al, al
    9.                 jz      Clear_final
    10.                 test    al, 4
    11.                 jnz     SMBus_Err
    12.                 test    al, 1          ;busy ?
    13.                 jz      Not_Smbusy
    14.                 ror     ecx, 16
    15.                 mov     cx, 0x1000
    16.         @@:
    17.                 loop    @B
    18.                 ror     ecx, 16
    19. Not_Smbusy:
    20.                 out     dx,al
    21.                 loop    Chk_I2c_OK
    22. SMBus_Err:
    23.                 out     dx, al                   ;clear status
    24.                 NEWIODELAY
    25.                 in      al, dx
    26.                 test    al, 4                  ;device error ?
    27.                 jnz     SMBus_Err
    28.                 stc
    29. Clear_final:
    30.                 ret
    ну и еще 2 копейки по поводу правильности и дотошности подхода.
    Наиболее правильно с точки зрения именно ожидания, считаю это решение:
    Code (Text):
    1.                mov     cx, 800h
    2. loc_EAFCF:
    3.                 in      al, dx
    4.                 out     0EBh, al
    5.                 out     dx, al
    6.                 test    al, 2
    7.                 jnz     loc_EAFE5
    8.                 and     al, 0BFh
    9.                 or      al, al
    10.                 jz      loc_EAFE5
    11.                 test    al, 4
    12.                 jnz     loc_EAFE3
    13.                 loop    loc_EAFCF
    14. loc_EAFE3:
    15.                 stc
    16.                 ret
    17. loc_EAFE5:
    18.                 clc
    19.                 ret
    собственно имеется ввиду это
    Code (Text):
    1.        in      al, dx
    2.                 out     0EBh, al
    3.                 out     dx, al
    т.к. согласно даташитам биты нулятся обратной записью...
    но тут сразу они все нулятся после чтения, вне зависимости от дальнейшей паузы или ветвления или еще чего либо, но далее по ходу можно быть наверняка уверенным, что в данном регистре при новом его прочтении будут НАВЕРНЯКА правильные статусы.
    Ну вот и все, что я хотел молвить :)"...думайте сами, решайте сами, иметь или не иметь"
     
  13. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Отсутствием компилятора) лень его искать, да и нарынке явно етсь необходимая программа
     
  14. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Код Pavia оказался более правильным, должно, кстати, быть так:
    Code (Text):
    1. while ((Status & 0x80) != 0x80);
    Мой код оказалось возвращает сначало какой-то левый байт в начале. То есть мой результат оказался смещенным на 1 байт.
     
  15. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Самое странное что эта проверка выдает что SMBus отключен, но при этом я спокойно его считываю. Вот мне тоже интересно получить ответ, как и на что он влияет. Да и правильно ли я адрес этого регистра получаю большой вопрос. VaStaNi можешь просветить? Если надо могу доработанную версию программы выложить, но пока без этого регистра
     
  16. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    Спасибо за такой развернутый ответ. Тогда можешь посказать где в спецификации можно найти адреса других устройств подключенных к SMBus? Я читал спецификацию 2.0, там в конце приведена табличка, но я в ней ничего не понял( там все в основном ссылается к предыдущим спецификациям. Да и мне интересны свободные адреса.. Не знаешь где их посмотреть?
     
  17. Pavia

    Pavia Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 17, 2003
    Messages:
    2,409
    Location:
    Fryazino
    drem1lin
    Не хоте вас прерывать, вы так мирно беседовали.

    В ICH9 контроллер не отключается только PCI CFG запрещается.

    ICH10 не смотрел.

    По поводу адресов. В спецификации ты их не найдешь. Каждый производитель волен выбрать адреса по своему усмотрению. Но в стандарте часть за резервирована. Адрес там записан в битовом формате. Нулевой бит не показан так как он за адрес не отвечает, а только за запись или чтение. А другие адреса можно узнать из различных спецификаций. Но записывают его в разных форматах некоторые нулевой бит пишут и ставят 0. А некоторые его не записывают.
    К примеру генератор частот имеет 1101 0010 = D2h а если без нулевого бита то имеем 69h
    А еще в материках PIIX4 для пентиумов вторых он был реализован с ошибкой. В результате код которой выше приводит к зависанию. Надо менять команду чтения.

    SPD используют адреса 50h, 51h, 52h, 53h без младшего бита.
    1010 000
    1010 001
    1010 010
    1010 011


    Теперь пройдемся по спецификации. Адреса без нулевого бита.
    0001 000 =10h - это адрес хоста или ведущего контроллера именно его мы и программируем этот адрес используют подчиненные устройства если хотят что-то от хоста. Используется в ARP протоколе.
    0001 100 =18h - это адрес тревоги. Если кому то из подчиненных устройств надо СРОЧНО передать сообщение он должен использовать адрес. Датчик должен вопить на этот адрес в случае перегрева.


    А вот сам датчик, а вернее Super IO висит на адресе
    0101 111 =2Fh - адрес не устоявшейся.

    1111 0XX признак 10-bit адреса мало кто поддерживает XX задает старшие биты адреса следующий байт оставшиеся.
    1111 1XX зарезервированы

    0001 001, 0001 010, 0001 011 для батареек можно встретить на ноутбуках и не только.

    Остальные адреса свободны. Хотя ряд хотят занять для IPMI.
     
  18. Protorus

    Protorus New Member

    Blog Posts:
    0
    Joined:
    Dec 30, 2009
    Messages:
    51
    Перечитал все посты несколько раз, и понял что ничего не понял..

    Для drem1lin (из твоего кода)
    Code (Text):
    1. test al,80  ;{данные пришли} <- здесь 80d = 0x50 = 01010000b
    2. jnz  loc_E932D
    Здесь вроде как у Pavia опечатка, т.к. по идее должно быть 0x80.
    Но если, вдруг, у Pavia это верно, то неверно у тебя.
    Чем отличается это
    Code (Text):
    1. while (Status & 0x80 != 0x80);
    и это
    Code (Text):
    1. while ((Status & 0x80) != 0x80);
    я не вижу.

    Я бит 7 (0x80) у себя не проверяю вообще, и вот почему.
    Во первых, на ICH8, он у меня никогда не устанавливается, может потому что используется протокол 010 = Byte Data. И твой код с while приведет у меня зависанию (странно что у тебя работает), код Pavia (в разных его вариантах) - нет, т.к. там используется счетчик.
    Во вторых, мой код так же используется на мосту ATI SB700, а здесь биты 7 - 5 вообще зарезервированы, а 4 - 0 такие же как на ICH8.
    Но, в любом случае результат чтения байта из eeprom будет не верный.

    Для Pavia (из твоего кода http://www.xlevel.ru/forum/YaBB.cgi?board=programming;action=display;num=1186920031)
    Code (Text):
    1. ...
    2. MOV  CX, 0800h       ; Время выполнения команды 0.0012207  секунд для передачи 40ит в 2 конца  32768 бит/с
    3. .Loop:
    4. NEWIODELAY
    5. IN   AL, DX
    6. TEST AL, 2
    7. JNZ  .ok
    8. LOOP .Loop  
    9. ADD  DX,2
    10. MOV  AL,2           ; Тайм аут истек, выставляем Kill бит
    11. OUT  DX,AL
    12. SUB  DX,2
    13. IN   AL, DX  
    14. .ok:
    15. NEWIODELAY
    16. OUT  DX, AL          ; Очищаем выставленные биты
    17. ADD  DX, 5           ; Data0
    18. IN   AL, DX
    19. ...
    Является ли этот код минимальным и достаточным для определения момента окончания чтения хостом по шине I2С? Нужно ли выставлять бит KILL, если истек тайм-аут (в выше приведенных здесь вариантах, например из сорцов биоса) это не делается?

    Для VaStaNi

    Спасибо за варианты по поводу правильности и дотошности подхода. Кое-что попробую в своем коде, в частности сброс статусов в цикле и проверку на все брошенные биты в статусе.
     
  19. Protorus

    Protorus New Member

    Blog Posts:
    0
    Joined:
    Dec 30, 2009
    Messages:
    51
    По поводу

    Динамическое назначение адреса утройства — основано на уникальном идентификаторе устройства UDID (Unique Device Identifier) — 128-битной структуре, содержащей описание возможностей, версию, идентификаторы производителя, устройства, подсистемы и специфическую информацию.
    Чтение идентификатора выполняется ведущим устройством ARP по протоколу блочного чтения по «дежурному» адресу SMBus.

    Так вот, адреса всех устройств подключенных к SMBus можно определить опросом этих устройств (перебором всех возможных адресов).
    А вот можно ли как-то запросить у хоста (ведущего устройства ведающим «переучетом» всех устройств на шине) этот индификатор для устройсва по конкретному адресу?
    А уж из него узнать производителя устройства и его идентификатор.
     
  20. drem1lin

    drem1lin Member

    Blog Posts:
    0
    Joined:
    Mar 17, 2009
    Messages:
    300
    В ICH9 контроллер не отключается только PCI CFG запрещается.



    Что означает, что PCI CFG запрещается? в ICH 6 вроде запрещается все. То есть по сути этот бит можно не смотреть?
    Спасибо за информацию по адресам.