uGuru 数据手册¶
首先,我所了解的 uGuru 并非基于 Abit 提供的任何帮助、提示或数据手册。我所获得的 uGuru 数据是通过我“逆向工程”的微薄知识汇集而成的。顺便说一句,您可能已经注意到 uGuru 并非如 Abit 所声称的那样是他们自己开发的芯片。它实际上只是由华邦 (Winbond) 制造的微处理器 (uC) (W83L950D)。而且,阅读此特定微处理器的手册或向华邦发送邮件寻求帮助,都无法获得关于 uGuru 的任何有用数据,因为响应调用的是微处理器内部的程序。
Olle Sandberg <ollebull@gmail.com>,2005-05-25
本文件最初版本由 Olle Sandberg 完成,他承担了初期逆向工程的繁重工作。本版本已几乎完全重写,以提高清晰度,并扩展了写入支持和更多数据存储区的信息。写入支持再次由 Olle 逆向工程完成,而额外的数据存储区则由我逆向工程完成。我谨向 Olle 表示感谢,没有他的努力,本文件和 Linux 驱动程序将无法编写。
注意:由于缺乏规格说明,本文仅描述了 uGuru 的传感器部分,而不包括 CPU / 内存 / 等的电压和频率控制。
Hans de Goede <j.w.r.degoede@hhs.nl>,2006-01-28
检测¶
据了解,uGuru 始终位于并使用 (ISA) I/O 端口 0xE0 和 0xE4,因此我们无需扫描任何端口范围,只需检查这两个端口持有的值即可进行检测。我们将 0xE0 称为 CMD(命令端口),将 0xE4 称为 DATA,因为 Abit 使用这些名称来指代它们。
如果 DATA 端口值为 0x00 或 0x08,并且 CMD 端口值为 0x00 或 0xAC,则可能存在 uGuru。我们必须检查数据端口的两个不同值,因为重启后 uGuru 在此处将保持 0x00,但如果驱动程序被移除后又重新加载,数据端口将保持 0x08,稍后会详细介绍。
经过对 Linux 内核驱动程序的广泛测试,发现某些 uGuru 变体在 CMD 端口上会保持 0x00 而不是 0xAC,因此我们也必须检查 CMD 的两个不同值。在这些 uGuru 上,DATA 最初会保持 0x09,并且只有在首先读取 CMD 后才会保持 0x08,因此必须首先读取 CMD!
为确保 uGuru 确实存在,应进行一次或多次寄存器集的测试读取。
读取 / 写入¶
寻址¶
uGuru 具有多个不同的寻址级别。我们将第一个寻址级别称为“bank”(存储区)。一个存储区保存一个或多个传感器的数据。存储区中每个传感器的数据为一个或多个字节大小。
给定存储区的字节数是固定的,您应始终读取或写入相应数量的字节;读取/写入更多字节将会失败,而写入少于给定存储区字节数的结果是不确定的。
有关所有已知存储区地址、该存储区中的传感器数量、每个传感器的数据字节数以及这些字节的内容/含义,请参见下文。
尽管本文档和内核驱动程序都沿用了存储区内寻址的传感器术语,但这并非 100% 准确,例如在存储区 0x24 中,存储区内的寻址选择的是 PWM 输出而非传感器。
请注意,有些存储区同时具有读取地址和写入地址,uGuru 就是通过这种方式判断是对存储区进行读取还是写入操作的;因此,读取时应始终使用读取地址,写入时应使用写入地址。写入地址总是比读取地址大一 (1)。
uGuru 准备就绪¶
在您能够从 uGuru 读取或向其写入之前,必须首先将 uGuru 置于“准备就绪”模式。
要将 uGuru 置于准备就绪模式,首先向 DATA 写入 0x00,然后等待 DATA 保持 0x09,DATA 应在 250 个读取周期内读取到 0x09。
接下来必须读取 CMD,并且其值应为 0xAC;通常 CMD 第一次读取时就为 0xAC,但有时需要一段时间 CMD 才能保持 0xAC,因此需要多次读取(最多 50 次)。
读取 CMD 后,DATA 应保持 0x08,这意味着 uGuru 已准备好接收输入。如上所述,DATA 通常在第一次读取时保持 0x08,但并非总是如此。此步骤可以跳过,但如果 uGuru 尚未在 DATA 端口报告 0x08 而您继续写入存储区地址,则会发生什么情况尚不确定。
向 uGuru 发送存储区和传感器地址¶
首先,uGuru 必须处于如上所述的“准备就绪”模式,DATA 应保持 0x08,表明 uGuru 需要输入,在此情况下是存储区地址。
接下来将存储区地址写入 DATA。写入存储区地址后,等待 DATA 再次保持 0x08,表明它需要/已准备好接收更多输入(最多 250 次读取)。
一旦 DATA 再次保持 0x08,将传感器地址写入 CMD。
读取¶
首先,如上所述发送存储区和传感器地址。然后,对于您要读取的每个数据字节,等待 DATA 保持 0x01,这表明 uGuru 已准备好进行读取(最多 250 次读取),一旦 DATA 保持 0x01,则从 CMD 读取该字节。
一旦所有字节都被读取,数据将保持 0x09,但没有理由对此进行测试。请注意,字节数取决于存储区地址,参见上文和下文。
成功读取完成后,建议将 uGuru 重新置于准备就绪模式,以便它为下一个读取/写入周期做好准备。这样,如果您的程序/驱动程序被卸载后又重新加载,上述检测算法仍将起作用。
写入¶
首先,如上所述发送存储区和传感器地址。然后,对于您要写入的每个数据字节,等待 DATA 保持 0x00,这表明 uGuru 已准备好进行写入(最多 250 次读取),一旦 DATA 保持 0x00,则将该字节写入 CMD。
一旦所有字节都已写入,等待 DATA 保持 0x01(最多 250 次读取),不要问为什么会这样。
一旦 DATA 保持 0x01,读取 CMD,它现在应该保持 0xAC。
成功写入完成后,建议将 uGuru 重新置于准备就绪模式,以便它为下一个读取/写入周期做好准备。这样,如果您的程序/驱动程序被卸载后又重新加载,上述检测算法仍将起作用。
注意事项¶
在对 Linux 内核驱动程序进行更广泛的测试后,发现一些 uGuru 变体在写入存储区地址后,无法在 250 次读取内使 DATA 保持 0x08。对于这些版本,这种情况发生得很频繁,使用更大的超时时间也无济于事,它们只是离线一两秒钟,进行一些内部校准或其他操作。您的代码应该准备好处理这种情况,并且在此特定情况下,如果没有响应,只需暂停一段时间,然后重试。
地址映射¶
存储区 0x20 警报 (R)¶
该存储区包含 0 个传感器,即传感器地址被忽略(但必须写入),只需使用 0。存储区 0x20 包含 3 个字节。
- 字节 0
此字节保存传感器存储区 1 中传感器 0-7 的警报标志,其中位 0 对应传感器 0,位 1 对应传感器 1,依此类推。
- 字节 1
此字节保存传感器存储区 1 中传感器 8-15 的警报标志,其中位 0 对应传感器 8,位 1 对应传感器 9,依此类推。
- 字节 2
此字节保存传感器存储区 2 中传感器 0-5 的警报标志,其中位 0 对应传感器 0,位 1 对应传感器 1,依此类推。
存储区 0x21 传感器存储区 1 值 / 读数 (R)¶
该存储区包含 16 个传感器,每个传感器包含 1 个字节。迄今为止,已知以下传感器在所有主板上都可用:
传感器 0 CPU 温度
传感器 1 系统温度
传感器 3 CPU 核心电压
传感器 4 DDR 电压
传感器 10 DDR Vtt 电压
传感器 15 PWM 温度
- 字节 0
此字节保存传感器的读数。存储区 1 中的传感器可以是电压传感器,也可以是温度传感器,这取决于主板。然而,uGuru 似乎知道(已编程)连接的是哪种传感器,详见传感器存储区 1 设置说明。
电压传感器使用线性刻度,读数 0 对应 0 伏特,读数 255 对应 3494 毫伏。然而,更高电压的传感器通过分压电路连接。目前已知使用的分压电路产生的范围有:0-4361mV、0-6248mV 或 0-14510mV。3.3 伏电源使用 0-4361mV 范围,5 伏电源使用 0-6248mV,12 伏电源使用 0-14510mV。
温度传感器也使用线性刻度,读数 0 对应 0 摄氏度,读数 255 对应 255 摄氏度。
存储区 0x22 传感器存储区 1 设置 (R) 和 存储区 0x23 传感器存储区 1 设置 (W)¶
这些存储区包含 16 个传感器,每个传感器包含 3 个字节。每组 3 个字节包含存储区 0x21 中具有相同传感器地址的传感器的设置。
- 字节 0
所选传感器的警报行为。1 表示启用所述行为。
- 位 0
如果测量温度超过警告阈值,则发出警报 (RW) [1]
- 位 1
如果测量电压超过最大阈值,则发出警报 (RW) [2]
- 位 2
如果测量电压低于最小阈值,则发出警报 (RW) [2]
- 位 3
如果警报则蜂鸣 (RW)
- 位 4
如果警报原因是测量温度超过警告阈值,则为 1 (R)
- 位 5
如果警报原因是测量电压超过最大阈值,则为 1 (R)
- 位 6
如果警报原因是测量电压低于最小阈值,则为 1 (R)
- 位 7
电压传感器:如果警报持续超过 4 秒则关机 (RW)
温度传感器:如果温度超过关机阈值则关机 (RW)
- 字节 1
温度传感器:警告阈值(按存储区 0x21 比例)
电压传感器:最小阈值(按存储区 0x21 比例)
- 字节 2
温度传感器:关机阈值(按存储区 0x21 比例)
电压传感器:最大阈值(按存储区 0x21 比例)
存储区 0x24 风扇 PWM 输出 (R) 和 存储区 0x25 风扇 PWM 输出 (W)¶
- 这些存储区包含 3 个“传感器”,每个传感器包含 5 个字节。
传感器 0 通常控制 CPU 风扇
传感器 1 通常控制北桥 (NB)(或单芯片组)风扇
传感器 2 通常控制系统风扇
- 字节 0
标志 0x80 用于启用控制,禁用时风扇以 100% 运行。存储区 0x21 中的低半字节(温度)传感器地址用于控制。
- 字节 1
0-255 = 0-12V (线性),指定风扇在低于低阈值温度(在字节 3 中指定)时转动的电压
- 字节 2
0-255 = 0-12V (线性),指定风扇在高于高阈值温度(在字节 4 中指定)时转动的电压
- 字节 3
低阈值温度(按存储区 0x21 比例)
- 字节 4
高阈值温度(按存储区 0x21 比例)
存储区 0x26 传感器存储区 2 值 / 读数 (R)¶
该存储区包含 6 个传感器(据我所知),每个传感器包含 1 个字节。
- 迄今为止,已知以下传感器在所有主板上都可用:
传感器 0:CPU 风扇速度
传感器 1:北桥 (NB)(或单芯片组)风扇速度
传感器 2:系统风扇速度
- 字节 0
此字节保存传感器的读数。0-255 = 0-15300 (线性)
存储区 0x27 传感器存储区 2 设置 (R) 和 存储区 0x28 传感器存储区 2 设置 (W)¶
这些存储区包含 6 个传感器(据我所知),每个传感器包含 2 个字节。
- 字节 0
所选传感器的警报行为。1 表示启用所述行为。
- 位 0
如果测量转速低于最小阈值,则发出警报 (RW)
- 位 3
如果警报则蜂鸣 (RW)
- 位 7
如果警报持续超过 4 秒则关机 (RW)
- 字节 1
最小阈值(按存储区 0x26 比例)
给勇于探索者的警告¶
在此提醒那些想要尝试并找出电压/时钟编程方法的人:我曾尝试使用传感器存储区 (0x20-0x28) 的读取代码来读取(且仅读取)存储区 0-0x30,结果导致电压被 _永久性_ 重新编程。幸运的是,我的传感器部分已配置为在任何超出规格的电压下关闭系统,这可能保护了我的电脑(重启后我设法立即进入 BIOS 并重新加载了默认设置)。这可能意味着非传感器部分的读写周期与传感器部分的读写周期不同。