Hardware/ATI/ADL.cs
author moel.mich
Tue, 09 Mar 2010 22:27:10 +0000
changeset 79 9cdbe1d8d12a
parent 12 a105b5eee02f
child 160 f7d962d25af4
permissions -rw-r--r--
Changed the CPU clock calculation. If no invariant TSC is available, then the max CPU clock is estimated at startup under load, otherwise an average over one second is used.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@1
    40
using System.Runtime.InteropServices;
moel@1
    41
moel@1
    42
namespace OpenHardwareMonitor.Hardware.ATI {
moel@1
    43
  
moel@1
    44
  [StructLayout(LayoutKind.Sequential)]
moel@1
    45
  public struct ADLAdapterInfo {
moel@1
    46
    public int Size;
moel@1
    47
    public int AdapterIndex;
moel@1
    48
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    49
    public string UDID;
moel@1
    50
    public int BusNumber;
moel@3
    51
    public int DeviceNumber;
moel@1
    52
    public int FunctionNumber;
moel@1
    53
    public int VendorID;
moel@1
    54
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    55
    public string AdapterName;
moel@1
    56
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    57
    public string DisplayName;
moel@1
    58
    public int Present;
moel@1
    59
    public int Exist;
moel@1
    60
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    61
    public string DriverPath;
moel@1
    62
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    63
    public string DriverPathExt;
moel@1
    64
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ADL.ADL_MAX_PATH)]
moel@1
    65
    public string PNPString;
moel@1
    66
    public int OSDisplayIndex;
moel@1
    67
  }
moel@1
    68
moel@1
    69
  [StructLayout(LayoutKind.Sequential)]
moel@1
    70
  public struct ADLPMActivity {
moel@1
    71
    public int Size;
moel@1
    72
    public int EngineClock;
moel@1
    73
    public int MemoryClock;
moel@1
    74
    public int Vddc;
moel@1
    75
    public int ActivityPercent;
moel@1
    76
    public int CurrentPerformanceLevel;
moel@1
    77
    public int CurrentBusSpeed;
moel@1
    78
    public int CurrentBusLanes;
moel@1
    79
    public int MaximumBusLanes;
moel@1
    80
    public int Reserved;
moel@1
    81
  }
moel@1
    82
moel@1
    83
  [StructLayout(LayoutKind.Sequential)]
moel@1
    84
  public struct ADLTemperature {
moel@1
    85
    public int Size;
moel@1
    86
    public int Temperature;
moel@1
    87
  }
moel@1
    88
moel@1
    89
  [StructLayout(LayoutKind.Sequential)]
moel@1
    90
  public struct ADLFanSpeedValue {
moel@1
    91
    public int Size;
moel@1
    92
    public int SpeedType;
moel@1
    93
    public int FanSpeed;
moel@1
    94
    public int Flags;
moel@1
    95
  }
moel@1
    96
moel@1
    97
  [StructLayout(LayoutKind.Sequential)]
moel@1
    98
  public struct ADLFanSpeedInfo {
moel@1
    99
    public int Size;
moel@1
   100
    public int Flags;
moel@1
   101
    public int MinPercent;
moel@1
   102
    public int MaxPercent;
moel@1
   103
    public int MinRPM;
moel@1
   104
    public int MaxRPM;
moel@1
   105
  }
moel@1
   106
