Hardware/LPC/LPCGroup.cs
author moel.mich
Thu, 04 Feb 2010 21:19:27 +0000
changeset 26 0e01b63e1fdc
parent 19 890e8fca7f33
child 31 c4d1fb76a9e1
permissions -rw-r--r--
Release version 0.1.13. Replaced PerformanceCounter based CPU load sensors with an implementation using NtQuerySystemInformation. Fixed a temperature reading problem for W83627DHG chips (sensors with invalid value 127?C).
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     5   The contents of this file are subject to the Mozilla Public License Version
     6   1.1 (the "License"); you may not use this file except in compliance with
     7   the License. You may obtain a copy of the License at
     8  
     9   http://www.mozilla.org/MPL/
    10 
    11   Software distributed under the License is distributed on an "AS IS" basis,
    12   WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    13   for the specific language governing rights and limitations under the License.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    17   The Initial Developer of the Original Code is 
    18   Michael Möller <m.moeller@gmx.ch>.
    19   Portions created by the Initial Developer are Copyright (C) 2009-2010
    20   the Initial Developer. All Rights Reserved.
    21 
    22   Contributor(s):
    23 
    24   Alternatively, the contents of this file may be used under the terms of
    25   either the GNU General Public License Version 2 or later (the "GPL"), or
    26   the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    27   in which case the provisions of the GPL or the LGPL are applicable instead
    28   of those above. If you wish to allow use of your version of this file only
    29   under the terms of either the GPL or the LGPL, and not to allow others to
    30   use your version of this file under the terms of the MPL, indicate your
    31   decision by deleting the provisions above and replace them with the notice
    32   and other provisions required by the GPL or the LGPL. If you do not delete
    33   the provisions above, a recipient may use your version of this file under
    34   the terms of any one of the MPL, the GPL or the LGPL.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.Text;
    41 using System.Threading;
    42 
    43 namespace OpenHardwareMonitor.Hardware.LPC {
    44   public class LPCGroup : IGroup {
    45     private List<IHardware> hardware = new List<IHardware>();
    46 
    47     private Chip chip = Chip.Unknown;
    48 
    49     // I/O Ports
    50     private ushort[] REGISTER_PORTS = new ushort[] { 0x2e, 0x4e };
    51     private ushort[] VALUE_PORTS = new ushort[] { 0x2f, 0x4f };
    52 
    53     private ushort registerPort;
    54     private ushort valuePort;
    55 
    56     // Registers
    57     private const byte CONFIGURATION_CONTROL_REGISTER = 0x02;
    58     private const byte DEVCIE_SELECT_REGISTER = 0x07;
    59     private const byte CHIP_ID_REGISTER = 0x20;
    60     private const byte CHIP_REVISION_REGISTER = 0x21;
    61     private const byte BASE_ADDRESS_REGISTER = 0x60;
    62 
    63     private byte ReadByte(byte register) {
    64       WinRing0.WriteIoPortByte(registerPort, register);
    65       return WinRing0.ReadIoPortByte(valuePort);
    66     } 
    67 
    68     private ushort ReadWord(byte register) {
    69       return (ushort)((ReadByte(register) << 8) | 
    70         ReadByte((byte)(register + 1)));
    71     }
    72 
    73     private void Select(byte logicalDeviceNumber) {
    74       WinRing0.WriteIoPortByte(registerPort, DEVCIE_SELECT_REGISTER);
    75       WinRing0.WriteIoPortByte(valuePort, logicalDeviceNumber);
    76     }
    77 
    78     private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;    
    79 
    80     private void IT87Enter() {
    81       WinRing0.WriteIoPortByte(registerPort, 0x87);
    82       WinRing0.WriteIoPortByte(registerPort, 0x01);
    83       WinRing0.WriteIoPortByte(registerPort, 0x55);
    84       WinRing0.WriteIoPortByte(registerPort, 0x55);
    85     }
    86 
    87     internal void IT87Exit() {
    88       WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
    89       WinRing0.WriteIoPortByte(valuePort, 0x02);
    90     }
    91 
    92     // Winbond, Fintek
    93     private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
    94     private const ushort FINTEK_VENDOR_ID = 0x1934;
    95 
    96     private const byte W83627DHG_HARDWARE_MONITOR_LDN = 0x0B;
    97 
    98     private const byte F71858_HARDWARE_MONITOR_LDN = 0x02;
    99     private const byte FINTEK_HARDWARE_MONITOR_LDN = 0x04;
   100 
   101     private void WinbondFintekEnter() {
   102       WinRing0.WriteIoPortByte(registerPort, 0x87);
   103       WinRing0.WriteIoPortByte(registerPort, 0x87);
   104     }
   105 
   106     private void WinbondFintekExit() {
   107       WinRing0.WriteIoPortByte(registerPort, 0xAA);      
   108     }
   109 
   110     public LPCGroup() {
   111       if (!WinRing0.IsAvailable)
   112         return;
   113 
   114       for (int i = 0; i < REGISTER_PORTS.Length; i++) {
   115         registerPort = REGISTER_PORTS[i];
   116         valuePort = VALUE_PORTS[i];
   117 
   118         WinbondFintekEnter();
   119 
   120         byte logicalDeviceNumber;
   121         byte id = ReadByte(CHIP_ID_REGISTER);
   122         byte revision = ReadByte(CHIP_REVISION_REGISTER);
   123         switch (id) {
   124           case 0x05:
   125             switch (revision) {
   126               case 0x41:
   127                 chip = Chip.F71882;
   128                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   129                 break;
   130               default:
   131                 chip = Chip.Unknown;
   132                 logicalDeviceNumber = 0;
   133                 break;
   134             } break;
   135           case 0x06:
   136             switch (revision) {             
   137               case 0x01:
   138                 chip = Chip.F71862;
   139                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   140                 break;
   141               default:
   142                 chip = Chip.Unknown;
   143                 logicalDeviceNumber = 0;
   144                 break;
   145             } break;
   146           case 0x07:
   147             switch (revision) {
   148               case 0x23:
   149                 chip = Chip.F71889;
   150                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   151                 break;
   152               default:
   153                 chip = Chip.Unknown;
   154                 logicalDeviceNumber = 0;
   155                 break;
   156             } break;
   157           case 0x08:
   158             switch (revision) {
   159               case 0x14:
   160                 chip = Chip.F71869;
   161                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   162                 break;
   163               default:
   164                 chip = Chip.Unknown;
   165                 logicalDeviceNumber = 0;
   166                 break;
   167             } break;
   168           case 0xA0:
   169             switch (revision & 0xF0) {
   170               case 0x20: 
   171                 chip = Chip.W83627DHG;
   172                 logicalDeviceNumber = W83627DHG_HARDWARE_MONITOR_LDN;  
   173                 break;
   174               default: 
   175                 chip = Chip.Unknown;
   176                 logicalDeviceNumber = 0;
   177                 break;
   178             } break;
   179           case 0xB0:
   180             switch (revision & 0xF0) {
   181               case 0x70:
   182                 chip = Chip.W83627DHGP;
   183                 logicalDeviceNumber = W83627DHG_HARDWARE_MONITOR_LDN;
   184                 break;
   185               default:
   186                 chip = Chip.Unknown;
   187                 logicalDeviceNumber = 0;
   188                 break;
   189             } break;  
   190           default:
   191             chip = Chip.Unknown; 
   192             logicalDeviceNumber = 0;
   193             break;
   194         }
   195         if (chip != Chip.Unknown) {
   196 
   197           Select(logicalDeviceNumber);
   198           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   199           Thread.Sleep(1);
   200           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   201 
   202           ushort vendorID = 0;
   203           if (chip == Chip.F71862 || chip == Chip.F71882 || chip == Chip.F71889)
   204             vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
   205 
   206           WinbondFintekExit();
   207 
   208           if (address != verify || address == 0 || (address & 0xF007) != 0)
   209             return;
   210           
   211           switch (chip) {
   212             case Chip.W83627DHG:
   213             case Chip.W83627DHGP:
   214               W83627DHG w83627dhg = new W83627DHG(chip, revision, address);
   215               if (w83627dhg.IsAvailable)
   216                 hardware.Add(w83627dhg);
   217               break;
   218             case Chip.F71862:
   219             case Chip.F71882:
   220             case Chip.F71889: 
   221               if (vendorID == FINTEK_VENDOR_ID)
   222                 hardware.Add(new F718XX(chip, address));
   223               break;
   224             case Chip.F71869:
   225               hardware.Add(new F718XX(chip, address));
   226               break;
   227             default: break;
   228           }
   229           
   230           return;
   231         }
   232 
   233         IT87Enter();
   234 
   235         switch (ReadWord(CHIP_ID_REGISTER)) {
   236           case 0x8716: chip = Chip.IT8716F; break;
   237           case 0x8718: chip = Chip.IT8718F; break;
   238           case 0x8720: chip = Chip.IT8720F; break;
   239           case 0x8726: chip = Chip.IT8726F; break;
   240           default: chip = Chip.Unknown; break;
   241         }
   242 
   243         if (chip != Chip.Unknown) {
   244           Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   245           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   246           Thread.Sleep(1);
   247           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   248 
   249           IT87Exit();
   250 
   251           if (address != verify || address == 0 || (address & 0xF007) != 0)
   252             return;
   253 
   254           IT87XX it87 = new IT87XX(chip, address);
   255           if (it87.IsAvailable)
   256             hardware.Add(it87);
   257 
   258           return;
   259         }
   260       }   
   261     }
   262 
   263     public IHardware[] Hardware {
   264       get {
   265         return hardware.ToArray();
   266       }
   267     }
   268 
   269     public string GetReport() {
   270       return null;
   271     }
   272 
   273     public void Close() { }
   274   }
   275 }