Можете ли вы собрать воедино следующие подсказки, которые помогут мне определить температуру из микросхемы Winbond W83793? - PullRequest
5 голосов
/ 22 августа 2011

Я пытаюсь получить OpenHardwareMonitor для чтения данных о температуре из чипа Winbond W83793 на моей материнской плате Supermicro X7DWA.Проблема в том, что у меня нет никакого опыта программирования на низком уровне, и доступные документы в Интернете, кажется, не достаточны для объяснения того, как получить доступ к температурам.

Однако за месяц, в течение которого я работал над этой проблемой, я обнаружил несколько значений и низкоуровневых методов, которые могут стать ключом к решению моей проблемы.Мне просто нужно выяснить, как их использовать, чтобы получить то, что я хочу.Вот где я обращаюсь к вам, потому что вы, в отличие от меня, можете понять, что означает эта информация и как ее применять.Я уже сделал свою большую долю возни, в результате чего много синих экранов и перезагрузок компьютера.Хватит гадать, мне нужно собрать эти ключи вместе.Вот что я знаю до сих пор:

  1. Для чтения из чипа мне как-то понадобится доступ к SMBus, потому что именно так получают программы мониторинга, такие как CPUID HWMonitorинформация.OpenHardwareMonitor, насколько я знаю, не имеет никакого кода для доступа к SMBus, поэтому он может не считывать данные с чипа.Однако OpenHardwareMonitor имеет следующие методы, включенные в класс Ring0 , который он использует для доступа к информации из других чипов.Возможно, я смогу использовать эти методы в своих интересах:

    void Ring0.WriteIOPort(uint port, byte value);
    byte Ring0.ReadIOPort(uint port);
    
  2. Помимо прочих сведений, HWMonitor сообщает мне следующую информацию о микросхеме Winbond W83793 при сохранении отчета:

    Область регистра: SMBus, базовый адрес = 0x01100

    Запрос SMBus: канал 0x0, адрес 0x2F

    Похоже, это важные значения, но яне знаю точно, что они имеют в виду, и как я могу использовать их в сочетании с методами Ring0 выше.Хм ... так много подсказок.Другие значения, которые HWMonitor показывает мне, - это фактические напряжения, температуры и скорости вращения вентиляторов, а также массив шестнадцатеричных значений, представляющих данные из какого-то места на чипе, которые я воспроизведу здесь, если вы захотите посмотреть на них.

  3. Наконец, в листе данных W83793, на странице 53 (если у вас есть открытый документ), здесь указаны адреса в шестнадцатеричном формате с температурами, которые я хотел бы прочитать (я полагаю):

    Считывание TD1 - адрес банка 0 1C

    Считывание TD2 - адрес банка 0 1D

    Считывание TD3 - адрес банка 0 1E

    Считывание TD4 - адрес банка 01F

    Считывание младших битов - Банк 0 Адрес 22 * ​​1041 *

    TR1 Считывание - Банк 0 Адрес 20

    TR2 Считывание - Банк 0 Адрес 21

Это все, что я знаю до сих пор.OpenHardwareMonitor, чип W83793 и код Ring0 доступны по ссылкам, указанным выше.Как я уже говорил ранее, я занимался этим уже месяц, и я пока не смог разгадать эту загадку.Я надеюсь, что вы можете мне помочь.Вся эта информация может показаться немного пугающей, но я уверен, что это будет иметь смысл для кого-то с небольшим опытом программирования низкого уровня.

Чтобы подвести итог моего вопроса, используйте подсказки, предоставленные выше, чтобы выяснить, как получитьOpenHardwareMonitor для считывания температуры из чипа W83793.Мне не нужны подробности о создании чипа в OpenHardwareMonitor.У меня уже есть готовый класс.Мне просто нужны последовательность и формат для записи команд Ring0, если это то, что мне нужно сделать.

РЕДАКТИРОВАТЬ: Я нашел еще немного информации.Я распечатал отчет об устройстве SMBus от HWMonitor, и, помимо прочего, я получил эту строку, включенную сюда, потому что там написано 0x2F:

Устройство SMB: I / O = 0x1100, адрес 0x2F, канал = 0

Это должно означать, что мне нужно как-то объединить адреса ввода / вывода с адресом чипа, который, кажется, 0x2F. Я попытался сложить их вместе, но затем я получил все значения температуры 255, так что это было неправильное предположение.

Ответы [ 2 ]

4 голосов
/ 22 августа 2011