moel@1
   107
  public class ADL {
moel@1
   108
    public const int ADL_MAX_PATH = 256;
moel@1
   109
    public const int ADL_MAX_ADAPTERS = 40;
moel@1
   110
    public const int ADL_MAX_DISPLAYS = 40;
moel@1
   111
    public const int ADL_MAX_DEVICENAME = 32;
moel@6
   112
    public const int ADL_OK = 0;
moel@15
   113
    public const int ADL_ERR = -1;
moel@1
   114
    public const int ADL_DRIVER_OK = 0;
moel@1
   115
    public const int ADL_MAX_GLSYNC_PORTS = 8;
moel@1
   116
    public const int ADL_MAX_GLSYNC_PORT_LEDS = 8;
moel@1
   117
    public const int ADL_MAX_NUM_DISPLAYMODES = 1024;
moel@1
   118
moel@1
   119
    public const int ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1;
moel@1
   120
    public const int ADL_DL_FANCTRL_SPEED_TYPE_RPM = 2;
moel@1
   121
moel@1
   122
    public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ = 1;
moel@1
   123
    public const int ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE = 2;
moel@1
   124
    public const int ADL_DL_FANCTRL_SUPPORTS_RPM_READ = 4;
moel@1
   125
    public const int ADL_DL_FANCTRL_SUPPORTS_RPM_WRITE = 8;
moel@1
   126
moel@3
   127
    public const int ATI_VENDOR_ID1 = 1002;
moel@3
   128
    public const int ATI_VENDOR_ID2 = 0x1002;
moel@3
   129
moel@1
   130
    private delegate int ADL_Main_Control_CreateDelegate(
moel@1
   131
      ADL_Main_Memory_AllocDelegate callback, int enumConnectedAdapters);
moel@1
   132
    private delegate int ADL_Adapter_AdapterInfo_GetDelegate(IntPtr info,
moel@1
   133
      int size);
moel@1
   134
moel@1
   135
    public delegate int ADL_Main_Control_DestroyDelegate();
moel@1
   136
    public delegate int ADL_Adapter_NumberOfAdapters_GetDelegate(
moel@1
   137
      ref int numAdapters);    
moel@1
   138
    public delegate int ADL_Adapter_ID_GetDelegate(int adapterIndex,
moel@1
   139
      out int adapterID);
moel@12
   140
    public delegate int ADL_Display_AdapterID_GetDelegate(int adapterIndex,
moel@12
   141
      out int adapterID);      	
moel@1
   142
    public delegate int ADL_Adapter_Active_GetDelegate(int adapterIndex,
moel@1
   143
      out int status);
moel@1
   144
    public delegate int ADL_Overdrive5_CurrentActivity_GetDelegate(
moel@1
   145
      int iAdapterIndex, ref ADLPMActivity activity);
moel@1
   146
    public delegate int ADL_Overdrive5_Temperature_GetDelegate(int adapterIndex,
moel@1
   147
        int thermalControllerIndex, ref ADLTemperature temperature);
moel@1
   148
    public delegate int ADL_Overdrive5_FanSpeed_GetDelegate(int adapterIndex,
moel@1
   149
        int thermalControllerIndex, ref	ADLFanSpeedValue fanSpeedValue);
moel@1
   150
    public delegate int ADL_Overdrive5_FanSpeedInfo_GetDelegate(
moel@1
   151
      int adapterIndex, int thermalControllerIndex,
moel@1
   152
      ref ADLFanSpeedInfo fanSpeedInfo);
moel@1
   153
moel@1
   154
    private static ADL_Main_Control_CreateDelegate
moel@1
   155
      _ADL_Main_Control_Create;
moel@1
   156
    private static ADL_Adapter_AdapterInfo_GetDelegate
moel@1
   157
      _ADL_Adapter_AdapterInfo_Get;
moel@1
   158
moel@12
   159
    public static ADL_Main_Control_DestroyDelegate 
moel@1
   160
      ADL_Main_Control_Destroy;
moel@1
   161
    public static ADL_Adapter_NumberOfAdapters_GetDelegate
moel@1
   162
      ADL_Adapter_NumberOfAdapters_Get;
moel@12
   163
    public static ADL_Adapter_ID_GetDelegate 
moel@12
   164
      _ADL_Adapter_ID_Get;
moel@12
   165
    public static ADL_Display_AdapterID_GetDelegate 
moel@12
   166
      _ADL_Display_AdapterID_Get;
moel@12
   167
    public static ADL_Adapter_Active_GetDelegate 
moel@1
   168
      ADL_Adapter_Active_Get;
moel@1
   169
    public static ADL_Overdrive5_CurrentActivity_GetDelegate
moel@1
   170
      ADL_Overdrive5_CurrentActivity_Get;
moel@1
   171
    public static ADL_Overdrive5_Temperature_GetDelegate
moel@1
   172
      ADL_Overdrive5_Temperature_Get;
moel@1
   173
    public static ADL_Overdrive5_FanSpeed_GetDelegate
moel@1
   174
      ADL_Overdrive5_FanSpeed_Get;
moel@1
   175
    public static ADL_Overdrive5_FanSpeedInfo_GetDelegate
moel@1
   176
      ADL_Overdrive5_FanSpeedInfo_Get;
moel@1
   177
moel@8
   178
    private static string dllName;
moel@1
   179
moel@1
   180
    private static void GetDelegate<T>(string entryPoint, out T newDelegate)
moel@1
   181
      where T : class 
moel@1
   182
    {
moel@8
   183
      DllImportAttribute attribute = new DllImportAttribute(dllName);
moel@1
   184
      attribute.CallingConvention = CallingConvention.StdCall;
moel@1
   185
      attribute.PreserveSig = true;
moel@1
   186
      attribute.EntryPoint = entryPoint;
moel@1
   187
      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@1
   188
    }
moel@1
   189
moel@8
   190
    private static void CreateDelegates(string name) {
moel@8
   191
      int p = (int)System.Environment.OSVersion.Platform;
moel@8
   192
      if ((p == 4) || (p == 128))
moel@8
   193
        dllName = name + ".so";
moel@8
   194
      else
moel@8
   195
        dllName = name + ".dll";
moel@8
   196
moel@8
   197
      GetDelegate("ADL_Main_Control_Create",
moel@8
   198
        out _ADL_Main_Control_Create);
moel@8
   199
      GetDelegate("ADL_Adapter_AdapterInfo_Get",
moel@8
   200
        out _ADL_Adapter_AdapterInfo_Get);
moel@8
   201
      GetDelegate("ADL_Main_Control_Destroy",
moel@8
   202
        out ADL_Main_Control_Destroy);
moel@8
   203
      GetDelegate("ADL_Adapter_NumberOfAdapters_Get",
moel@8
   204
        out ADL_Adapter_NumberOfAdapters_Get);
moel@8
   205
      GetDelegate("ADL_Adapter_ID_Get",
moel@12
   206
        out _ADL_Adapter_ID_Get);
moel@12
   207
      GetDelegate("ADL_Display_AdapterID_Get", 
moel@12
   208
        out _ADL_Display_AdapterID_Get);
moel@8
   209
      GetDelegate("ADL_Adapter_Active_Get",
moel@8
   210
        out ADL_Adapter_Active_Get);
moel@8
   211
      GetDelegate("ADL_Overdrive5_CurrentActivity_Get",
moel@8
   212
        out ADL_Overdrive5_CurrentActivity_Get);
moel@8
   213
      GetDelegate("ADL_Overdrive5_Temperature_Get",
moel@8
   214
        out ADL_Overdrive5_Temperature_Get);
moel@8
   215
      GetDelegate("ADL_Overdrive5_FanSpeed_Get",
moel@8
   216
        out ADL_Overdrive5_FanSpeed_Get);
moel@8
   217
      GetDelegate("ADL_Overdrive5_FanSpeedInfo_Get",
moel@8
   218
        out ADL_Overdrive5_FanSpeedInfo_Get);
moel@8
   219
    }
moel@8
   220
moel@1
   221
    static ADL() {
moel@8
   222
      CreateDelegates("atiadlxx");
moel@1
   223
    }
moel@1
   224
moel@1
   225
    private ADL() { }
moel@1
   226
moel@1
   227
    public static int ADL_Main_Control_Create(int enumConnectedAdapters) {
moel@8
   228
      try {
moel@8
   229
        return _ADL_Main_Control_Create(Main_Memory_Alloc,
moel@8
   230
          enumConnectedAdapters);
moel@8
   231
      } catch (DllNotFoundException) {
moel@8
   232
        CreateDelegates("atiadlxy");
moel@8
   233
        return _ADL_Main_Control_Create(Main_Memory_Alloc,
moel@8
   234
          enumConnectedAdapters);
moel@8
   235
      }
moel@1
   236
    }
moel@1
   237
moel@1
   238
    public static int ADL_Adapter_AdapterInfo_Get(ADLAdapterInfo[] info) {
moel@1
   239
      int elementSize = Marshal.SizeOf(typeof(ADLAdapterInfo));
moel@1
   240
      int size = info.Length * elementSize;
moel@1
   241
      IntPtr ptr = Marshal.AllocHGlobal(size);
moel@1
   242
      int result = _ADL_Adapter_AdapterInfo_Get(ptr, size);
moel@1
   243
      for (int i = 0; i < info.Length; i++)
moel@1
   244
        info[i] = (ADLAdapterInfo)
moel@1
   245
          Marshal.PtrToStructure((IntPtr)((long)ptr + i * elementSize),
moel@1
   246
          typeof(ADLAdapterInfo));
moel@1
   247
      Marshal.FreeHGlobal(ptr);
moel@1
   248
      return result;
moel@1
   249
    }
moel@1
   250
moel@12
   251
    public static int ADL_Adapter_ID_Get(int adapterIndex,
moel@12
   252
      out int adapterID) {
moel@12
   253
      try {
moel@12
   254
        return _ADL_Adapter_ID_Get(adapterIndex, out adapterID);
moel@12
   255
      } catch (EntryPointNotFoundException) {
moel@12
   256
        try {
moel@12
   257
          return _ADL_Display_AdapterID_Get(adapterIndex, out adapterID);
moel@12
   258
        } catch (EntryPointNotFoundException) {
moel@12
   259
          adapterID = 1;
moel@12
   260
          return ADL_OK;
moel@12
   261
        }
moel@12
   262
      }
moel@12
   263
    }
moel@12
   264
moel@1
   265
    private delegate IntPtr ADL_Main_Memory_AllocDelegate(int size);
moel@1
   266
moel@1
   267
    private static IntPtr Main_Memory_Alloc(int size) {
moel@1
   268
      return Marshal.AllocHGlobal(size);;
moel@1
   269
    }
moel@1
   270
moel@1
   271
    private static void Main_Memory_Free(IntPtr buffer) {
moel@1
   272
      if (IntPtr.Zero != buffer)
moel@1
   273
        Marshal.FreeHGlobal(buffer);
moel@1
   274
    }
moel@1
   275
  }
moel@1
   276
}