Added support for reading the TAMG ACPI table on Gigabyte mainboards. Fixed a small problem with HDD/SSD names (0 chars are trimmed now as well).

This commit is contained in:
Michael Möller
2011-07-07 20:41:09 +00:00
parent ae81e8f22c
commit 938263fef2
6 changed files with 308 additions and 4 deletions
+121
View File
@@ -0,0 +1,121 @@
/*
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.
The Original Code is the Open Hardware Monitor code.
The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2011
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace OpenHardwareMonitor.Hardware {
internal static class FirmwareTable {
public static byte[] GetTable(Provider provider, string table) {
int id = table[3] << 24 | table[2] << 16 | table[1] << 8 | table[0];
return GetTable(provider, id);
}
public static byte[] GetTable(Provider provider, int table) {
int size;
try {
size = NativeMethods.GetSystemFirmwareTable(provider, table,
IntPtr.Zero, 0);
} catch (DllNotFoundException) { return null; }
catch (EntryPointNotFoundException) { return null; }
if (size <= 0)
return null;
IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
NativeMethods.GetSystemFirmwareTable(provider, table, nativeBuffer, size);
if (Marshal.GetLastWin32Error() != 0)
return null;
byte[] buffer = new byte[size];
Marshal.Copy(nativeBuffer, buffer, 0, size);
Marshal.FreeHGlobal(nativeBuffer);
return buffer;
}
public static string[] EnumerateTables(Provider provider) {
int size;
try {
size = NativeMethods.EnumSystemFirmwareTables(
provider, IntPtr.Zero, 0);
} catch (DllNotFoundException) { return null; }
catch (EntryPointNotFoundException) { return null; }
IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
NativeMethods.EnumSystemFirmwareTables(
provider, nativeBuffer, size);
byte[] buffer = new byte[size];
Marshal.Copy(nativeBuffer, buffer, 0, size);
Marshal.FreeHGlobal(nativeBuffer);
string[] result = new string[size / 4];
for (int i = 0; i < result.Length; i++)
result[i] = Encoding.ASCII.GetString(buffer, 4 * i, 4);
return result;
}
public enum Provider : int {
ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I',
FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M',
RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B'
}
private static class NativeMethods {
private const string KERNEL = "kernel32.dll";
[DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
SetLastError = true)]
public static extern int EnumSystemFirmwareTables(
Provider firmwareTableProviderSignature,
IntPtr firmwareTableBuffer, int bufferSize);
[DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
SetLastError = true)]
public static extern int GetSystemFirmwareTable(
Provider firmwareTableProviderSignature,
int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize);
}
}
}
+2 -2
View File
@@ -16,7 +16,7 @@
The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2009-2010
Portions created by the Initial Developer are Copyright (C) 2009-2011
the Initial Developer. All Rights Reserved.
Contributor(s): Paul Werelds
@@ -462,7 +462,7 @@ namespace OpenHardwareMonitor.Hardware.HDD {
chars[i + 1] = (char)bytes[i];
}
return new string(chars).Trim();
return new string(chars).Trim(new char[] {' ', '\0'});
}
}
+174
View File
@@ -0,0 +1,174 @@
/*
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.
The Original Code is the Open Hardware Monitor code.
The Initial Developer of the Original Code is
Michael Möller <m.moeller@gmx.ch>.
Portions created by the Initial Developer are Copyright (C) 2011
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text;
namespace OpenHardwareMonitor.Hardware.Mainboard {
internal class GigabyteTAMG {
private byte[] table;
private Sensor[] sensors;
private struct Sensor {
public string Name;
public SensorType Type;
public int Channel;
public float Value;
}
private enum SensorType {
Voltage = 1,
Temperature = 2,
Fan = 4,
Case = 8,
}
public GigabyteTAMG(byte[] table) {
if (table == null)
throw new ArgumentNullException("table");
this.table = table;
int index = IndexOf(table, Encoding.ASCII.GetBytes("$HEALTH$"), 0);
if (index >= 0) {
index += 8;
using (MemoryStream m =
new MemoryStream(table, index, table.Length - index))
using (BinaryReader r = new BinaryReader(m)) {
try {
r.ReadInt64();
int count = r.ReadInt32();
r.ReadInt64();
r.ReadInt32();
sensors = new Sensor[count];
for (int i = 0; i < sensors.Length; i++) {
sensors[i].Name = new string(r.ReadChars(32)).TrimEnd('\0');
sensors[i].Type = (SensorType)r.ReadByte();
sensors[i].Channel = r.ReadInt16();
sensors[i].Channel |= r.ReadByte() << 24;
r.ReadInt64();
int value = r.ReadInt32();
switch (sensors[i].Type) {
case SensorType.Voltage:
sensors[i].Value = 1e-3f * value; break;
default:
sensors[i].Value = value; break;
}
r.ReadInt64();
}
} catch (IOException) { sensors = new Sensor[0]; }
}
} else {
sensors = new Sensor[0];
}
}
public static int IndexOf(byte[] array, byte[] pattern, int startIndex) {
if (array == null || pattern == null || pattern.Length > array.Length)
return -1;
for (int i = startIndex; i < array.Length - pattern.Length; i++) {
bool found = true;
for (int j = 0; j < pattern.Length; j++) {
if (array[i + j] != pattern[j]) {
found = false;
break;
}
}
if (found)
return i;
}
return -1;
}
private string GetCompressedAndEncodedTable() {
string base64;
using (MemoryStream m = new MemoryStream()) {
using (GZipStream c = new GZipStream(m, CompressionMode.Compress)) {
c.Write(table, 0, table.Length);
}
base64 = Convert.ToBase64String(m.ToArray());
}
StringBuilder r = new StringBuilder();
for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
r.Append(" ");
for (int j = 0; j < 0x40; j++) {
int index = (i << 6) | j;
if (index < base64.Length) {
r.Append(base64[index]);
}
}
r.AppendLine();
}
return r.ToString();
}
public string GetReport() {
StringBuilder r = new StringBuilder();
if (sensors.Length > 0) {
r.AppendLine("Gigabyte TAMG Sensors");
r.AppendLine();
foreach (Sensor sensor in sensors) {
r.AppendFormat(" {0,-10}: {1,8:G6} ({2})", sensor.Name, sensor.Value,
sensor.Type);
r.AppendLine();
}
r.AppendLine();
}
if (table.Length > 0) {
r.AppendLine("Gigabyte TAMG Table");
r.AppendLine();
r.Append(GetCompressedAndEncodedTable());
r.AppendLine();
}
return r.ToString();
}
}
}
+7
View File
@@ -124,6 +124,13 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
if (lpcio != null)
r.Append(lpcio.GetReport());
byte[] table =
FirmwareTable.GetTable(FirmwareTable.Provider.ACPI, "TAMG");
if (table != null) {
GigabyteTAMG tamg = new GigabyteTAMG(table);
r.Append(tamg.GetReport());
}
return r.ToString();
}
+2
View File
@@ -61,6 +61,7 @@
<Compile Include="Hardware\ATI\ATIGPU.cs" />
<Compile Include="Hardware\ATI\ATIGroup.cs" />
<Compile Include="Hardware\Control.cs" />
<Compile Include="Hardware\FirmwareTable.cs" />
<Compile Include="Hardware\IControl.cs" />
<Compile Include="Hardware\IOControlCode.cs" />
<Compile Include="Hardware\Computer.cs" />
@@ -73,6 +74,7 @@
<Compile Include="Hardware\CPU\CPULoad.cs" />
<Compile Include="Hardware\CPU\IntelCPU.cs" />
<Compile Include="Hardware\LPC\NCT677X.cs" />
<Compile Include="Hardware\Mainboard\GigabyteTAMG.cs" />
<Compile Include="Hardware\Opcode.cs" />
<Compile Include="Hardware\Ring0.cs" />
<Compile Include="Hardware\KernelDriver.cs" />
+2 -2
View File
@@ -37,5 +37,5 @@
using System.Reflection;
[assembly: AssemblyVersion("0.3.2.4")]
[assembly: AssemblyInformationalVersion("0.3.2.4 Alpha")]
[assembly: AssemblyVersion("0.3.2.5")]
[assembly: AssemblyInformationalVersion("0.3.2.5 Alpha")]