Методы ввода-вывода - это то, что вам нужно.На аппаратном обеспечении x86 фактически существует два пула адресов, а не один.Один предназначен для памяти, на него ссылается чип при чтении инструкций и имеет тысячи полезных и удобных методов доступа.Другой предназначен для адресации внешних микросхем и имеет очень ограниченный и относительно медленный набор операций чтения и записи.Методы, которые вы определили, дают вам доступ ко второй области.

Поскольку регистры, которые вы хотите прочитать, находятся в банке 0, то сначала вам нужно выбрать банк 0 на чипе, как показано на странице 12.На диаграмме в разделе 8.1.2.1 вам нужно написать 0x80 по адресу 00. На основании вашего отчета, что базовый адрес для чипа - 0x01100, это должно означать запись от 0x80 до 0x01100 через WriteIOPort.

.чтобы вы могли читать нужные значения через ReadIOPort из 0x01100 + 0x1c, 0x01100 + 0x1d и т. д.

У меня не было времени полностью переварить документ, на который вы ссылаетесь, но эторазумные догадки.В некоторых чипах есть немного более сложная процедура, в которой вы должны записать значение, а затем подтвердить результат, но я не вижу ничего подобного в документации.Вам также следует опасаться многозадачности - если ваш код прерывается между установкой банка 0 и чтением соответствующих регистров, то какой-то промежуточный процесс может установить другой банк, в результате чего значения, которые вы читаете, будут произвольными другими значениями.Я предполагаю, что OpenHardwareMonitor имеет какой-то механизм, чтобы справиться с этим, но стоит помнить, если вы попробуете быструю реализацию чисто в пользовательском пространстве и иногда получите странные результаты.

2 голосов
/ 25 августа 2011

В конце концов, автор OpenHardwareMonitor любезно помог мне, и теперь я могу считать температуру из своего чипа. В то время как полное решение этой проблемы немного сложнее и все еще за пределами моего понимания, здесь есть базовое чтение и запись с использованием класса Ring0 для всех, кто заинтересован. Обратите внимание, что это относится к моей машине и чипу. Для вас базовый адрес и адрес подчиненного устройства могут различаться, но вы можете найти их с помощью CPUID HWMonitor, распечатав отчет.

Во-первых, вот константы, которые были использованы:

private const int   BASE_ADDRESS    = 0x1100;
private const uint  SLAVE_ADDRESS   = 0X2F; // as we figured out already
private const byte  HOST_STAT_REG   = 0;    // host status register
private const byte  HOST_BUSY       = 1;    
private const byte  HOST_CTRL_REG   = 2;    // host control register
private const byte  HOST_CMD_REG    = 3;    // host command register
private const byte  T_SLAVE_ADR_REG = 4;    // transmit slave address register
private const byte  HOST_DATA_0_REG = 5;  
private const byte  BYTE_DATA_COMM  = 0x08; // byte data command
private const byte  START_COMM      = 0x40; // start command
private const byte  READ            = 1;
private const byte  WRITE           = 0;

Далее приведен базовый код для считывания определенного байта из регистра на чипе:

// first wait until ready
byte status;
do
{
  status = Ring0.ReadIoPort(BASE_ADDRESS + HOST_STAT_REG);
} while ((status & HOST_BUSY) > 0);
if ((status & 0x1E) != 0)
{
  Ring0.WriteIoPort(BASE_ADDRESS + HOST_STAT_REG, status);
}

// now get the value
Ring0.WriteIoPort(BASE_ADDRESS + HOST_DATA_0_REG, 0);
Ring0.WriteIoPort(BASE_ADDRESS + HOST_COMM_REG, theRegister)
Ring0.WriteIoPort(BASE_ADDRESS + T_SLAVE_ADR_REG, 
            (byte)((SLAVE_ADDRESS << 1) | READ));
Ring0.WriteIoPort(BASE_ADDRESS + HOST_CTRL_REG,
            START_COMM | BYTE_DATA_COMM);
Ring0.ReadIoPort(BASE_ADDRESS + HOST_DATA_0_REGISTER); // this returns the value

// now wait for it to end
while ((Ring0.ReadIoPort(BASE_ADDRESS + HOST_STAT_REG) & HOST_BUSY) > 0) {}

Хотя я не очень хорошо понимаю это, это может послужить приблизительным ориентиром для кого-то с более низким уровнем опыта, чем я, у которого аналогичная проблема.

...