Hardware/LPC/LPCGroup.cs
author moel.mich
Mon, 22 Feb 2010 09:57:02 +0000
changeset 60 0e62c377c08c
parent 54 f940fe2a7c2b
child 67 bb5696abab23
permissions -rw-r--r--
Fintek super I/O chips with base address 0x..5 are detected now as well. Set Pack = 1 for NVAPI struct interop (should fix GPU enumeration).
     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     // ITE
    79     private const byte IT87_ENVIRONMENT_CONTROLLER_LDN = 0x04;    
    80 
    81     private void IT87Enter() {
    82       WinRing0.WriteIoPortByte(registerPort, 0x87);
    83       WinRing0.WriteIoPortByte(registerPort, 0x01);
    84       WinRing0.WriteIoPortByte(registerPort, 0x55);
    85       WinRing0.WriteIoPortByte(registerPort, 0x55);
    86     }
    87 
    88     internal void IT87Exit() {
    89       WinRing0.WriteIoPortByte(registerPort, CONFIGURATION_CONTROL_REGISTER);
    90       WinRing0.WriteIoPortByte(valuePort, 0x02);
    91     }
    92 
    93     // Winbond, Fintek
    94     private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
    95     private const ushort FINTEK_VENDOR_ID = 0x1934;
    96 
    97     private const byte WINBOND_HARDWARE_MONITOR_LDN = 0x0B;
    98 
    99     private const byte F71858_HARDWARE_MONITOR_LDN = 0x02;
   100     private const byte FINTEK_HARDWARE_MONITOR_LDN = 0x04;
   101 
   102     private void WinbondFintekEnter() {
   103       WinRing0.WriteIoPortByte(registerPort, 0x87);
   104       WinRing0.WriteIoPortByte(registerPort, 0x87);
   105     }
   106 
   107     private void WinbondFintekExit() {
   108       WinRing0.WriteIoPortByte(registerPort, 0xAA);      
   109     }
   110 
   111     public LPCGroup() {
   112       if (!WinRing0.IsAvailable)
   113         return;
   114 
   115       for (int i = 0; i < REGISTER_PORTS.Length; i++) {
   116         registerPort = REGISTER_PORTS[i];
   117         valuePort = VALUE_PORTS[i];
   118 
   119         WinbondFintekEnter();
   120 
   121         byte logicalDeviceNumber;
   122         byte id = ReadByte(CHIP_ID_REGISTER);
   123         byte revision = ReadByte(CHIP_REVISION_REGISTER);
   124         chip = Chip.Unknown;
   125         logicalDeviceNumber = 0;
   126         switch (id) {
   127           case 0x05:
   128             switch (revision) {
   129               case 0x41:
   130                 chip = Chip.F71882;
   131                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   132                 break;              
   133             } break;
   134           case 0x06:
   135             switch (revision) {             
   136               case 0x01:
   137                 chip = Chip.F71862;
   138                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   139                 break;              
   140             } break;
   141           case 0x07:
   142             switch (revision) {
   143               case 0x23:
   144                 chip = Chip.F71889;
   145                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   146                 break;              
   147             } break;
   148           case 0x08:
   149             switch (revision) {
   150               case 0x14:
   151                 chip = Chip.F71869;
   152                 logicalDeviceNumber = FINTEK_HARDWARE_MONITOR_LDN;
   153                 break;              
   154             } break;
   155           case 0x52:
   156             switch (revision) {
   157               case 0x17:
   158               case 0x3A:
   159                 chip = Chip.W83627HF;
   160                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
   161                 break;             
   162             } break;
   163           case 0x82:
   164             switch (revision) {
   165               case 0x83:
   166                 chip = Chip.W83627THF;
   167                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
   168                 break;
   169             } break;
   170           case 0x88:
   171             switch (revision & 0xF0) {
   172               case 0x60:
   173                 chip = Chip.W83627EHF;
   174                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
   175                 break;
   176             } break;
   177           case 0xA0:
   178             switch (revision & 0xF0) {
   179               case 0x20: 
   180                 chip = Chip.W83627DHG;
   181                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;  
   182                 break;             
   183             } break;
   184           case 0xA5:
   185             switch (revision & 0xF0) {
   186               case 0x10:
   187                 chip = Chip.W83667HG;
   188                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
   189                 break;
   190             } break;
   191           case 0xB0:
   192             switch (revision & 0xF0) {
   193               case 0x70:
   194                 chip = Chip.W83627DHGP;
   195                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
   196                 break;             
   197             } break;
   198           case 0xB3:
   199             switch (revision & 0xF0) {
   200               case 0x50:
   201                 chip = Chip.W83667HGB;
   202                 logicalDeviceNumber = WINBOND_HARDWARE_MONITOR_LDN;
   203                 break;
   204             } break; 
   205         }
   206         if (chip != Chip.Unknown) {
   207 
   208           Select(logicalDeviceNumber);
   209           ushort address = ReadWord(BASE_ADDRESS_REGISTER);          
   210           Thread.Sleep(1);
   211           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   212           
   213           ushort vendorID = 0;
   214           if (chip == Chip.F71862 || chip == Chip.F71882 || chip == Chip.F71889)
   215             vendorID = ReadWord(FINTEK_VENDOR_ID_REGISTER);
   216 
   217           WinbondFintekExit();
   218 
   219           if (address != verify)
   220             return;
   221 
   222           // some Fintek chips have address register offset 0x05 added already
   223           if ((address & 0x07) == 0x05)
   224             address &= 0xFFF8;
   225 
   226           if (address < 0x100 || (address & 0xF007) != 0)
   227             return;
   228           
   229           switch (chip) {
   230             case Chip.W83627DHG:
   231             case Chip.W83627DHGP:
   232             case Chip.W83627EHF:
   233             case Chip.W83627HF:
   234             case Chip.W83627THF:
   235             case Chip.W83667HG:
   236             case Chip.W83667HGB:
   237               W836XX w836XX = new W836XX(chip, revision, address);
   238               if (w836XX.IsAvailable)
   239                 hardware.Add(w836XX);
   240               break;
   241             case Chip.F71862:
   242             case Chip.F71882:
   243             case Chip.F71889: 
   244               if (vendorID == FINTEK_VENDOR_ID)
   245                 hardware.Add(new F718XX(chip, address));
   246               break;
   247             case Chip.F71869:
   248               hardware.Add(new F718XX(chip, address));
   249               break;
   250             default: break;
   251           }
   252           
   253           return;
   254         }
   255 
   256         IT87Enter();
   257 
   258         switch (ReadWord(CHIP_ID_REGISTER)) {
   259           case 0x8716: chip = Chip.IT8716F; break;
   260           case 0x8718: chip = Chip.IT8718F; break;
   261           case 0x8720: chip = Chip.IT8720F; break;
   262           case 0x8726: chip = Chip.IT8726F; break;
   263           default: chip = Chip.Unknown; break;
   264         }
   265 
   266         if (chip != Chip.Unknown) {
   267           Select(IT87_ENVIRONMENT_CONTROLLER_LDN);
   268           ushort address = ReadWord(BASE_ADDRESS_REGISTER);
   269           Thread.Sleep(1);
   270           ushort verify = ReadWord(BASE_ADDRESS_REGISTER);
   271 
   272           IT87Exit();
   273 
   274           if (address != verify || address < 0x100 || (address & 0xF007) != 0)
   275             return;
   276 
   277           IT87XX it87 = new IT87XX(chip, address);
   278           if (it87.IsAvailable)
   279             hardware.Add(it87);
   280 
   281           return;
   282         }
   283       }   
   284     }
   285 
   286     public IHardware[] Hardware {
   287       get {
   288         return hardware.ToArray();
   289       }
   290     }
   291 
   292     public string GetReport() {
   293       return null;
   294     }
   295 
   296     public void Close() { }
   297   }
   298 }