Hardware/LPC/LPCGroup.cs
author moel.mich
Fri, 12 Feb 2010 22:46:31 +0000 (2010-02-12)
changeset 42 47385d4fc990
parent 31 c4d1fb76a9e1
child 54 f940fe2a7c2b
permissions -rw-r--r--
Tray sensor display default color is black and color can be changed now. Fixed CPU load reading for AMD CPUs and added additional misc device for AMD core temperature reading.
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.Text;
moel@1
    41
using System.Threading;
moel@1
    42
moel@1
    43
namespace OpenHardwareMonitor.Hardware.LPC {
moel@1
    44
  public class LPCGroup : IGroup {
moel@1
    45
    private List<IHardware> hardware = new List<IHardware>();
moel@1
    46
moel@1
    47
    private Chip chip = Chip.Unknown;
moel@1
    48
moel@1
    49
    // I/O Ports
moel@7
    50
    private ushort[] REGISTER_PORTS = new ushort[] { 0x2e, 0x4e };
moel@7
    51
    private ushort[] VALUE_PORTS = new ushort[] { 0x2f, 0x4f };
moel@7
    52
moel@7
    53
    private ushort registerPort;
moel@7
    54
    private ushort valuePort;
moel@1
    55
moel@1
    56
    // Registers
moel@1
    57
    private const byte CONFIGURATION_CONTROL_REGISTER = 0x02;
moel@1
    58
    private const byte DEVCIE_SELECT_REGISTER = 0x07;
moel@1
    59
    private const byte CHIP_ID_REGISTER = 0x20;
moel@1
    60
    private const byte CHIP_REVISION_REGISTER = 0x21;
moel@7
    61
    private const byte BASE_ADDRESS_REGISTER = 0x60;
moel@1
    62
moel@7
    63
    private byte ReadByte(byte register) {
moel@7
    64
      WinRing0.WriteIoPortByte(registerPort, register);
moel@7
    65
      return WinRing0.ReadIoPortByte(valuePort);
moel@13
    66
    } 
moel@1
    67
moel@7
    68
    private ushort ReadWord(byte register) {
moel@7
    69
      return (ushort)((ReadByte(register) << 8) | 
moel@7
    70
        ReadByte((byte)(register + 1)));
moel@1
    71
    }
moel@1
    72
moel@7
    73
    private void Select(byte logicalDeviceNumber) {
moel@7
    74
      WinRing0.WriteIoPortByte(registerPort, DEVCIE_SELECT_REGISTER);
moel@7
    75
      WinRing0.WriteIoPortByte(valuePort, logicalDeviceNumber);
moel@1
    76
    }
moel@1
    77
moel@34
    78
    // ITE
moel@7
    79
    private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;    
moel@1
    80
moel@7
    81
    private void IT87Enter() {
moel@7
    82
      WinRing0.WriteIoPortByte(registerPort, 0x87);
moel@7
    83
      WinRing0.WriteIoPortByte(registerPort, 0x01);
moel@7
    84
      WinRing0.WriteIoPortByte(registerPort, 0x55);
moel@7
    85
      WinRing0.WriteIoPortByte(registerPort, 0x55);
moel@1
    86
    }
moel@1
    87
moel@7
    88
    internal void IT87Exit() {
moel@7
    89
      WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
moel@7
    90
      WinRing0.WriteIoPortByte(valuePort, 0x02);
moel@1
    91
    }
moel@1
    92
moel@7
    93
    // Winbond, Fintek
moel@7
    94
    private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
moel@7
    95
    private const ushort FINTEK_VENDOR_ID = 0x1934;
moel@7
    96
moel@34
    97
    private const byte WINBOND_HARDWARE_MONITOR_LDN = 0x0B;
moel@16
    98
moel@16
    99
    private const byte F71858_HARDWARE_MONITOR_LDN = 0x02;
moel@16
   100
    private const byte FINTEK_HARDWARE_MONITOR_LDN = 0x04;
moel@7
   101
moel@7
   102
    private void WinbondFintekEnter() {
moel@7
   103
      WinRing0.WriteIoPortByte(registerPort, 0x87);
moel@7
   104
      WinRing0.WriteIoPortByte(registerPort, 0x87);
moel@1
   105
    }
moel@1
   106
moel@7
   107
    private void WinbondFintekExit() {
moel@7
   108
      WinRing0.WriteIoPortByte(registerPort, 0xAA);      
moel@1
   109
    }
moel@1
   110
moel@1
   111
    public LPCGroup() {
moel@1
   112
      if (!WinRing0.IsAvailable)
moel@1
   113
        return;
moel@1
   114
moel@7
   115
      for (int i = 0; i < REGISTER_PORTS.Length; i++) {
moel@7
   116
        registerPort = REGISTER_PORTS[i];
moel@7
   117
        valuePort = VALUE_PORTS[i];
moel@1
   118
moel@7
   119
        WinbondFintekEnter();
moel@1
   120
moel@16
   121
        byte logicalDeviceNumber;
moel@7
   122
        byte id = ReadByte(CHIP_ID_REGISTER);
moel@7
   123
        byte revision = ReadByte(CHIP_REVISION_REGISTER);
moel@34
   124
        chip = Chip.Unknown;
moel@34
   125
        logicalDeviceNumber = 0;
moel@7
   126
        switch (id) {
moel@16
   127
          case 0x05:
moel@16
   128
            switch (revision) {
moel@16
   129
              case 0x41:
moel@16
   130
                chip = Chip.F71882;
moel@16
   131
                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
moel@34
   132
                break;              
moel@16
   133
            } break;
moel@16
   134
          case 0x06:
moel@16
   135
            switch (revision) {             
moel@16
   136
              case 0x01:
moel@16
   137
                chip = Chip.F71862;
moel@16
   138
                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
moel@34
   139
                break;              
moel@16
   140
            } break;
moel@16
   141
          case 0x07:
moel@16
   142
            switch (revision) {
moel@16
   143
              case 0x23:
moel@16
   144
                chip = Chip.F71889;
moel@16
   145
                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
moel@34
   146
                break;              
moel@16
   147
            } break;
moel@16
   148
          case 0x08:
moel@16
   149
            switch (revision) {
moel@16
   150
              case 0x14:
moel@16
   151
                chip = Chip.F71869;
moel@16
   152
                logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
moel@34
   153
                break;              
moel@16
   154
            } break;
moel@31
   155
          case 0x52:
moel@31
   156
            switch (revision) {
moel@31
   157
              case 0x17:
moel@31
   158
              case 0x3A:
moel@31
   159
                chip = Chip.W83627HF;
moel@34
   160
                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
moel@34
   161
                break;             
moel@34
   162
            } break;
moel@34
   163
          case 0x88:
moel@34
   164
            switch (revision & 0xF0) {
moel@34
   165
              case 0x60:
moel@34
   166
                chip = Chip.W83627EHF;
moel@34
   167
                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
moel@31
   168
                break;
moel@31
   169
            } break;
moel@7
   170
          case 0xA0:
moel@7
   171
            switch (revision & 0xF0) {
moel@7
   172
              case 0x20: 
moel@7
   173
                chip = Chip.W83627DHG;
moel@34
   174
                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;  
moel@34
   175
                break;             
moel@34
   176
            } break;
moel@34
   177
          case 0xA5:
moel@34
   178
            switch (revision & 0xF0) {
moel@34
   179
              case 0x10:
moel@34
   180
                chip = Chip.W83667HG;
moel@34
   181
                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
moel@7
   182
                break;
moel@19
   183
            } break;
moel@19
   184
          case 0xB0:
moel@19
   185
            switch (revision & 0xF0) {
moel@19
   186
              case 0x70:
moel@19
   187
                chip = Chip.W83627DHGP;
moel@34
   188
                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
moel@34
   189
                break;             
moel@34
   190
            } break;
moel@34
   191
          case 0xB3:
moel@34
   192
            switch (revision & 0xF0) {
moel@34
   193
              case 0x50:
moel@34
   194
                chip = Chip.W83667HGB;
moel@34
   195
                logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
moel@19
   196
                break;
moel@34
   197
            } break; 
moel@7
   198
        }
moel@7
   199
        if (chip != Chip.Unknown) {
moel@1
   200
moel@16
   201
          Select(logicalDeviceNumber);
moel@7
   202
          ushort address = ReadWord(BASE_ADDRESS_REGISTER);
moel@7
   203
          Thread.Sleep(1);
moel@7
   204
          ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
moel@1
   205
moel@7
   206
          ushort vendorID = 0;
moel@16
   207
          if (chip == Chip.F71862 || chip == Chip.F71882 || chip == Chip.F71889)
moel@7
   208
            vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
moel@1
   209
moel@7
   210
          WinbondFintekExit();
moel@1
   211
moel@34
   212
          if (address != verify || address < 0x100 || (address & 0xF007) != 0)
moel@7
   213
            return;
moel@7
   214
          
moel@7
   215
          switch (chip) {
moel@7
   216
            case Chip.W83627DHG:
moel@19
   217
            case Chip.W83627DHGP:
moel@34
   218
            case Chip.W83627EHF:
moel@31
   219
            case Chip.W83627HF:
moel@34
   220
            case Chip.W83667HG:
moel@34
   221
            case Chip.W83667HGB:
moel@34
   222
              W836XX w836XX = new W836XX(chip, revision, address);
moel@34
   223
              if (w836XX.IsAvailable)
moel@34
   224
                hardware.Add(w836XX);
moel@7
   225
              break;
moel@16
   226
            case Chip.F71862:
moel@16
   227
            case Chip.F71882:
moel@16
   228
            case Chip.F71889: 
moel@7
   229
              if (vendorID == FINTEK_VENDOR_ID)
moel@16
   230
                hardware.Add(new F718XX(chip, address));
moel@16
   231
              break;
moel@16
   232
            case Chip.F71869:
moel@16
   233
              hardware.Add(new F718XX(chip, address));
moel@7
   234
              break;
moel@7
   235
            default: break;
moel@7
   236
          }
moel@7
   237
          
moel@7
   238
          return;
moel@7
   239
        }
moel@1
   240
moel@7
   241
        IT87Enter();
moel@1
   242
moel@7
   243
        switch (ReadWord(CHIP_ID_REGISTER)) {
moel@21
   244
          case 0x8716: chip = Chip.IT8716F; break;
moel@21
   245
          case 0x8718: chip = Chip.IT8718F; break;
moel@21
   246
          case 0x8720: chip = Chip.IT8720F; break;
moel@21
   247
          case 0x8726: chip = Chip.IT8726F; break;
moel@7
   248
          default: chip = Chip.Unknown; break;
moel@7
   249
        }
moel@7
   250
moel@7
   251
        if (chip != Chip.Unknown) {
moel@7
   252
          Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
moel@7
   253
          ushort address = ReadWord(BASE_ADDRESS_REGISTER);
moel@7
   254
          Thread.Sleep(1);
moel@7
   255
          ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
moel@7
   256
moel@7
   257
          IT87Exit();
moel@7
   258
moel@34
   259
          if (address != verify || address < 0x100 || (address & 0xF007) != 0)
moel@7
   260
            return;
moel@7
   261
moel@16
   262
          IT87XX it87 = new IT87XX(chip, address);
moel@7
   263
          if (it87.IsAvailable)
moel@7
   264
            hardware.Add(it87);
moel@7
   265
moel@1
   266
          return;
moel@7
   267
        }
moel@7
   268
      }   
moel@1
   269
    }
moel@1
   270
moel@1
   271
    public IHardware[] Hardware {
moel@1
   272
      get {
moel@1
   273
        return hardware.ToArray();
moel@1
   274
      }
moel@1
   275
    }
moel@1
   276
moel@1
   277
    public string GetReport() {
moel@1
   278
      return null;
moel@1
   279
    }
moel@1
   280
moel@1
   281
    public void Close() { }
moel@1
   282
  }
moel@1
   283
}