diff --git a/Aga.Controls/Aga.Controls.csproj b/Aga.Controls/Aga.Controls.csproj index 92f17ce..58a2d1e 100644 --- a/Aga.Controls/Aga.Controls.csproj +++ b/Aga.Controls/Aga.Controls.csproj @@ -124,4 +124,4 @@ - \ No newline at end of file + diff --git a/InpOut/InpOut32.Net/CSharpExample.cs b/InpOut/InpOut32.Net/CSharpExample.cs deleted file mode 100644 index 28b4ff2..0000000 --- a/InpOut/InpOut32.Net/CSharpExample.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; - -using System.Runtime.InteropServices; - -namespace InpOut32.Net -{ - public partial class CSharpExample : Form - { - - [DllImport("inpout32.dll")] - private static extern UInt32 IsInpOutDriverOpen(); - [DllImport("inpout32.dll")] - private static extern void Out32(short PortAddress, short Data); - [DllImport("inpout32.dll")] - private static extern char Inp32(short PortAddress); - - [DllImport("inpout32.dll")] - private static extern void DlPortWritePortUshort(short PortAddress, ushort Data); - [DllImport("inpout32.dll")] - private static extern ushort DlPortReadPortUshort(short PortAddress); - - [DllImport("inpout32.dll")] - private static extern void DlPortWritePortUlong(int PortAddress, uint Data); - [DllImport("inpout32.dll")] - private static extern uint DlPortReadPortUlong(int PortAddress); - - [DllImport("inpoutx64.dll")] - private static extern bool GetPhysLong(ref int PortAddress, ref uint Data); - [DllImport("inpoutx64.dll")] - private static extern bool SetPhysLong(ref int PortAddress, ref uint Data); - - - [DllImport("inpoutx64.dll", EntryPoint="IsInpOutDriverOpen")] - private static extern UInt32 IsInpOutDriverOpen_x64(); - [DllImport("inpoutx64.dll", EntryPoint = "Out32")] - private static extern void Out32_x64(short PortAddress, short Data); - [DllImport("inpoutx64.dll", EntryPoint = "Inp32")] - private static extern char Inp32_x64(short PortAddress); - - [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUshort")] - private static extern void DlPortWritePortUshort_x64(short PortAddress, ushort Data); - [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUshort")] - private static extern ushort DlPortReadPortUshort_x64(short PortAddress); - - [DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUlong")] - private static extern void DlPortWritePortUlong_x64(int PortAddress, uint Data); - [DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUlong")] - private static extern uint DlPortReadPortUlong_x64(int PortAddress); - - [DllImport("inpoutx64.dll", EntryPoint = "GetPhysLong")] - private static extern bool GetPhysLong_x64(ref int PortAddress, ref uint Data); - [DllImport("inpoutx64.dll", EntryPoint = "SetPhysLong")] - private static extern bool SetPhysLong_x64(ref int PortAddress, ref uint Data); - - - bool m_bX64 = false; - - public CSharpExample() - { - InitializeComponent(); - try - { - uint nResult = 0; - try - { - nResult = IsInpOutDriverOpen(); - } - catch (BadImageFormatException) - { - nResult = IsInpOutDriverOpen_x64(); - if (nResult != 0) - m_bX64 = true; - - } - - if (nResult == 0) - { - lblMessage.Text = "Unable to open InpOut32 driver"; - button1.Enabled = false; - button2.Enabled = false; - button3.Enabled = false; - button4.Enabled = false; - button5.Enabled = false; - button6.Enabled = false; - button7.Enabled = false; - } - } - catch (DllNotFoundException ex) - { - System.Diagnostics.Debug.WriteLine(ex.ToString()); - lblMessage.Text = "Unable to find InpOut32.dll"; - button1.Enabled = false; - button2.Enabled = false; - button3.Enabled = false; - button4.Enabled = false; - button5.Enabled = false; - button6.Enabled = false; - button7.Enabled = false; - } - } - - private void button1_Click(object sender, EventArgs e) - { - try - { - short iPort = Convert.ToInt16(textBox1.Text); - - char c; - if (m_bX64) - c = Inp32_x64(iPort); - else - c = Inp32(iPort); - - textBox2.Text = Convert.ToInt32(c).ToString(); - } - catch (Exception ex) - { - MessageBox.Show("An error occured:\n" + ex.Message); - } - } - - private void button2_Click(object sender, EventArgs e) - { - try - { - short iPort = Convert.ToInt16(textBox1.Text); - short iData = Convert.ToInt16(textBox2.Text); - textBox2.Text = ""; - if (m_bX64) - Out32_x64(iPort, iData); - else - Out32(iPort, iData); - - - } - catch (Exception ex) - { - MessageBox.Show("An error occured:\n" + ex.Message); - } - } - - private void button3_Click(object sender, EventArgs e) - { - try - { - short iPort = Convert.ToInt16(textBox1.Text); - ushort s; - if (m_bX64) - s = DlPortReadPortUshort_x64(iPort); - else - s = DlPortReadPortUshort(iPort); - - textBox2.Text = Convert.ToUInt16(s).ToString(); - } - catch (Exception ex) - { - MessageBox.Show("An error occured:\n" + ex.Message); - } - } - - private void button4_Click(object sender, EventArgs e) - { - try - { - int nPort = Convert.ToInt32(textBox1.Text); - - uint l; - if (m_bX64) - l = DlPortReadPortUlong_x64(nPort); - else - l = DlPortReadPortUlong(nPort); - - textBox2.Text = l.ToString(); - } - catch (Exception ex) - { - MessageBox.Show("An error occured:\n" + ex.Message); - } - } - - private void button5_Click(object sender, EventArgs e) - { - try - { - short sPort = Convert.ToInt16(textBox1.Text); - ushort iData = Convert.ToUInt16(textBox2.Text); - textBox2.Text = ""; - - if (m_bX64) - DlPortWritePortUshort_x64(sPort, iData); - else - DlPortWritePortUshort(sPort, iData); - } - catch (Exception ex) - { - MessageBox.Show("An error occured:\n" + ex.Message); - } - } - - private void button6_Click(object sender, EventArgs e) - { - try - { - int nPort = Convert.ToInt32(textBox1.Text); - uint nData = Convert.ToUInt32(textBox2.Text); - textBox2.Text = ""; - if (m_bX64) - DlPortWritePortUlong_x64(nPort, nData); - else - DlPortWritePortUlong(nPort, nData); - } - catch (Exception ex) - { - MessageBox.Show("An error occured:\n" + ex.Message); - } - } - - private void Beep(uint freq) - { - if (m_bX64) - { - Out32_x64(0x43, 0xB6); - Out32_x64(0x42, (byte)(freq & 0xFF)); - Out32_x64(0x42, (byte)(freq >> 9)); - System.Threading.Thread.Sleep(10); - Out32_x64(0x61, (byte)(Convert.ToByte(Inp32_x64(0x61)) | 0x03)); - } - else - { - Out32(0x43, 0xB6); - Out32(0x42, (byte)(freq & 0xFF)); - Out32(0x42, (byte)(freq >> 9)); - System.Threading.Thread.Sleep(10); - Out32(0x61, (byte)(Convert.ToByte(Inp32(0x61)) | 0x03)); - } - } - - private void StopBeep() - { - if (m_bX64) - Out32_x64(0x61, (byte)(Convert.ToByte(Inp32_x64(0x61)) & 0xFC)); - else - Out32(0x61, (byte)(Convert.ToByte(Inp32(0x61)) & 0xFC)); - } - - private void CSharpExample_Load(object sender, EventArgs e) - { - button7_Click(this, null); - } - - - private void ThreadBeeper() - { - for (uint i = 440000; i < 500000; i += 1000) - { - uint freq = 1193180000 / i; // 440Hz - Beep(freq); - } - StopBeep(); - } - - private void button7_Click(object sender, EventArgs e) - { - System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadBeeper)); - t.Start(); - } - } -} \ No newline at end of file diff --git a/InpOut/InstallDriver/InstallDriver.cpp b/InpOut/InstallDriver/InstallDriver.cpp deleted file mode 100644 index 142571c..0000000 --- a/InpOut/InstallDriver/InstallDriver.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// InstallDriver.cpp : Defines the entry point for the console application. -// - -#include "stdafx.h" -#include "InstallDriver.h" -#include "..\inpout32.h" -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -// The one and only application object -int APIENTRY _tWinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPTSTR lpCmdLine, - int nCmdShow) -{ - int nRetCode = 0; - BOOL bResult = IsInpOutDriverOpen(); - - if (IsXP64Bit()) - { - if (bResult) - MessageBox(NULL, _T("Successfully installed and opened\n64bit InpOut driver InpOutx64.sys."), _T("InpOut Installation"), 0); - else - MessageBox(NULL, _T("Unable to install or open the\n64bit InpOut driver InpOutx64.sys.\n\nPlease try running as Administrator"), _T("InpOut Installation"), 0); - } - else - { - if (bResult) - MessageBox(NULL, _T("Successfully installed and opened\n32bit InpOut driver InpOut32.sys."), _T("InpOut Installation"), 0); - else - MessageBox(NULL, _T("Unable to install or open the\n32bit InpOut driver InpOut32.sys.\n\nPlease try running as Administrator"), _T("InpOut Installation"), 0); - } - return nRetCode; -} diff --git a/InpOut/InstallDriver/InstallDriver.h b/InpOut/InstallDriver/InstallDriver.h deleted file mode 100644 index d00d47e..0000000 --- a/InpOut/InstallDriver/InstallDriver.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include "resource.h" diff --git a/InpOut/InstallDriver/InstallDriver.manifest b/InpOut/InstallDriver/InstallDriver.manifest deleted file mode 100644 index c4b6440..0000000 --- a/InpOut/InstallDriver/InstallDriver.manifest +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - diff --git a/InpOut/InstallDriver/InstallDriver.rc b/InpOut/InstallDriver/InstallDriver.rc deleted file mode 100644 index 21ebcee..0000000 --- a/InpOut/InstallDriver/InstallDriver.rc +++ /dev/null @@ -1,113 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,0,0 - PRODUCTVERSION 1,4,0,0 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904b0" - BEGIN - VALUE "CompanyName", "Highresolution Enterprises" - VALUE "FileDescription", "InstallDriver Windows Vista/7 support application" - VALUE "FileVersion", "1, 4, 0, 0" - VALUE "InternalName", "InstallDriver" - VALUE "LegalCopyright", "Copyright (C) 2007-2011 Highresolution Enterprises" - VALUE "OriginalFilename", "InstallDriver.exe" - VALUE "ProductName", "InstallDriver Application" - VALUE "ProductVersion", "1, 4, 0, 0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x809, 1200 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_APP_TITLE "InstallDriver" -END - -#endif // English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/InpOut/InstallDriver/InstallDriver.vcproj b/InpOut/InstallDriver/InstallDriver.vcproj deleted file mode 100644 index 4990c69..0000000 --- a/InpOut/InstallDriver/InstallDriver.vcproj +++ /dev/null @@ -1,254 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InpOut/InstallDriver/ReadMe.txt b/InpOut/InstallDriver/ReadMe.txt deleted file mode 100644 index d6dc61e..0000000 --- a/InpOut/InstallDriver/ReadMe.txt +++ /dev/null @@ -1,46 +0,0 @@ -======================================================================== - CONSOLE APPLICATION : InstallDriver Project Overview -======================================================================== - -AppWizard has created this InstallDriver application for you. - -This file contains a summary of what you will find in each of the files that -make up your InstallDriver application. - - -InstallDriver.vcproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -InstallDriver.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -AppWizard has created the following resources: - -InstallDriver.rc - This is a listing of all of the Microsoft Windows resources that the - program uses. It includes the icons, bitmaps, and cursors that are stored - in the RES subdirectory. This file can be directly edited in Microsoft - Visual C++. - -Resource.h - This is the standard header file, which defines new resource IDs. - Microsoft Visual C++ reads and updates this file. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named InstallDriver.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/InpOut/InstallDriver/Resource.h b/InpOut/InstallDriver/Resource.h deleted file mode 100644 index 0d098f8..0000000 --- a/InpOut/InstallDriver/Resource.h +++ /dev/null @@ -1,17 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by InstallDriver.rc -// -#define IDR_MANIFEST 1 -#define IDS_APP_TITLE 103 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/InpOut/InstallDriver/stdafx.cpp b/InpOut/InstallDriver/stdafx.cpp deleted file mode 100644 index ceedb5d..0000000 --- a/InpOut/InstallDriver/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// InstallDriver.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/InpOut/InstallDriver/stdafx.h b/InpOut/InstallDriver/stdafx.h deleted file mode 100644 index 42732dc..0000000 --- a/InpOut/InstallDriver/stdafx.h +++ /dev/null @@ -1,27 +0,0 @@ -// Modify the following defines if you have to target a platform prior to the ones specified below. -// Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Allow use of features specific to Windows XP or later. -#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. -#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. -#endif - -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. -#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. -#endif - -#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. -#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. -#endif - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include - -// C RunTime Header Files -#include -#include -#include -#include \ No newline at end of file diff --git a/InpOut/ReadMe.txt b/InpOut/ReadMe.txt deleted file mode 100644 index c6e0f8d..0000000 --- a/InpOut/ReadMe.txt +++ /dev/null @@ -1,24 +0,0 @@ -InpOut32Drv Driver Interface DLL -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Modified for x64 compatibility and built by Phillip Gibbons (Phil@highrez.co.uk). -See http://www.highrez.co.uk/Downloads/InpOut32 or the Highrez Forums (http://forums.highrez.co.uk) for information. -Many thanks to Red Fox UK for supporting the community and providing Driver signatures allowing Vista/7 x64 compatibility. - - - -Based on the original written by Logix4U (www.logix4u.net). - - -Notes: - - The InpOut32 device driver supports writing to "old fashioned" hardware port addresses. - It does NOT support USB devices such as USB Parallel ports or even PCI parallel ports (as I am lead to believe). - - - The device driver is installed at runtime. To do this however needs administrator privileges. - On Vista & later, using UAC, you can run the InstallDriver.exe in the \Win32 folder to install the driver - appropriate for your OS. Doing so will request elevation and ask for your permission (or for the administrator - password). Once the driver is installed for the first time, it can then be used by any user *without* - administrator privileges - diff --git a/InpOut/StdAfx.cpp b/InpOut/StdAfx.cpp deleted file mode 100644 index 6b6294f..0000000 --- a/InpOut/StdAfx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// inpout32drv.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/InpOut/StdAfx.h b/InpOut/StdAfx.h deleted file mode 100644 index 92e3273..0000000 --- a/InpOut/StdAfx.h +++ /dev/null @@ -1,39 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__7ACF5BF3_42A3_43EB_9034_6218487B5231__INCLUDED_) -#define AFX_STDAFX_H__7ACF5BF3_42A3_43EB_9034_6218487B5231__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -#ifndef WINVER -#define WINVER 0x0400 -#endif - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0400 -#endif - -#ifndef _WIN32_WINDOWS -#define _WIN32_WINDOWS 0x0410 -#endif - -#ifndef _WIN32_IE -#define _WIN32_IE 0x0600 -#endif - -#define WIN32_LEAN_AND_MEAN -#include -#include - -// TODO: reference additional headers your program requires here - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__7ACF5BF3_42A3_43EB_9034_6218487B5231__INCLUDED_) diff --git a/InpOut/hwinterfacedrv.h b/InpOut/hwinterfacedrv.h deleted file mode 100644 index 9fd4043..0000000 --- a/InpOut/hwinterfacedrv.h +++ /dev/null @@ -1,29 +0,0 @@ - -#define IOCTL_READ_PORT_UCHAR -1673519100 //CTL_CODE(40000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_WRITE_PORT_UCHAR -1673519096 //CTL_CODE(40000, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_READ_PORT_USHORT -1673519092 //CTL_CODE(40000, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_WRITE_PORT_USHORT -1673519088 //CTL_CODE(40000, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_READ_PORT_ULONG -1673519084 //CTL_CODE(40000, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_WRITE_PORT_ULONG -1673519080 //CTL_CODE(40000, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_WINIO_MAPPHYSTOLIN -1673519076 -#define IOCTL_WINIO_UNMAPPHYSADDR -1673519072 - -BOOL _stdcall IsXP64Bit(); -int SystemVersion(); -BOOL DisableWOW64(PVOID* oldValue); -BOOL RevertWOW64(PVOID* oldValue); - -#pragma pack(push) -#pragma pack(1) - -struct tagPhys32Struct -{ - HANDLE PhysicalMemoryHandle; - SIZE_T dwPhysMemSizeInBytes; - PVOID pvPhysAddress; - PVOID pvPhysMemLin; -}; - -extern struct tagPhys32Struct Phys32Struct; - -#pragma pack(pop) \ No newline at end of file diff --git a/InpOut/inpout32.h b/InpOut/inpout32.h deleted file mode 100644 index 65df096..0000000 --- a/InpOut/inpout32.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -//Functions exported from DLL. -//For easy inclusion is user projects. -//Original InpOut32 function support -void _stdcall Out32(short PortAddress, short data); -short _stdcall Inp32(short PortAddress); - -//My extra functions for making life easy -BOOL _stdcall IsInpOutDriverOpen(); //Returns TRUE if the InpOut driver was opened successfully -BOOL _stdcall IsXP64Bit(); //Returns TRUE if the OS is 64bit (x64) Windows. - -//DLLPortIO function support -UCHAR _stdcall DlPortReadPortUchar (USHORT port); -void _stdcall DlPortWritePortUchar(USHORT port, UCHAR Value); - -USHORT _stdcall DlPortReadPortUshort (USHORT port); -void _stdcall DlPortWritePortUshort(USHORT port, USHORT Value); - -ULONG _stdcall DlPortReadPortUlong(ULONG port); -void _stdcall DlPortWritePortUlong(ULONG port, ULONG Value); - -//WinIO function support (Untested and probably does NOT work - esp. on x64!) -PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle); -BOOL _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr); -BOOL _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal); -BOOL _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal); - - - - - diff --git a/InpOut/inpout32.sys b/InpOut/inpout32.sys deleted file mode 100644 index 0f68c5e..0000000 Binary files a/InpOut/inpout32.sys and /dev/null differ diff --git a/InpOut/inpout32drv.cpp b/InpOut/inpout32drv.cpp deleted file mode 100644 index bdbc248..0000000 --- a/InpOut/inpout32drv.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/***********************************************************************\ -* * -* InpOut32drv.cpp * -* * -* The entry point for the InpOut DLL * -* Provides the 32 and 64bit implementation of InpOut32 DLL to install * -* and call the appropriate driver and write directly to hardware ports. * -* * -* Written by Phillip Gibbons (Highrez.co.uk) * -* Based on orriginal, written by Logix4U (www.logix4u.net) * -* * -\***********************************************************************/ - -#include "stdafx.h" -#include -#include -#include - -#include "hwinterfacedrv.h" -#include "resource.h" - -int inst32(); -int inst64(); -int start(LPCTSTR pszDriver); - -//First, lets set the DRIVERNAME depending on our configuraiton. -#define DRIVERNAMEx64 _T("inpoutx64\0") -#define DRIVERNAMEi386 _T("inpout32\0") - -char str[10]; -int vv; - -HANDLE hdriver=NULL; -TCHAR path[MAX_PATH]; -HINSTANCE hmodule; -SECURITY_ATTRIBUTES sa; -int sysver; - -int Opendriver(BOOL bX64); -void Closedriver(void); - -BOOL APIENTRY DllMain( HINSTANCE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - hmodule = hModule; - BOOL bx64 = IsXP64Bit(); - switch(ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - { - sysver = SystemVersion(); - if(sysver==2) - { - Opendriver(bx64); - } - } - - break; - case DLL_PROCESS_DETACH: - { - if(sysver==2) - { - Closedriver(); - } - } - break; - } - return TRUE; -} - -/***********************************************************************/ - -void Closedriver(void) -{ - if (hdriver) - { - OutputDebugString(_T("Closing InpOut driver...\n")); - CloseHandle(hdriver); - hdriver=NULL; - } -} - -void _stdcall Out32(short PortAddress, short data) -{ - { - switch(sysver) - { - case 1: -#ifdef _M_IX86 - _outp( PortAddress,data); //Will ONLY compile on i386 architecture -#endif - break; - case 2: - unsigned int error; - DWORD BytesReturned; - BYTE Buffer[3]={NULL}; - unsigned short* pBuffer; - pBuffer = (unsigned short *)&Buffer[0]; - *pBuffer = LOWORD(PortAddress); - Buffer[2] = LOBYTE(data); - - error = DeviceIoControl(hdriver, - IOCTL_WRITE_PORT_UCHAR, - &Buffer, - 3, - NULL, - 0, - &BytesReturned, - NULL); - break; - } - } -} - -/*********************************************************************/ - -short _stdcall Inp32(short PortAddress) -{ - { - BYTE retval(0); - switch(sysver) - { - case 1: -#ifdef _M_IX86 - retval = _inp(PortAddress); -#endif - return retval; - break; - case 2: - unsigned int error; - DWORD BytesReturned; - unsigned char Buffer[3]={NULL}; - unsigned short * pBuffer; - pBuffer = (unsigned short *)&Buffer; - *pBuffer = LOWORD(PortAddress); - Buffer[2] = 0; - error = DeviceIoControl(hdriver, - IOCTL_READ_PORT_UCHAR, - &Buffer, - 2, - &Buffer, - 1, - &BytesReturned, - NULL); - - if (error==0) - { - DWORD dwError = GetLastError(); - TCHAR tszError[255]; - _stprintf_s(tszError, 255, _T("Error %d\n"), dwError); - OutputDebugString(tszError); - } - - //Do this to ensure only the first byte is returned, we dont really want to return a short as were only reading a byte. - //but we also dont want to change the InpOut interface! - UCHAR ucRes = (UCHAR)Buffer[0]; - return ucRes; - - break; - } - } - return 0; -} - -/*********************************************************************/ - -int Opendriver(BOOL bX64) -{ - OutputDebugString(_T("Attempting to open InpOut driver...\n")); - TCHAR szFileName[MAX_PATH] = {NULL}; - _stprintf_s(szFileName, MAX_PATH, _T("\\\\.\\%s"), bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); - - hdriver = CreateFile(szFileName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if(hdriver == INVALID_HANDLE_VALUE) - { - if(start(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386)) - { - if (bX64) - inst64(); //Install the x64 driver - else - inst32(); //Install the i386 driver - - int nResult = start(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); - - if (nResult == ERROR_SUCCESS) - { - hdriver = CreateFile(szFileName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if(hdriver != INVALID_HANDLE_VALUE) - { - OutputDebugString(_T("Successfully opened ")); - OutputDebugString(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); - OutputDebugString(_T(" driver\n")); - return 0; - } - } - else - { - TCHAR szMsg[MAX_PATH] = {NULL}; - _stprintf_s(szMsg, MAX_PATH, _T("Unable to open %s driver. Error code %d.\n"), bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386, nResult); - OutputDebugString(szMsg); - - //RemoveDriver(); - } - } - return 1; - } - OutputDebugString(_T("Successfully opened ")); - OutputDebugString(bX64 ? DRIVERNAMEx64 : DRIVERNAMEi386); - OutputDebugString(_T(" driver\n")); - return 0; -} - -/***********************************************************************/ -int inst32() -{ - TCHAR szDriverSys[MAX_PATH]; - _tcscpy_s(szDriverSys, MAX_PATH, DRIVERNAMEi386); - _tcscat_s(szDriverSys, MAX_PATH, _T(".sys\0")); - - SC_HANDLE Mgr; - SC_HANDLE Ser; - GetSystemDirectory(path, MAX_PATH); - HRSRC hResource = FindResource(hmodule, MAKEINTRESOURCE(IDR_INPOUT32), _T("bin")); - if(hResource) - { - HGLOBAL binGlob = LoadResource(hmodule, hResource); - - if(binGlob) - { - void *binData = LockResource(binGlob); - - if(binData) - { - HANDLE file; - - _tcscat_s(path, sizeof(path), _T("\\Drivers\\")); - _tcscat_s(path, sizeof(path), szDriverSys); - - file = CreateFile(path, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - 0, - NULL); - - if (file && file != INVALID_HANDLE_VALUE) - { - DWORD size, written; - size = SizeofResource(hmodule, hResource); - WriteFile(file, binData, size, &written, NULL); - CloseHandle(file); - } - else - { - //Error - } - } - } - } - - Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS); - if (Mgr == NULL) - { //No permission to create service - if (GetLastError() == ERROR_ACCESS_DENIED) - { - return 5; // error access denied - } - } - else - { - TCHAR szFullPath[MAX_PATH] = _T("System32\\Drivers\\\0"); - _tcscat_s(szFullPath, MAX_PATH, szDriverSys); - Ser = CreateService (Mgr, - DRIVERNAMEi386, - DRIVERNAMEi386, - SERVICE_ALL_ACCESS, - SERVICE_KERNEL_DRIVER, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - szFullPath, - NULL, - NULL, - NULL, - NULL, - NULL - ); - } - CloseServiceHandle(Ser); - CloseServiceHandle(Mgr); - - return 0; -} - -int inst64() -{ - TCHAR szDriverSys[MAX_PATH]; - _tcscpy_s(szDriverSys, MAX_PATH, DRIVERNAMEx64); - _tcscat_s(szDriverSys, MAX_PATH, _T(".sys\0")); - - SC_HANDLE Mgr; - SC_HANDLE Ser; - GetSystemDirectory(path, MAX_PATH); - HRSRC hResource = FindResource(hmodule, MAKEINTRESOURCE(IDR_INPOUTX64), _T("bin")); - if(hResource) - { - HGLOBAL binGlob = LoadResource(hmodule, hResource); - - if(binGlob) - { - void *binData = LockResource(binGlob); - - if(binData) - { - HANDLE file; - _tcscat_s(path, sizeof(path), _T("\\Drivers\\")); - _tcscat_s(path, sizeof(path), szDriverSys); - - PVOID OldValue; - DisableWOW64(&OldValue); - file = CreateFile(path, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - 0, - NULL); - - if(file && file != INVALID_HANDLE_VALUE) - { - DWORD size, written; - - size = SizeofResource(hmodule, hResource); - WriteFile(file, binData, size, &written, NULL); - CloseHandle(file); - } - else - { - //error - } - RevertWOW64(&OldValue); - } - } - } - - Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS); - if (Mgr == NULL) - { //No permission to create service - if (GetLastError() == ERROR_ACCESS_DENIED) - { - return 5; // error access denied - } - } - else - { - TCHAR szFullPath[MAX_PATH] = _T("System32\\Drivers\\\0"); - _tcscat_s(szFullPath, MAX_PATH, szDriverSys); - Ser = CreateService (Mgr, - DRIVERNAMEx64, - DRIVERNAMEx64, - SERVICE_ALL_ACCESS, - SERVICE_KERNEL_DRIVER, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - szFullPath, - NULL, - NULL, - NULL, - NULL, - NULL - ); - } - CloseServiceHandle(Ser); - CloseServiceHandle(Mgr); - - return 0; -} - -/**************************************************************************/ -int start(LPCTSTR pszDriver) -{ - SC_HANDLE Mgr; - SC_HANDLE Ser; - - Mgr = OpenSCManager (NULL, NULL,SC_MANAGER_ALL_ACCESS); - - if (Mgr == NULL) - { //No permission to create service - if (GetLastError() == ERROR_ACCESS_DENIED) - { - Mgr = OpenSCManager (NULL, NULL, GENERIC_READ); - Ser = OpenService(Mgr, pszDriver, GENERIC_EXECUTE); - if (Ser) - { // we have permission to start the service - if(!StartService(Ser,0,NULL)) - { - CloseServiceHandle (Ser); - return 4; // we could open the service but unable to start - } - } - } - } - else - {// Successfuly opened Service Manager with full access - Ser = OpenService(Mgr, pszDriver, SERVICE_ALL_ACCESS); - if (Ser) - { - if(!StartService(Ser,0,NULL)) - { - CloseServiceHandle (Ser); - return 3; // opened the Service handle with full access permission, but unable to start - } - else - { - CloseServiceHandle (Ser); - return 0; - } - } - } - return 1; -} - -BOOL _stdcall IsInpOutDriverOpen() -{ - sysver = SystemVersion(); - if (sysver==2) - { - if (hdriver!=INVALID_HANDLE_VALUE && hdriver != NULL) - return TRUE; - } - else if (sysver==1) - { - return TRUE; - } - return FALSE; -} - -UCHAR _stdcall DlPortReadPortUchar (USHORT port) -{ - UCHAR retval(0); - switch(sysver) - { - case 1: -#ifdef _M_IX86 - retval = _inp((USHORT)port); -#endif - return retval; - break; - case 2: - unsigned int error; - DWORD BytesReturned; - BYTE Buffer[3]={NULL}; - unsigned short * pBuffer; - pBuffer = (unsigned short *)&Buffer; - *pBuffer = port; - Buffer[2] = 0; - error = DeviceIoControl(hdriver, - IOCTL_READ_PORT_UCHAR, - &Buffer, - sizeof(Buffer), - &Buffer, - sizeof(Buffer), - &BytesReturned, - NULL); - - return((UCHAR)Buffer[0]); - - break; - } - return 0; -} - -void _stdcall DlPortWritePortUchar (USHORT port, UCHAR Value) -{ - switch(sysver) - { - case 1: -#ifdef _M_IX86 - _outp((UINT)port,Value); //Will ONLY compile on i386 architecture -#endif - break; - case 2: - unsigned int error; - DWORD BytesReturned; - BYTE Buffer[3]={NULL}; - unsigned short * pBuffer; - pBuffer = (unsigned short *)&Buffer[0]; - *pBuffer = port; - Buffer[2] = Value; - - error = DeviceIoControl(hdriver, - IOCTL_WRITE_PORT_UCHAR, - &Buffer, - sizeof(Buffer), - NULL, - 0, - &BytesReturned, - NULL); - break; - } -} - -USHORT _stdcall DlPortReadPortUshort (USHORT port) -{ - if (sysver!=2) - return 0; - - ULONG retval(0); - unsigned int error; - DWORD BytesReturned; - unsigned short sPort=port; - error = DeviceIoControl(hdriver, - IOCTL_READ_PORT_USHORT, - &sPort, - sizeof(unsigned short), - &sPort, - sizeof(unsigned short), - &BytesReturned, - NULL); - return(sPort); -} - -void _stdcall DlPortWritePortUshort (USHORT port, USHORT Value) -{ - if (sysver!=2) - return; - - unsigned int error; - DWORD BytesReturned; - BYTE Buffer[5]={NULL}; - unsigned short * pBuffer; - pBuffer = (unsigned short *)&Buffer[0]; - *pBuffer = LOWORD(port); - *(pBuffer+1) = Value; - - error = DeviceIoControl(hdriver, - IOCTL_WRITE_PORT_USHORT, - &Buffer, - sizeof(Buffer), - NULL, - 0, - &BytesReturned, - NULL); -} - -ULONG _stdcall DlPortReadPortUlong(ULONG port) -{ - if (sysver!=2) - return 0; - - ULONG retval(0); - unsigned int error; - DWORD BytesReturned; - unsigned long lPort=port; - - PULONG ulBuffer; - ulBuffer = (PULONG)&lPort; - ULONG test = ulBuffer[0]; - - error = DeviceIoControl(hdriver, - IOCTL_READ_PORT_ULONG, - &lPort, - sizeof(unsigned long), - &lPort, - sizeof(unsigned long), - &BytesReturned, - NULL); - return(lPort); -} - -void _stdcall DlPortWritePortUlong (ULONG port, ULONG Value) -{ - if (sysver!=2) - return; - - unsigned int error; - DWORD BytesReturned; - BYTE Buffer[8] = {NULL}; - unsigned long* pBuffer; - pBuffer = (unsigned long*)&Buffer[0]; - *pBuffer = port; - *(pBuffer+1) = Value; - - error = DeviceIoControl(hdriver, - IOCTL_WRITE_PORT_ULONG, - &Buffer, - sizeof(Buffer), - NULL, - 0, - &BytesReturned, - NULL); -} - - -// Support functions for WinIO -PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle) -{ - PBYTE pbLinAddr; - tagPhys32Struct Phys32Struct; - DWORD dwBytesReturned; - - if (sysver!=2) - return false; - - Phys32Struct.dwPhysMemSizeInBytes = dwPhysSize; - Phys32Struct.pvPhysAddress = pbPhysAddr; - - if (!DeviceIoControl(hdriver, IOCTL_WINIO_MAPPHYSTOLIN, &Phys32Struct, - sizeof(tagPhys32Struct), &Phys32Struct, sizeof(tagPhys32Struct), - &dwBytesReturned, NULL)) - return NULL; - else - { -#ifdef _M_X64 - pbLinAddr = (PBYTE)((LONGLONG)Phys32Struct.pvPhysMemLin + (LONGLONG)pbPhysAddr - (LONGLONG)Phys32Struct.pvPhysAddress); -#else - pbLinAddr = (PBYTE)((DWORD)Phys32Struct.pvPhysMemLin + (DWORD)pbPhysAddr - (DWORD)Phys32Struct.pvPhysAddress); -#endif - *pPhysicalMemoryHandle = Phys32Struct.PhysicalMemoryHandle; - } - return pbLinAddr; -} - - -BOOL _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr) -{ - tagPhys32Struct Phys32Struct; - DWORD dwBytesReturned; - - if (sysver!=2) - return false; - - Phys32Struct.PhysicalMemoryHandle = PhysicalMemoryHandle; - Phys32Struct.pvPhysMemLin = pbLinAddr; - - if (!DeviceIoControl(hdriver, IOCTL_WINIO_UNMAPPHYSADDR, &Phys32Struct, - sizeof(tagPhys32Struct), NULL, 0, &dwBytesReturned, NULL)) - return false; - - return true; -} - -BOOL _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal) -{ - PDWORD pdwLinAddr; - HANDLE PhysicalMemoryHandle; - - if (sysver!=2) - return false; - - pdwLinAddr = (PDWORD)MapPhysToLin(pbPhysAddr, 4, &PhysicalMemoryHandle); - if (pdwLinAddr == NULL) - return false; - - *pdwPhysVal = *pdwLinAddr; - UnmapPhysicalMemory(PhysicalMemoryHandle, (PBYTE)pdwLinAddr); - return true; -} - - -BOOL _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal) -{ - PDWORD pdwLinAddr; - HANDLE PhysicalMemoryHandle; - if (sysver!=2) - return false; - - pdwLinAddr = (PDWORD)MapPhysToLin(pbPhysAddr, 4, &PhysicalMemoryHandle); - if (pdwLinAddr == NULL) - return false; - - *pdwLinAddr = dwPhysVal; - UnmapPhysicalMemory(PhysicalMemoryHandle, (PBYTE)pdwLinAddr); - return true; -} diff --git a/InpOut/inpout32drv.def b/InpOut/inpout32drv.def deleted file mode 100644 index e2b60cf..0000000 --- a/InpOut/inpout32drv.def +++ /dev/null @@ -1,18 +0,0 @@ -EXPORTS - -Inp32 @1 -Out32 @2 -IsInpOutDriverOpen @3 - -DlPortReadPortUchar @4 -DlPortWritePortUchar @5 -DlPortReadPortUshort @6 -DlPortWritePortUshort @7 -DlPortReadPortUlong @8 -DlPortWritePortUlong @9 -IsXP64Bit @10 - -MapPhysToLin @11 -UnmapPhysicalMemory @12 -GetPhysLong @13 -SetPhysLong @14 \ No newline at end of file diff --git a/InpOut/inpout32drv.rc b/InpOut/inpout32drv.rc deleted file mode 100644 index 700ac33..0000000 --- a/InpOut/inpout32drv.rc +++ /dev/null @@ -1,125 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,0,0 - PRODUCTVERSION 1,5,0,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080004b0" - BEGIN - VALUE "Comments", "Includes signed x64 drivers for Vista compatibility." - VALUE "CompanyName", "Highresolution Enterprises" - VALUE "FileDescription", "inpout32/64" - VALUE "FileVersion", "1, 5, 0, 0" - VALUE "InternalName", "inpout32" - VALUE "LegalCopyright", "Freeware" - VALUE "LegalTrademarks", "Copyright © 2008-2011 Highresolution Enterprises. Portions Copyright Logix4U" - VALUE "OriginalFilename", "inpout32.dll" - VALUE "ProductName", "inpout32" - VALUE "ProductVersion", "1, 5, 0, 0" - VALUE "SpecialBuild", "x64 Compatible build\r\nIncludes basic DLPortIO Compatibility\r\nIncludes signed drivers (Thanks to Red Fox UK) for Vista x64 compatiblity.\r\n" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x800, 1200 - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// Neutral (Sys. Default) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// BIN -// - -IDR_INPOUT32 BIN "inpout32.sys" -IDR_INPOUTX64 BIN "inpoutx64.sys" -#endif // Neutral (Sys. Default) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/InpOut/inpout32drv.sln b/InpOut/inpout32drv.sln deleted file mode 100644 index 9d797be..0000000 --- a/InpOut/inpout32drv.sln +++ /dev/null @@ -1,100 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inpout32drv", "inpout32drv.vcproj", "{18AEFF0B-D208-45B0-88E1-7057B9BA78F3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InstallDriver", "InstallDriver\InstallDriver.vcproj", "{233B1347-4B15-42DC-AC23-C2FE2ABEAF54}" - ProjectSection(ProjectDependencies) = postProject - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3} = {18AEFF0B-D208-45B0-88E1-7057B9BA78F3} - EndProjectSection -EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "InpOut32.VB.Net", "InpOut32.Net\InpOut32.VB.Net\InpOut32.VB.Net.vbproj", "{F90F25E7-E912-4948-B9CE-168FFA3014C8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InpOut32.CSharp.Net", "InpOut32.Net\InpOut32.CSharp.Net\InpOut32.CSharp.Net.csproj", "{784B3C36-7CAD-4B06-82A5-E60D17193F27}" -EndProject -Global - GlobalSection(SourceCodeControl) = preSolution - SccNumberOfProjects = 5 - SccLocalPath0 = . - SccProjectUniqueName1 = inpout32drv.vcproj - SccLocalPath1 = . - SccProjectUniqueName2 = InstallDriver\\InstallDriver.vcproj - SccLocalPath2 = . - SccProjectFilePathRelativizedFromConnection2 = InstallDriver\\ - SccProjectUniqueName3 = InpOut32.Net\\InpOut32.VB.Net\\InpOut32.VB.Net.vbproj - SccLocalPath3 = . - SccProjectFilePathRelativizedFromConnection3 = InpOut32.Net\\InpOut32.VB.Net\\ - SccProjectUniqueName4 = InpOut32.Net\\InpOut32.CSharp.Net\\InpOut32.CSharp.Net.csproj - SccProjectName4 = \u0022$/inpout32drv.root/inpout32drv/InpOut32.Net/InpOut32.CSharp.Net\u0022,\u0020DHHAAAAA - SccLocalPath4 = InpOut32.Net\\InpOut32.CSharp.Net - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Any CPU.ActiveCfg = Debug|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Mixed Platforms.Build.0 = Debug|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Win32.ActiveCfg = Debug|Win32 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|Win32.Build.0 = Debug|Win32 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|x64.ActiveCfg = Debug|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Debug|x64.Build.0 = Debug|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Any CPU.ActiveCfg = Release|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Mixed Platforms.ActiveCfg = Release|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Mixed Platforms.Build.0 = Release|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Win32.ActiveCfg = Release|Win32 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|Win32.Build.0 = Release|Win32 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|x64.ActiveCfg = Release|x64 - {18AEFF0B-D208-45B0-88E1-7057B9BA78F3}.Release|x64.Build.0 = Release|x64 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Win32.ActiveCfg = Debug|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|Win32.Build.0 = Debug|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Debug|x64.ActiveCfg = Debug|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Any CPU.ActiveCfg = Release|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Mixed Platforms.Build.0 = Release|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Win32.ActiveCfg = Release|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|Win32.Build.0 = Release|Win32 - {233B1347-4B15-42DC-AC23-C2FE2ABEAF54}.Release|x64.ActiveCfg = Release|Win32 - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Win32.ActiveCfg = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|Win32.Build.0 = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|x64.ActiveCfg = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Debug|x64.Build.0 = Debug|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Any CPU.Build.0 = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Win32.ActiveCfg = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|Win32.Build.0 = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|x64.ActiveCfg = Release|Any CPU - {F90F25E7-E912-4948-B9CE-168FFA3014C8}.Release|x64.Build.0 = Release|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|Win32.ActiveCfg = Debug|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Debug|x64.ActiveCfg = Debug|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Any CPU.Build.0 = Release|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|Win32.ActiveCfg = Release|Any CPU - {784B3C36-7CAD-4B06-82A5-E60D17193F27}.Release|x64.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/InpOut/inpout32drv.vcproj b/InpOut/inpout32drv.vcproj deleted file mode 100644 index be97fea..0000000 --- a/InpOut/inpout32drv.vcproj +++ /dev/null @@ -1,621 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InpOut/inpoutx64.sys b/InpOut/inpoutx64.sys deleted file mode 100644 index 4ddbcbb..0000000 Binary files a/InpOut/inpoutx64.sys and /dev/null differ diff --git a/InpOut/license.txt b/InpOut/license.txt deleted file mode 100644 index e6b145a..0000000 --- a/InpOut/license.txt +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) <2003-2015> Phil Gibbons -Portions Copyright (c) <2000> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - - - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - - - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/InpOut/osversion.cpp b/InpOut/osversion.cpp deleted file mode 100644 index b5e0ead..0000000 --- a/InpOut/osversion.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "stdafx.h" -#include "hwinterfacedrv.h" - -typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); -typedef BOOL (WINAPI *LPFN_WOW64DISABLE) (PVOID*); -typedef BOOL (WINAPI *LPFN_WOW64REVERT) (PVOID); - -LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")),"IsWow64Process"); -LPFN_WOW64DISABLE fnWow64Disable = (LPFN_WOW64DISABLE)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64DisableWow64FsRedirection"); -LPFN_WOW64REVERT fnWow64Revert = (LPFN_WOW64REVERT)GetProcAddress(GetModuleHandle(_T("kernel32")),"Wow64RevertWow64FsRedirection"); - -//Purpose: Return TRUE if we are running in WOW64 (i.e. a 32bit process on XP x64 edition) -BOOL _stdcall IsXP64Bit() -{ -#ifdef _M_X64 - return TRUE; //Urrr if its a x64 build of the DLL, we MUST be running on X64 nativly! -#endif - - BOOL bIsWow64 = FALSE; - if (NULL != fnIsWow64Process) - { - if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) - { - // handle error - } - } - return bIsWow64; -} - -BOOL DisableWOW64(PVOID* oldValue) -{ -#ifdef _M_X64 - return TRUE; // If were 64b under x64, we dont wanna do anything! -#endif - return fnWow64Disable(oldValue); -} - -BOOL RevertWOW64(PVOID* oldValue) -{ -#ifdef _M_X64 - return TRUE; // If were 64b under x64, we dont wanna do anything! -#endif - return fnWow64Revert (oldValue); -} - -int SystemVersion() -{ - OSVERSIONINFOEX osvi; - BOOL bOsVersionInfoEx; - - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - - if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) - { - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - - if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) - return 0; - } - - switch (osvi.dwPlatformId) - { - case VER_PLATFORM_WIN32_NT: - - return 2; //WINNT - - break; - - case VER_PLATFORM_WIN32_WINDOWS: - - return 1; //WIN9X - - break; - - } - return 0; -} diff --git a/InpOut/resource.h b/InpOut/resource.h deleted file mode 100644 index 3e0ae19..0000000 --- a/InpOut/resource.h +++ /dev/null @@ -1,18 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by inpout32drv.rc -// -#define IDR_BIN1 101 -#define IDR_INPOUT32 101 -#define IDR_INPOUTX64 104 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/LibreHardwareMonitor/LibreHardwareMonitor.csproj b/LibreHardwareMonitor/LibreHardwareMonitor.csproj index e62f598..bc3a6ef 100644 --- a/LibreHardwareMonitor/LibreHardwareMonitor.csproj +++ b/LibreHardwareMonitor/LibreHardwareMonitor.csproj @@ -16,6 +16,7 @@ ..\bin\$(Configuration)\ latest AnyCPU + true full diff --git a/LibreHardwareMonitor/Resources/PawnIO_setup.exe b/LibreHardwareMonitor/Resources/PawnIO_setup.exe new file mode 100644 index 0000000..042dd0b Binary files /dev/null and b/LibreHardwareMonitor/Resources/PawnIO_setup.exe differ diff --git a/LibreHardwareMonitor/UI/MainForm.cs b/LibreHardwareMonitor/UI/MainForm.cs index 5416ad8..5249f98 100644 --- a/LibreHardwareMonitor/UI/MainForm.cs +++ b/LibreHardwareMonitor/UI/MainForm.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; @@ -16,6 +17,7 @@ using Aga.Controls.Tree; using Aga.Controls.Tree.NodeControls; using LibreHardwareMonitor.Hardware; using LibreHardwareMonitor.Hardware.Storage; +using LibreHardwareMonitor.PawnIo; using LibreHardwareMonitor.UI.Themes; using LibreHardwareMonitor.Utilities; using LibreHardwareMonitor.Wmi; @@ -166,8 +168,56 @@ public sealed partial class MainForm : Form _computer.HardwareAdded += HardwareAdded; _computer.HardwareRemoved += HardwareRemoved; + + if (PawnIo.PawnIo.IsInstalled) + { + if (PawnIo.PawnIo.Version() < new Version(2, 0, 0, 0)) + { + DialogResult result = MessageBox.Show("PawnIO is outdated, do you want to update it?", nameof(LibreHardwareMonitor), MessageBoxButtons.OKCancel); + if (result == DialogResult.OK) + InstallPawnIO(); + } + } + else + { + DialogResult result = MessageBox.Show("PawnIO is not installed, do you want to install it?", nameof(LibreHardwareMonitor), MessageBoxButtons.OKCancel); + if (result == DialogResult.OK) + InstallPawnIO(); + } + _computer.Open(); + static void InstallPawnIO() + { + string path = ExtractPawnIO(); + if (!string.IsNullOrEmpty(path)) + { + var process = Process.Start(new ProcessStartInfo(path, "-install")); + process?.WaitForExit(); + + File.Delete(path); + } + } + + static string ExtractPawnIO() + { + string destination = Path.Combine(Directory.GetCurrentDirectory(), "PawnIO_setup.exe"); + + try + { + + using Stream resourceStream = typeof(MainForm).Assembly.GetManifestResourceStream("LibreHardwareMonitor.Resources.PawnIO_setup.exe"); + using FileStream fileStream = new(destination, FileMode.Create, FileAccess.Write); + resourceStream.CopyTo(fileStream); + + return destination; + } + catch + { + return null; + } + } + backgroundUpdater.DoWork += BackgroundUpdater_DoWork; timer.Enabled = true; @@ -183,7 +233,7 @@ public sealed partial class MainForm : Form UserOption showMax = new("maxMenuItem", true, maxMenuItem, _settings); showMax.Changed += delegate { treeView.Columns[3].IsVisible = showMax.Value; }; - var _ = new UserOption("startMinMenuItem", false, startMinMenuItem, _settings); + _ = new UserOption("startMinMenuItem", false, startMinMenuItem, _settings); _minimizeToTray = new UserOption("minTrayMenuItem", true, minTrayMenuItem, _settings); _minimizeToTray.Changed += delegate { _systemTray.IsMainIconEnabled = _minimizeToTray.Value; }; diff --git a/LibreHardwareMonitorLib/Hardware/Computer.cs b/LibreHardwareMonitorLib/Hardware/Computer.cs index 517a978..a3ff091 100644 --- a/LibreHardwareMonitorLib/Hardware/Computer.cs +++ b/LibreHardwareMonitorLib/Hardware/Computer.cs @@ -34,7 +34,7 @@ public class Computer : IComputer private readonly List _groups = new(); private readonly object _lock = new(); private readonly ISettings _settings; - + private bool _batteryEnabled; private bool _controllerEnabled; private bool _cpuEnabled; @@ -46,7 +46,6 @@ public class Computer : IComputer private bool _psuEnabled; private SMBios _smbios; private bool _storageEnabled; - private bool _ring0Enabled = true; /// /// Creates a new instance with basic initial . @@ -280,16 +279,6 @@ public class Computer : IComputer } } - /// - public bool IsRing0Enabled - { - get { return _ring0Enabled; } - set - { - _ring0Enabled = value; - } - } - /// /// Contains computer information table read in accordance with System Management BIOS (SMBIOS) Reference Specification. /// @@ -331,14 +320,6 @@ public class Computer : IComputer w.WriteLine(IntPtr.Size == 4 ? "32-Bit" : "64-Bit"); w.WriteLine(); - string r = Ring0.GetReport(); - if (r != null) - { - NewSection(w); - w.Write(r); - w.WriteLine(); - } - NewSection(w); w.WriteLine("Sensors"); w.WriteLine(); @@ -474,7 +455,7 @@ public class Computer : IComputer private void RemoveType() where T : IGroup { - List list = new(); + List list = []; lock (_lock) { @@ -490,7 +471,7 @@ public class Computer : IComputer } /// - /// If hasn't been opened before, opens , , and triggers the private method depending on which categories are + /// If hasn't been opened before, opens , and triggers the private method depending on which categories are /// enabled. /// public void Open() @@ -500,9 +481,6 @@ public class Computer : IComputer _smbios = new SMBios(); - if (IsRing0Enabled) - Ring0.Open(); - Mutexes.Open(); OpCode.Open(); @@ -627,7 +605,7 @@ public class Computer : IComputer } /// - /// If opened before, removes all and triggers , and . + /// If opened before, removes all and triggers . /// public void Close() { @@ -644,8 +622,6 @@ public class Computer : IComputer } OpCode.Close(); - InpOut.Close(); - Ring0.Close(); Mutexes.Close(); _smbios = null; diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/Amd0FCpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/Amd0FCpu.cs index cbea3ba..5dd7b83 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/Amd0FCpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/Amd0FCpu.cs @@ -4,10 +4,8 @@ // Partial Copyright (C) Michael Möller and Contributors. // All Rights Reserved. -using System; -using System.Globalization; -using System.Text; using System.Threading; +using LibreHardwareMonitor.PawnIo; namespace LibreHardwareMonitor.Hardware.Cpu; @@ -16,13 +14,20 @@ internal sealed class Amd0FCpu : AmdCpu private readonly Sensor _busClock; private readonly Sensor[] _coreClocks; private readonly Sensor[] _coreTemperatures; - private readonly uint _miscellaneousControlAddress; - private readonly byte _thermSenseCoreSelCPU0; - private readonly byte _thermSenseCoreSelCPU1; + private readonly AmdFamily0F _pawnModule; + + /// + public override void Close() + { + base.Close(); + _pawnModule.Close(); + } public Amd0FCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings) { + _pawnModule = new AmdFamily0F(); + float offset = -49.0f; // AM2+ 65nm +21 offset @@ -30,19 +35,6 @@ internal sealed class Amd0FCpu : AmdCpu if (model is >= 0x69 and not 0xc1 and not 0x6c and not 0x7c) offset += 21; - if (model < 40) - { - // AMD Athlon 64 Processors - _thermSenseCoreSelCPU0 = 0x0; - _thermSenseCoreSelCPU1 = 0x4; - } - else - { - // AMD NPT Family 0Fh Revision F, G have the core selection swapped - _thermSenseCoreSelCPU0 = 0x4; - _thermSenseCoreSelCPU1 = 0x0; - } - // check if processor supports a digital thermal sensor if (cpuId[0][0].ExtData.GetLength(0) > 7 && (cpuId[0][0].ExtData[7, 3] & 1) != 0) { @@ -53,16 +45,15 @@ internal sealed class Amd0FCpu : AmdCpu i, SensorType.Temperature, this, - new[] { new ParameterDescription("Offset [°C]", "Temperature offset of the thermal sensor.\nTemperature = Value + Offset.", offset) }, + [new ParameterDescription("Offset [°C]", "Temperature offset of the thermal sensor.\nTemperature = Value + Offset.", offset)], settings); } } else { - _coreTemperatures = Array.Empty(); + _coreTemperatures = []; } - _miscellaneousControlAddress = GetPciAddress(MISCELLANEOUS_CONTROL_FUNCTION, MISCELLANEOUS_CONTROL_DEVICE_ID); _busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); _coreClocks = new Sensor[_coreCount]; for (int i = 0; i < _coreClocks.Length; i++) @@ -75,46 +66,28 @@ internal sealed class Amd0FCpu : AmdCpu Update(); } - protected override uint[] GetMsrs() - { - return new[] { FIDVID_STATUS }; - } - - public override string GetReport() - { - StringBuilder r = new(); - r.Append(base.GetReport()); - r.Append("Miscellaneous Control Address: 0x"); - r.AppendLine(_miscellaneousControlAddress.ToString("X", CultureInfo.InvariantCulture)); - r.AppendLine(); - return r.ToString(); - } - public override void Update() { base.Update(); if (Mutexes.WaitPciBus(10)) { - if (_miscellaneousControlAddress != Interop.Ring0.INVALID_PCI_ADDRESS) + for (uint i = 0; i < _coreTemperatures.Length; i++) { - for (uint i = 0; i < _coreTemperatures.Length; i++) + uint value; + + try { - if (Ring0.WritePciConfig(_miscellaneousControlAddress, - THERMTRIP_STATUS_REGISTER, - i > 0 ? _thermSenseCoreSelCPU1 : _thermSenseCoreSelCPU0)) - { - if (Ring0.ReadPciConfig(_miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER, out uint value)) - { - _coreTemperatures[i].Value = ((value >> 16) & 0xFF) + _coreTemperatures[i].Parameters[0].Value; - ActivateSensor(_coreTemperatures[i]); - } - else - { - DeactivateSensor(_coreTemperatures[i]); - } - } + value = _pawnModule.GetThermtrip(Index, i); } + catch + { + DeactivateSensor(_coreTemperatures[i]); + continue; + } + + _coreTemperatures[i].Value = ((value >> 16) & 0xFF) + _coreTemperatures[i].Parameters[0].Value; + ActivateSensor(_coreTemperatures[i]); } Mutexes.ReleasePciBus(); @@ -128,7 +101,7 @@ internal sealed class Amd0FCpu : AmdCpu { Thread.Sleep(1); - if (Ring0.ReadMsr(FIDVID_STATUS, out uint eax, out uint _, _cpuId[i][0].Affinity)) + if (_pawnModule.ReadMsr(FIDVID_STATUS, out uint eax, out uint _, _cpuId[i][0].Affinity)) { // CurrFID can be found in eax bits 0-5, MaxFID in 16-21 // 8-13 hold StartFID, we don't use that here. @@ -154,8 +127,5 @@ internal sealed class Amd0FCpu : AmdCpu // ReSharper disable InconsistentNaming private const uint FIDVID_STATUS = 0xC0010042; - private const ushort MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1103; - private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3; - private const uint THERMTRIP_STATUS_REGISTER = 0xE4; // ReSharper restore InconsistentNaming } diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/Amd10Cpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/Amd10Cpu.cs index 0688835..edcb03c 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/Amd10Cpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/Amd10Cpu.cs @@ -5,12 +5,12 @@ // All Rights Reserved. using System; -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Text; using System.Threading; +using LibreHardwareMonitor.PawnIo; namespace LibreHardwareMonitor.Hardware.Cpu; @@ -20,17 +20,19 @@ internal sealed class Amd10Cpu : AmdCpu private readonly Sensor[] _coreClocks; private readonly Sensor _coreTemperature; private readonly Sensor _coreVoltage; - private readonly byte _cStatesIoOffset; private readonly Sensor[] _cStatesResidency; private readonly bool _hasSmuTemperatureRegister; private readonly bool _isSvi2; - private readonly uint _miscellaneousControlAddress; private readonly Sensor _northbridgeVoltage; private readonly FileStream _temperatureStream; private readonly double _timeStampCounterMultiplier; + private readonly AmdFamily10 _pawnModule; + public Amd10Cpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings) { + _pawnModule = new AmdFamily10(); + // AMD family 1Xh processors support only one temperature sensor ushort miscellaneousControlDeviceId; _coreTemperature = new Sensor("CPU Cores", 0, SensorType.Temperature, this, new[] { new ParameterDescription("Offset [°C]", "Temperature offset.", 0) }, settings); @@ -41,61 +43,18 @@ internal sealed class Amd10Cpu : AmdCpu _isSvi2 = (_family == 0x15 && _model >= 0x10) || _family == 0x16; - switch (_family) + if (_family == 0x15) { - case 0x10: - miscellaneousControlDeviceId = FAMILY_10H_MISCELLANEOUS_CONTROL_DEVICE_ID; - break; - case 0x11: - miscellaneousControlDeviceId = FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID; - break; - case 0x12: - miscellaneousControlDeviceId = FAMILY_12H_MISCELLANEOUS_CONTROL_DEVICE_ID; - break; - case 0x14: - miscellaneousControlDeviceId = FAMILY_14H_MISCELLANEOUS_CONTROL_DEVICE_ID; - break; - case 0x15: switch (_model & 0xF0) { - case 0x00: - miscellaneousControlDeviceId = FAMILY_15H_MODEL_00_MISC_CONTROL_DEVICE_ID; - break; - case 0x10: - miscellaneousControlDeviceId = FAMILY_15H_MODEL_10_MISC_CONTROL_DEVICE_ID; - break; - case 0x30: - miscellaneousControlDeviceId = FAMILY_15H_MODEL_30_MISC_CONTROL_DEVICE_ID; - break; - case 0x70: - miscellaneousControlDeviceId = FAMILY_15H_MODEL_70_MISC_CONTROL_DEVICE_ID; - _hasSmuTemperatureRegister = true; - break; case 0x60: - miscellaneousControlDeviceId = FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID; + case 0x70: _hasSmuTemperatureRegister = true; break; - default: - miscellaneousControlDeviceId = 0; - break; } - - break; - case 0x16: - miscellaneousControlDeviceId = (_model & 0xF0) switch - { - 0x00 => FAMILY_16H_MODEL_00_MISC_CONTROL_DEVICE_ID, - 0x30 => FAMILY_16H_MODEL_30_MISC_CONTROL_DEVICE_ID, - _ => 0 - }; - break; - default: - miscellaneousControlDeviceId = 0; - break; } // get the pci address for the Miscellaneous Control registers - _miscellaneousControlAddress = GetPciAddress(MISCELLANEOUS_CONTROL_FUNCTION, miscellaneousControlDeviceId); _busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); _coreClocks = new Sensor[_coreCount]; for (int i = 0; i < _coreClocks.Length; i++) @@ -105,28 +64,10 @@ internal sealed class Amd10Cpu : AmdCpu ActivateSensor(_coreClocks[i]); } - bool corePerformanceBoostSupport = (cpuId[0][0].ExtData[7, 3] & (1 << 9)) > 0; - // set affinity to the first thread for all frequency estimations GroupAffinity previousAffinity = ThreadAffinity.Set(cpuId[0][0].Affinity); - // disable core performance boost - Ring0.ReadMsr(HWCR, out uint hwcrEax, out uint hwcrEdx); - if (corePerformanceBoostSupport) - Ring0.WriteMsr(HWCR, hwcrEax | (1 << 25), hwcrEdx); - - Ring0.ReadMsr(PERF_CTL_0, out uint ctlEax, out uint ctlEdx); - Ring0.ReadMsr(PERF_CTR_0, out uint ctrEax, out uint ctrEdx); - - _timeStampCounterMultiplier = EstimateTimeStampCounterMultiplier(); - - // restore the performance counter registers - Ring0.WriteMsr(PERF_CTL_0, ctlEax, ctlEdx); - Ring0.WriteMsr(PERF_CTR_0, ctrEax, ctrEdx); - - // restore core performance boost - if (corePerformanceBoostSupport) - Ring0.WriteMsr(HWCR, hwcrEax, hwcrEdx); + _timeStampCounterMultiplier = MeasureTimeStampCounterMultiplier(); // restore the thread affinity. ThreadAffinity.Set(previousAffinity); @@ -156,20 +97,7 @@ internal sealed class Amd10Cpu : AmdCpu } } - uint addr = Ring0.GetPciAddress(0, 20, 0); - if (Ring0.ReadPciConfig(addr, 0, out uint dev)) - { - Ring0.ReadPciConfig(addr, 8, out uint rev); - - _cStatesIoOffset = dev switch - { - 0x43851002 => (byte)((rev & 0xFF) < 0x40 ? 0xB3 : 0x9C), - 0x780B1022 or 0x790B1022 => 0x9C, - _ => _cStatesIoOffset - }; - } - - if (_cStatesIoOffset != 0) + if (_pawnModule.HaveCstateResidencyInfo()) { _cStatesResidency = new[] { new Sensor("CPU Package C2", 0, SensorType.Level, this, settings), new Sensor("CPU Package C3", 1, SensorType.Level, this, settings) }; ActivateSensor(_cStatesResidency[0]); @@ -179,76 +107,26 @@ internal sealed class Amd10Cpu : AmdCpu Update(); } - private double EstimateTimeStampCounterMultiplier() + private double MeasureTimeStampCounterMultiplier() { - // preload the function - EstimateTimeStampCounterMultiplier(0); - EstimateTimeStampCounterMultiplier(0); + _pawnModule.MeasureTscMultiplier(out var ctrPerTick, out var cofVid); - // estimate the multiplier - List estimate = new(3); - for (int i = 0; i < 3; i++) - estimate.Add(EstimateTimeStampCounterMultiplier(0.025)); + double coreMultiplier = GetCoreMultiplier((uint)cofVid); - estimate.Sort(); - return estimate[1]; - } - - private double EstimateTimeStampCounterMultiplier(double timeWindow) - { - // select event "076h CPU Clocks not Halted" and enable the counter - Ring0.WriteMsr(PERF_CTL_0, - (1 << 22) | // enable performance counter - (1 << 17) | // count events in user mode - (1 << 16) | // count events in operating-system mode - 0x76, - 0x00000000); - - // set the counter to 0 - Ring0.WriteMsr(PERF_CTR_0, 0, 0); - - long ticks = (long)(timeWindow * Stopwatch.Frequency); - - long timeBegin = Stopwatch.GetTimestamp() + - (long)Math.Ceiling(0.001 * ticks); - - long timeEnd = timeBegin + ticks; - while (Stopwatch.GetTimestamp() < timeBegin) - { } - - Ring0.ReadMsr(PERF_CTR_0, out uint lsbBegin, out uint msbBegin); - - while (Stopwatch.GetTimestamp() < timeEnd) - { } - - Ring0.ReadMsr(PERF_CTR_0, out uint lsbEnd, out uint msbEnd); - Ring0.ReadMsr(COFVID_STATUS, out uint eax, out uint _); - double coreMultiplier = GetCoreMultiplier(eax); - - ulong countBegin = ((ulong)msbBegin << 32) | lsbBegin; - ulong countEnd = ((ulong)msbEnd << 32) | lsbEnd; - - double coreFrequency = 1e-6 * ((double)(countEnd - countBegin) * Stopwatch.Frequency) / (timeEnd - timeBegin); + double coreFrequency = 1e-6 * ((double)ctrPerTick * Stopwatch.Frequency); double busFrequency = coreFrequency / coreMultiplier; return 0.25 * Math.Round(4 * TimeStampCounterFrequency / busFrequency); } - protected override uint[] GetMsrs() - { - return new[] { PERF_CTL_0, PERF_CTR_0, HWCR, P_STATE_0, COFVID_STATUS }; - } - public override string GetReport() { StringBuilder r = new(); r.Append(base.GetReport()); - r.Append("Miscellaneous Control Address: 0x"); - r.AppendLine(_miscellaneousControlAddress.ToString("X", CultureInfo.InvariantCulture)); r.Append("Time Stamp Counter Multiplier: "); r.AppendLine(_timeStampCounterMultiplier.ToString(CultureInfo.InvariantCulture)); if (_family == 0x14) { - Ring0.ReadPciConfig(_miscellaneousControlAddress, CLOCK_POWER_TIMING_CONTROL_0_REGISTER, out uint value); + uint value = _pawnModule.ReadMiscCtl(Index, CLOCK_POWER_TIMING_CONTROL_0_REGISTER); r.Append("PCI Register D18F3xD4: "); r.AppendLine(value.ToString("X8", CultureInfo.InvariantCulture)); } @@ -299,7 +177,7 @@ internal sealed class Amd10Cpu : AmdCpu // 3:0: current CPU core divisor ID least significant digit uint divisorIdMsd = (cofVidEax >> 4) & 0x1F; uint divisorIdLsd = cofVidEax & 0xF; - Ring0.ReadPciConfig(_miscellaneousControlAddress, CLOCK_POWER_TIMING_CONTROL_0_REGISTER, out uint value); + uint value = _pawnModule.ReadMiscCtl(Index, CLOCK_POWER_TIMING_CONTROL_0_REGISTER); uint frequencyId = value & 0x1F; return (frequencyId + 0x10) / (divisorIdMsd + (divisorIdLsd * 0.25) + 1); @@ -334,36 +212,39 @@ internal sealed class Amd10Cpu : AmdCpu if (_temperatureStream == null) { - if (_miscellaneousControlAddress != Interop.Ring0.INVALID_PCI_ADDRESS) + bool isValueValid = true; + uint value = 0; + try { - bool isValueValid = _hasSmuTemperatureRegister - ? ReadSmuRegister(SMU_REPORTED_TEMP_CTRL_OFFSET, out uint value) - : Ring0.ReadPciConfig(_miscellaneousControlAddress, REPORTED_TEMPERATURE_CONTROL_REGISTER, out value); + if (_hasSmuTemperatureRegister) + ReadSmuRegister(SMU_REPORTED_TEMP_CTRL_OFFSET, out value); + else + value = _pawnModule.ReadMiscCtl(Index, REPORTED_TEMPERATURE_CONTROL_REGISTER); + } + catch + { + isValueValid = false; + } - if (isValueValid) + if (isValueValid) + { + if ((_family == 0x15 || _family == 0x16) && (value & 0x30000) == 0x3000) { - if ((_family == 0x15 || _family == 0x16) && (value & 0x30000) == 0x3000) + if (_family == 0x15 && (_model & 0xF0) == 0x00) { - if (_family == 0x15 && (_model & 0xF0) == 0x00) - { - _coreTemperature.Value = (((value >> 21) & 0x7FC) / 8.0f) + _coreTemperature.Parameters[0].Value - 49; - } - else - { - _coreTemperature.Value = (((value >> 21) & 0x7FF) / 8.0f) + _coreTemperature.Parameters[0].Value - 49; - } + _coreTemperature.Value = (((value >> 21) & 0x7FC) / 8.0f) + _coreTemperature.Parameters[0].Value - 49; } else { - _coreTemperature.Value = (((value >> 21) & 0x7FF) / 8.0f) + _coreTemperature.Parameters[0].Value; + _coreTemperature.Value = (((value >> 21) & 0x7FF) / 8.0f) + _coreTemperature.Parameters[0].Value - 49; } - - ActivateSensor(_coreTemperature); } else { - DeactivateSensor(_coreTemperature); + _coreTemperature.Value = (((value >> 21) & 0x7FF) / 8.0f) + _coreTemperature.Parameters[0].Value; } + + ActivateSensor(_coreTemperature); } else { @@ -393,7 +274,7 @@ internal sealed class Amd10Cpu : AmdCpu { Thread.Sleep(1); - if (Ring0.ReadMsr(COFVID_STATUS, out uint curEax, out uint _, _cpuId[i][0].Affinity)) + if (_pawnModule.ReadMsr(COFVID_STATUS, out uint curEax, out uint _, _cpuId[i][0].Affinity)) { double multiplier = GetCoreMultiplier(curEax); @@ -441,64 +322,46 @@ internal sealed class Amd10Cpu : AmdCpu if (_cStatesResidency != null) { + var results = _pawnModule.ReadCstateResidency(); for (int i = 0; i < _cStatesResidency.Length; i++) { - Ring0.WriteIoPort(CSTATES_IO_PORT, (byte)(_cStatesIoOffset + i)); - _cStatesResidency[i].Value = Ring0.ReadIoPort(CSTATES_IO_PORT + 1) / 256f * 100; + _cStatesResidency[i].Value = results[i] / 256f * 100; } } } - private static bool ReadSmuRegister(uint address, out uint value) + private bool ReadSmuRegister(uint address, out uint value) { - if (Mutexes.WaitPciBus(10)) - { - if (!Ring0.WritePciConfig(0, 0xB8, address)) - { - value = 0; - - Mutexes.ReleasePciBus(); - return false; - } - - bool result = Ring0.ReadPciConfig(0, 0xBC, out value); - - Mutexes.ReleasePciBus(); - return result; - } - value = 0; - return false; + if (!Mutexes.WaitPciBus(10)) + return false; + + try + { + value = _pawnModule.ReadSmu(address); + return true; + } + catch + { + return false; + } + finally + { + Mutexes.ReleasePciBus(); + } } public override void Close() { - _temperatureStream?.Close(); base.Close(); + _temperatureStream?.Close(); + _pawnModule.Close(); } // ReSharper disable InconsistentNaming private const uint CLOCK_POWER_TIMING_CONTROL_0_REGISTER = 0xD4; - private const uint COFVID_STATUS = 0xC0010071; - private const uint CSTATES_IO_PORT = 0xCD6; - private const uint SMU_REPORTED_TEMP_CTRL_OFFSET = 0xD8200CA4; - private const uint HWCR = 0xC0010015; - private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3; - private const uint P_STATE_0 = 0xC0010064; - private const uint PERF_CTL_0 = 0xC0010000; - private const uint PERF_CTR_0 = 0xC0010004; private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4; - - private const ushort FAMILY_10H_MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1203; - private const ushort FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1303; - private const ushort FAMILY_12H_MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1703; - private const ushort FAMILY_14H_MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1703; - private const ushort FAMILY_15H_MODEL_00_MISC_CONTROL_DEVICE_ID = 0x1603; - private const ushort FAMILY_15H_MODEL_10_MISC_CONTROL_DEVICE_ID = 0x1403; - private const ushort FAMILY_15H_MODEL_30_MISC_CONTROL_DEVICE_ID = 0x141D; - private const ushort FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID = 0x1573; - private const ushort FAMILY_15H_MODEL_70_MISC_CONTROL_DEVICE_ID = 0x15B3; - private const ushort FAMILY_16H_MODEL_00_MISC_CONTROL_DEVICE_ID = 0x1533; - private const ushort FAMILY_16H_MODEL_30_MISC_CONTROL_DEVICE_ID = 0x1583; + private const uint COFVID_STATUS = 0xC0010071; + private const uint SMU_REPORTED_TEMP_CTRL_OFFSET = 0xD8200CA4; // ReSharper restore InconsistentNaming } diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/Amd17Cpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/Amd17Cpu.cs index 63081be..0e5fe50 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/Amd17Cpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/Amd17Cpu.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using LibreHardwareMonitor.PawnIo; namespace LibreHardwareMonitor.Hardware.Cpu; @@ -15,9 +16,12 @@ internal sealed class Amd17Cpu : AmdCpu private readonly Processor _processor; private readonly Dictionary _sensorTypeIndex; private readonly RyzenSMU _smu; + private readonly AmdFamily17 _pawnModule; public Amd17Cpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings) { + _pawnModule = new AmdFamily17(); + _sensorTypeIndex = new Dictionary(); foreach (SensorType type in Enum.GetValues(typeof(SensorType))) { @@ -26,7 +30,7 @@ internal sealed class Amd17Cpu : AmdCpu _sensorTypeIndex[SensorType.Load] = _active.Count(x => x.SensorType == SensorType.Load); - _smu = new RyzenSMU(_family, _model, _packageType); + _smu = new RyzenSMU(); // Add all numa nodes. // Register ..1E_2, [10:8] + 1 @@ -65,11 +69,6 @@ internal sealed class Amd17Cpu : AmdCpu Update(); } - protected override uint[] GetMsrs() - { - return new[] { PERF_CTL_0, PERF_CTR_0, HWCR, MSR_PSTATE_0, COFVID_STATUS }; - } - public override string GetReport() { StringBuilder r = new(); @@ -78,6 +77,14 @@ internal sealed class Amd17Cpu : AmdCpu return r.ToString(); } + /// + public override void Close() + { + base.Close(); + _pawnModule.Close(); + _smu.Close(); + } + public override void Update() { base.Update(); @@ -160,7 +167,7 @@ internal sealed class Amd17Cpu : AmdCpu // TU [19:16] // ESU [12:8] -> Unit 15.3 micro Joule per increment (default), 1/2^ESU micro Joule // PU [3:0] - Ring0.ReadMsr(MSR_PWR_UNIT, out uint eax, out uint _); + _cpu._pawnModule.ReadMsr(MSR_PWR_UNIT, out uint eax, out uint _); int esu = (int)((eax >> 8) & 0x1F); double energyBaseUnit = Math.Pow(0.5,esu); @@ -168,7 +175,7 @@ internal sealed class Amd17Cpu : AmdCpu // MSRC001_029B // total_energy [31:0] DateTime sampleTime = DateTime.UtcNow; - Ring0.ReadMsr(MSR_PKG_ENERGY_STAT, out eax, out _); + _cpu._pawnModule.ReadMsr(MSR_PKG_ENERGY_STAT, out eax, out _); uint totalEnergy = eax; @@ -180,13 +187,11 @@ internal sealed class Amd17Cpu : AmdCpu { // THM_TCON_CUR_TMP // CUR_TEMP [31:21] - Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_THM_TCON_CUR_TMP); - Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint temperature); + uint temperature = _cpu._pawnModule.ReadSmn(F17H_M01H_THM_TCON_CUR_TMP); // SVI0_TFN_PLANE0 [0] // SVI0_TFN_PLANE1 [1] - Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x8); - Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smuSvi0Tfn); + smuSvi0Tfn = _cpu._pawnModule.ReadSmn(F17H_M01H_SVI + 0x8); bool supportsPerCcdTemperatures = false; @@ -224,13 +229,11 @@ internal sealed class Amd17Cpu : AmdCpu // SVI0_PLANE0_VDDCOR [24:16] // SVI0_PLANE0_IDDCOR [7:0] - Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, sviPlane0Offset); - Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smuSvi0TelPlane0); + smuSvi0TelPlane0 = _cpu._pawnModule.ReadSmn(sviPlane0Offset); // SVI0_PLANE1_VDDCOR [24:16] // SVI0_PLANE1_IDDCOR [7:0] - Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, sviPlane1Offset); - Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out smuSvi0TelPlane1); + smuSvi0TelPlane1 = _cpu._pawnModule.ReadSmn(sviPlane1Offset); ThreadAffinity.Set(previousAffinity); @@ -241,7 +244,7 @@ internal sealed class Amd17Cpu : AmdCpu _lastSampleTime = sampleTime; _lastPwrValue = totalEnergy; } - + _lastSampleTime = sampleTime; // ticks diff @@ -308,11 +311,12 @@ internal sealed class Amd17Cpu : AmdCpu { for (uint i = 0; i < _ccdTemperatures.Length; i++) { + uint ccd1Offset = 0; if (cpuId.Model is 0x61 or 0x44) // Raphael or GraniteRidge - Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M61H_CCD1_TEMP + (i * 0x4)); + ccd1Offset = F17H_M61H_CCD1_TEMP + i * 0x4; else - Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M70H_CCD1_TEMP + (i * 0x4)); - Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint ccdRawTemp); + ccd1Offset = F17H_M70H_CCD1_TEMP + i * 0x4; + uint ccdRawTemp = _cpu._pawnModule.ReadSmn(ccd1Offset); ccdRawTemp &= 0xFFF; float ccdTemp = ((ccdRawTemp * 125) - 305000) * 0.001f; @@ -410,7 +414,7 @@ internal sealed class Amd17Cpu : AmdCpu _cpu.ActivateSensor(sensor.Value); } } - } + } } public void UpdateVirtualSensor() @@ -427,7 +431,7 @@ internal sealed class Amd17Cpu : AmdCpu private double GetTimeStampCounterMultiplier() { - Ring0.ReadMsr(MSR_PSTATE_0, out uint eax, out _); + _cpu._pawnModule.ReadMsr(MSR_PSTATE_0, out uint eax, out _); if (_cpu._family == 0x1a) { @@ -538,8 +542,9 @@ internal sealed class Amd17Cpu : AmdCpu private ulong _mperfDelta = 0; private ulong _aperfDelta = 0; - private CpuId _cpu; - public CpuId Cpu { get { return _cpu; } } + private CpuId _cpuId; + private Amd17Cpu _cpu; + public CpuId Cpu { get { return _cpuId; } } public TimeSpan SampleDuration { get; private set; }= TimeSpan.Zero; public double EffectiveClock { get; private set; } = 0; @@ -547,9 +552,10 @@ internal sealed class Amd17Cpu : AmdCpu public ulong MperfDelta { get { return _mperfDelta; } } public ulong AperfDelta { get { return _aperfDelta; } } - public CpuThread(CpuId cpu) + public CpuThread(Amd17Cpu cpu, CpuId cpuId) { _cpu = cpu; + _cpuId = cpuId; } public void ReadPerformanceCounter() @@ -560,10 +566,10 @@ internal sealed class Amd17Cpu : AmdCpu // performance counter // MSRC000_00E7, P0 state counter - Ring0.ReadMsr(MSR_MPERF_RO, out ulong edxeax); + _cpu._pawnModule.ReadMsr(MSR_MPERF_RO, out ulong edxeax); _mperf = edxeax; // MSRC000_00E8, C0 state counter - Ring0.ReadMsr(MSR_APERF_RO, out edxeax); + _cpu._pawnModule.ReadMsr(MSR_APERF_RO, out edxeax); _aperf = edxeax; } @@ -653,9 +659,9 @@ internal sealed class Amd17Cpu : AmdCpu public List Threads { get; } = new List(); - public void AppedThread(CpuId cpu) + public void AppedThread(CpuId cpuId) { - CpuThread t = new CpuThread(cpu); + CpuThread t = new CpuThread(_cpu, cpuId); Threads.Add(t); } @@ -671,14 +677,14 @@ internal sealed class Amd17Cpu : AmdCpu // TU [19:16] // ESU [12:8] -> Unit 15.3 micro Joule per increment (default), 1/2^ESU micro Joule // PU [3:0] - Ring0.ReadMsr(MSR_PWR_UNIT, out uint eax, out uint _); + _cpu._pawnModule.ReadMsr(MSR_PWR_UNIT, out uint eax, out uint _); int esu = (int)((eax >> 8) & 0x1F); double energyBaseUnit = Math.Pow(0.5, esu); // MSRC001_029A // total_energy [31:0] DateTime sampleTime = DateTime.UtcNow; - Ring0.ReadMsr(MSR_CORE_ENERGY_STAT, out eax, out _); + _cpu._pawnModule.ReadMsr(MSR_CORE_ENERGY_STAT, out eax, out _); uint totalEnergy = eax; // MSRC001_0293 @@ -687,7 +693,7 @@ internal sealed class Amd17Cpu : AmdCpu // CurCpuDfsId [13:8] // CurCpuFid [7:0] zen1..4 // CurCpuFid [11:0] zen5 - Ring0.ReadMsr(MSR_HARDWARE_PSTATE_STATUS, out eax, out _); + _cpu._pawnModule.ReadMsr(MSR_HARDWARE_PSTATE_STATUS, out eax, out _); uint msrPstate = eax; int curCpuVid = (int)((eax >> 14) & 0xff); diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/AmdCpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/AmdCpu.cs index e1a4360..c0a1d3a 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/AmdCpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/AmdCpu.cs @@ -6,31 +6,5 @@ namespace LibreHardwareMonitor.Hardware.Cpu; -internal abstract class AmdCpu : GenericCpu -{ - protected AmdCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings) - { } - - protected uint GetPciAddress(byte function, ushort deviceId) - { - // assemble the pci address - uint address = Ring0.GetPciAddress(PCI_BUS, (byte)(PCI_BASE_DEVICE + Index), function); - - // verify that we have the correct bus, device and function - if (!Ring0.ReadPciConfig(address, DEVICE_VENDOR_ID_REGISTER, out uint deviceVendor)) - return Interop.Ring0.INVALID_PCI_ADDRESS; - - if (deviceVendor != (deviceId << 16 | AMD_VENDOR_ID)) - return Interop.Ring0.INVALID_PCI_ADDRESS; - - return address; - } - - // ReSharper disable InconsistentNaming - private const ushort AMD_VENDOR_ID = 0x1022; - private const byte DEVICE_VENDOR_ID_REGISTER = 0; - private const byte PCI_BASE_DEVICE = 0x18; - - private const byte PCI_BUS = 0; - // ReSharper restore InconsistentNaming -} \ No newline at end of file +internal abstract class AmdCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) + : GenericCpu(processorIndex, cpuId, settings); diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/GenericCpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/GenericCpu.cs index f7de8cf..61010f1 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/GenericCpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/GenericCpu.cs @@ -192,24 +192,6 @@ public class GenericCpu : Hardware error = beginError + endError; } - private static void AppendMsrData(StringBuilder r, uint msr, GroupAffinity affinity) - { - if (Ring0.ReadMsr(msr, out uint eax, out uint edx, affinity)) - { - r.Append(" "); - r.Append(msr.ToString("X8", CultureInfo.InvariantCulture)); - r.Append(" "); - r.Append(edx.ToString("X8", CultureInfo.InvariantCulture)); - r.Append(" "); - r.Append(eax.ToString("X8", CultureInfo.InvariantCulture)); - r.AppendLine(); - } - } - - protected virtual uint[] GetMsrs() - { - return null; - } public override string GetReport() { @@ -242,21 +224,6 @@ public class GenericCpu : Hardware r.AppendLine(string.Format(CultureInfo.InvariantCulture, "Time Stamp Counter Frequency: {0} MHz", Math.Round(TimeStampCounterFrequency * 100) * 0.01)); r.AppendLine(); - uint[] msrArray = GetMsrs(); - if (msrArray is { Length: > 0 }) - { - for (int i = 0; i < _cpuId.Length; i++) - { - r.AppendLine("MSR Core #" + (i + 1)); - r.AppendLine(); - r.AppendLine(" MSR EDX EAX"); - foreach (uint msr in msrArray) - AppendMsrData(r, msr, _cpuId[i][0].Affinity); - - r.AppendLine(); - } - } - return r.ToString(); } diff --git a/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs b/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs index 21156a4..87cb66d 100644 --- a/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Cpu/IntelCpu.cs @@ -1,748 +1,742 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// Partial Copyright (C) Michael Möller and Contributors. -// All Rights Reserved. - -using System; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; - -namespace LibreHardwareMonitor.Hardware.Cpu; - -internal sealed class IntelCpu : GenericCpu -{ - private readonly Sensor _busClock; - private readonly Sensor _coreAvg; - private readonly Sensor[] _coreClocks; - private readonly Sensor _coreMax; - private readonly Sensor[] _coreTemperatures; - private readonly Sensor[] _coreVIDs; - private readonly Sensor _coreVoltage; - private readonly Sensor[] _distToTjMaxTemperatures; - - private readonly uint[] _energyStatusMsrs = { MSR_PKG_ENERGY_STATUS, MSR_PP0_ENERGY_STATUS, MSR_PP1_ENERGY_STATUS, MSR_DRAM_ENERGY_STATUS, MSR_PLATFORM_ENERGY_STATUS }; - private readonly uint[] _lastEnergyConsumed; - private readonly DateTime[] _lastEnergyTime; - - private readonly MicroArchitecture _microArchitecture; - private readonly Sensor _packageTemperature; - private readonly Sensor[] _powerSensors; - private readonly double _timeStampCounterMultiplier; - - public IntelCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings) - { - uint eax; - - // set tjMax - float[] tjMax; - switch (_family) - { - case 0x06: - { - switch (_model) - { - case 0x0F: // Intel Core 2 (65nm) - _microArchitecture = MicroArchitecture.Core; - tjMax = _stepping switch - { - // B2 - 0x06 => _coreCount switch - { - 2 => Floats(80 + 10), - 4 => Floats(90 + 10), - _ => Floats(85 + 10) - }, - // G0 - 0x0B => Floats(90 + 10), - // M0 - 0x0D => Floats(85 + 10), - _ => Floats(85 + 10) - }; - break; - - case 0x17: // Intel Core 2 (45nm) - _microArchitecture = MicroArchitecture.Core; - tjMax = Floats(100); - break; - - case 0x1C: // Intel Atom (45nm) - _microArchitecture = MicroArchitecture.Atom; - tjMax = _stepping switch - { - // C0 - 0x02 => Floats(90), - // A0, B0 - 0x0A => Floats(100), - _ => Floats(90) - }; - break; - - case 0x1A: // Intel Core i7 LGA1366 (45nm) - case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) - case 0x1F: // Intel Core i5, i7 - case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) - case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core - case 0x2E: // Intel Xeon Processor 7500 series (45nm) - case 0x2F: // Intel Xeon Processor (32nm) - _microArchitecture = MicroArchitecture.Nehalem; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x2A: // Intel Core i5, i7 2xxx LGA1155 (32nm) - case 0x2D: // Next Generation Intel Xeon, i7 3xxx LGA2011 (32nm) - _microArchitecture = MicroArchitecture.SandyBridge; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x3A: // Intel Core i5, i7 3xxx LGA1155 (22nm) - case 0x3E: // Intel Core i7 4xxx LGA2011 (22nm) - _microArchitecture = MicroArchitecture.IvyBridge; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x3C: // Intel Core i5, i7 4xxx LGA1150 (22nm) - case 0x3F: // Intel Xeon E5-2600/1600 v3, Core i7-59xx - // LGA2011-v3, Haswell-E (22nm) - case 0x45: // Intel Core i5, i7 4xxxU (22nm) - case 0x46: - _microArchitecture = MicroArchitecture.Haswell; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x3D: // Intel Core M-5xxx (14nm) - case 0x47: // Intel i5, i7 5xxx, Xeon E3-1200 v4 (14nm) - case 0x4F: // Intel Xeon E5-26xx v4 - case 0x56: // Intel Xeon D-15xx - _microArchitecture = MicroArchitecture.Broadwell; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x36: // Intel Atom S1xxx, D2xxx, N2xxx (32nm) - _microArchitecture = MicroArchitecture.Atom; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x37: // Intel Atom E3xxx, Z3xxx (22nm) - case 0x4A: - case 0x4D: // Intel Atom C2xxx (22nm) - case 0x5A: - case 0x5D: - _microArchitecture = MicroArchitecture.Silvermont; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x4E: - case 0x5E: // Intel Core i5, i7 6xxxx LGA1151 (14nm) - case 0x55: // Intel Core X i7, i9 7xxx LGA2066 (14nm) - _microArchitecture = MicroArchitecture.Skylake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x4C: // Intel Airmont (Cherry Trail, Braswell) - _microArchitecture = MicroArchitecture.Airmont; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x8E: // Intel Core i5, i7 7xxxx (14nm) (Kaby Lake) and 8xxxx (14nm++) (Coffee Lake) - case 0x9E: - _microArchitecture = MicroArchitecture.KabyLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x5C: // Goldmont (Apollo Lake) - case 0x5F: // (Denverton) - _microArchitecture = MicroArchitecture.Goldmont; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x7A: // Goldmont plus (Gemini Lake) - _microArchitecture = MicroArchitecture.GoldmontPlus; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x66: // Intel Core i3 8xxx (10nm) (Cannon Lake) - _microArchitecture = MicroArchitecture.CannonLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x7D: // Intel Core i3, i5, i7 10xxx (10nm) (Ice Lake) - case 0x7E: - case 0x6A: // Ice Lake server - case 0x6C: - _microArchitecture = MicroArchitecture.IceLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0xA5: - case 0xA6: // Intel Core i3, i5, i7 10xxxU (14nm) - _microArchitecture = MicroArchitecture.CometLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x86: // Tremont (10nm) (Elkhart Lake, Skyhawk Lake) - _microArchitecture = MicroArchitecture.Tremont; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x8C: // Tiger Lake (Intel 10 nm SuperFin, Gen. 11) - case 0x8D: - _microArchitecture = MicroArchitecture.TigerLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x97: // Alder Lake (Intel 7 (10ESF), Gen. 12) - case 0x9A: // Alder Lake-L (Intel 7 (10ESF), Gen. 12) - case 0xBE: // Alder Lake-N (Intel 7 (10ESF), Gen. 12) - _microArchitecture = MicroArchitecture.AlderLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0xB7: // Raptor Lake (Intel 7 (10ESF), Gen. 13) - case 0xBA: // Raptor Lake-P (Intel 7 (10ESF), Gen. 13) - case 0xBF: // Raptor Lake-N (Intel 7 (10ESF), Gen. 13) - _microArchitecture = MicroArchitecture.RaptorLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0xAC: // Meteor Lake (Intel 4, TSMC N5/N6, Gen. 14) - case 0xAA: // Meteor Lake-L (Intel 4, TSMC N5/N6, Gen. 14) - _microArchitecture = MicroArchitecture.MeteorLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0x9C: // Jasper Lake (10nm) - _microArchitecture = MicroArchitecture.JasperLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0xA7: // Intel Core i5, i6, i7 11xxx (14nm) (Rocket Lake) - _microArchitecture = MicroArchitecture.RocketLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0xC5: // Intel Core Ultra 9 200 Series ArrowLake - case 0xC6: // Intel Core Ultra 7 200 Series ArrowLake - _microArchitecture = MicroArchitecture.ArrowLake; - tjMax = GetTjMaxFromMsr(); - break; - - case 0xBD: // Intel Core Ultra 5/7 200 Series LunarLake - _microArchitecture = MicroArchitecture.LunarLake; - tjMax = GetTjMaxFromMsr(); - break; - case 0x8F: // Intel Xeon W5-3435X // SapphireRapids - _microArchitecture = MicroArchitecture.SapphireRapids; - tjMax = GetTjMaxFromMsr(); - break; - case 0x96: // Intel Celeron ElkhartLake - _microArchitecture = MicroArchitecture.ElkhartLake; - tjMax = GetTjMaxFromMsr(); - break; - - default: - _microArchitecture = MicroArchitecture.Unknown; - tjMax = Floats(100); - break; - } - } - - break; - case 0x0F: - switch (_model) - { - case 0x00: // Pentium 4 (180nm) - case 0x01: // Pentium 4 (130nm) - case 0x02: // Pentium 4 (130nm) - case 0x03: // Pentium 4, Celeron D (90nm) - case 0x04: // Pentium 4, Pentium D, Celeron D (90nm) - case 0x06: // Pentium 4, Pentium D, Celeron D (65nm) - _microArchitecture = MicroArchitecture.NetBurst; - tjMax = Floats(100); - break; - - default: - _microArchitecture = MicroArchitecture.Unknown; - tjMax = Floats(100); - break; - } - - break; - default: - _microArchitecture = MicroArchitecture.Unknown; - tjMax = Floats(100); - break; - } - - // set timeStampCounterMultiplier - switch (_microArchitecture) - { - case MicroArchitecture.Atom: - case MicroArchitecture.Core: - case MicroArchitecture.NetBurst: - if (Ring0.ReadMsr(IA32_PERF_STATUS, out uint _, out uint edx)) - _timeStampCounterMultiplier = ((edx >> 8) & 0x1f) + (0.5 * ((edx >> 14) & 1)); - - break; - case MicroArchitecture.Airmont: - case MicroArchitecture.AlderLake: - case MicroArchitecture.ArrowLake: - case MicroArchitecture.Broadwell: - case MicroArchitecture.CannonLake: - case MicroArchitecture.CometLake: - case MicroArchitecture.Goldmont: - case MicroArchitecture.GoldmontPlus: - case MicroArchitecture.Haswell: - case MicroArchitecture.IceLake: - case MicroArchitecture.IvyBridge: - case MicroArchitecture.JasperLake: - case MicroArchitecture.KabyLake: - case MicroArchitecture.LunarLake: - case MicroArchitecture.Nehalem: - case MicroArchitecture.MeteorLake: - case MicroArchitecture.RaptorLake: - case MicroArchitecture.RocketLake: - case MicroArchitecture.SandyBridge: - case MicroArchitecture.Silvermont: - case MicroArchitecture.Skylake: - case MicroArchitecture.TigerLake: - case MicroArchitecture.SapphireRapids: - case MicroArchitecture.ElkhartLake: - case MicroArchitecture.Tremont: - if (Ring0.ReadMsr(MSR_PLATFORM_INFO, out eax, out uint _)) - _timeStampCounterMultiplier = (eax >> 8) & 0xff; - - break; - default: - _timeStampCounterMultiplier = 0; - break; - } - - int coreSensorId = 0; - - //core temp avg and max value - //is only available when the cpu has more than 1 core - if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown && _coreCount > 1) - { - _coreMax = new Sensor("Core Max", coreSensorId, SensorType.Temperature, this, settings); - ActivateSensor(_coreMax); - coreSensorId++; - - _coreAvg = new Sensor("Core Average", coreSensorId, SensorType.Temperature, this, settings); - ActivateSensor(_coreAvg); - coreSensorId++; - } - else - { - _coreMax = null; - _coreAvg = null; - } - - // check if processor supports a digital thermal sensor at core level - if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown) - { - _coreTemperatures = new Sensor[_coreCount]; - for (int i = 0; i < _coreTemperatures.Length; i++) - { - _coreTemperatures[i] = new Sensor(CoreString(i), - coreSensorId, - SensorType.Temperature, - this, - new[] - { - new ParameterDescription("TjMax [°C]", "TjMax temperature of the core sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[i]), - new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) - }, - settings); - - ActivateSensor(_coreTemperatures[i]); - coreSensorId++; - } - } - else - _coreTemperatures = Array.Empty(); - - // check if processor supports a digital thermal sensor at package level - if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown) - { - _packageTemperature = new Sensor("CPU Package", - coreSensorId, - SensorType.Temperature, - this, - new[] - { - new ParameterDescription("TjMax [°C]", "TjMax temperature of the package sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[0]), - new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) - }, - settings); - - ActivateSensor(_packageTemperature); - coreSensorId++; - } - - // dist to tjmax sensor - if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown) - { - _distToTjMaxTemperatures = new Sensor[_coreCount]; - for (int i = 0; i < _distToTjMaxTemperatures.Length; i++) - { - _distToTjMaxTemperatures[i] = new Sensor(CoreString(i) + " Distance to TjMax", coreSensorId, SensorType.Temperature, this, settings); - ActivateSensor(_distToTjMaxTemperatures[i]); - coreSensorId++; - } - } - else - _distToTjMaxTemperatures = Array.Empty(); - - _busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); - _coreClocks = new Sensor[_coreCount]; - for (int i = 0; i < _coreClocks.Length; i++) - { - _coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings); - if (HasTimeStampCounter && _microArchitecture != MicroArchitecture.Unknown) - ActivateSensor(_coreClocks[i]); - } - - if (_microArchitecture is MicroArchitecture.Airmont or - MicroArchitecture.AlderLake or - MicroArchitecture.ArrowLake or - MicroArchitecture.Broadwell or - MicroArchitecture.CannonLake or - MicroArchitecture.CometLake or - MicroArchitecture.Goldmont or - MicroArchitecture.GoldmontPlus or - MicroArchitecture.Haswell or - MicroArchitecture.IceLake or - MicroArchitecture.IvyBridge or - MicroArchitecture.JasperLake or - MicroArchitecture.KabyLake or - MicroArchitecture.LunarLake or - MicroArchitecture.MeteorLake or - MicroArchitecture.RaptorLake or - MicroArchitecture.RocketLake or - MicroArchitecture.SandyBridge or - MicroArchitecture.Silvermont or - MicroArchitecture.Skylake or - MicroArchitecture.TigerLake or - MicroArchitecture.SapphireRapids or - MicroArchitecture.ElkhartLake or - MicroArchitecture.Tremont) - { - _powerSensors = new Sensor[_energyStatusMsrs.Length]; - _lastEnergyTime = new DateTime[_energyStatusMsrs.Length]; - _lastEnergyConsumed = new uint[_energyStatusMsrs.Length]; - - if (Ring0.ReadMsr(MSR_RAPL_POWER_UNIT, out eax, out uint _)) - { - EnergyUnitsMultiplier = _microArchitecture switch - { - MicroArchitecture.Silvermont or MicroArchitecture.Airmont => 1.0e-6f * (1 << (int)((eax >> 8) & 0x1F)), - _ => 1.0f / (1 << (int)((eax >> 8) & 0x1F)) - }; - } - - if (EnergyUnitsMultiplier != 0) - { - string[] powerSensorLabels = { "CPU Package", "CPU Cores", "CPU Graphics", "CPU Memory", "CPU Platform" }; - - for (int i = 0; i < _energyStatusMsrs.Length; i++) - { - if (!Ring0.ReadMsr(_energyStatusMsrs[i], out eax, out uint _)) - continue; - - // Don't show the "GPU Graphics" sensor on windows, it will show up under the GPU instead. - if (i == 2 && !Software.OperatingSystem.IsUnix) - continue; - - _lastEnergyTime[i] = DateTime.UtcNow; - _lastEnergyConsumed[i] = eax; - _powerSensors[i] = new Sensor(powerSensorLabels[i], - i, - SensorType.Power, - this, - settings); - - ActivateSensor(_powerSensors[i]); - } - } - } - - if (Ring0.ReadMsr(IA32_PERF_STATUS, out eax, out uint _) && ((eax >> 32) & 0xFFFF) > 0) - { - _coreVoltage = new Sensor("CPU Core", 0, SensorType.Voltage, this, settings); - ActivateSensor(_coreVoltage); - } - - _coreVIDs = new Sensor[_coreCount]; - for (int i = 0; i < _coreVIDs.Length; i++) - { - _coreVIDs[i] = new Sensor(CoreString(i), i + 1, SensorType.Voltage, this, settings); - ActivateSensor(_coreVIDs[i]); - } - - Update(); - } - - public float EnergyUnitsMultiplier { get; } - - private float[] Floats(float f) - { - float[] result = new float[_coreCount]; - for (int i = 0; i < _coreCount; i++) - result[i] = f; - - return result; - } - - private float[] GetTjMaxFromMsr() - { - float[] result = new float[_coreCount]; - for (int i = 0; i < _coreCount; i++) - { - if (Ring0.ReadMsr(IA32_TEMPERATURE_TARGET, out uint eax, out uint _, _cpuId[i][0].Affinity)) - result[i] = (eax >> 16) & 0xFF; - else - result[i] = 100; - } - - return result; - } - - protected override uint[] GetMsrs() - { - return new[] - { - MSR_PLATFORM_INFO, - IA32_PERF_STATUS, - IA32_THERM_STATUS_MSR, - IA32_TEMPERATURE_TARGET, - IA32_PACKAGE_THERM_STATUS, - MSR_RAPL_POWER_UNIT, - MSR_PKG_ENERGY_STATUS, - MSR_DRAM_ENERGY_STATUS, - MSR_PP0_ENERGY_STATUS, - MSR_PP1_ENERGY_STATUS, - MSR_PLATFORM_ENERGY_STATUS, - }; - } - - public override string GetReport() - { - StringBuilder r = new(); - r.Append(base.GetReport()); - r.Append("MicroArchitecture: "); - r.AppendLine(_microArchitecture.ToString()); - r.Append("Time Stamp Counter Multiplier: "); - r.AppendLine(_timeStampCounterMultiplier.ToString(CultureInfo.InvariantCulture)); - r.AppendLine(); - return r.ToString(); - } - - public override void Update() - { - base.Update(); - - float coreMax = float.MinValue; - float coreAvg = 0; - uint eax; - - for (int i = 0; i < _coreTemperatures.Length; i++) - { - // if reading is valid - if (Ring0.ReadMsr(IA32_THERM_STATUS_MSR, out eax, out _, _cpuId[i][0].Affinity) && (eax & 0x80000000) != 0) - { - // get the dist from tjMax from bits 22:16 - float deltaT = (eax & 0x007F0000) >> 16; - float tjMax = _coreTemperatures[i].Parameters[0].Value; - float tSlope = _coreTemperatures[i].Parameters[1].Value; - _coreTemperatures[i].Value = tjMax - (tSlope * deltaT); - - coreAvg += (float)_coreTemperatures[i].Value; - if (coreMax < _coreTemperatures[i].Value) - coreMax = (float)_coreTemperatures[i].Value; - - _distToTjMaxTemperatures[i].Value = deltaT; - } - else - { - _coreTemperatures[i].Value = null; - _distToTjMaxTemperatures[i].Value = null; - } - } - - //calculate average cpu temperature over all cores - if (_coreMax != null && coreMax != float.MinValue) - { - _coreMax.Value = coreMax; - coreAvg /= _coreTemperatures.Length; - _coreAvg.Value = coreAvg; - } - - if (_packageTemperature != null) - { - // if reading is valid - if (Ring0.ReadMsr(IA32_PACKAGE_THERM_STATUS, out eax, out _, _cpuId[0][0].Affinity) && (eax & 0x80000000) != 0) - { - // get the dist from tjMax from bits 22:16 - float deltaT = (eax & 0x007F0000) >> 16; - float tjMax = _packageTemperature.Parameters[0].Value; - float tSlope = _packageTemperature.Parameters[1].Value; - _packageTemperature.Value = tjMax - (tSlope * deltaT); - } - else - { - _packageTemperature.Value = null; - } - } - - if (HasTimeStampCounter && _timeStampCounterMultiplier > 0) - { - double newBusClock = 0; - for (int i = 0; i < _coreClocks.Length; i++) - { - System.Threading.Thread.Sleep(1); - if (Ring0.ReadMsr(IA32_PERF_STATUS, out eax, out _, _cpuId[i][0].Affinity)) - { - newBusClock = TimeStampCounterFrequency / _timeStampCounterMultiplier; - switch (_microArchitecture) - { - case MicroArchitecture.Nehalem: - _coreClocks[i].Value = (float)((eax & 0xff) * newBusClock); - break; - case MicroArchitecture.Airmont: - case MicroArchitecture.AlderLake: - case MicroArchitecture.ArrowLake: - case MicroArchitecture.Broadwell: - case MicroArchitecture.CannonLake: - case MicroArchitecture.CometLake: - case MicroArchitecture.Goldmont: - case MicroArchitecture.GoldmontPlus: - case MicroArchitecture.Haswell: - case MicroArchitecture.IceLake: - case MicroArchitecture.IvyBridge: - case MicroArchitecture.JasperLake: - case MicroArchitecture.KabyLake: - case MicroArchitecture.LunarLake: - case MicroArchitecture.MeteorLake: - case MicroArchitecture.RaptorLake: - case MicroArchitecture.RocketLake: - case MicroArchitecture.SandyBridge: - case MicroArchitecture.Silvermont: - case MicroArchitecture.Skylake: - case MicroArchitecture.TigerLake: - case MicroArchitecture.SapphireRapids: - case MicroArchitecture.ElkhartLake: - case MicroArchitecture.Tremont: - _coreClocks[i].Value = (float)(((eax >> 8) & 0xff) * newBusClock); - break; - default: - _coreClocks[i].Value = (float)((((eax >> 8) & 0x1f) + (0.5 * ((eax >> 14) & 1))) * newBusClock); - break; - } - } - else - { - // if IA32_PERF_STATUS is not available, assume TSC frequency - _coreClocks[i].Value = (float)TimeStampCounterFrequency; - } - } - - if (newBusClock > 0) - { - _busClock.Value = (float)newBusClock; - ActivateSensor(_busClock); - } - } - - if (_powerSensors != null) - { - foreach (Sensor sensor in _powerSensors) - { - if (sensor == null) - continue; - - if (!Ring0.ReadMsr(_energyStatusMsrs[sensor.Index], out eax, out _)) - continue; - - DateTime time = DateTime.UtcNow; - uint energyConsumed = eax; - float deltaTime = (float)(time - _lastEnergyTime[sensor.Index]).TotalSeconds; - if (deltaTime < 0.01) - continue; - - sensor.Value = EnergyUnitsMultiplier * unchecked(energyConsumed - _lastEnergyConsumed[sensor.Index]) / deltaTime; - _lastEnergyTime[sensor.Index] = time; - _lastEnergyConsumed[sensor.Index] = energyConsumed; - } - } - - if (_coreVoltage != null && Ring0.ReadMsr(IA32_PERF_STATUS, out _, out uint edx)) - { - _coreVoltage.Value = ((edx >> 32) & 0xFFFF) / (float)(1 << 13); - } - - for (int i = 0; i < _coreVIDs.Length; i++) - { - if (Ring0.ReadMsr(IA32_PERF_STATUS, out _, out edx, _cpuId[i][0].Affinity) && ((edx >> 32) & 0xFFFF) > 0) - { - _coreVIDs[i].Value = ((edx >> 32) & 0xFFFF) / (float)(1 << 13); - ActivateSensor(_coreVIDs[i]); - } - else - { - DeactivateSensor(_coreVIDs[i]); - } - } - } - - [SuppressMessage("ReSharper", "IdentifierTypo")] - private enum MicroArchitecture - { - Airmont, - AlderLake, - Atom, - ArrowLake, // Gen. 15 (0xC6, -H = 0xC5) - Broadwell, - CannonLake, - CometLake, - Core, - Goldmont, - GoldmontPlus, - Haswell, - IceLake, - IvyBridge, - JasperLake, - KabyLake, - LunarLake, - Nehalem, - NetBurst, - MeteorLake, - RocketLake, - SandyBridge, - Silvermont, - Skylake, - TigerLake, - Tremont, - RaptorLake, - SapphireRapids, - ElkhartLake, - Unknown - } - - // ReSharper disable InconsistentNaming - private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1; - private const uint IA32_PERF_STATUS = 0x0198; - private const uint IA32_TEMPERATURE_TARGET = 0x01A2; - private const uint IA32_THERM_STATUS_MSR = 0x019C; - - private const uint MSR_DRAM_ENERGY_STATUS = 0x619; - private const uint MSR_PKG_ENERGY_STATUS = 0x611; - private const uint MSR_PLATFORM_INFO = 0xCE; - private const uint MSR_PP0_ENERGY_STATUS = 0x639; - private const uint MSR_PP1_ENERGY_STATUS = 0x641; - private const uint MSR_PLATFORM_ENERGY_STATUS = 0x64D; - - private const uint MSR_RAPL_POWER_UNIT = 0x606; - // ReSharper restore InconsistentNaming -} +// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) LibreHardwareMonitor and Contributors. +// Partial Copyright (C) Michael Möller and Contributors. +// All Rights Reserved. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Text; +using LibreHardwareMonitor.PawnIo; + +namespace LibreHardwareMonitor.Hardware.Cpu; + +internal sealed class IntelCpu : GenericCpu +{ + private readonly Sensor _busClock; + private readonly Sensor _coreAvg; + private readonly Sensor[] _coreClocks; + private readonly Sensor _coreMax; + private readonly Sensor[] _coreTemperatures; + private readonly Sensor[] _coreVIDs; + private readonly Sensor _coreVoltage; + private readonly Sensor[] _distToTjMaxTemperatures; + + private readonly uint[] _energyStatusMsrs = { MSR_PKG_ENERGY_STATUS, MSR_PP0_ENERGY_STATUS, MSR_PP1_ENERGY_STATUS, MSR_DRAM_ENERGY_STATUS, MSR_PLATFORM_ENERGY_STATUS }; + private readonly uint[] _lastEnergyConsumed; + private readonly DateTime[] _lastEnergyTime; + + private readonly MicroArchitecture _microArchitecture; + private readonly Sensor _packageTemperature; + private readonly Sensor[] _powerSensors; + private readonly double _timeStampCounterMultiplier; + + private readonly IntelMsr _pawnModule; + + public IntelCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings) + { + _pawnModule = new IntelMsr(); + + uint eax; + + // set tjMax + float[] tjMax; + switch (_family) + { + case 0x06: + { + switch (_model) + { + case 0x0F: // Intel Core 2 (65nm) + _microArchitecture = MicroArchitecture.Core; + tjMax = _stepping switch + { + // B2 + 0x06 => _coreCount switch + { + 2 => Floats(80 + 10), + 4 => Floats(90 + 10), + _ => Floats(85 + 10) + }, + // G0 + 0x0B => Floats(90 + 10), + // M0 + 0x0D => Floats(85 + 10), + _ => Floats(85 + 10) + }; + break; + + case 0x17: // Intel Core 2 (45nm) + _microArchitecture = MicroArchitecture.Core; + tjMax = Floats(100); + break; + + case 0x1C: // Intel Atom (45nm) + _microArchitecture = MicroArchitecture.Atom; + tjMax = _stepping switch + { + // C0 + 0x02 => Floats(90), + // A0, B0 + 0x0A => Floats(100), + _ => Floats(90) + }; + break; + + case 0x1A: // Intel Core i7 LGA1366 (45nm) + case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) + case 0x1F: // Intel Core i5, i7 + case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) + case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core + case 0x2E: // Intel Xeon Processor 7500 series (45nm) + case 0x2F: // Intel Xeon Processor (32nm) + _microArchitecture = MicroArchitecture.Nehalem; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x2A: // Intel Core i5, i7 2xxx LGA1155 (32nm) + case 0x2D: // Next Generation Intel Xeon, i7 3xxx LGA2011 (32nm) + _microArchitecture = MicroArchitecture.SandyBridge; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x3A: // Intel Core i5, i7 3xxx LGA1155 (22nm) + case 0x3E: // Intel Core i7 4xxx LGA2011 (22nm) + _microArchitecture = MicroArchitecture.IvyBridge; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x3C: // Intel Core i5, i7 4xxx LGA1150 (22nm) + case 0x3F: // Intel Xeon E5-2600/1600 v3, Core i7-59xx + // LGA2011-v3, Haswell-E (22nm) + case 0x45: // Intel Core i5, i7 4xxxU (22nm) + case 0x46: + _microArchitecture = MicroArchitecture.Haswell; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x3D: // Intel Core M-5xxx (14nm) + case 0x47: // Intel i5, i7 5xxx, Xeon E3-1200 v4 (14nm) + case 0x4F: // Intel Xeon E5-26xx v4 + case 0x56: // Intel Xeon D-15xx + _microArchitecture = MicroArchitecture.Broadwell; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x36: // Intel Atom S1xxx, D2xxx, N2xxx (32nm) + _microArchitecture = MicroArchitecture.Atom; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x37: // Intel Atom E3xxx, Z3xxx (22nm) + case 0x4A: + case 0x4D: // Intel Atom C2xxx (22nm) + case 0x5A: + case 0x5D: + _microArchitecture = MicroArchitecture.Silvermont; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x4E: + case 0x5E: // Intel Core i5, i7 6xxxx LGA1151 (14nm) + case 0x55: // Intel Core X i7, i9 7xxx LGA2066 (14nm) + _microArchitecture = MicroArchitecture.Skylake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x4C: // Intel Airmont (Cherry Trail, Braswell) + _microArchitecture = MicroArchitecture.Airmont; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x8E: // Intel Core i5, i7 7xxxx (14nm) (Kaby Lake) and 8xxxx (14nm++) (Coffee Lake) + case 0x9E: + _microArchitecture = MicroArchitecture.KabyLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x5C: // Goldmont (Apollo Lake) + case 0x5F: // (Denverton) + _microArchitecture = MicroArchitecture.Goldmont; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x7A: // Goldmont plus (Gemini Lake) + _microArchitecture = MicroArchitecture.GoldmontPlus; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x66: // Intel Core i3 8xxx (10nm) (Cannon Lake) + _microArchitecture = MicroArchitecture.CannonLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x7D: // Intel Core i3, i5, i7 10xxx (10nm) (Ice Lake) + case 0x7E: + case 0x6A: // Ice Lake server + case 0x6C: + _microArchitecture = MicroArchitecture.IceLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0xA5: + case 0xA6: // Intel Core i3, i5, i7 10xxxU (14nm) + _microArchitecture = MicroArchitecture.CometLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x86: // Tremont (10nm) (Elkhart Lake, Skyhawk Lake) + _microArchitecture = MicroArchitecture.Tremont; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x8C: // Tiger Lake (Intel 10 nm SuperFin, Gen. 11) + case 0x8D: + _microArchitecture = MicroArchitecture.TigerLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x97: // Alder Lake (Intel 7 (10ESF), Gen. 12) + case 0x9A: // Alder Lake-L (Intel 7 (10ESF), Gen. 12) + case 0xBE: // Alder Lake-N (Intel 7 (10ESF), Gen. 12) + _microArchitecture = MicroArchitecture.AlderLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0xB7: // Raptor Lake (Intel 7 (10ESF), Gen. 13) + case 0xBA: // Raptor Lake-P (Intel 7 (10ESF), Gen. 13) + case 0xBF: // Raptor Lake-N (Intel 7 (10ESF), Gen. 13) + _microArchitecture = MicroArchitecture.RaptorLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0xAC: // Meteor Lake (Intel 4, TSMC N5/N6, Gen. 14) + case 0xAA: // Meteor Lake-L (Intel 4, TSMC N5/N6, Gen. 14) + _microArchitecture = MicroArchitecture.MeteorLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0x9C: // Jasper Lake (10nm) + _microArchitecture = MicroArchitecture.JasperLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0xA7: // Intel Core i5, i6, i7 11xxx (14nm) (Rocket Lake) + _microArchitecture = MicroArchitecture.RocketLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0xC5: // Intel Core Ultra 9 200 Series ArrowLake + case 0xC6: // Intel Core Ultra 7 200 Series ArrowLake + _microArchitecture = MicroArchitecture.ArrowLake; + tjMax = GetTjMaxFromMsr(); + break; + + case 0xBD: // Intel Core Ultra 5/7 200 Series LunarLake + _microArchitecture = MicroArchitecture.LunarLake; + tjMax = GetTjMaxFromMsr(); + break; + case 0x8F: // Intel Xeon W5-3435X // SapphireRapids + _microArchitecture = MicroArchitecture.SapphireRapids; + tjMax = GetTjMaxFromMsr(); + break; + case 0x96: // Intel Celeron ElkhartLake + _microArchitecture = MicroArchitecture.ElkhartLake; + tjMax = GetTjMaxFromMsr(); + break; + + default: + _microArchitecture = MicroArchitecture.Unknown; + tjMax = Floats(100); + break; + } + } + + break; + case 0x0F: + switch (_model) + { + case 0x00: // Pentium 4 (180nm) + case 0x01: // Pentium 4 (130nm) + case 0x02: // Pentium 4 (130nm) + case 0x03: // Pentium 4, Celeron D (90nm) + case 0x04: // Pentium 4, Pentium D, Celeron D (90nm) + case 0x06: // Pentium 4, Pentium D, Celeron D (65nm) + _microArchitecture = MicroArchitecture.NetBurst; + tjMax = Floats(100); + break; + + default: + _microArchitecture = MicroArchitecture.Unknown; + tjMax = Floats(100); + break; + } + + break; + default: + _microArchitecture = MicroArchitecture.Unknown; + tjMax = Floats(100); + break; + } + + // set timeStampCounterMultiplier + switch (_microArchitecture) + { + case MicroArchitecture.Atom: + case MicroArchitecture.Core: + case MicroArchitecture.NetBurst: + if (_pawnModule.ReadMsr(IA32_PERF_STATUS, out uint _, out uint edx)) + _timeStampCounterMultiplier = ((edx >> 8) & 0x1f) + (0.5 * ((edx >> 14) & 1)); + + break; + case MicroArchitecture.Airmont: + case MicroArchitecture.AlderLake: + case MicroArchitecture.ArrowLake: + case MicroArchitecture.Broadwell: + case MicroArchitecture.CannonLake: + case MicroArchitecture.CometLake: + case MicroArchitecture.Goldmont: + case MicroArchitecture.GoldmontPlus: + case MicroArchitecture.Haswell: + case MicroArchitecture.IceLake: + case MicroArchitecture.IvyBridge: + case MicroArchitecture.JasperLake: + case MicroArchitecture.KabyLake: + case MicroArchitecture.LunarLake: + case MicroArchitecture.Nehalem: + case MicroArchitecture.MeteorLake: + case MicroArchitecture.RaptorLake: + case MicroArchitecture.RocketLake: + case MicroArchitecture.SandyBridge: + case MicroArchitecture.Silvermont: + case MicroArchitecture.Skylake: + case MicroArchitecture.TigerLake: + case MicroArchitecture.SapphireRapids: + case MicroArchitecture.ElkhartLake: + case MicroArchitecture.Tremont: + if (_pawnModule.ReadMsr(MSR_PLATFORM_INFO, out eax, out uint _)) + _timeStampCounterMultiplier = (eax >> 8) & 0xff; + + break; + default: + _timeStampCounterMultiplier = 0; + break; + } + + int coreSensorId = 0; + + //core temp avg and max value + //is only available when the cpu has more than 1 core + if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown && _coreCount > 1) + { + _coreMax = new Sensor("Core Max", coreSensorId, SensorType.Temperature, this, settings); + ActivateSensor(_coreMax); + coreSensorId++; + + _coreAvg = new Sensor("Core Average", coreSensorId, SensorType.Temperature, this, settings); + ActivateSensor(_coreAvg); + coreSensorId++; + } + else + { + _coreMax = null; + _coreAvg = null; + } + + // check if processor supports a digital thermal sensor at core level + if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown) + { + _coreTemperatures = new Sensor[_coreCount]; + for (int i = 0; i < _coreTemperatures.Length; i++) + { + _coreTemperatures[i] = new Sensor(CoreString(i), + coreSensorId, + SensorType.Temperature, + this, + new[] + { + new ParameterDescription("TjMax [°C]", "TjMax temperature of the core sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[i]), + new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) + }, + settings); + + ActivateSensor(_coreTemperatures[i]); + coreSensorId++; + } + } + else + _coreTemperatures = Array.Empty(); + + // check if processor supports a digital thermal sensor at package level + if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown) + { + _packageTemperature = new Sensor("CPU Package", + coreSensorId, + SensorType.Temperature, + this, + new[] + { + new ParameterDescription("TjMax [°C]", "TjMax temperature of the package sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[0]), + new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1) + }, + settings); + + ActivateSensor(_packageTemperature); + coreSensorId++; + } + + // dist to tjmax sensor + if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown) + { + _distToTjMaxTemperatures = new Sensor[_coreCount]; + for (int i = 0; i < _distToTjMaxTemperatures.Length; i++) + { + _distToTjMaxTemperatures[i] = new Sensor(CoreString(i) + " Distance to TjMax", coreSensorId, SensorType.Temperature, this, settings); + ActivateSensor(_distToTjMaxTemperatures[i]); + coreSensorId++; + } + } + else + _distToTjMaxTemperatures = Array.Empty(); + + _busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); + _coreClocks = new Sensor[_coreCount]; + for (int i = 0; i < _coreClocks.Length; i++) + { + _coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings); + if (HasTimeStampCounter && _microArchitecture != MicroArchitecture.Unknown) + ActivateSensor(_coreClocks[i]); + } + + if (_microArchitecture is MicroArchitecture.Airmont or + MicroArchitecture.AlderLake or + MicroArchitecture.ArrowLake or + MicroArchitecture.Broadwell or + MicroArchitecture.CannonLake or + MicroArchitecture.CometLake or + MicroArchitecture.Goldmont or + MicroArchitecture.GoldmontPlus or + MicroArchitecture.Haswell or + MicroArchitecture.IceLake or + MicroArchitecture.IvyBridge or + MicroArchitecture.JasperLake or + MicroArchitecture.KabyLake or + MicroArchitecture.LunarLake or + MicroArchitecture.MeteorLake or + MicroArchitecture.RaptorLake or + MicroArchitecture.RocketLake or + MicroArchitecture.SandyBridge or + MicroArchitecture.Silvermont or + MicroArchitecture.Skylake or + MicroArchitecture.TigerLake or + MicroArchitecture.SapphireRapids or + MicroArchitecture.ElkhartLake or + MicroArchitecture.Tremont) + { + _powerSensors = new Sensor[_energyStatusMsrs.Length]; + _lastEnergyTime = new DateTime[_energyStatusMsrs.Length]; + _lastEnergyConsumed = new uint[_energyStatusMsrs.Length]; + + if (_pawnModule.ReadMsr(MSR_RAPL_POWER_UNIT, out eax, out uint _)) + { + EnergyUnitsMultiplier = _microArchitecture switch + { + MicroArchitecture.Silvermont or MicroArchitecture.Airmont => 1.0e-6f * (1 << (int)((eax >> 8) & 0x1F)), + _ => 1.0f / (1 << (int)((eax >> 8) & 0x1F)) + }; + } + + if (EnergyUnitsMultiplier != 0) + { + string[] powerSensorLabels = { "CPU Package", "CPU Cores", "CPU Graphics", "CPU Memory", "CPU Platform" }; + + for (int i = 0; i < _energyStatusMsrs.Length; i++) + { + if (!_pawnModule.ReadMsr(_energyStatusMsrs[i], out eax, out uint _)) + continue; + + // Don't show the "GPU Graphics" sensor on windows, it will show up under the GPU instead. + if (i == 2 && !Software.OperatingSystem.IsUnix) + continue; + + _lastEnergyTime[i] = DateTime.UtcNow; + _lastEnergyConsumed[i] = eax; + _powerSensors[i] = new Sensor(powerSensorLabels[i], + i, + SensorType.Power, + this, + settings); + + ActivateSensor(_powerSensors[i]); + } + } + } + + if (_pawnModule.ReadMsr(IA32_PERF_STATUS, out eax, out uint _) && ((eax >> 32) & 0xFFFF) > 0) + { + _coreVoltage = new Sensor("CPU Core", 0, SensorType.Voltage, this, settings); + ActivateSensor(_coreVoltage); + } + + _coreVIDs = new Sensor[_coreCount]; + for (int i = 0; i < _coreVIDs.Length; i++) + { + _coreVIDs[i] = new Sensor(CoreString(i), i + 1, SensorType.Voltage, this, settings); + ActivateSensor(_coreVIDs[i]); + } + + Update(); + } + + public float EnergyUnitsMultiplier { get; } + + private float[] Floats(float f) + { + float[] result = new float[_coreCount]; + for (int i = 0; i < _coreCount; i++) + result[i] = f; + + return result; + } + + private float[] GetTjMaxFromMsr() + { + float[] result = new float[_coreCount]; + for (int i = 0; i < _coreCount; i++) + { + if (_pawnModule.ReadMsr(IA32_TEMPERATURE_TARGET, out uint eax, out uint _, _cpuId[i][0].Affinity)) + result[i] = (eax >> 16) & 0xFF; + else + result[i] = 100; + } + + return result; + } + + public override string GetReport() + { + StringBuilder r = new(); + r.Append(base.GetReport()); + r.Append("MicroArchitecture: "); + r.AppendLine(_microArchitecture.ToString()); + r.Append("Time Stamp Counter Multiplier: "); + r.AppendLine(_timeStampCounterMultiplier.ToString(CultureInfo.InvariantCulture)); + r.AppendLine(); + return r.ToString(); + } + + /// + public override void Close() + { + base.Close(); + _pawnModule.Close(); + } + + public override void Update() + { + base.Update(); + + float coreMax = float.MinValue; + float coreAvg = 0; + uint eax; + + for (int i = 0; i < _coreTemperatures.Length; i++) + { + // if reading is valid + if (_pawnModule.ReadMsr(IA32_THERM_STATUS_MSR, out eax, out _, _cpuId[i][0].Affinity) && (eax & 0x80000000) != 0) + { + // get the dist from tjMax from bits 22:16 + float deltaT = (eax & 0x007F0000) >> 16; + float tjMax = _coreTemperatures[i].Parameters[0].Value; + float tSlope = _coreTemperatures[i].Parameters[1].Value; + _coreTemperatures[i].Value = tjMax - (tSlope * deltaT); + + coreAvg += (float)_coreTemperatures[i].Value; + if (coreMax < _coreTemperatures[i].Value) + coreMax = (float)_coreTemperatures[i].Value; + + _distToTjMaxTemperatures[i].Value = deltaT; + } + else + { + _coreTemperatures[i].Value = null; + _distToTjMaxTemperatures[i].Value = null; + } + } + + //calculate average cpu temperature over all cores + if (_coreMax != null && coreMax != float.MinValue) + { + _coreMax.Value = coreMax; + coreAvg /= _coreTemperatures.Length; + _coreAvg.Value = coreAvg; + } + + if (_packageTemperature != null) + { + // if reading is valid + if (_pawnModule.ReadMsr(IA32_PACKAGE_THERM_STATUS, out eax, out _, _cpuId[0][0].Affinity) && (eax & 0x80000000) != 0) + { + // get the dist from tjMax from bits 22:16 + float deltaT = (eax & 0x007F0000) >> 16; + float tjMax = _packageTemperature.Parameters[0].Value; + float tSlope = _packageTemperature.Parameters[1].Value; + _packageTemperature.Value = tjMax - (tSlope * deltaT); + } + else + { + _packageTemperature.Value = null; + } + } + + if (HasTimeStampCounter && _timeStampCounterMultiplier > 0) + { + double newBusClock = 0; + for (int i = 0; i < _coreClocks.Length; i++) + { + System.Threading.Thread.Sleep(1); + if (_pawnModule.ReadMsr(IA32_PERF_STATUS, out eax, out _, _cpuId[i][0].Affinity)) + { + newBusClock = TimeStampCounterFrequency / _timeStampCounterMultiplier; + switch (_microArchitecture) + { + case MicroArchitecture.Nehalem: + _coreClocks[i].Value = (float)((eax & 0xff) * newBusClock); + break; + case MicroArchitecture.Airmont: + case MicroArchitecture.AlderLake: + case MicroArchitecture.ArrowLake: + case MicroArchitecture.Broadwell: + case MicroArchitecture.CannonLake: + case MicroArchitecture.CometLake: + case MicroArchitecture.Goldmont: + case MicroArchitecture.GoldmontPlus: + case MicroArchitecture.Haswell: + case MicroArchitecture.IceLake: + case MicroArchitecture.IvyBridge: + case MicroArchitecture.JasperLake: + case MicroArchitecture.KabyLake: + case MicroArchitecture.LunarLake: + case MicroArchitecture.MeteorLake: + case MicroArchitecture.RaptorLake: + case MicroArchitecture.RocketLake: + case MicroArchitecture.SandyBridge: + case MicroArchitecture.Silvermont: + case MicroArchitecture.Skylake: + case MicroArchitecture.TigerLake: + case MicroArchitecture.SapphireRapids: + case MicroArchitecture.ElkhartLake: + case MicroArchitecture.Tremont: + _coreClocks[i].Value = (float)(((eax >> 8) & 0xff) * newBusClock); + break; + default: + _coreClocks[i].Value = (float)((((eax >> 8) & 0x1f) + (0.5 * ((eax >> 14) & 1))) * newBusClock); + break; + } + } + else + { + // if IA32_PERF_STATUS is not available, assume TSC frequency + _coreClocks[i].Value = (float)TimeStampCounterFrequency; + } + } + + if (newBusClock > 0) + { + _busClock.Value = (float)newBusClock; + ActivateSensor(_busClock); + } + } + + if (_powerSensors != null) + { + foreach (Sensor sensor in _powerSensors) + { + if (sensor == null) + continue; + + if (!_pawnModule.ReadMsr(_energyStatusMsrs[sensor.Index], out eax, out _)) + continue; + + DateTime time = DateTime.UtcNow; + uint energyConsumed = eax; + float deltaTime = (float)(time - _lastEnergyTime[sensor.Index]).TotalSeconds; + if (deltaTime < 0.01) + continue; + + sensor.Value = EnergyUnitsMultiplier * unchecked(energyConsumed - _lastEnergyConsumed[sensor.Index]) / deltaTime; + _lastEnergyTime[sensor.Index] = time; + _lastEnergyConsumed[sensor.Index] = energyConsumed; + } + } + + if (_coreVoltage != null && _pawnModule.ReadMsr(IA32_PERF_STATUS, out _, out uint edx)) + { + _coreVoltage.Value = ((edx >> 32) & 0xFFFF) / (float)(1 << 13); + } + + for (int i = 0; i < _coreVIDs.Length; i++) + { + if (_pawnModule.ReadMsr(IA32_PERF_STATUS, out _, out edx, _cpuId[i][0].Affinity) && ((edx >> 32) & 0xFFFF) > 0) + { + _coreVIDs[i].Value = ((edx >> 32) & 0xFFFF) / (float)(1 << 13); + ActivateSensor(_coreVIDs[i]); + } + else + { + DeactivateSensor(_coreVIDs[i]); + } + } + } + + [SuppressMessage("ReSharper", "IdentifierTypo")] + private enum MicroArchitecture + { + Airmont, + AlderLake, + Atom, + ArrowLake, // Gen. 15 (0xC6, -H = 0xC5) + Broadwell, + CannonLake, + CometLake, + Core, + Goldmont, + GoldmontPlus, + Haswell, + IceLake, + IvyBridge, + JasperLake, + KabyLake, + LunarLake, + Nehalem, + NetBurst, + MeteorLake, + RocketLake, + SandyBridge, + Silvermont, + Skylake, + TigerLake, + Tremont, + RaptorLake, + SapphireRapids, + ElkhartLake, + Unknown + } + + // ReSharper disable InconsistentNaming + private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1; + private const uint IA32_PERF_STATUS = 0x0198; + private const uint IA32_TEMPERATURE_TARGET = 0x01A2; + private const uint IA32_THERM_STATUS_MSR = 0x019C; + + private const uint MSR_DRAM_ENERGY_STATUS = 0x619; + private const uint MSR_PKG_ENERGY_STATUS = 0x611; + private const uint MSR_PLATFORM_INFO = 0xCE; + private const uint MSR_PP0_ENERGY_STATUS = 0x639; + private const uint MSR_PP1_ENERGY_STATUS = 0x641; + private const uint MSR_PLATFORM_ENERGY_STATUS = 0x64D; + + private const uint MSR_RAPL_POWER_UNIT = 0x606; + // ReSharper restore InconsistentNaming +} diff --git a/LibreHardwareMonitorLib/Hardware/Gpu/IntelIntegratedGpu.cs b/LibreHardwareMonitorLib/Hardware/Gpu/IntelIntegratedGpu.cs index 60ace33..6d0d185 100644 --- a/LibreHardwareMonitorLib/Hardware/Gpu/IntelIntegratedGpu.cs +++ b/LibreHardwareMonitorLib/Hardware/Gpu/IntelIntegratedGpu.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Linq; +using LibreHardwareMonitor.PawnIo; using Microsoft.Win32; namespace LibreHardwareMonitor.Hardware.Gpu; @@ -23,11 +24,15 @@ internal class IntelIntegratedGpu : GenericGpu private uint _lastEnergyConsumed; private DateTime _lastEnergyTime; + private readonly IntelMsr _pawnModule; + public IntelIntegratedGpu(Cpu.IntelCpu intelCpu, string deviceId, D3DDisplayDevice.D3DDeviceInfo deviceInfo, ISettings settings) : base(GetName(deviceId), new Identifier("gpu-intel-integrated", deviceId.ToString(CultureInfo.InvariantCulture)), settings) { + _pawnModule = new IntelMsr(); + _deviceId = deviceId; int memorySensorIndex = 0; @@ -45,7 +50,7 @@ internal class IntelIntegratedGpu : GenericGpu _sharedMemoryLimit = new Sensor("D3D Shared Memory Total", memorySensorIndex++, SensorType.SmallData, this, settings); } - if (Ring0.ReadMsr(MSR_PP1_ENERGY_STATUS, out uint eax, out uint _)) + if (_pawnModule.ReadMsr(MSR_PP1_ENERGY_STATUS, out uint eax, out uint _)) { _energyUnitMultiplier = intelCpu.EnergyUnitsMultiplier; if (_energyUnitMultiplier != 0) @@ -99,7 +104,7 @@ internal class IntelIntegratedGpu : GenericGpu _sharedMemoryUsage.Value = 1f * deviceInfo.GpuSharedUsed / 1024 / 1024; ActivateSensor(_sharedMemoryUsage); - if (_powerSensor != null && Ring0.ReadMsr(MSR_PP1_ENERGY_STATUS, out uint eax, out uint _)) + if (_powerSensor != null && _pawnModule.ReadMsr(MSR_PP1_ENERGY_STATUS, out uint eax, out uint _)) { DateTime time = DateTime.UtcNow; float deltaTime = (float)(time - _lastEnergyTime).TotalSeconds; @@ -127,6 +132,13 @@ internal class IntelIntegratedGpu : GenericGpu } } + /// + public override void Close() + { + base.Close(); + _pawnModule.Close(); + } + private static string GetName(string deviceId) { string path = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\" + D3DDisplayDevice.GetActualDeviceIdentifier(deviceId); diff --git a/LibreHardwareMonitorLib/Hardware/IComputer.cs b/LibreHardwareMonitorLib/Hardware/IComputer.cs index 8ea1dc8..e3a0738 100644 --- a/LibreHardwareMonitorLib/Hardware/IComputer.cs +++ b/LibreHardwareMonitorLib/Hardware/IComputer.cs @@ -108,13 +108,6 @@ public interface IComputer : IElement /// if a given category of devices is already enabled. bool IsStorageEnabled { get; } - /// - /// Gets or sets a value indicating whether the Ring0 driver should be installed if user privileges is sufficient. - /// - /// if Ring0 driver installation is enabled - /// Default value is . Only affects Windows. - bool IsRing0Enabled { get; } - /// /// Generates full LibreHardwareMonitor report for devices that have been enabled. /// diff --git a/LibreHardwareMonitorLib/Hardware/InpOut.cs b/LibreHardwareMonitorLib/Hardware/InpOut.cs deleted file mode 100644 index 1a67655..0000000 --- a/LibreHardwareMonitorLib/Hardware/InpOut.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.IO.Compression; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Threading; -using LibreHardwareMonitor.Interop; - -namespace LibreHardwareMonitor.Hardware; - -internal static class InpOut -{ - private static string _filePath; - private static IntPtr _libraryHandle; - private static Interop.InpOut.MapPhysToLinDelegate _mapPhysToLin; - private static Interop.InpOut.UnmapPhysicalMemoryDelegate _unmapPhysicalMemory; - - public static bool IsOpen { get; private set; } - - public static bool Open() - { - if (Software.OperatingSystem.IsUnix) - return false; - - if (IsOpen) - return true; - - _filePath = GetFilePath(); - if (_filePath != null && (File.Exists(_filePath) || Extract(_filePath))) - { - _libraryHandle = Kernel32.LoadLibrary(_filePath); - if (_libraryHandle != IntPtr.Zero) - { - IntPtr mapPhysToLinAddress = Kernel32.GetProcAddress(_libraryHandle, "MapPhysToLin"); - IntPtr unmapPhysicalMemoryAddress = Kernel32.GetProcAddress(_libraryHandle, "UnmapPhysicalMemory"); - - if (mapPhysToLinAddress != IntPtr.Zero) - _mapPhysToLin = Marshal.GetDelegateForFunctionPointer(mapPhysToLinAddress); - - if (unmapPhysicalMemoryAddress != IntPtr.Zero) - _unmapPhysicalMemory = Marshal.GetDelegateForFunctionPointer(unmapPhysicalMemoryAddress); - - IsOpen = true; - } - } - - if (!IsOpen) - Delete(); - - return IsOpen; - } - - public static void Close() - { - if (_libraryHandle != IntPtr.Zero) - { - Kernel32.FreeLibrary(_libraryHandle); - Delete(); - - _libraryHandle = IntPtr.Zero; - } - - IsOpen = false; - } - - public static byte[] ReadMemory(IntPtr baseAddress, uint size) - { - if (_mapPhysToLin != null && _unmapPhysicalMemory != null) - { - IntPtr pdwLinAddr = _mapPhysToLin(baseAddress, size, out IntPtr pPhysicalMemoryHandle); - if (pdwLinAddr != IntPtr.Zero) - { - byte[] bytes = new byte[size]; - Marshal.Copy(pdwLinAddr, bytes, 0, bytes.Length); - _unmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr); - - return bytes; - } - } - - return null; - } - - public static bool WriteMemory(IntPtr baseAddress, byte value) - { - if (_mapPhysToLin == null || _unmapPhysicalMemory == null) - return false; - - IntPtr pdwLinAddr = _mapPhysToLin(baseAddress, 1, out IntPtr pPhysicalMemoryHandle); - if (pdwLinAddr == IntPtr.Zero) - return false; - - Marshal.WriteByte(pdwLinAddr, value); - _unmapPhysicalMemory(pPhysicalMemoryHandle, pdwLinAddr); - - return true; - } - - public static IntPtr MapMemory(IntPtr baseAddress, uint size, out IntPtr handle) - { - if (_mapPhysToLin == null) - { - handle = IntPtr.Zero; - return IntPtr.Zero; - } - - return _mapPhysToLin(baseAddress, size, out handle); - } - - public static bool UnmapMemory(IntPtr handle, IntPtr address) - { - if (_unmapPhysicalMemory == null) - return false; - - return _unmapPhysicalMemory(handle, address); - } - - private static void Delete() - { - try - { - // try to delete the DLL - if (_filePath != null && File.Exists(_filePath)) - File.Delete(_filePath); - - _filePath = null; - } - catch - { } - } - - private static string GetFilePath() - { - string filePath; - - try - { - filePath = Path.GetTempFileName(); - if (!string.IsNullOrEmpty(filePath)) - return Path.ChangeExtension(filePath, ".dll"); - } - catch (IOException) - { } - - const string fileName = "inpout.dll"; - - try - { - ProcessModule processModule = Process.GetCurrentProcess().MainModule; - if (!string.IsNullOrEmpty(processModule?.FileName)) - return Path.Combine(Path.GetDirectoryName(processModule.FileName) ?? string.Empty, fileName); - } - catch - { - // Continue with the other options. - } - - filePath = GetPathFromAssembly(Assembly.GetExecutingAssembly()); - if (!string.IsNullOrEmpty(filePath)) - return Path.Combine(Path.GetDirectoryName(filePath) ?? string.Empty, fileName); - - filePath = GetPathFromAssembly(typeof(InpOut).Assembly); - if (!string.IsNullOrEmpty(filePath)) - return Path.Combine(Path.GetDirectoryName(filePath) ?? string.Empty, fileName); - - return null; - - static string GetPathFromAssembly(Assembly assembly) - { - try - { - string location = assembly?.Location; - return !string.IsNullOrEmpty(location) ? location : null; - } - catch - { - return null; - } - } - } - - private static bool Extract(string filePath) - { - string resourceName = $"{nameof(LibreHardwareMonitor)}.Resources.{(Software.OperatingSystem.Is64Bit ? "inpoutx64.gz" : "inpout32.gz")}"; - - Assembly assembly = typeof(InpOut).Assembly; - long requiredLength = 0; - - try - { - using Stream stream = assembly.GetManifestResourceStream(resourceName); - - if (stream != null) - { - using FileStream target = new(filePath, FileMode.Create); - - stream.Position = 1; // Skip first byte. - - using var gzipStream = new GZipStream(stream, CompressionMode.Decompress); - - gzipStream.CopyTo(target); - - requiredLength = target.Length; - } - } - catch - { - return false; - } - - if (HasValidFile()) - return true; - - // Ensure the file is actually written to the file system. - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (stopwatch.ElapsedMilliseconds < 2000) - { - if (HasValidFile()) - return true; - - Thread.Yield(); - } - - return false; - - bool HasValidFile() - { - try - { - return File.Exists(filePath) && new FileInfo(filePath).Length == requiredLength; - } - catch - { - return false; - } - } - } -} diff --git a/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs b/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs index bd5dd40..4d6eb9d 100644 --- a/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs +++ b/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs @@ -29,17 +29,17 @@ internal class MemoryGroup : IGroup, IHardwareChanged public MemoryGroup(ISettings settings) { - if (Ring0.IsOpen && (DriverManager.Driver is null || !DriverManager.Driver.IsOpen)) + if (DriverManager.Driver is null || !DriverManager.Driver.IsOpen) { // Assign implementation of IDriver. - DriverManager.Driver = new RAMSPDToolkitDriver(Ring0.KernelDriver); + DriverManager.Driver = new RAMSPDToolkitDriver(); SMBusManager.UseWMI = false; } _hardware.Add(new VirtualMemory(settings)); _hardware.Add(new TotalMemory(settings)); - if (DriverManager.Driver == null) + if (DriverManager.Driver == null || !DriverManager.LoadDriver()) { return; } diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/WindowsEmbeddedControllerIO.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/WindowsEmbeddedControllerIO.cs index 62d46a3..ba59f60 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/WindowsEmbeddedControllerIO.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/WindowsEmbeddedControllerIO.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; using System.Threading; +using LibreHardwareMonitor.PawnIo; namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC; @@ -22,14 +23,18 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO private const int FailuresBeforeSkip = 20; private const int MaxRetries = 5; - // implementation + // implementation private const int WaitSpins = 50; private bool _disposed; private int _waitReadFailures; + private readonly LpcAcpiEc _pawnModule; + public WindowsEmbeddedControllerIO() { + _pawnModule = new LpcAcpiEc(); + if (!Mutexes.WaitEc(10)) { throw new BusMutexLockingFailedException(); @@ -38,7 +43,7 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO public void Read(ushort[] registers, byte[] data) { - Trace.Assert(registers.Length <= data.Length, + Trace.Assert(registers.Length <= data.Length, "data buffer length has to be greater or equal to the registers array length"); byte bank = 0; @@ -79,6 +84,7 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO { _disposed = true; Mutexes.ReleaseEc(); + _pawnModule.Close(); } } @@ -156,12 +162,12 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO private byte ReadIOPort(Port port) { - return Ring0.ReadIoPort((uint)port); + return _pawnModule.ReadPort((byte)port); } private void WriteIOPort(Port port, byte datum) { - Ring0.WriteIoPort((uint)port, datum); + _pawnModule.WritePort((byte)port, datum); } public class BusMutexLockingFailedException : EmbeddedController.IOException diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EcioPortGigabyteController.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EcioPortGigabyteController.cs deleted file mode 100644 index ee09b0a..0000000 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EcioPortGigabyteController.cs +++ /dev/null @@ -1,77 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// Partial Copyright (C) Michael Möller and Contributors. -// All Rights Reserved. - -using System; -using System.Threading; - -namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; - -internal class EcioPortGigabyteController : IGigabyteController -{ - private const ushort ControllerVersionOffset = 0x00; - private const ushort ControllerEnableRegister = 0x47; - private const ushort ControllerFanControlArea = 0x900; - - private const ushort EcioRegisterPort = 0x3F4; - private const ushort EcioValuePort = 0x3F0; - - private readonly IT879xEcioPort _port; - - private bool? _initialState; - - private EcioPortGigabyteController(IT879xEcioPort port) - { - _port = port; - } - - public static EcioPortGigabyteController TryCreate() - { - IT879xEcioPort port = new(EcioRegisterPort, EcioValuePort); - - // Check compatibility by querying its version. - if (!port.Read(ControllerFanControlArea + ControllerVersionOffset, out byte majorVersion) || majorVersion != 1) - { - return null; - } - - return new EcioPortGigabyteController(port); - } - - public bool Enable(bool enabled) - { - ushort offset = ControllerFanControlArea + ControllerEnableRegister; - - if (!_port.Read(offset, out byte bCurrent)) - { - return false; - } - - bool current = Convert.ToBoolean(bCurrent); - - _initialState ??= current; - - if (current != enabled) - { - if (!_port.Write(offset, Convert.ToByte(enabled))) - { - return false; - } - - // Allow the system to catch up. - Thread.Sleep(500); - } - - return true; - } - - public void Restore() - { - if (_initialState.HasValue) - { - Enable(_initialState.Value); - } - } -} diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/F718XX.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/F718XX.cs index 62ee32e..f66b5d9 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/F718XX.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/F718XX.cs @@ -14,12 +14,14 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; internal class F718XX : ISuperIO { + private readonly LpcPort _port; private readonly ushort _address; private readonly byte[] _initialFanPwmControl = new byte[4]; private readonly bool[] _restoreDefaultFanPwmControlRequired = new bool[4]; - public F718XX(Chip chip, ushort address) + public F718XX(LpcPort port, Chip chip, ushort address) { + _port = port; _address = address; Chip = chip; @@ -204,6 +206,12 @@ internal class F718XX : ISuperIO Mutexes.ReleaseIsaBus(); } + /// + public void Close() + { + _port.Close(); + } + private void SaveDefaultFanPwmControl(int index) { if (!_restoreDefaultFanPwmControlRequired[index]) @@ -224,14 +232,14 @@ internal class F718XX : ISuperIO private byte ReadByte(byte register) { - Ring0.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); - return Ring0.ReadIoPort((ushort)(_address + DATA_REGISTER_OFFSET)); + _port.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); + return _port.ReadIoPort((ushort)(_address + DATA_REGISTER_OFFSET)); } private void WriteByte(byte register, byte value) { - Ring0.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); - Ring0.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), value); + _port.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); + _port.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), value); } // ReSharper disable InconsistentNaming diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/ISuperIO.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/ISuperIO.cs index 845864d..cedea70 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/ISuperIO.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/ISuperIO.cs @@ -30,4 +30,6 @@ internal interface ISuperIO string GetReport(); void Update(); -} \ No newline at end of file + + void Close(); +} diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT879xEcioPort.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT879xEcioPort.cs deleted file mode 100644 index 32a36cb..0000000 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT879xEcioPort.cs +++ /dev/null @@ -1,139 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// Partial Copyright (C) Michael Möller and Contributors. -// All Rights Reserved. - -using System.Diagnostics; - -namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; - -internal class IT879xEcioPort -{ - public IT879xEcioPort(ushort registerPort, ushort valuePort) - { - RegisterPort = registerPort; - ValuePort = valuePort; - } - - public ushort RegisterPort { get; } - - public ushort ValuePort { get; } - - public bool Read(ushort offset, out byte value) - { - if (!Init(0xB0, offset)) - { - value = 0; - return false; - } - - return ReadFromValue(out value); - } - - public bool Write(ushort offset, byte value) - { - if (!Init(0xB1, offset)) - { - return false; - } - - return WriteToValue(value); - } - - private bool Init(byte command, ushort offset) - { - if (!WriteToRegister(command)) - { - return false; - } - - if (!WriteToValue((byte)((offset >> 8) & 0xFF))) - { - return false; - } - - if (!WriteToValue((byte)(offset & 0xFF))) - { - return false; - } - - return true; - } - - private bool WriteToRegister(byte value) - { - if (!WaitIBE()) - { - return false; - } - - Ring0.WriteIoPort(RegisterPort, value); - return true; - } - - private bool WriteToValue(byte value) - { - if (!WaitIBE()) - { - return false; - } - - Ring0.WriteIoPort(ValuePort, value); - return true; - } - - private bool ReadFromValue(out byte value) - { - if (!WaitOBF()) - { - value = 0; - return false; - } - - value = Ring0.ReadIoPort(ValuePort); - return true; - } - - private bool WaitIBE() - { - Stopwatch stopwatch = Stopwatch.StartNew(); - try - { - while ((Ring0.ReadIoPort(RegisterPort) & 2) != 0) - { - if (stopwatch.ElapsedMilliseconds > WAIT_TIMEOUT) - { - return false; - } - } - return true; - } - finally - { - stopwatch.Stop(); - } - } - - private bool WaitOBF() - { - Stopwatch stopwatch = Stopwatch.StartNew(); - try - { - while ((Ring0.ReadIoPort(RegisterPort) & 1) == 0) - { - if (stopwatch.ElapsedMilliseconds > WAIT_TIMEOUT) - { - return false; - } - } - return true; - } - finally - { - stopwatch.Stop(); - } - } - - private const long WAIT_TIMEOUT = 1000L; -} diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs index 2259d18..30cb9f6 100755 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs @@ -25,19 +25,21 @@ internal class IT87XX : ISuperIO private readonly int _gpioCount; private readonly bool _has16BitFanCounter; private readonly bool _hasExtReg; - private readonly bool[] _initialFanOutputModeEnabled = new bool[3]; // Initial Fan Controller Main Control Register value. + private readonly bool[] _initialFanOutputModeEnabled = new bool[3]; // Initial Fan Controller Main Control Register value. private readonly byte[] _initialFanPwmControl = new byte[MaxFanHeaders]; // This will also store the 2nd control register value. private readonly byte[] _initialFanPwmControlExt = new byte[MaxFanHeaders]; private readonly bool[] _restoreDefaultFanPwmControlRequired = new bool[MaxFanHeaders]; private readonly byte _version; private readonly float _voltageGain; private IGigabyteController _gigabyteController; + private readonly LpcPort _port; private readonly bool _requiresBankSelect; // Fix #780 Set to true for those chips that need a SelectBank(0) to fix dodgy temps and fan speeds private bool SupportsMultipleBanks => _bankCount > 1; - public IT87XX(Chip chip, ushort address, ushort gpioAddress, byte version, Motherboard motherboard, IGigabyteController gigabyteController) + public IT87XX(LpcPort port, Chip chip, ushort address, ushort gpioAddress, byte version, Motherboard motherboard, IGigabyteController gigabyteController) { + _port = port; _address = address; _version = version; _addressReg = (ushort)(address + ADDRESS_REGISTER_OFFSET); @@ -267,7 +269,7 @@ internal class IT87XX : ISuperIO if (index >= _gpioCount) return null; - return Ring0.ReadIoPort((ushort)(_gpioAddress + index)); + return _port.ReadIoPort((ushort)(_gpioAddress + index)); } public void WriteGpio(int index, byte value) @@ -275,7 +277,7 @@ internal class IT87XX : ISuperIO if (index >= _gpioCount) return; - Ring0.WriteIoPort((ushort)(_gpioAddress + index), value); + _port.WriteIoPort((ushort)(_gpioAddress + index), value); } public void SetControl(int index, byte? value) @@ -527,11 +529,13 @@ internal class IT87XX : ISuperIO Mutexes.ReleaseIsaBus(); } + public void Close() => _port.Close(); + private byte ReadByte(byte register, out bool valid) { - Ring0.WriteIoPort(_addressReg, register); - byte value = Ring0.ReadIoPort(_dataReg); - valid = register == Ring0.ReadIoPort(_addressReg) || Chip == Chip.IT8688E; + _port.WriteIoPort(_addressReg, register); + byte value = _port.ReadIoPort(_dataReg); + valid = register == _port.ReadIoPort(_addressReg) || Chip == Chip.IT8688E; // IT8688E doesn't return the value we wrote to // addressReg when we read it back. @@ -540,9 +544,9 @@ internal class IT87XX : ISuperIO private void WriteByte(byte register, byte value) { - Ring0.WriteIoPort(_addressReg, register); - Ring0.WriteIoPort(_dataReg, value); - Ring0.ReadIoPort(_addressReg); + _port.WriteIoPort(_addressReg, register); + _port.WriteIoPort(_dataReg, value); + _port.ReadIoPort(_addressReg); } private void SaveDefaultFanPwmControl(int index) diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Ipmi.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Ipmi.cs index 8087034..c953efc 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Ipmi.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Ipmi.cs @@ -124,6 +124,10 @@ internal class Ipmi : ISuperIO Update(null); } + /// + public void Close() + { } + private unsafe void Update(StringBuilder stringBuilder) { _fans.Clear(); diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs deleted file mode 100644 index ab21846..0000000 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IsaBridgeGigabyteController.cs +++ /dev/null @@ -1,199 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// Partial Copyright (C) Michael Möller and Contributors. -// All Rights Reserved. - -using System; -using System.Runtime.InteropServices; -using System.Threading; -using LibreHardwareMonitor.Hardware.Cpu; - -namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; - -/// -/// This is a controller present on some Gigabyte motherboards for both Intel and AMD, that is in custom firmware -/// loaded onto the 2nd ITE EC. -/// It can be accessed by using memory mapped IO, mapping its internal RAM onto main RAM via the ISA Bridge. -/// This class can disable it so that the regular IT87XX code can drive the fans. -/// -internal class IsaBridgeGigabyteController : IGigabyteController -{ - private const uint ControllerAddressRange = 0xFF; - private const int ControllerEnableRegister = 0x47; - private const uint ControllerFanControlArea = 0x900; - - /// - /// Base address in PCI RAM that maps to the EC's RAM - /// - private readonly uint _controllerBaseAddress; - - private readonly Vendor _vendor; - - private bool? _initialState; - - public IsaBridgeGigabyteController(uint address, Vendor vendor) - { - _controllerBaseAddress = address; - _vendor = vendor; - } - - /// - /// Enable/Disable Fan Control - /// - /// - /// true on success - public bool Enable(bool enabled) - { - return _vendor switch - { - Vendor.Intel => IntelEnable(enabled), - Vendor.AMD => AmdEnable(enabled), - _ => false - }; - } - - private bool IntelEnable(bool enabled) - { - if (!Mutexes.WaitPciBus(10)) - return false; - - bool result = false; - - uint intelIsaBridgeAddress = Ring0.GetPciAddress(0x0, 0x1F, 0x0); - - const uint ioOrMemoryPortDecodeEnableRegister = 0xD8; - const uint romAddressRange2Register = 0x98; - - uint controllerFanControlAddress = _controllerBaseAddress + ControllerFanControlArea; - - Ring0.ReadPciConfig(intelIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, out uint originalDecodeEnableRegister); - Ring0.ReadPciConfig(intelIsaBridgeAddress, romAddressRange2Register, out uint originalRomAddressRegister); - - bool originalMmIoEnabled = false; - if (!enabled) - { - originalMmIoEnabled = ((int)originalDecodeEnableRegister & 1) == 0 || ((int)originalRomAddressRegister & 1) == 1; - } - else - { - originalMmIoEnabled = ((int)originalDecodeEnableRegister & 1) == 0 && ((int)originalRomAddressRegister & 1) == 1; - } - - if (enabled == originalMmIoEnabled) - { - result = Enable(enabled, new IntPtr(controllerFanControlAddress)); - Mutexes.ReleasePciBus(); - return result; - } - - uint lpcBiosDecodeEnable; - uint lpcMemoryRange; - if (enabled) - { - lpcBiosDecodeEnable = ioOrMemoryPortDecodeEnableRegister & ~(uint)(1 << 0); - lpcMemoryRange = romAddressRange2Register | (uint)(1 << 0); - } - else - { - lpcBiosDecodeEnable = Convert.ToUInt32(ioOrMemoryPortDecodeEnableRegister | (uint)(1 << 0)); - lpcMemoryRange = Convert.ToUInt32(romAddressRange2Register & ~(uint)(1 << 0)); - } - - Ring0.WritePciConfig(intelIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, lpcBiosDecodeEnable); - Ring0.WritePciConfig(intelIsaBridgeAddress, romAddressRange2Register, lpcMemoryRange); - - result = Enable(enabled, new IntPtr(controllerFanControlAddress)); - - Mutexes.ReleasePciBus(); - - return result; - } - - private bool AmdEnable(bool enabled) - { - if (!Mutexes.WaitPciBus(10)) - return false; - - // see D14F3x https://www.amd.com/system/files/TechDocs/55072_AMD_Family_15h_Models_70h-7Fh_BKDG.pdf - uint amdIsaBridgeAddress = Ring0.GetPciAddress(0x0, 0x14, 0x3); - - const uint ioOrMemoryPortDecodeEnableRegister = 0x48; - const uint memoryRangePortEnableMask = 0x1 << 5; - const uint pciMemoryAddressForLpcTargetCyclesRegister = 0x60; - const uint romAddressRange2Register = 0x6C; - - uint controllerFanControlAddress = _controllerBaseAddress + ControllerFanControlArea; - - uint pciAddressStart = _controllerBaseAddress >> 0x10; - uint pciAddressEnd = pciAddressStart + 1; - - uint enabledPciMemoryAddressRegister = pciAddressEnd << 0x10 | pciAddressStart; - uint enabledRomAddressRegister = 0xFFFFU << 0x10 | pciAddressEnd; - - Ring0.ReadPciConfig(amdIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, out uint originalDecodeEnableRegister); - Ring0.ReadPciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, out uint originalPciMemoryAddressRegister); - Ring0.ReadPciConfig(amdIsaBridgeAddress, romAddressRange2Register, out uint originalRomAddressRegister); - - bool originalMmIoEnabled = (originalDecodeEnableRegister & memoryRangePortEnableMask) != 0 && - originalPciMemoryAddressRegister == enabledPciMemoryAddressRegister && - originalRomAddressRegister == enabledRomAddressRegister; - - if (!originalMmIoEnabled) - { - Ring0.WritePciConfig(amdIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, originalDecodeEnableRegister | memoryRangePortEnableMask); - Ring0.WritePciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, enabledPciMemoryAddressRegister); - Ring0.WritePciConfig(amdIsaBridgeAddress, romAddressRange2Register, enabledRomAddressRegister); - } - - bool result = Enable(enabled, new IntPtr(controllerFanControlAddress)); - - // Restore previous values - if (!originalMmIoEnabled) - { - Ring0.WritePciConfig(amdIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, originalDecodeEnableRegister); - Ring0.WritePciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, originalPciMemoryAddressRegister); - Ring0.WritePciConfig(amdIsaBridgeAddress, romAddressRange2Register, originalRomAddressRegister); - } - - Mutexes.ReleasePciBus(); - - return result; - } - - private bool Enable(bool enabled, IntPtr pciMmIoBaseAddress) - { - // Map PCI memory to this process memory - if (!InpOut.Open()) - return false; - - IntPtr mapped = InpOut.MapMemory(pciMmIoBaseAddress, ControllerAddressRange, out IntPtr handle); - - if (mapped == IntPtr.Zero) - return false; - - bool current = Convert.ToBoolean(Marshal.ReadByte(mapped, ControllerEnableRegister)); - - _initialState ??= current; - - // Update Controller State - if (current != enabled) - { - Marshal.WriteByte(mapped, ControllerEnableRegister, Convert.ToByte(enabled)); - // Give it some time to see the change - Thread.Sleep(500); - } - - InpOut.UnmapMemory(handle, mapped); - return true; - } - - /// - /// Restore settings back to initial values - /// - public void Restore() - { - if (_initialState.HasValue) - Enable(_initialState.Value); - } -} diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs index aa5dca9..ed98db0 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using System.Globalization; using System.Text; using System.Threading; -using LibreHardwareMonitor.Hardware.Cpu; namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; @@ -20,7 +19,7 @@ internal class LpcIO public LpcIO(Motherboard motherboard) { - if (!Ring0.IsOpen || !Mutexes.WaitIsaBus(100)) + if (!Mutexes.WaitIsaBus(100)) return; Detect(motherboard); @@ -54,6 +53,7 @@ internal class LpcIO if (chipId is not 0 and not 0xffff) { + port.FindBars(); port.SmscExit(); ReportUnknownChip(port, "SMSC", chipId); } @@ -67,11 +67,16 @@ internal class LpcIO { var port = new LpcPort(REGISTER_PORTS[i], VALUE_PORTS[i]); - if (DetectWinbondFintek(port, motherboard)) continue; + if (DetectWinbondFintek(port, motherboard)) + continue; - if (DetectIT87(port, motherboard)) continue; + if (DetectIT87(port, motherboard)) + continue; - if (DetectSmsc(port)) continue; + if (DetectSmsc(port)) + continue; + + port.Close(); } } @@ -85,6 +90,12 @@ internal class LpcIO return null; } + public void Close() + { + foreach (ISuperIO superIO in _superIOs) + superIO.Close(); + } + private bool DetectWinbondFintek(LpcPort port, Motherboard motherboard) { port.WinbondNuvotonFintekEnter(); @@ -450,6 +461,7 @@ internal class LpcIO } else { + port.FindBars(); port.Select(logicalDeviceNumber); ushort address = port.ReadWord(BASE_ADDRESS_REGISTER); Thread.Sleep(1); @@ -505,7 +517,7 @@ internal class LpcIO case Chip.W83667HG: case Chip.W83667HGB: case Chip.W83687THF: - _superIOs.Add(new W836XX(chip, revision, address)); + _superIOs.Add(new W836XX(port, chip, revision, address)); break; case Chip.NCT610XD: @@ -527,7 +539,7 @@ internal class LpcIO case Chip.NCT6687DR: case Chip.NCT6683D: case Chip.NCT6701D: - _superIOs.Add(new Nct677X(chip, revision, address, port)); + _superIOs.Add(new Nct677X(port, chip, revision, address)); break; case Chip.F71858: @@ -553,7 +565,7 @@ internal class LpcIO return false; } - _superIOs.Add(new F718XX(chip, address)); + _superIOs.Add(new F718XX(port, chip, address)); break; } @@ -619,6 +631,7 @@ internal class LpcIO } else { + port.FindBars(); port.Select(IT87_ENVIRONMENT_CONTROLLER_LDN); ushort address = port.ReadWord(BASE_ADDRESS_REGISTER); @@ -645,8 +658,6 @@ internal class LpcIO gpioVerify = port.ReadWord(BASE_ADDRESS_REGISTER + 2); } - IGigabyteController gigabyteController = FindGigabyteEC(port, chip, motherboard); - port.IT87Exit(); if (address != verify || address < 0x100 || (address & 0xF007) != 0) @@ -671,91 +682,13 @@ internal class LpcIO return false; } - _superIOs.Add(new IT87XX(chip, address, gpioAddress, version, motherboard, gigabyteController)); + _superIOs.Add(new IT87XX(port, chip, address, gpioAddress, version, motherboard, null)); return true; } return false; } - private IGigabyteController FindGigabyteEC(LpcPort port, Chip chip, Motherboard motherboard) - { - // The controller only affects the 2nd ITE chip if present, and only a few - // models are known to use this controller. - // IT8795E likely to need this too, but may use different registers. - if (motherboard.Manufacturer != Manufacturer.Gigabyte || port.RegisterPort != 0x4E || chip is not (Chip.IT8790E or Chip.IT8792E or Chip.IT87952E)) - return null; - - Vendor vendor = DetectVendor(); - - IGigabyteController gigabyteController = FindGigabyteECUsingSmfi(port, chip, vendor); - if (gigabyteController != null) - return gigabyteController; - - // ECIO is only available on AMD motherboards with IT8791E/IT8792E/IT8795E. - if (chip == Chip.IT8792E && vendor == Vendor.AMD) - { - gigabyteController = EcioPortGigabyteController.TryCreate(); - if (gigabyteController != null) - return gigabyteController; - } - - return null; - - Vendor DetectVendor() - { - string manufacturer = motherboard.SMBios.Processors[0].ManufacturerName; - if (manufacturer.IndexOf("Intel", StringComparison.OrdinalIgnoreCase) != -1) - return Vendor.Intel; - - if (manufacturer.IndexOf("Advanced Micro Devices", StringComparison.OrdinalIgnoreCase) != -1 || manufacturer.StartsWith("AMD", StringComparison.OrdinalIgnoreCase)) - return Vendor.AMD; - - return Vendor.Unknown; - } - } - - private IGigabyteController FindGigabyteECUsingSmfi(LpcPort port, Chip chip, Vendor vendor) - { - port.Select(IT87XX_SMFI_LDN); - - // Check if the SMFI logical device is enabled - byte enabled = port.ReadByte(IT87_LD_ACTIVE_REGISTER); - Thread.Sleep(1); - byte enabledVerify = port.ReadByte(IT87_LD_ACTIVE_REGISTER); - - // The EC has no SMFI or it's RAM access is not enabled, assume the controller is not present - if (enabled != enabledVerify || enabled == 0) - return null; - - // Read the host RAM address that maps to the Embedded Controller's RAM (two registers). - uint addressHi = 0; - uint addressHiVerify = 0; - uint address = port.ReadWord(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER); - if (chip == Chip.IT87952E) - addressHi = port.ReadByte(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH); - - Thread.Sleep(1); - uint addressVerify = port.ReadWord(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER); - if (chip == Chip.IT87952E) - addressHiVerify = port.ReadByte(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH); - - if ((address != addressVerify) || (addressHi != addressHiVerify)) - return null; - - // Address is xryy, Host Address is FFyyx000 - // For IT87952E, Address is rzxryy, Host Address is (0xFC000000 | 0x0zyyx000) - uint hostAddress; - if (chip == Chip.IT87952E) - hostAddress = 0xFC000000; - else - hostAddress = 0xFF000000; - - hostAddress |= (address & 0xF000) | ((address & 0xFF) << 16) | ((addressHi & 0xF) << 24); - - return new IsaBridgeGigabyteController(hostAddress, vendor); - } - // ReSharper disable InconsistentNaming private const byte BASE_ADDRESS_REGISTER = 0x60; private const byte CHIP_ID_REGISTER = 0x20; @@ -768,16 +701,12 @@ internal class LpcIO private const byte IT87XX_GPIO_LDN = 0x07; // Shared Memory/Flash Interface - private const byte IT87XX_SMFI_LDN = 0x0F; private const byte WINBOND_NUVOTON_HARDWARE_MONITOR_LDN = 0x0B; private const ushort FINTEK_VENDOR_ID = 0x1934; private const byte FINTEK_VENDOR_ID_REGISTER = 0x23; private const byte IT87_CHIP_VERSION_REGISTER = 0x22; - private const byte IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER = 0xF5; - private const byte IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH = 0xFC; - private const byte IT87_LD_ACTIVE_REGISTER = 0x30; private readonly ushort[] REGISTER_PORTS = { 0x2E, 0x4E }; diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcPort.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcPort.cs index d0df353..9c4dec3 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcPort.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcPort.cs @@ -8,31 +8,43 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; internal class LpcPort { + private PawnIo.LpcIo _pawnModule; + public LpcPort(ushort registerPort, ushort valuePort) { RegisterPort = registerPort; ValuePort = valuePort; + _pawnModule = new PawnIo.LpcIo(); + _pawnModule.SelectSlot(registerPort == 0x2e ? 0 : 1); } public ushort RegisterPort { get; } public ushort ValuePort { get; } + public byte ReadIoPort(ushort port) + { + return _pawnModule.ReadPort(port); + } + + public void WriteIoPort(ushort port, byte value) + { + _pawnModule.WritePort(port, value); + } + public byte ReadByte(byte register) { - Ring0.WriteIoPort(RegisterPort, register); - return Ring0.ReadIoPort(ValuePort); + return _pawnModule.ReadByte(register); } public void WriteByte(byte register, byte value) { - Ring0.WriteIoPort(RegisterPort, register); - Ring0.WriteIoPort(ValuePort, value); + _pawnModule.WriteByte(register, value); } public ushort ReadWord(byte register) { - return (ushort)((ReadByte(register) << 8) | ReadByte((byte)(register + 1))); + return _pawnModule.ReadWord(register); } public bool TryReadWord(byte register, out ushort value) @@ -41,21 +53,25 @@ internal class LpcPort return value != 0xFFFF; } + public void FindBars() + { + _pawnModule.FindBars(); + } + public void Select(byte logicalDeviceNumber) { - Ring0.WriteIoPort(RegisterPort, DEVICE_SELECT_REGISTER); - Ring0.WriteIoPort(ValuePort, logicalDeviceNumber); + WriteByte(DEVICE_SELECT_REGISTER, logicalDeviceNumber); } public void WinbondNuvotonFintekEnter() { - Ring0.WriteIoPort(RegisterPort, 0x87); - Ring0.WriteIoPort(RegisterPort, 0x87); + _pawnModule.WritePort(RegisterPort, 0x87); + _pawnModule.WritePort(RegisterPort, 0x87); } public void WinbondNuvotonFintekExit() { - Ring0.WriteIoPort(RegisterPort, 0xAA); + _pawnModule.WritePort(RegisterPort, 0xAA); } public void NuvotonDisableIOSpaceLock() @@ -71,10 +87,10 @@ internal class LpcPort public void IT87Enter() { - Ring0.WriteIoPort(RegisterPort, 0x87); - Ring0.WriteIoPort(RegisterPort, 0x01); - Ring0.WriteIoPort(RegisterPort, 0x55); - Ring0.WriteIoPort(RegisterPort, RegisterPort == 0x4E ? (byte)0xAA : (byte)0x55); + _pawnModule.WritePort(RegisterPort, 0x87); + _pawnModule.WritePort(RegisterPort, 0x01); + _pawnModule.WritePort(RegisterPort, 0x55); + _pawnModule.WritePort(RegisterPort, RegisterPort == 0x4E ? (byte)0xAA : (byte)0x55); } public void IT87Exit() @@ -82,21 +98,23 @@ internal class LpcPort // Do not exit config mode for secondary super IO. if (RegisterPort != 0x4E) { - Ring0.WriteIoPort(RegisterPort, CONFIGURATION_CONTROL_REGISTER); - Ring0.WriteIoPort(ValuePort, 0x02); + _pawnModule.WritePort(RegisterPort, CONFIGURATION_CONTROL_REGISTER); + _pawnModule.WritePort(ValuePort, 0x02); } } public void SmscEnter() { - Ring0.WriteIoPort(RegisterPort, 0x55); + _pawnModule.WritePort(RegisterPort, 0x55); } public void SmscExit() { - Ring0.WriteIoPort(RegisterPort, 0xAA); + _pawnModule.WritePort(RegisterPort, 0xAA); } + public void Close() => _pawnModule.Close(); + // ReSharper disable InconsistentNaming private const byte CONFIGURATION_CONTROL_REGISTER = 0x02; private const byte DEVICE_SELECT_REGISTER = 0x07; diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs index 165828e..1c9ec15 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Nct677X.cs @@ -51,7 +51,7 @@ internal class Nct677X : ISuperIO private readonly ushort[] _voltageRegisters; private readonly ushort _voltageVBatRegister; - public Nct677X(Chip chip, byte revision, ushort port, LpcPort lpcPort) + public Nct677X(LpcPort lpcPort, Chip chip, byte revision, ushort port) { Chip = chip; _revision = revision; @@ -71,7 +71,7 @@ internal class Nct677X : ISuperIO } else if (chip is Chip.NCT6683D or Chip.NCT6686D or Chip.NCT6687D) //These work on older NCT6687D boards, but only fans 0, 1 and 3 on newer (X870 and Z890) motherboards. Unsure of controls for "next pack of 8". { - FAN_PWM_OUT_REG = new ushort[] { 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167 }; // Next 8 fans will be 0xE00, 0xE01, 0xE02, 0xE03, 0xE04, 0xE05, 0xE06, 0xE07 + FAN_PWM_OUT_REG = new ushort[] { 0x160, 0x161, 0x162, 0x163, 0x164, 0x165, 0x166, 0x167 }; // Next 8 fans will be 0xE00, 0xE01, 0xE02, 0xE03, 0xE04, 0xE05, 0xE06, 0xE07 FAN_PWM_COMMAND_REG = new ushort[] { 0xA28, 0xA29, 0xA2A, 0xA2B, 0xA2C, 0xA2D, 0xA2E, 0xA2F }; // Possibly 0X260, 0X261, 0X262, 0X263, 0X264, 0X265, 0X266, 0X267 but can't confirm FAN_CONTROL_MODE_REG = new ushort[] { 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00 }; // Not sure of next 8, MSI won't provide info FAN_PWM_REQUEST_REG = new ushort[] { 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01, 0xA01 }; // Not sure of next 8, MSI won't provide info @@ -734,6 +734,12 @@ internal class Nct677X : ISuperIO Mutexes.ReleaseIsaBus(); } + /// + public void Close() + { + _lpcPort.Close(); + } + public string GetReport() { StringBuilder r = new(); @@ -907,10 +913,10 @@ internal class Nct677X : ISuperIO { byte bank = (byte)(address >> 8); byte register = (byte)(address & 0xFF); - Ring0.WriteIoPort(_port + ADDRESS_REGISTER_OFFSET, BANK_SELECT_REGISTER); - Ring0.WriteIoPort(_port + DATA_REGISTER_OFFSET, bank); - Ring0.WriteIoPort(_port + ADDRESS_REGISTER_OFFSET, register); - return Ring0.ReadIoPort(_port + DATA_REGISTER_OFFSET); + _lpcPort.WriteIoPort((ushort)(_port + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); + _lpcPort.WriteIoPort((ushort)(_port + DATA_REGISTER_OFFSET), bank); + _lpcPort.WriteIoPort((ushort)(_port + ADDRESS_REGISTER_OFFSET), register); + return _lpcPort.ReadIoPort((ushort)(_port + DATA_REGISTER_OFFSET)); } byte page = (byte)(address >> 8); @@ -923,25 +929,25 @@ internal class Nct677X : ISuperIO DateTime timeout = DateTime.UtcNow.AddMilliseconds(500); while (true) { - access = Ring0.ReadIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET); + access = _lpcPort.ReadIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET)); if (access == EC_SPACE_PAGE_SELECT || DateTime.UtcNow > timeout) break; - System.Threading.Thread.Sleep(1); + Thread.Sleep(1); } if (access != EC_SPACE_PAGE_SELECT) { // Failed to gain access: force register access - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET), EC_SPACE_PAGE_SELECT); } - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, page); - Ring0.WriteIoPort(_port + EC_SPACE_INDEX_REGISTER_OFFSET, index); - byte result = Ring0.ReadIoPort(_port + EC_SPACE_DATA_REGISTER_OFFSET); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET), page); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_INDEX_REGISTER_OFFSET), index); + byte result = _lpcPort.ReadIoPort((ushort)(_port + EC_SPACE_DATA_REGISTER_OFFSET)); //free access for other instances - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET), EC_SPACE_PAGE_SELECT); return result; } @@ -952,10 +958,10 @@ internal class Nct677X : ISuperIO { byte bank = (byte)(address >> 8); byte register = (byte)(address & 0xFF); - Ring0.WriteIoPort(_port + ADDRESS_REGISTER_OFFSET, BANK_SELECT_REGISTER); - Ring0.WriteIoPort(_port + DATA_REGISTER_OFFSET, bank); - Ring0.WriteIoPort(_port + ADDRESS_REGISTER_OFFSET, register); - Ring0.WriteIoPort(_port + DATA_REGISTER_OFFSET, value); + _lpcPort.WriteIoPort((ushort)(_port + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); + _lpcPort.WriteIoPort((ushort)(_port + DATA_REGISTER_OFFSET), bank); + _lpcPort.WriteIoPort((ushort)(_port + ADDRESS_REGISTER_OFFSET), register); + _lpcPort.WriteIoPort((ushort)(_port + DATA_REGISTER_OFFSET), value); } else { @@ -969,7 +975,7 @@ internal class Nct677X : ISuperIO DateTime timeout = DateTime.UtcNow.AddMilliseconds(500); while (true) { - access = Ring0.ReadIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET); + access = _lpcPort.ReadIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET)); if (access == EC_SPACE_PAGE_SELECT || DateTime.UtcNow > timeout) break; @@ -979,15 +985,15 @@ internal class Nct677X : ISuperIO if (access != EC_SPACE_PAGE_SELECT) { // Failed to gain access: force register access - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET), EC_SPACE_PAGE_SELECT); } - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, page); - Ring0.WriteIoPort(_port + EC_SPACE_INDEX_REGISTER_OFFSET, index); - Ring0.WriteIoPort(_port + EC_SPACE_DATA_REGISTER_OFFSET, value); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET), page); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_INDEX_REGISTER_OFFSET), index); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_DATA_REGISTER_OFFSET), value); //free access for other instances - Ring0.WriteIoPort(_port + EC_SPACE_PAGE_REGISTER_OFFSET, EC_SPACE_PAGE_SELECT); + _lpcPort.WriteIoPort((ushort)(_port + EC_SPACE_PAGE_REGISTER_OFFSET), EC_SPACE_PAGE_SELECT); } } @@ -1004,8 +1010,8 @@ internal class Nct677X : ISuperIO int targetFanCurveAddr = initFanCurveReg; // Address of the Current Fan Curve Register we're writing to ushort targetFanCurveReg; // Integer value of the current fan curve register address, not the value within byte currentSpeed = ReadByte(FAN_PWM_OUT_REG[index]); // Current Speed of the target fan - - // If current fan duty cycle matches requested duty cycle, skip re-writing the fan curve + + // If current fan duty cycle matches requested duty cycle, skip re-writing the fan curve if (currentSpeed == value.Value) { return; @@ -1166,7 +1172,7 @@ internal class Nct677X : ISuperIO } // ReSharper disable InconsistentNaming - private const uint ADDRESS_REGISTER_OFFSET = 0x05; + private const ushort ADDRESS_REGISTER_OFFSET = 0x05; private const byte BANK_SELECT_REGISTER = 0x4E; private const uint DATA_REGISTER_OFFSET = 0x06; diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/W836XX.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/W836XX.cs index 07efe72..16cc6ff 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/W836XX.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/W836XX.cs @@ -14,6 +14,7 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc; internal class W836XX : ISuperIO { + private readonly LpcPort _port; private readonly ushort _address; private readonly byte _revision; private readonly bool[] _peciTemperature = Array.Empty(); @@ -35,8 +36,9 @@ internal class W836XX : ISuperIO private readonly byte[] _initialFanTertiaryControlValue = Array.Empty(); private readonly bool[] _restoreDefaultFanPwmControlRequired = Array.Empty(); - public W836XX(Chip chip, byte revision, ushort address) + public W836XX(LpcPort port, Chip chip, byte revision, ushort address) { + _port = port; _address = address; _revision = revision; Chip = chip; @@ -400,6 +402,12 @@ internal class W836XX : ISuperIO Mutexes.ReleaseIsaBus(); } + /// + public void Close() + { + _port.Close(); + } + public string GetReport() { StringBuilder r = new(); @@ -460,18 +468,18 @@ internal class W836XX : ISuperIO private byte ReadByte(byte bank, byte register) { - Ring0.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); - Ring0.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), bank); - Ring0.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); - return Ring0.ReadIoPort((ushort)(_address + DATA_REGISTER_OFFSET)); + _port.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); + _port.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), bank); + _port.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); + return _port.ReadIoPort((ushort)(_address + DATA_REGISTER_OFFSET)); } private void WriteByte(byte bank, byte register, byte value) { - Ring0.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); - Ring0.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), bank); - Ring0.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); - Ring0.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), value); + _port.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); + _port.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), bank); + _port.WriteIoPort((ushort)(_address + ADDRESS_REGISTER_OFFSET), register); + _port.WriteIoPort((ushort)(_address + DATA_REGISTER_OFFSET), value); } private bool IsWinbondVendor() diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Motherboard.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Motherboard.cs index 9cd3156..ce82199 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Motherboard.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Motherboard.cs @@ -197,6 +197,8 @@ public class Motherboard : IHardware public void Close() { _lmSensors?.Close(); + _lpcIO?.Close(); + foreach (IHardware iHardware in SubHardware) { if (iHardware is Hardware hardware) diff --git a/LibreHardwareMonitorLib/Hardware/RAMSPDToolkitDriver.cs b/LibreHardwareMonitorLib/Hardware/RAMSPDToolkitDriver.cs deleted file mode 100644 index 20583ff..0000000 --- a/LibreHardwareMonitorLib/Hardware/RAMSPDToolkitDriver.cs +++ /dev/null @@ -1,414 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// Partial Copyright (C) Michael Möller and Contributors. -// All Rights Reserved. - -using System.Runtime.InteropServices; -using RAMSPDToolkit.Windows.Driver; - -using IOCC = LibreHardwareMonitor.Interop.Ring0; - -namespace LibreHardwareMonitor.Hardware -{ - /// - /// Implementation of interface for RAMSPDToolkit. - /// - internal class RAMSPDToolkitDriver : IDriver - { - private KernelDriver _kernelDriver; - - private const byte PCI_MAX_NUMBER_OF_BUS = 255; - private const byte PCI_NUMBER_OF_DEVICE = 32; - private const byte PCI_NUMBER_OF_FUNCTION = 8; - - public bool IsOpen => _kernelDriver?.IsOpen ?? false; - - public RAMSPDToolkitDriver(KernelDriver kernelDriver) - { - _kernelDriver = kernelDriver; - } - - //Driver is being managed internally by other classes, so nothing to do in Load + Unload - - public bool Load() - { - return true; - } - - public void Unload() - { - } - - public byte ReadIoPortByte(ushort port) - { - byte value = 0; - - ReadIoPortByteEx(port, ref value); - - return value; - } - - public ushort ReadIoPortWord(ushort port) - { - ushort value = 0; - - ReadIoPortWordEx(port, ref value); - - return value; - } - - public uint ReadIoPortDword(ushort port) - { - uint value = 0; - - ReadIoPortDwordEx(port, ref value); - - return value; - } - - public bool ReadIoPortByteEx(ushort port, ref byte value) - { - if (!IsOpen) - return false; - - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_READ_IO_PORT_BYTE, port, ref value); - } - - public bool ReadIoPortWordEx(ushort port, ref ushort value) - { - if (!IsOpen) - return false; - - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_READ_IO_PORT_WORD, port, ref value); - } - - public bool ReadIoPortDwordEx(ushort port, ref uint value) - { - if (!IsOpen) - return false; - - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_READ_IO_PORT_DWORD, port, ref value); - } - - public void WriteIoPortByte(ushort port, byte value) - { - WriteIoPortByteEx(port, value); - } - - public void WriteIoPortWord(ushort port, ushort value) - { - WriteIoPortWordEx(port, value); - } - - public void WriteIoPortDword(ushort port, uint value) - { - WriteIoPortDwordEx(port, value); - } - - public bool WriteIoPortByteEx(ushort port, byte value) - { - if (!IsOpen) - return false; - - var input = new WriteIoPortInputByte { PortNumber = port, Value = value }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_WRITE_IO_PORT_BYTE, input); - } - - public bool WriteIoPortWordEx(ushort port, ushort value) - { - if (!IsOpen) - return false; - - var input = new WriteIoPortInputWord { PortNumber = port, Value = value }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_WRITE_IO_PORT_WORD, input); - } - - public bool WriteIoPortDwordEx(ushort port, uint value) - { - if (!IsOpen) - return false; - - var input = new WriteIoPortInputDword { PortNumber = port, Value = value }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_WRITE_IO_PORT_DWORD, input); - } - - public uint FindPciDeviceById(ushort vendorId, ushort deviceId, byte index) - { - if (!IsOpen) - return uint.MaxValue; - - if (vendorId == ushort.MaxValue) - { - return uint.MaxValue; - } - - uint count = 0; - - for (byte bus = 0; bus < PCI_MAX_NUMBER_OF_BUS; ++bus) - { - for (byte dev = 0; dev < PCI_NUMBER_OF_DEVICE; ++dev) - { - bool multiFuncFlag = false; - - for (byte func = 0; func < PCI_NUMBER_OF_FUNCTION; ++func) - { - if (!multiFuncFlag && func > 0) - { - break; - } - - uint pciAddress = Ring0.GetPciAddress(bus, dev, func); - - uint id = 0; - - if (PciConfigRead(pciAddress, 0, ref id)) - { - if (func == 0) //Is Multi Function Device - { - byte type = 0; - - if (PciConfigRead(pciAddress, 0x0E, ref type)) - { - if ((type & 0x80) != 0) - { - multiFuncFlag = true; - } - } - } - - if (id == (vendorId | ((uint)deviceId << 16))) - { - if (count == index) - { - return pciAddress; - } - - ++count; - continue; - } - } - } - } - } - - return uint.MaxValue; - } - - public uint FindPciDeviceByClass(byte baseClass, byte subClass, byte programIf, byte index) - { - if (!IsOpen) - return uint.MaxValue; - - uint count = 0; - - for (byte bus = 0; bus < PCI_MAX_NUMBER_OF_BUS; ++bus) - { - for (byte dev = 0; dev < PCI_NUMBER_OF_DEVICE; ++dev) - { - bool multiFuncFlag = false; - - for (byte func = 0; func < PCI_NUMBER_OF_FUNCTION; ++func) - { - if (!multiFuncFlag && func > 0) - { - break; - } - - uint pciAddress = Ring0.GetPciAddress(bus, dev, func); - - var conf = new Conf(); - - if (PciConfigRead(pciAddress, 0, ref conf)) - { - if (func == 0) //Is Multi Function Device - { - byte type = 0; - - if (PciConfigRead(pciAddress, 0x0E, ref type)) - { - if ((type & 0x80) != 0) - { - multiFuncFlag = true; - } - } - } - - var temp = (uint)baseClass << 24 | (uint)subClass << 16 | (uint)programIf << 8; - - if ((conf.C & 0xFFFFFF00) == temp) - { - if (count == index) - { - return pciAddress; - } - - ++count; - continue; - } - } - } - } - } - - return uint.MaxValue; - } - - public byte ReadPciConfigByte(uint pciAddress, byte regAddress) - { - byte value = 0; - - if (ReadPciConfigByteEx(pciAddress, regAddress, ref value)) - { - return value; - } - else - { - return byte.MaxValue; - } - } - - public ushort ReadPciConfigWord(uint pciAddress, byte regAddress) - { - ushort value = 0; - - if (ReadPciConfigWordEx(pciAddress, regAddress, ref value)) - { - return value; - } - else - { - return ushort.MaxValue; - } - } - - public uint ReadPciConfigDword(uint pciAddress, byte regAddress) - { - uint value = 0; - - if (ReadPciConfigDwordEx(pciAddress, regAddress, ref value)) - { - return value; - } - else - { - return uint.MaxValue; - } - } - - public bool ReadPciConfigByteEx(uint pciAddress, uint regAddress, ref byte value) - { - return PciConfigRead(pciAddress, regAddress, ref value); - } - - public bool ReadPciConfigWordEx(uint pciAddress, uint regAddress, ref ushort value) - { - return PciConfigRead(pciAddress, regAddress, ref value); - } - - public bool ReadPciConfigDwordEx(uint pciAddress, uint regAddress, ref uint value) - { - return PciConfigRead(pciAddress, regAddress, ref value); - } - - public void WritePciConfigByte(uint pciAddress, byte regAddress, byte value) - { - WritePciConfigByteEx(pciAddress, regAddress, value); - } - - public void WritePciConfigWord(uint pciAddress, byte regAddress, ushort value) - { - WritePciConfigWordEx(pciAddress, regAddress, value); - } - - public void WritePciConfigDword(uint pciAddress, byte regAddress, uint value) - { - WritePciConfigDwordEx(pciAddress, regAddress, value); - } - - public bool WritePciConfigByteEx(uint pciAddress, uint regAddress, byte value) - { - var input = new WritePciConfigInputByte { PciAddress = pciAddress, RegAddress = regAddress, Value = value }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_WRITE_PCI_CONFIG, input); - } - - public bool WritePciConfigWordEx(uint pciAddress, uint regAddress, ushort value) - { - var input = new WritePciConfigInputWord { PciAddress = pciAddress, RegAddress = regAddress, Value = value }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_WRITE_PCI_CONFIG, input); - } - - public bool WritePciConfigDwordEx(uint pciAddress, uint regAddress, uint value) - { - var input = new WritePciConfigInputDword { PciAddress = pciAddress, RegAddress = regAddress, Value = value }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_WRITE_PCI_CONFIG, input); - } - - private bool PciConfigRead(uint pciAddress, uint regAddress, ref TValue value) - where TValue : struct - { - var input = new ReadPciConfigInput { PciAddress = pciAddress, RegAddress = regAddress }; - return _kernelDriver.DeviceIOControl(IOCC.IOCTL_OLS_READ_PCI_CONFIG, input, ref value); - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WriteIoPortInputByte - { - public uint PortNumber; - public byte Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WriteIoPortInputWord - { - public uint PortNumber; - public ushort Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WriteIoPortInputDword - { - public uint PortNumber; - public uint Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct ReadPciConfigInput - { - public uint PciAddress; - public uint RegAddress; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WritePciConfigInputByte - { - public uint PciAddress; - public uint RegAddress; - public byte Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WritePciConfigInputWord - { - public uint PciAddress; - public uint RegAddress; - public ushort Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WritePciConfigInputDword - { - public uint PciAddress; - public uint RegAddress; - public uint Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct Conf - { - public uint A; - public uint B; - public uint C; - } - } -} diff --git a/LibreHardwareMonitorLib/Hardware/Ring0.cs b/LibreHardwareMonitorLib/Hardware/Ring0.cs deleted file mode 100644 index 6dcbef9..0000000 --- a/LibreHardwareMonitorLib/Hardware/Ring0.cs +++ /dev/null @@ -1,465 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// Partial Copyright (C) Michael Möller and Contributors. -// All Rights Reserved. - -using System.Diagnostics; -using System.IO; -using System.IO.Compression; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; - -namespace LibreHardwareMonitor.Hardware; - -internal static class Ring0 -{ - private static KernelDriver _driver; - private static string _filePath; - - private static readonly StringBuilder _report = new(); - - public static bool IsOpen => _driver != null; - - internal static KernelDriver KernelDriver => _driver; - - public static void Open() - { - // no implementation for unix systems - if (Software.OperatingSystem.IsUnix) - return; - - if (_driver != null) - return; - - // clear the current report - _report.Length = 0; - - _driver = new KernelDriver(GetServiceName(), "WinRing0_1_2_0"); - _driver.Open(); - - if (!_driver.IsOpen) - { - // driver is not loaded, try to install and open - _filePath = GetFilePath(); - if (_filePath != null && Extract(_filePath)) - { - if (_driver.Install(_filePath, out string installError)) - { - _driver.Open(); - - if (!_driver.IsOpen) - _report.AppendLine("Status: Opening driver failed after install"); - } - else - { - // install failed, try to delete and reinstall - _driver.Delete(); - - // wait a short moment to give the OS a chance to remove the driver - Thread.Sleep(2000); - - if (_driver.Install(_filePath, out string secondError)) - { - _driver.Open(); - - if (!_driver.IsOpen) - _report.AppendLine("Status: Opening driver failed after reinstall"); - } - else - { - _report.Append($"Status: Installing driver \"{_filePath}\" failed").AppendLine(File.Exists(_filePath) ? " and file exists" : string.Empty); - _report.Append("First Exception: ").AppendLine(installError); - _report.Append("Second Exception: ").AppendLine(secondError); - } - } - - if (!_driver.IsOpen) - { - _driver.Delete(); - Delete(); - } - } - else - { - _report.AppendLine("Status: Extracting driver failed"); - } - } - - if (!_driver.IsOpen) - _driver = null; - } - - private static bool Extract(string filePath) - { - string resourceName = $"{nameof(LibreHardwareMonitor)}.Resources.{(Software.OperatingSystem.Is64Bit ? "WinRing0x64.gz" : "WinRing0.gz")}"; - - Assembly assembly = typeof(Ring0).Assembly; - long requiredLength = 0; - - try - { - using Stream stream = assembly.GetManifestResourceStream(resourceName); - - if (stream != null) - { - using FileStream target = new(filePath, FileMode.Create); - - stream.Position = 1; // Skip first byte. - - using var gzipStream = new GZipStream(stream, CompressionMode.Decompress); - - gzipStream.CopyTo(target); - - requiredLength = target.Length; - } - } - catch - { - return false; - } - - if (HasValidFile()) - return true; - - // Ensure the file is actually written to the file system. - var stopwatch = new Stopwatch(); - stopwatch.Start(); - - while (stopwatch.ElapsedMilliseconds < 2000) - { - if (HasValidFile()) - return true; - - Thread.Yield(); - } - - return false; - - bool HasValidFile() - { - try - { - return File.Exists(filePath) && new FileInfo(filePath).Length == requiredLength; - } - catch - { - return false; - } - } - } - - private static void Delete() - { - try - { - // Try to delete the driver file - if (_filePath != null && File.Exists(_filePath)) - File.Delete(_filePath); - - _filePath = null; - } - catch - { - // Ignored. - } - } - - private static string GetServiceName() - { - string name; - - try - { - ProcessModule processModule = Process.GetCurrentProcess().MainModule; - if (!string.IsNullOrEmpty(processModule?.FileName)) - { - name = Path.GetFileNameWithoutExtension(processModule.FileName); - if (!string.IsNullOrEmpty(name)) - return GetName(name); - } - } - catch - { - // Continue with the other options. - } - - name = GetNameFromAssembly(Assembly.GetExecutingAssembly()); - if (!string.IsNullOrEmpty(name)) - return GetName(name); - - name = GetNameFromAssembly(typeof(Ring0).Assembly); - if (!string.IsNullOrEmpty(name)) - return GetName(name); - - name = nameof(LibreHardwareMonitor); - return GetName(name); - - static string GetNameFromAssembly(Assembly assembly) - { - return assembly?.GetName().Name; - } - - static string GetName(string name) - { - return $"R0{name}".Replace(" ", string.Empty).Replace(".", "_"); - } - } - - private static string GetFilePath() - { - string filePath = null; - - try - { - ProcessModule processModule = Process.GetCurrentProcess().MainModule; - if (!string.IsNullOrEmpty(processModule?.FileName)) - { - filePath = Path.ChangeExtension(processModule.FileName, ".sys"); - if (CanCreate(filePath)) - return filePath; - } - } - catch - { - // Continue with the other options. - } - - string previousFilePath = filePath; - filePath = GetPathFromAssembly(Assembly.GetExecutingAssembly()); - if (previousFilePath != filePath && !string.IsNullOrEmpty(filePath) && CanCreate(filePath)) - return filePath; - - previousFilePath = filePath; - filePath = GetPathFromAssembly(typeof(Ring0).Assembly); - if (previousFilePath != filePath && !string.IsNullOrEmpty(filePath) && CanCreate(filePath)) - return filePath; - - try - { - filePath = Path.GetTempFileName(); - if (!string.IsNullOrEmpty(filePath)) - { - filePath = Path.ChangeExtension(filePath, ".sys"); - if (CanCreate(filePath)) - return filePath; - } - } - catch - { - return null; - } - - return null; - - static string GetPathFromAssembly(Assembly assembly) - { - try - { - string location = assembly?.Location; - return !string.IsNullOrEmpty(location) ? Path.ChangeExtension(location, ".sys") : null; - } - catch - { - return null; - } - } - - static bool CanCreate(string path) - { - try - { - using (File.Create(path, 1, FileOptions.DeleteOnClose)) - return true; - } - catch - { - return false; - } - } - } - - public static void Close() - { - if (_driver != null) - { - uint refCount = 0; - _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_GET_REFCOUNT, null, ref refCount); - _driver.Close(); - - if (refCount <= 1) - _driver.Delete(); - - _driver = null; - } - - // try to delete temporary driver file again if failed during open - Delete(); - } - - public static string GetReport() - { - if (_report.Length > 0) - { - StringBuilder r = new(); - r.AppendLine("Ring0"); - r.AppendLine(); - r.Append(_report); - r.AppendLine(); - return r.ToString(); - } - - return null; - } - - public static bool ReadMsr(uint index, out uint eax, out uint edx) - { - if (_driver == null) - { - eax = 0; - edx = 0; - return false; - } - - ulong buffer = 0; - bool result = _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_MSR, index, ref buffer); - edx = (uint)((buffer >> 32) & 0xFFFFFFFF); - eax = (uint)(buffer & 0xFFFFFFFF); - return result; - } - - public static bool ReadMsr(uint index, out ulong edxeax) - { - if (_driver == null) - { - edxeax = 0; - return false; - } - - ulong buffer = 0; - bool result = _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_MSR, index, ref buffer); - edxeax = buffer; - return result; - } - - public static bool ReadMsr(uint index, out uint eax, out uint edx, GroupAffinity affinity) - { - GroupAffinity previousAffinity = ThreadAffinity.Set(affinity); - bool result = ReadMsr(index, out eax, out edx); - ThreadAffinity.Set(previousAffinity); - return result; - } - - public static bool WriteMsr(uint index, uint eax, uint edx) - { - if (_driver == null) - return false; - - WriteMsrInput input = new() { Register = index, Value = ((ulong)edx << 32) | eax }; - return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_WRITE_MSR, input); - } - - public static byte ReadIoPort(uint port) - { - if (_driver == null) - return 0; - - uint value = 0; - _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_IO_PORT_BYTE, port, ref value); - return (byte)(value & 0xFF); - } - - public static void WriteIoPort(uint port, byte value) - { - if (_driver == null) - return; - - WriteIoPortInput input = new() { PortNumber = port, Value = value }; - _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_WRITE_IO_PORT_BYTE, input); - } - - public static uint GetPciAddress(byte bus, byte device, byte function) - { - return (uint)(((bus & 0xFF) << 8) | ((device & 0x1F) << 3) | (function & 7)); - } - - public static bool ReadPciConfig(uint pciAddress, uint regAddress, out uint value) - { - if (_driver == null || (regAddress & 3) != 0) - { - value = 0; - return false; - } - - ReadPciConfigInput input = new() { PciAddress = pciAddress, RegAddress = regAddress }; - - value = 0; - return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_PCI_CONFIG, input, ref value); - } - - public static bool WritePciConfig(uint pciAddress, uint regAddress, uint value) - { - if (_driver == null || (regAddress & 3) != 0) - return false; - - WritePciConfigInput input = new() { PciAddress = pciAddress, RegAddress = regAddress, Value = value }; - return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_WRITE_PCI_CONFIG, input); - } - - public static bool ReadMemory(ulong address, ref T buffer) - { - if (_driver == null) - return false; - - ReadMemoryInput input = new() { Address = address, UnitSize = 1, Count = (uint)Marshal.SizeOf(buffer) }; - return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_MEMORY, input, ref buffer); - } - - public static bool ReadMemory(ulong address, ref T[] buffer) - { - if (_driver == null) - return false; - - ReadMemoryInput input = new() { Address = address, UnitSize = (uint)Marshal.SizeOf(typeof(T)), Count = (uint)buffer.Length }; - return _driver.DeviceIOControl(Interop.Ring0.IOCTL_OLS_READ_MEMORY, input, ref buffer); - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WriteMsrInput - { - public uint Register; - public ulong Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WriteIoPortInput - { - public uint PortNumber; - public byte Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct ReadPciConfigInput - { - public uint PciAddress; - public uint RegAddress; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WritePciConfigInput - { - public uint PciAddress; - public uint RegAddress; - public uint Value; - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct ReadMemoryInput - { - public ulong Address; - public uint UnitSize; - public uint Count; - } -} diff --git a/LibreHardwareMonitorLib/Hardware/RyzenSMU.cs b/LibreHardwareMonitorLib/Hardware/RyzenSMU.cs index 0e5d5ba..3a69ecf 100644 --- a/LibreHardwareMonitorLib/Hardware/RyzenSMU.cs +++ b/LibreHardwareMonitorLib/Hardware/RyzenSMU.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Text; -using System.Threading; +using LibreHardwareMonitor.PawnIo; // ReSharper disable InconsistentNaming @@ -12,13 +12,9 @@ namespace LibreHardwareMonitor.Hardware; internal class RyzenSMU { - private const byte SMU_PCI_ADDR_REG = 0xC4; - private const byte SMU_PCI_DATA_REG = 0xC8; - private const uint SMU_REQ_MAX_ARGS = 6; - private const uint SMU_RETRIES_MAX = 8096; - private readonly CpuCodeName _cpuCodeName; private readonly bool _supportedCPU; + private readonly Exception _unsupportedCPUException; private readonly Dictionary> _supportedPmTableVersions = new() { @@ -148,60 +144,36 @@ internal class RyzenSMU } }; - private uint _argsAddr; - private uint _cmdAddr; - private uint _dramAddrHi; - private uint _dramBaseAddr; private uint _pmTableSize; private uint _pmTableSizeAlt; private uint _pmTableVersion; - private uint _rspAddr; + private uint _dramBaseAddr; - public RyzenSMU(uint family, uint model, uint packageType) + private readonly RyzenSmu _ryzenSmu; + + public RyzenSMU() { - _cpuCodeName = GetCpuCodeName(family, model, packageType); - - _supportedCPU = Environment.Is64BitOperatingSystem == Environment.Is64BitProcess && SetAddresses(_cpuCodeName); - - if (_supportedCPU && InpOut.Open()) - SetupPmTableAddrAndSize(); - } - - private static CpuCodeName GetCpuCodeName(uint family, uint model, uint packageType) - { - return family switch + try { - 0x17 => model switch - { - 0x01 => packageType == 7 ? CpuCodeName.Threadripper : CpuCodeName.SummitRidge, - 0x08 => packageType == 7 ? CpuCodeName.Colfax : CpuCodeName.PinnacleRidge, - 0x11 => CpuCodeName.RavenRidge, - 0x18 => packageType == 2 ? CpuCodeName.RavenRidge2 : CpuCodeName.Picasso, - 0x20 => CpuCodeName.Dali, - 0x31 => CpuCodeName.CastlePeak, - 0x60 => CpuCodeName.Renoir, - 0x71 => CpuCodeName.Matisse, - 0x90 => CpuCodeName.Vangogh, - _ => CpuCodeName.Undefined - }, - 0x19 => model switch - { - 0x00 => CpuCodeName.Milan, - 0x20 or 0x21 => CpuCodeName.Vermeer, - 0x40 => CpuCodeName.Rembrandt, - 0x50 => CpuCodeName.Cezanne, - 0x61 => CpuCodeName.Raphael, - _ => CpuCodeName.Undefined - }, - 0x1A => model switch - { - 0x44 => CpuCodeName.GraniteRidge, - _ => CpuCodeName.Undefined - }, - _ => CpuCodeName.Undefined - }; + _ryzenSmu = new RyzenSmu(); + + _cpuCodeName = (CpuCodeName)_ryzenSmu.GetCodeName(); + + _ryzenSmu.ResolvePmTable(out _pmTableVersion, out _dramBaseAddr); + + SetupPmTableSize(); + + _supportedCPU = true; + } + catch (Exception e) + { + _supportedCPU = false; + _unsupportedCPUException = e; + } } + public void Close() => _ryzenSmu.Close(); + public string GetReport() { StringBuilder r = new(); @@ -218,64 +190,30 @@ internal class RyzenSMU r.AppendLine($" PM table start address: 0x{_dramBaseAddr:X8}"); r.AppendLine(); r.AppendLine(" PM table dump:"); - r.AppendLine(" Idx Offset Value"); - r.AppendLine(" ------------------------"); - float[] pm_values = GetPmTable(); - for (int i = 0; i < pm_values.Length; i++) + try { - r.AppendLine($" {i,4} 0x{i * 4:X3} {pm_values[i]}"); + float[] pm_values = UpdateAndReadDram(); + r.AppendLine(" Idx Offset Value"); + r.AppendLine(" ------------------------"); + for (int i = 0; i < pm_values.Length; i++) + { + r.AppendLine($" {i,4} 0x{i * 4:X3} {pm_values[i]}"); + } } + catch (Exception e) + { + r.AppendLine($" Exception: {e.Message}"); + } + } + else + { + r.AppendLine($" Initialization exception: {_unsupportedCPUException.Message}"); } return r.ToString(); } - private bool SetAddresses(CpuCodeName codeName) - { - switch (codeName) - { - case CpuCodeName.CastlePeak: - case CpuCodeName.Matisse: - case CpuCodeName.Vermeer: - case CpuCodeName.Raphael: - case CpuCodeName.GraniteRidge: - _cmdAddr = 0x3B10524; - _rspAddr = 0x3B10570; - _argsAddr = 0x3B10A40; - return true; - - case CpuCodeName.Colfax: - case CpuCodeName.SummitRidge: - case CpuCodeName.Threadripper: - case CpuCodeName.PinnacleRidge: - _cmdAddr = 0x3B1051C; - _rspAddr = 0x3B10568; - _argsAddr = 0x3B10590; - return true; - - case CpuCodeName.Renoir: - case CpuCodeName.Picasso: - case CpuCodeName.RavenRidge: - case CpuCodeName.RavenRidge2: - case CpuCodeName.Dali: - _cmdAddr = 0x3B10A20; - _rspAddr = 0x3B10A80; - _argsAddr = 0x3B10A88; - return true; - - default: - return false; - } - } - - public uint GetSmuVersion() - { - uint[] args = [1]; - - return SendCommand(0x02, ref args) ? args[0] : 0; - } - public Dictionary GetPmTableStructure() { if (!IsPmTableLayoutDefined()) @@ -291,51 +229,44 @@ internal class RyzenSMU public float[] GetPmTable() { - if (!_supportedCPU || !TransferTableToDram()) + if (!_supportedCPU) return [0]; - float[] table = ReadDramToArray(); - - // Fix for Zen+ empty values on first call. - if (table.Length == 0 || table[0] == 0) + float[] table = null; + for (int tries_left = 2; tries_left != 0; --tries_left) { - Thread.Sleep(10); - TransferTableToDram(); - table = ReadDramToArray(); + table = null; + try + { + table = UpdateAndReadDram(); + } + catch + { + // ignored + } + + if (table is { Length: > 0 } && table[0] != 0) + { + return table; + } } - return table; + return table is { Length: > 0 } ? table : [0]; } - private float[] ReadDramToArray() + private float[] UpdateAndReadDram() { float[] table = new float[_pmTableSize / 4]; - IntPtr pMemory = Environment.Is64BitProcess ? new IntPtr(_dramBaseAddr | (long)_dramAddrHi << 32) : new IntPtr(_dramBaseAddr); - - byte[] bytes = InpOut.ReadMemory(pMemory, _pmTableSize); - if (bytes != null) - Buffer.BlockCopy(bytes, 0, table, 0, bytes.Length); + _ryzenSmu.UpdatePmTable(); + long[] read = _ryzenSmu.ReadPmTable((int)((_pmTableSize + 7) / 8)); + Buffer.BlockCopy(read, 0, table, 0, (int)_pmTableSize); return table; } - private bool SetupPmTableAddrAndSize() - { - if (_pmTableSize == 0) - SetupPmTableSize(); - - if (_dramBaseAddr == 0) - SetupDramBaseAddr(); - - return _dramBaseAddr != 0 && _pmTableSize != 0; - } - private void SetupPmTableSize() { - if (!GetPmTableVersion(ref _pmTableVersion)) - return; - switch (_cpuCodeName) { case CpuCodeName.Matisse: @@ -454,288 +385,6 @@ internal class RyzenSMU } } - private bool GetPmTableVersion(ref uint version) - { - uint[] args = [0]; - uint fn; - - switch (_cpuCodeName) - { - case CpuCodeName.RavenRidge: - case CpuCodeName.Picasso: - fn = 0x0c; - break; - case CpuCodeName.Matisse: - case CpuCodeName.Vermeer: - fn = 0x08; - break; - case CpuCodeName.Renoir: - fn = 0x06; - break; - case CpuCodeName.Raphael: - case CpuCodeName.GraniteRidge: - fn = 0x05; - break; - default: - return false; - } - - bool ret = SendCommand(fn, ref args); - version = args[0]; - - return ret; - } - - private void SetupAddrClass1(uint[] fn) - { - uint[] args = [1, 1]; - - bool command = SendCommand(fn[0], ref args); - if (!command) - return; - - _dramBaseAddr = args[0]; - _dramAddrHi = args[1]; - } - - private void SetupAddrClass2(uint[] fn) - { - uint[] args = [0, 0, 0, 0, 0, 0]; - - bool command = SendCommand(fn[0], ref args); - if (!command) - return; - - args = [0]; - command = SendCommand(fn[1], ref args); - if (!command) - return; - - _dramBaseAddr = args[0]; - } - - private void SetupAddrClass3(uint[] fn) - { - uint[] parts = [0, 0]; - - // == Part 1 == - uint[] args = [3]; - bool command = SendCommand(fn[0], ref args); - if (!command) - return; - - args = [3]; - command = SendCommand(fn[2], ref args); - if (!command) - return; - - // 1st Base. - parts[0] = args[0]; - // == Part 1 End == - - // == Part 2 == - args = [3]; - command = SendCommand(fn[1], ref args); - if (!command) - return; - - args = [5]; - command = SendCommand(fn[0], ref args); - if (!command) - return; - - args = [5]; - command = SendCommand(fn[2], ref args); - if (!command) - return; - - // 2nd base. - parts[1] = args[0]; - // == Part 2 End == - - _dramBaseAddr = parts[0] & 0xFFFFFFFF; - } - - private void SetupDramBaseAddr() - { - uint[] fn = [0, 0, 0]; - - switch (_cpuCodeName) - { - case CpuCodeName.Raphael: - case CpuCodeName.GraniteRidge: - fn[0] = 0x04; - SetupAddrClass1(fn); - return; - case CpuCodeName.Vermeer: - case CpuCodeName.Matisse: - case CpuCodeName.CastlePeak: - fn[0] = 0x06; - SetupAddrClass1(fn); - return; - case CpuCodeName.Renoir: - fn[0] = 0x66; - SetupAddrClass1(fn); - return; - case CpuCodeName.Colfax: - case CpuCodeName.PinnacleRidge: - fn[0] = 0x0b; - fn[1] = 0x0c; - SetupAddrClass2(fn); - return; - case CpuCodeName.Dali: - case CpuCodeName.Picasso: - case CpuCodeName.RavenRidge: - case CpuCodeName.RavenRidge2: - fn[0] = 0x0a; - fn[1] = 0x3d; - fn[2] = 0x0b; - SetupAddrClass3(fn); - return; - default: - return; - } - } - - public bool TransferTableToDram() - { - uint[] args = [0]; - uint fn; - - switch (_cpuCodeName) - { - case CpuCodeName.Raphael: - case CpuCodeName.GraniteRidge: - fn = 0x03; - break; - case CpuCodeName.Matisse: - case CpuCodeName.Vermeer: - fn = 0x05; - break; - case CpuCodeName.Renoir: - args[0] = 3; - fn = 0x65; - break; - case CpuCodeName.Picasso: - case CpuCodeName.RavenRidge: - case CpuCodeName.RavenRidge2: - args[0] = 3; - fn = 0x3d; - break; - default: - return false; - } - - return SendCommand(fn, ref args); - } - - private bool SendCommand(uint msg, ref uint[] args) - { - uint[] cmdArgs = new uint[SMU_REQ_MAX_ARGS]; - int argsLength = Math.Min(args.Length, cmdArgs.Length); - - for (int i = 0; i < argsLength; ++i) - cmdArgs[i] = args[i]; - - uint tmp = 0; - if (Mutexes.WaitPciBus(5000)) - { - // Step 1: Wait until the RSP register is non-zero. - - tmp = 0; - uint retries = SMU_RETRIES_MAX; - do - { - if (!ReadReg(_rspAddr, ref tmp)) - { - Mutexes.ReleasePciBus(); - return false; - } - } - while (tmp == 0 && retries-- != 0); - - // Step 1.b: A command is still being processed meaning a new command cannot be issued. - - if (retries == 0 && tmp == 0) - { - Mutexes.ReleasePciBus(); - return false; - } - - // Step 2: Write zero (0) to the RSP register - WriteReg(_rspAddr, 0); - - // Step 3: Write the argument(s) into the argument register(s) - for (int i = 0; i < cmdArgs.Length; ++i) - WriteReg(_argsAddr + (uint)(i * 4), cmdArgs[i]); - - // Step 4: Write the message Id into the Message ID register - WriteReg(_cmdAddr, msg); - - // Step 5: Wait until the Response register is non-zero. - tmp = 0; - retries = SMU_RETRIES_MAX; - do - { - if (!ReadReg(_rspAddr, ref tmp)) - { - Mutexes.ReleasePciBus(); - return false; - } - } - while (tmp == 0 && retries-- != 0); - - if (retries == 0 && tmp != (uint)Status.OK) - { - Mutexes.ReleasePciBus(); - return false; - } - - // Step 6: If the Response register contains OK, then SMU has finished processing the message. - - args = new uint[SMU_REQ_MAX_ARGS]; - for (byte i = 0; i < SMU_REQ_MAX_ARGS; i++) - { - if (!ReadReg(_argsAddr + (uint)(i * 4), ref args[i])) - { - Mutexes.ReleasePciBus(); - return false; - } - } - - ReadReg(_rspAddr, ref tmp); - Mutexes.ReleasePciBus(); - } - - return tmp == (uint)Status.OK; - } - - private static void WriteReg(uint addr, uint data) - { - if (Mutexes.WaitPciBus(10)) - { - if (Ring0.WritePciConfig(0x00, SMU_PCI_ADDR_REG, addr)) - Ring0.WritePciConfig(0x00, SMU_PCI_DATA_REG, data); - - Mutexes.ReleasePciBus(); - } - } - - private static bool ReadReg(uint addr, ref uint data) - { - bool read = false; - - if (Mutexes.WaitPciBus(10)) - { - if (Ring0.WritePciConfig(0x00, SMU_PCI_ADDR_REG, addr)) - read = Ring0.ReadPciConfig(0x00, SMU_PCI_DATA_REG, out data); - - Mutexes.ReleasePciBus(); - } - - return read; - } - public struct SmuSensorType { public string Name; @@ -743,18 +392,10 @@ internal class RyzenSMU public float Scale; } - private enum Status : uint - { - OK = 0x01, - CmdRejectedBusy = 0xFC, - CmdRejectedPrereq = 0xFD, - UnknownCmd = 0xFE, - Failed = 0xFF - } private enum CpuCodeName { - Undefined, + Undefined = -1, Colfax, Renoir, Picasso, diff --git a/LibreHardwareMonitorLib/Interop/InpOut.cs b/LibreHardwareMonitorLib/Interop/InpOut.cs deleted file mode 100644 index 1e5a216..0000000 --- a/LibreHardwareMonitorLib/Interop/InpOut.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace LibreHardwareMonitor.Interop; - -internal class InpOut -{ - public delegate IntPtr MapPhysToLinDelegate(IntPtr pbPhysAddr, uint dwPhysSize, out IntPtr pPhysicalMemoryHandle); - - public delegate bool UnmapPhysicalMemoryDelegate(IntPtr PhysicalMemoryHandle, IntPtr pbLinAddr); - - [DllImport("inpout.dll", EntryPoint = "MapPhysToLin", CallingConvention = CallingConvention.StdCall)] - public static extern IntPtr MapPhysToLin(IntPtr pbPhysAddr, uint dwPhysSize, out IntPtr pPhysicalMemoryHandle); - - [DllImport("inpout.dll", EntryPoint = "UnmapPhysicalMemory", CallingConvention = CallingConvention.StdCall)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, IntPtr pbLinAddr); -} \ No newline at end of file diff --git a/LibreHardwareMonitorLib/Interop/Ring0.cs b/LibreHardwareMonitorLib/Interop/Ring0.cs deleted file mode 100644 index f3b25a2..0000000 --- a/LibreHardwareMonitorLib/Interop/Ring0.cs +++ /dev/null @@ -1,35 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Copyright (C) LibreHardwareMonitor and Contributors. -// All Rights Reserved. - -// ReSharper disable InconsistentNaming -// ReSharper disable IdentifierTypo - -namespace LibreHardwareMonitor.Interop; - -/// -/// Driver with access at kernel level. -/// -internal static class Ring0 -{ - public const uint INVALID_PCI_ADDRESS = 0xFFFFFFFF; - - private const uint OLS_TYPE = 40000; - - public static readonly Kernel32.IOControlCode IOCTL_OLS_GET_REFCOUNT = new(OLS_TYPE, 0x801, Kernel32.IOControlCode.Access.Any); - public static readonly Kernel32.IOControlCode IOCTL_OLS_READ_MSR = new(OLS_TYPE, 0x821, Kernel32.IOControlCode.Access.Any); - public static readonly Kernel32.IOControlCode IOCTL_OLS_WRITE_MSR = new(OLS_TYPE, 0x822, Kernel32.IOControlCode.Access.Any); - public static readonly Kernel32.IOControlCode IOCTL_OLS_READ_MEMORY = new(OLS_TYPE, 0x841, Kernel32.IOControlCode.Access.Read); - - public static readonly Kernel32.IOControlCode IOCTL_OLS_READ_IO_PORT_BYTE = new(OLS_TYPE, 0x833, Kernel32.IOControlCode.Access.Read); - public static readonly Kernel32.IOControlCode IOCTL_OLS_READ_IO_PORT_WORD = new(OLS_TYPE, 0x834, Kernel32.IOControlCode.Access.Read); - public static readonly Kernel32.IOControlCode IOCTL_OLS_READ_IO_PORT_DWORD = new(OLS_TYPE, 0x835, Kernel32.IOControlCode.Access.Read); - - public static readonly Kernel32.IOControlCode IOCTL_OLS_WRITE_IO_PORT_BYTE = new(OLS_TYPE, 0x836, Kernel32.IOControlCode.Access.Write); - public static readonly Kernel32.IOControlCode IOCTL_OLS_WRITE_IO_PORT_WORD = new(OLS_TYPE, 0x837, Kernel32.IOControlCode.Access.Write); - public static readonly Kernel32.IOControlCode IOCTL_OLS_WRITE_IO_PORT_DWORD = new(OLS_TYPE, 0x838, Kernel32.IOControlCode.Access.Write); - - public static readonly Kernel32.IOControlCode IOCTL_OLS_READ_PCI_CONFIG = new(OLS_TYPE, 0x851, Kernel32.IOControlCode.Access.Read); - public static readonly Kernel32.IOControlCode IOCTL_OLS_WRITE_PCI_CONFIG = new(OLS_TYPE, 0x852, Kernel32.IOControlCode.Access.Write); -} diff --git a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj index d3f98cb..6234904 100644 --- a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj +++ b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj @@ -17,6 +17,7 @@ https://github.com/LibreHardwareMonitor/LibreHardwareMonitor latest packageicon.png + true ..\bin\Debug\ @@ -28,10 +29,16 @@ true - - - - + + + + + + + + + + @@ -41,7 +48,7 @@ - + diff --git a/LibreHardwareMonitorLib/PawnIo/AmdFamily0F.cs b/LibreHardwareMonitorLib/PawnIo/AmdFamily0F.cs new file mode 100644 index 0000000..9299f0a --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/AmdFamily0F.cs @@ -0,0 +1,47 @@ +using LibreHardwareMonitor.Hardware; + +namespace LibreHardwareMonitor.PawnIo; + +public class AmdFamily0F +{ + private readonly PawnIo _pawnIO = PawnIo.LoadModuleFromResource(typeof(AmdFamily0F).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.AMDFamily0F.bin"); + + public bool ReadMsr(uint index, out uint eax, out uint edx) + { + long[] inArray = new long[1]; + inArray[0] = index; + eax = 0; + edx = 0; + try + { + long[] outArray = _pawnIO.Execute("ioctl_read_msr", inArray, 1); + eax = (uint)outArray[0]; + edx = (uint)(outArray[0] >> 32); + } + catch + { + return false; + } + + return true; + } + + public bool ReadMsr(uint index, out uint eax, out uint edx, GroupAffinity affinity) + { + GroupAffinity previousAffinity = ThreadAffinity.Set(affinity); + bool result = ReadMsr(index, out eax, out edx); + ThreadAffinity.Set(previousAffinity); + return result; + } + + public uint GetThermtrip(int cpuIndex, uint coreIndex) + { + long[] inArray = new long[2]; + inArray[0] = cpuIndex; + inArray[1] = coreIndex; + long[] outArray = _pawnIO.Execute("ioctl_get_thermtrip", inArray, 1); + return (uint)outArray[0]; + } + + public void Close() => _pawnIO.Close(); +} diff --git a/LibreHardwareMonitorLib/PawnIo/AmdFamily10.cs b/LibreHardwareMonitorLib/PawnIo/AmdFamily10.cs new file mode 100644 index 0000000..1c7cf12 --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/AmdFamily10.cs @@ -0,0 +1,78 @@ +using LibreHardwareMonitor.Hardware; + +namespace LibreHardwareMonitor.PawnIo; + +public class AmdFamily10 +{ + private readonly PawnIo _pawnIo = PawnIo.LoadModuleFromResource(typeof(AmdFamily0F).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.AMDFamily10.bin"); + + public void MeasureTscMultiplier(out long ctrPerTick, out long cofVid) + { + long[] result = _pawnIo.Execute("ioctl_measure_tsc_multiplier", [], 2); + ctrPerTick = result[0]; + cofVid = result[1]; + } + + public bool HaveCstateResidencyInfo() + { + try + { + ReadCstateResidency(); + return true; + } + catch + { + // ignored + } + + return false; + } + + public byte[] ReadCstateResidency() + { + long[] result = _pawnIo.Execute("ioctl_read_cstate_residency", [], 2); + return [(byte)result[0], (byte)result[1]]; + } + + public uint ReadMiscCtl(int cpu, uint offset) + { + long[] result = _pawnIo.Execute("ioctl_read_miscctl", [cpu, offset], 1); + return (uint)result[0]; + } + + public uint ReadSmu(uint offset) + { + long[] result = _pawnIo.Execute("ioctl_read_smu", [offset], 1); + return (uint)result[0]; + } + + public bool ReadMsr(uint index, out uint eax, out uint edx) + { + long[] inArray = new long[1]; + inArray[0] = index; + eax = 0; + edx = 0; + try + { + long[] outArray = _pawnIo.Execute("ioctl_read_msr", inArray, 1); + eax = (uint)outArray[0]; + edx = (uint)(outArray[0] >> 32); + } + catch + { + return false; + } + + return true; + } + + public bool ReadMsr(uint index, out uint eax, out uint edx, GroupAffinity affinity) + { + GroupAffinity previousAffinity = ThreadAffinity.Set(affinity); + bool result = ReadMsr(index, out eax, out edx); + ThreadAffinity.Set(previousAffinity); + return result; + } + + public void Close() => _pawnIo.Close(); +} diff --git a/LibreHardwareMonitorLib/PawnIo/AmdFamily17.cs b/LibreHardwareMonitorLib/PawnIo/AmdFamily17.cs new file mode 100644 index 0000000..037100f --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/AmdFamily17.cs @@ -0,0 +1,52 @@ +namespace LibreHardwareMonitor.PawnIo; + +public class AmdFamily17 +{ + private readonly PawnIo _pawnIo = PawnIo.LoadModuleFromResource(typeof(AmdFamily0F).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.AMDFamily17.bin"); + + public uint ReadSmn(uint offset) + { + long[] result = _pawnIo.Execute("ioctl_read_smn", [offset], 1); + return (uint)result[0]; + } + + public bool ReadMsr(uint index, out uint eax, out uint edx) + { + long[] inArray = new long[1]; + inArray[0] = index; + eax = 0; + edx = 0; + try + { + long[] outArray = _pawnIo.Execute("ioctl_read_msr", inArray, 1); + eax = (uint)outArray[0]; + edx = (uint)(outArray[0] >> 32); + } + catch + { + return false; + } + + return true; + } + + public bool ReadMsr(uint index, out ulong eaxedx) + { + long[] inArray = new long[1]; + inArray[0] = index; + eaxedx = 0; + try + { + long[] outArray = _pawnIo.Execute("ioctl_read_msr", inArray, 1); + eaxedx = (ulong)outArray[0]; + } + catch + { + return false; + } + + return true; + } + + public void Close() => _pawnIo.Close(); +} diff --git a/LibreHardwareMonitorLib/PawnIo/IntelMsr.cs b/LibreHardwareMonitorLib/PawnIo/IntelMsr.cs new file mode 100644 index 0000000..8236d8d --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/IntelMsr.cs @@ -0,0 +1,55 @@ +using LibreHardwareMonitor.Hardware; + +namespace LibreHardwareMonitor.PawnIo; + +public class IntelMsr +{ + private readonly long[] _inArray = new long[1]; + private readonly PawnIo _pawnIO = PawnIo.LoadModuleFromResource(typeof(IntelMsr).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.IntelMSR.bin"); + + public bool ReadMsr(uint index, out ulong value) + { + _inArray[0] = index; + value = 0; + try + { + long[] outArray = _pawnIO.Execute("ioctl_read_msr", _inArray, 1); + value = (ulong)outArray[0]; + } + catch + { + return false; + } + + return true; + } + + public bool ReadMsr(uint index, out uint eax, out uint edx) + { + _inArray[0] = index; + eax = 0; + edx = 0; + try + { + long[] outArray = _pawnIO.Execute("ioctl_read_msr", _inArray, 1); + eax = (uint)outArray[0]; + edx = (uint)(outArray[0] >> 32); + } + catch + { + return false; + } + + return true; + } + + public bool ReadMsr(uint index, out uint eax, out uint edx, GroupAffinity affinity) + { + GroupAffinity previousAffinity = ThreadAffinity.Set(affinity); + bool result = ReadMsr(index, out eax, out edx); + ThreadAffinity.Set(previousAffinity); + return result; + } + + public void Close() => _pawnIO.Close(); +} diff --git a/LibreHardwareMonitorLib/PawnIo/LpcACPIEC.cs b/LibreHardwareMonitorLib/PawnIo/LpcACPIEC.cs new file mode 100644 index 0000000..850535b --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/LpcACPIEC.cs @@ -0,0 +1,24 @@ +namespace LibreHardwareMonitor.PawnIo; + +public class LpcAcpiEc +{ + private readonly PawnIo _pawnIO = PawnIo. LoadModuleFromResource(typeof(AmdFamily0F).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.LpcACPIEC.bin"); + + public byte ReadPort(byte port) + { + long[] inArray = new long[1]; + inArray[0] = port; + long[] outArray = _pawnIO.Execute("ioctl_pio_read", inArray, 1); + return (byte)outArray[0]; + } + + public void WritePort(byte port, byte value) + { + long[] inArray = new long[2]; + inArray[0] = port; + inArray[1] = value; + _pawnIO.Execute("ioctl_pio_write", inArray, 0); + } + + public void Close() => _pawnIO.Close(); +} diff --git a/LibreHardwareMonitorLib/PawnIo/LpcIO.cs b/LibreHardwareMonitorLib/PawnIo/LpcIO.cs new file mode 100644 index 0000000..e711b79 --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/LpcIO.cs @@ -0,0 +1,53 @@ +namespace LibreHardwareMonitor.PawnIo; + +internal class LpcIo +{ + private readonly long[] _doubleArgArray = new long[2]; + private readonly PawnIo _pawnIO = PawnIo.LoadModuleFromResource(typeof(LpcIo).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIO.LpcIO.bin"); + private readonly long[] _singleArgArray = new long[1]; + + public void SelectSlot(int slot) + { + _singleArgArray[0] = slot; + _pawnIO.Execute("ioctl_select_slot", _singleArgArray, 0); + } + + public void FindBars() + { + _pawnIO.Execute("ioctl_find_bars", [], 0); + } + + public byte ReadPort(ushort port) + { + _singleArgArray[0] = port; + return (byte)_pawnIO.Execute("ioctl_pio_inb", _singleArgArray, 1)[0]; + } + + public void WritePort(ushort port, byte value) + { + _doubleArgArray[0] = port; + _doubleArgArray[1] = value; + _pawnIO.Execute("ioctl_pio_outb", _doubleArgArray, 0); + } + + public byte ReadByte(byte register) + { + _singleArgArray[0] = register; + return (byte)_pawnIO.Execute("ioctl_superio_inb", _singleArgArray, 1)[0]; + } + + public ushort ReadWord(byte register) + { + _singleArgArray[0] = register; + return (ushort)_pawnIO.Execute("ioctl_superio_inw", _singleArgArray, 1)[0]; + } + + public void WriteByte(byte register, byte value) + { + _doubleArgArray[0] = register; + _doubleArgArray[1] = value; + _pawnIO.Execute("ioctl_superio_outb", _doubleArgArray, 0); + } + + public void Close() => _pawnIO.Close(); +} diff --git a/LibreHardwareMonitorLib/PawnIo/PawnIo.cs b/LibreHardwareMonitorLib/PawnIo/PawnIo.cs new file mode 100644 index 0000000..57cc3ed --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/PawnIo.cs @@ -0,0 +1,193 @@ +using System; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using LibreHardwareMonitor.Interop; +using Microsoft.Win32; + +namespace LibreHardwareMonitor.PawnIo; + +public unsafe class PawnIo +{ + private IntPtr _handle; + + /// + /// Gets the installation path of PawnIO, if it is installed on the system. + /// + public static string InstallPath + { + get + { + if ((Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PawnIO", "InstallLocation", null) ?? + Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\PawnIO", "Install_Dir", null) ?? + Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + Path.DirectorySeparatorChar + "PawnIO") is string + { + Length: > 0 + } path) + { + if (Directory.Exists(path)) + return path; + } + + return null; + } + } + + /// + /// Gets a value indicating whether PawnIO is installed on the system. + /// + public static bool IsInstalled + { + get { return !string.IsNullOrEmpty(InstallPath); } + } + + [DllImport("PawnIOLib", ExactSpelling = true, PreserveSig = false)] + private static extern void pawnio_version(out uint version); + + [DllImport("PawnIOLib", ExactSpelling = true, PreserveSig = false)] + private static extern void pawnio_open(out IntPtr handle); + + [DllImport("PawnIOLib", ExactSpelling = true, PreserveSig = false)] + private static extern void pawnio_load(IntPtr handle, byte* blob, IntPtr size); + + [DllImport("PawnIOLib", ExactSpelling = true, PreserveSig = false)] + private static extern void pawnio_execute + ( + IntPtr handle, + [MarshalAs(UnmanagedType.LPStr)] string name, + long[] inArray, + IntPtr inSize, + long[] outArray, + IntPtr outSize, + out IntPtr returnSize); + + [DllImport("PawnIOLib", ExactSpelling = true, EntryPoint = "pawnio_execute")] + private static extern int pawnio_execute_hr + ( + IntPtr handle, + [MarshalAs(UnmanagedType.LPStr)] string name, + long[] inArray, + IntPtr inSize, + long[] outArray, + IntPtr outSize, + out IntPtr returnSize); + + [DllImport("PawnIOLib", ExactSpelling = true, PreserveSig = false)] + private static extern void pawnio_close(IntPtr handle); + + private static void TryLoadLibrary() + { + try + { + // If already loaded, return immediately. + pawnio_version(out uint _); + return; + } + catch + { + // ignored + } + + try + { + if (IsInstalled) + Kernel32.LoadLibrary(InstallPath + Path.DirectorySeparatorChar + "PawnIOLib"); + } + catch + { + // ignored + } + } + + /// + /// Retrieves the version information for the underlying PawnIO library. + /// + public static Version Version() + { + try + { + TryLoadLibrary(); + pawnio_version(out uint version); + + return new Version((int)((version >> 16) & 0xFF), + (int)((version >> 8) & 0xFF), + (int)(version & 0xFF), + 0); + } + catch + { + return new Version(); + } + } + + public void Close() + { + if (_handle != IntPtr.Zero) + pawnio_close(_handle); + } + + public static PawnIo LoadModuleFromResource(Assembly assembly, string resourceName) + { + var pawnIO = new PawnIo(); + + using Stream s = assembly.GetManifestResourceStream(resourceName); + + if (s is UnmanagedMemoryStream ums) + { + TryLoadLibrary(); + + try + { + pawnio_open(out IntPtr handle); + pawnio_load(handle, ums.PositionPointer, (IntPtr)ums.Length); + pawnIO._handle = handle; + } + catch + { + // PawnIO is not available. + } + } + + return pawnIO; + } + + public long[] Execute(string name, long[] input, int outLength) + { + long[] result = new long[outLength]; + + if (_handle == IntPtr.Zero) + return result; + + pawnio_execute(_handle, + name, + input, + (IntPtr)input.Length, + result, + (IntPtr)result.Length, + out nint returnLength); + + Array.Resize(ref result, (int)returnLength); + return result; + } + + public int ExecuteHr(string name, long[] inBuffer, uint inSize, long[] outBuffer, uint outSize, out uint returnSize) + { + if (inBuffer.Length < inSize) + throw new ArgumentOutOfRangeException(nameof(inSize)); + + if (outBuffer.Length < outSize) + throw new ArgumentOutOfRangeException(nameof(outSize)); + + if (_handle == IntPtr.Zero) + { + returnSize = 0; + return 0; + } + + int ret = pawnio_execute_hr(_handle, name, inBuffer, (IntPtr)inSize, outBuffer, (IntPtr)outSize, out IntPtr retSize); + + returnSize = (uint)retSize; + + return ret; + } +} diff --git a/LibreHardwareMonitorLib/PawnIo/RyzenSmu.cs b/LibreHardwareMonitorLib/PawnIo/RyzenSmu.cs new file mode 100644 index 0000000..57674ea --- /dev/null +++ b/LibreHardwareMonitorLib/PawnIo/RyzenSmu.cs @@ -0,0 +1,74 @@ +using System; +using LibreHardwareMonitor.Hardware; + +namespace LibreHardwareMonitor.PawnIo; + +public class RyzenSmu +{ + private readonly PawnIo _pawnIO = PawnIo.LoadModuleFromResource(typeof(IntelMsr).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.RyzenSMU.bin"); + + public uint GetSmuVersion() + { + if (!Mutexes.WaitPciBus(5000)) + throw new TimeoutException("Timeout waiting for PCI bus mutex"); + + uint version; + try + { + long[] outArray = _pawnIO.Execute("ioctl_get_smu_version", [], 1); + version = (uint)outArray[0]; + } + finally + { + Mutexes.ReleasePciBus(); + } + + return version; + } + + public long GetCodeName() + { + long[] outArray = _pawnIO.Execute("ioctl_get_code_name", [], 1); + return outArray[0]; + } + + public long[] ReadPmTable(int size) + { + long[] outArray = _pawnIO.Execute("ioctl_read_pm_table", [], size); + return outArray; + } + + public void UpdatePmTable() + { + if (!Mutexes.WaitPciBus(5000)) + throw new TimeoutException("Timeout waiting for PCI bus mutex"); + + try + { + _pawnIO.Execute("ioctl_update_pm_table", [], 0); + } + finally + { + Mutexes.ReleasePciBus(); + } + } + + public void ResolvePmTable(out uint version, out uint tableBase) + { + if (!Mutexes.WaitPciBus(5000)) + throw new TimeoutException("Timeout waiting for PCI bus mutex"); + + try + { + long[] outArray = _pawnIO.Execute("ioctl_resolve_pm_table", [], 2); + version = (uint)outArray[0]; + tableBase = (uint)outArray[1]; + } + finally + { + Mutexes.ReleasePciBus(); + } + } + + public void Close() => _pawnIO.Close(); +} diff --git a/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs b/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs new file mode 100644 index 0000000..8ebee50 --- /dev/null +++ b/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs @@ -0,0 +1,58 @@ +using RAMSPDToolkit.I2CSMBus.Interop.PawnIO; +using RAMSPDToolkit.Windows.Driver.Interfaces; + +namespace LibreHardwareMonitor; + +internal class RAMSPDToolkitDriver : IPawnIODriver +{ + const string I801ModuleFilename = "SmbusI801.bin"; + const string Piix4ModuleFilename = "SmbusPIIX4.bin"; + const string Nct6793ModuleFilename = "SmbusNCT6793.bin"; + + private PawnIo.PawnIo _pawnIO; + + public bool IsOpen => true; + + public int Execute(string name, long[] inBuffer, uint inSize, long[] outBuffer, uint outSize, out uint returnSize) + { + return _pawnIO.ExecuteHr(name, inBuffer, inSize, outBuffer, outSize, out returnSize); + } + + public bool Load() + { + //Not required + return true; + } + + public bool LoadModule(PawnIOSMBusIdentifier pawnIOSMBusIdentifier) + { + string moduleResourceFilename = pawnIOSMBusIdentifier switch + { + PawnIOSMBusIdentifier.I801 => I801ModuleFilename, + PawnIOSMBusIdentifier.Piix4 => Piix4ModuleFilename, + PawnIOSMBusIdentifier.NCT6793 => Nct6793ModuleFilename, + _ => null + }; + + if (moduleResourceFilename == null) + { + return false; + } + + try + { + _pawnIO = PawnIo.PawnIo.LoadModuleFromResource(typeof(RAMSPDToolkitDriver).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIO.{moduleResourceFilename}"); + } + catch + { + return false; + } + + return _pawnIO != null; + } + + public void Unload() + { + _pawnIO.Close(); + } +} diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily0F.bin b/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily0F.bin new file mode 100644 index 0000000..427d62c Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily0F.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily10.bin b/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily10.bin new file mode 100644 index 0000000..7211718 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily10.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily17.bin b/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily17.bin new file mode 100644 index 0000000..d066f44 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/AMDFamily17.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/COPYING b/LibreHardwareMonitorLib/Resources/PawnIO/COPYING new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/LibreHardwareMonitorLib/Resources/PawnIO/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/IntelMSR.bin b/LibreHardwareMonitorLib/Resources/PawnIO/IntelMSR.bin new file mode 100644 index 0000000..1321342 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/IntelMSR.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/LpcACPIEC.bin b/LibreHardwareMonitorLib/Resources/PawnIO/LpcACPIEC.bin new file mode 100644 index 0000000..b1795e5 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/LpcACPIEC.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/LpcIO.bin b/LibreHardwareMonitorLib/Resources/PawnIO/LpcIO.bin new file mode 100644 index 0000000..478fb99 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/LpcIO.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/README b/LibreHardwareMonitorLib/Resources/PawnIO/README new file mode 100644 index 0000000..a6e4091 --- /dev/null +++ b/LibreHardwareMonitorLib/Resources/PawnIO/README @@ -0,0 +1,3 @@ +Signed PawnIO modules from the official repository, belonging to the 0.1.6 release: + +https://github.com/namazso/PawnIO.Modules/releases/tag/0.1.6 diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/RyzenSMU.bin b/LibreHardwareMonitorLib/Resources/PawnIO/RyzenSMU.bin new file mode 100644 index 0000000..a988421 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/RyzenSMU.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/SmbusI801.bin b/LibreHardwareMonitorLib/Resources/PawnIO/SmbusI801.bin new file mode 100644 index 0000000..48cf318 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/SmbusI801.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/SmbusNCT6793.bin b/LibreHardwareMonitorLib/Resources/PawnIO/SmbusNCT6793.bin new file mode 100644 index 0000000..88a144f Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/SmbusNCT6793.bin differ diff --git a/LibreHardwareMonitorLib/Resources/PawnIO/SmbusPIIX4.bin b/LibreHardwareMonitorLib/Resources/PawnIO/SmbusPIIX4.bin new file mode 100644 index 0000000..bfd72c2 Binary files /dev/null and b/LibreHardwareMonitorLib/Resources/PawnIO/SmbusPIIX4.bin differ diff --git a/LibreHardwareMonitorLib/Resources/WinRing0.gz b/LibreHardwareMonitorLib/Resources/WinRing0.gz deleted file mode 100644 index f5fd419..0000000 Binary files a/LibreHardwareMonitorLib/Resources/WinRing0.gz and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/WinRing0.sys b/LibreHardwareMonitorLib/Resources/WinRing0.sys deleted file mode 100644 index feaea41..0000000 Binary files a/LibreHardwareMonitorLib/Resources/WinRing0.sys and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/WinRing0x64.gz b/LibreHardwareMonitorLib/Resources/WinRing0x64.gz deleted file mode 100644 index b36fd87..0000000 Binary files a/LibreHardwareMonitorLib/Resources/WinRing0x64.gz and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/WinRing0x64.sys b/LibreHardwareMonitorLib/Resources/WinRing0x64.sys deleted file mode 100644 index 197c255..0000000 Binary files a/LibreHardwareMonitorLib/Resources/WinRing0x64.sys and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/inpout32.dll b/LibreHardwareMonitorLib/Resources/inpout32.dll deleted file mode 100644 index 8889280..0000000 Binary files a/LibreHardwareMonitorLib/Resources/inpout32.dll and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/inpout32.gz b/LibreHardwareMonitorLib/Resources/inpout32.gz deleted file mode 100644 index 017dbb6..0000000 Binary files a/LibreHardwareMonitorLib/Resources/inpout32.gz and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/inpoutx64.dll b/LibreHardwareMonitorLib/Resources/inpoutx64.dll deleted file mode 100644 index 82c343f..0000000 Binary files a/LibreHardwareMonitorLib/Resources/inpoutx64.dll and /dev/null differ diff --git a/LibreHardwareMonitorLib/Resources/inpoutx64.gz b/LibreHardwareMonitorLib/Resources/inpoutx64.gz deleted file mode 100644 index cf75735..0000000 Binary files a/LibreHardwareMonitorLib/Resources/inpoutx64.gz and /dev/null differ diff --git a/Licenses/License.html b/Licenses/License.html deleted file mode 100644 index 62092de..0000000 --- a/Licenses/License.html +++ /dev/null @@ -1,304 +0,0 @@ - - - - - - - -Libre Hardware Monitor - License - - - - - -
-
- -

Libre Hardware Monitor License

- -

-The binaries of the Libre Hardware Monitor have been made available by the Libre Hardware Monitor Project under the Mozilla Public License 2.0 (MPL). -

- -

-The source code of the Libre Hardware Monitor is available under licenses which are both free and open source. Most of it is available under the Mozilla Public License 2.0 (MPL). -

- - - -

-The remainder of the software which is not under the Mozilla Public License 2.0 (MPL) is available under one of a variety of other licenses which are given below. -

- - - -
-
- -

Mozilla Public License 2.0

-

1. Definitions

-
-
1.1. “Contributor”
-

means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software.

-
-
1.2. “Contributor Version”
-

means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution.

-
-
1.3. “Contribution”
-

means Covered Software of a particular Contributor.

-
-
1.4. “Covered Software”
-

means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof.

-
-
1.5. “Incompatible With Secondary Licenses”
-

means

-
    -
  1. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or

  2. -
  3. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License.

  4. -
-
-
1.6. “Executable Form”
-

means any form of the work other than Source Code Form.

-
-
1.7. “Larger Work”
-

means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software.

-
-
1.8. “License”
-

means this document.

-
-
1.9. “Licensable”
-

means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License.

-
-
1.10. “Modifications”
-

means any of the following:

-
    -
  1. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or

  2. -
  3. any new file in Source Code Form that contains any Covered Software.

  4. -
-
-
1.11. “Patent Claims” of a Contributor
-

means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version.

-
-
1.12. “Secondary License”
-

means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses.

-
-
1.13. “Source Code Form”
-

means the form of the work preferred for making modifications.

-
-
1.14. “You” (or “Your”)
-

means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.

-
-
-

2. License Grants and Conditions

-

2.1. Grants

-

Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:

-
    -
  1. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and

  2. -
  3. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version.

  4. -
-

2.2. Effective Date

-

The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution.

-

2.3. Limitations on Grant Scope

-

The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor:

-
    -
  1. for any code that a Contributor has removed from Covered Software; or

  2. -
  3. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or

  4. -
  5. under Patent Claims infringed by Covered Software in the absence of its Contributions.

  6. -
-

This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4).

-

2.4. Subsequent Licenses

-

No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3).

-

2.5. Representation

-

Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License.

-

2.6. Fair Use

-

This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents.

-

2.7. Conditions

-

Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1.

-

3. Responsibilities

-

3.1. Distribution of Source Form

-

All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients’ rights in the Source Code Form.

-

3.2. Distribution of Executable Form

-

If You distribute Covered Software in Executable Form then:

-
    -
  1. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and

  2. -
  3. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients’ rights in the Source Code Form under this License.

  4. -
-

3.3. Distribution of a Larger Work

-

You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s).

-

3.4. Notices

-

You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies.

-

3.5. Application of Additional Terms

-

You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction.

-

4. Inability to Comply Due to Statute or Regulation

-

If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.

-

5. Termination

-

5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice.

-

5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.

-

5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination.

-

6. Disclaimer of Warranty

-

Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer.

-

7. Limitation of Liability

-

Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.

-

8. Litigation

-

Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims.

-

9. Miscellaneous

-

This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor.

-

10. Versions of the License

-

10.1. New Versions

-

Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number.

-

10.2. Effect of New Versions

-

You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward.

-

10.3. Modified Versions

-

If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License).

-

10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses

-

If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached.

-

Exhibit A - Source Code Form License Notice

-
-

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

-
-

If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.

-

You may add additional accurate notices of copyright ownership.

-

Exhibit B - “Incompatible With Secondary Licenses” Notice

-
-

This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.

-
- -
- -

Aga.Controls License

-

-This license applies to the Aga.Controls assembly (TreeViewAdv component). -

-
-Copyright (c) 2009, Andrey Gliznetsov (a.gliznetsov@gmail.com)
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met
-
-- Redistributions of source code must retain the above copyright notice, this list
-of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice, this
-list of conditions and the following disclaimer in the documentation andor other
-materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- -
- -

WinRing0 License

-

-This license applies to the WinRing0 device drivers. -

-
-Copyright (c) 2007-2009 OpenLibSys.org. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- -
- -

InpOut License

-

-This license applies to the InpOut library. -

-
-Copyright (c) <2003-2015> Phil Gibbons 
-Portions Copyright (c) <2000> 
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
- -
-
- - - - \ No newline at end of file diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt new file mode 100644 index 0000000..d6e5e18 --- /dev/null +++ b/THIRD-PARTY-NOTICES.txt @@ -0,0 +1,489 @@ +License notice for Aga.Controls +------------------------------- + +The BSD License + +Copyright (c) 2009, Andrey Gliznetsov (a.gliznetsov@gmail.com) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided +that the following conditions are met + +- Redistributions of source code must retain the above copyright notice, this list of conditions +and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions +and the following disclaimer in the documentation andor other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +License notice for PawnIO.Modules +--------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. \ No newline at end of file diff --git a/WinRing0/COPYRIGHT.txt b/WinRing0/COPYRIGHT.txt deleted file mode 100644 index c875308..0000000 --- a/WinRing0/COPYRIGHT.txt +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2007-2009 OpenLibSys.org. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/WinRing0/MAKEFILE b/WinRing0/MAKEFILE deleted file mode 100644 index 5818975..0000000 --- a/WinRing0/MAKEFILE +++ /dev/null @@ -1,7 +0,0 @@ -# -# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source -# file to this component. This file merely indirects to the real make file -# that is shared by all the driver components of the Windows NT DDK -# - -!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/WinRing0/OlsIoctl.h b/WinRing0/OlsIoctl.h deleted file mode 100644 index 8d0f361..0000000 --- a/WinRing0/OlsIoctl.h +++ /dev/null @@ -1,170 +0,0 @@ -//----------------------------------------------------------------------------- -// Author : hiyohiyo -// Mail : hiyohiyo@crystalmark.info -// Web : http://openlibsys.org/ -// License : The modified BSD license -// -// Copyright 2007-2008 OpenLibSys.org. All rights reserved. -//----------------------------------------------------------------------------- - -#pragma once - -//----------------------------------------------------------------------------- -// -// The Device type codes form 32768 to 65535 are for customer use. -// -//----------------------------------------------------------------------------- - -#define OLS_TYPE 40000 - -//----------------------------------------------------------------------------- -// -// Version Information -// -//----------------------------------------------------------------------------- - -#define OLS_DRIVER_ID _T("WinRing0_1_2_0") - -#define OLS_DRIVER_MAJOR_VERSION 1 -#define OLS_DRIVER_MINOR_VERSION 2 -#define OLS_DRIVER_REVISION 0 -#define OLS_DRIVER_RELESE 5 - -#define OLS_DRIVER_VERSION \ - ((OLS_DRIVER_MAJOR_VERSION << 24) | (OLS_DRIVER_MINOR_VERSION << 16) \ - | (OLS_DRIVER_REVISION << 8) | OLS_DRIVER_RELESE) - -//----------------------------------------------------------------------------- -// -// The IOCTL function codes from 0x800 to 0xFFF are for customer use. -// -//----------------------------------------------------------------------------- -#define IOCTL_OLS_GET_DRIVER_VERSION \ - CTL_CODE(OLS_TYPE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_OLS_GET_REFCOUNT \ - CTL_CODE(OLS_TYPE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_OLS_READ_MSR \ - CTL_CODE(OLS_TYPE, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_OLS_WRITE_MSR \ - CTL_CODE(OLS_TYPE, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_OLS_READ_PMC \ - CTL_CODE(OLS_TYPE, 0x823, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_OLS_HALT \ - CTL_CODE(OLS_TYPE, 0x824, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define IOCTL_OLS_READ_IO_PORT \ - CTL_CODE(OLS_TYPE, 0x831, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_OLS_WRITE_IO_PORT \ - CTL_CODE(OLS_TYPE, 0x832, METHOD_BUFFERED, FILE_WRITE_ACCESS) - -#define IOCTL_OLS_READ_IO_PORT_BYTE \ - CTL_CODE(OLS_TYPE, 0x833, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_OLS_READ_IO_PORT_WORD \ - CTL_CODE(OLS_TYPE, 0x834, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_OLS_READ_IO_PORT_DWORD \ - CTL_CODE(OLS_TYPE, 0x835, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_OLS_WRITE_IO_PORT_BYTE \ - CTL_CODE(OLS_TYPE, 0x836, METHOD_BUFFERED, FILE_WRITE_ACCESS) - -#define IOCTL_OLS_WRITE_IO_PORT_WORD \ - CTL_CODE(OLS_TYPE, 0x837, METHOD_BUFFERED, FILE_WRITE_ACCESS) - -#define IOCTL_OLS_WRITE_IO_PORT_DWORD \ - CTL_CODE(OLS_TYPE, 0x838, METHOD_BUFFERED, FILE_WRITE_ACCESS) - -#define IOCTL_OLS_READ_MEMORY \ - CTL_CODE(OLS_TYPE, 0x841, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_OLS_WRITE_MEMORY \ - CTL_CODE(OLS_TYPE, 0x842, METHOD_BUFFERED, FILE_WRITE_ACCESS) - -#define IOCTL_OLS_READ_PCI_CONFIG \ - CTL_CODE(OLS_TYPE, 0x851, METHOD_BUFFERED, FILE_READ_ACCESS) - -#define IOCTL_OLS_WRITE_PCI_CONFIG \ - CTL_CODE(OLS_TYPE, 0x852, METHOD_BUFFERED, FILE_WRITE_ACCESS) - -//----------------------------------------------------------------------------- -// -// PCI Error Code -// -//----------------------------------------------------------------------------- - -#define OLS_ERROR_PCI_BUS_NOT_EXIST (0xE0000001L) -#define OLS_ERROR_PCI_NO_DEVICE (0xE0000002L) -#define OLS_ERROR_PCI_WRITE_CONFIG (0xE0000003L) -#define OLS_ERROR_PCI_READ_CONFIG (0xE0000004L) - -//----------------------------------------------------------------------------- -// -// Support Macros -// -//----------------------------------------------------------------------------- - -// Bus Number, Device Number and Function Number to PCI Device Address -#define PciBusDevFunc(Bus, Dev, Func) ((Bus&0xFF)<<8) | ((Dev&0x1F)<<3) | (Func&7) -// PCI Device Address to Bus Number -#define PciGetBus(address) ((address>>8) & 0xFF) -// PCI Device Address to Device Number -#define PciGetDev(address) ((address>>3) & 0x1F) -// PCI Device Address to Function Number -#define PciGetFunc(address) (address&7) - -//----------------------------------------------------------------------------- -// -// Typedef Struct -// -//----------------------------------------------------------------------------- - -#pragma pack(push,4) - -typedef struct _OLS_WRITE_MSR_INPUT { - ULONG Register; - ULARGE_INTEGER Value; -} OLS_WRITE_MSR_INPUT; - -typedef struct _OLS_WRITE_IO_PORT_INPUT { - ULONG PortNumber; - union { - ULONG LongData; - USHORT ShortData; - UCHAR CharData; - }; -} OLS_WRITE_IO_PORT_INPUT; - -typedef struct _OLS_READ_PCI_CONFIG_INPUT { - ULONG PciAddress; - ULONG PciOffset; -} OLS_READ_PCI_CONFIG_INPUT; - -typedef struct _OLS_WRITE_PCI_CONFIG_INPUT { - ULONG PciAddress; - ULONG PciOffset; - UCHAR Data[1]; -} OLS_WRITE_PCI_CONFIG_INPUT; - -typedef LARGE_INTEGER PHYSICAL_ADDRESS; - -typedef struct _OLS_READ_MEMORY_INPUT { - PHYSICAL_ADDRESS Address; - ULONG UnitSize; - ULONG Count; -} OLS_READ_MEMORY_INPUT; - -typedef struct _OLS_WRITE_MEMORY_INPUT { - PHYSICAL_ADDRESS Address; - ULONG UnitSize; - ULONG Count; - UCHAR Data[1]; -} OLS_WRITE_MEMORY_INPUT; - -#pragma pack(pop) diff --git a/WinRing0/OpenLibSys.c b/WinRing0/OpenLibSys.c deleted file mode 100644 index 6efeac6..0000000 --- a/WinRing0/OpenLibSys.c +++ /dev/null @@ -1,714 +0,0 @@ -//----------------------------------------------------------------------------- -// Author : hiyohiyo -// Mail : hiyohiyo@crystalmark.info -// Web : http://openlibsys.org/ -// License : The modified BSD license -// -// Copyright 2007-2008 OpenLibSys.org. All rights reserved. -//----------------------------------------------------------------------------- - -#include -#include -#include "OpenLibSys.h" - -//----------------------------------------------------------------------------- -// -// Global -// -//----------------------------------------------------------------------------- - -static ULONG refCount; - -//----------------------------------------------------------------------------- -// -// Classic NT driver -// DriverEntry / OlsDispatch / Unload -// -//----------------------------------------------------------------------------- - -NTSTATUS -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ) - -/* - -Return Value: - - STATUS_SUCCESS if the driver initialized correctly, otherwise an erroror - indicating the reason for failure. -*/ - -{ - NTSTATUS status; - UNICODE_STRING ntDeviceName; - UNICODE_STRING win32DeviceName; - PDEVICE_OBJECT deviceObject = NULL; - - RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME); - - status = IoCreateDevice( - DriverObject, // Our Driver Object - 0, // We don't use a device extension - &ntDeviceName, // Device name - OLS_TYPE, // Device type - FILE_DEVICE_SECURE_OPEN, // Device characteristics - FALSE, // Not an exclusive device - &deviceObject ); // Returned ptr to Device Object - - if(!NT_SUCCESS(status)) - { - refCount = (ULONG)-1; - return status; - } - else - { - refCount = 0; - } - - // Initialize the driver object with this driver's entry points. - DriverObject->MajorFunction[IRP_MJ_CREATE] = OlsDispatch; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = OlsDispatch; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OlsDispatch; - DriverObject->DriverUnload = Unload; - - // Initialize a Unicode String containing the Win32 name for our device. - RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); - - // Create a symbolic link between our device name and the Win32 name - status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName); - - if (!NT_SUCCESS(status)) - { - // Delete everything that this routine has allocated. - IoDeleteDevice( deviceObject ); - } - - return status; -} - -NTSTATUS -OlsDispatch( - IN PDEVICE_OBJECT pDO, - IN PIRP pIrp - ) - -/*++ - -Routine Description: - This routine is the dispatch handler for the driver. It is responsible - for processing the IRPs. - -Arguments: - - pDO - Pointer to device object. - - pIrp - Pointer to the current IRP. - -Return Value: - - STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror - indicating the reason for failure. - ---*/ - -{ - PIO_STACK_LOCATION pIrpStack; - NTSTATUS status; - int index; - - // Initialize the irp info field. - // This is used to return the number of bytes transfered. - pIrp->IoStatus.Information = 0; - pIrpStack = IoGetCurrentIrpStackLocation(pIrp); - - // Set default return status - status = STATUS_NOT_IMPLEMENTED; - - // Dispatch based on major fcn code. - switch(pIrpStack->MajorFunction) - { - case IRP_MJ_CREATE: - if(refCount != (ULONG)-1){refCount++;} - status = STATUS_SUCCESS; - break; - case IRP_MJ_CLOSE: - if(refCount != (ULONG)-1){refCount--;} - status = STATUS_SUCCESS; - break; - - case IRP_MJ_DEVICE_CONTROL: - // Dispatch on IOCTL - switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_OLS_GET_DRIVER_VERSION: - *(PULONG)pIrp->AssociatedIrp.SystemBuffer = OLS_DRIVER_VERSION; - pIrp->IoStatus.Information = 4; - status = STATUS_SUCCESS; - break; - - case IOCTL_OLS_GET_REFCOUNT: - *(PULONG)pIrp->AssociatedIrp.SystemBuffer = refCount; - pIrp->IoStatus.Information = sizeof(refCount); - status = STATUS_SUCCESS; - break; - - case IOCTL_OLS_READ_MSR: - status = ReadMsr( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - case IOCTL_OLS_WRITE_MSR: - status = WriteMsr( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - case IOCTL_OLS_READ_PMC: - status = ReadPmc( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - case IOCTL_OLS_HALT: - __halt(); - status = STATUS_SUCCESS; - break; - - case IOCTL_OLS_READ_IO_PORT: - case IOCTL_OLS_READ_IO_PORT_BYTE: - case IOCTL_OLS_READ_IO_PORT_WORD: - case IOCTL_OLS_READ_IO_PORT_DWORD: - status = ReadIoPort( - pIrpStack->Parameters.DeviceIoControl.IoControlCode, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - case IOCTL_OLS_WRITE_IO_PORT: - case IOCTL_OLS_WRITE_IO_PORT_BYTE: - case IOCTL_OLS_WRITE_IO_PORT_WORD: - case IOCTL_OLS_WRITE_IO_PORT_DWORD: - status = WriteIoPort( - pIrpStack->Parameters.DeviceIoControl.IoControlCode, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - - case IOCTL_OLS_READ_PCI_CONFIG: - status = ReadPciConfig( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - case IOCTL_OLS_WRITE_PCI_CONFIG: - status = WritePciConfig( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - - case IOCTL_OLS_READ_MEMORY: - status = ReadMemory( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - case IOCTL_OLS_WRITE_MEMORY: - status = WriteMemory( - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.InputBufferLength, - pIrp->AssociatedIrp.SystemBuffer, - pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, - (ULONG*)&pIrp->IoStatus.Information - ); - break; - - - } - break; - } - - // We're done with I/O request. Record the status of the I/O action. - pIrp->IoStatus.Status = status; - - // Don't boost priority when returning since this took little time. - IoCompleteRequest(pIrp, IO_NO_INCREMENT); - - return status; -} - -VOID -Unload( - PDRIVER_OBJECT DriverObject - ) -/*++ - -Routine Description: - - This routine is called by the I/O system to unload the driver. - - Any resources previously allocated must be freed. - -Arguments: - - DriverObject - a pointer to the object that represents our driver. - -Return Value: - - None ---*/ - -{ - PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; - UNICODE_STRING win32NameString; - - PAGED_CODE(); - - // Create counted string version of our Win32 device name. - RtlInitUnicodeString(&win32NameString, DOS_DEVICE_NAME); - - // Delete the link from our device name to a name in the Win32 namespace. - IoDeleteSymbolicLink(&win32NameString); - - if(deviceObject != NULL) - { - IoDeleteDevice(deviceObject); - } -} - -//----------------------------------------------------------------------------- -// -// CPU -// -//----------------------------------------------------------------------------- - -NTSTATUS -ReadMsr( void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - __try - { - ULONGLONG data = __readmsr(*(ULONG*)lpInBuffer); - memcpy((PULONG)lpOutBuffer, &data, 8); - *lpBytesReturned = 8; - return STATUS_SUCCESS; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - *lpBytesReturned = 0; - return STATUS_UNSUCCESSFUL; - } -} - -NTSTATUS -WriteMsr( void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - __try - { - OLS_WRITE_MSR_INPUT* param; - param = (OLS_WRITE_MSR_INPUT*)lpInBuffer; - - __writemsr(param->Register, param->Value.QuadPart); - *lpBytesReturned = 0; - return STATUS_SUCCESS; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - *lpBytesReturned = 0; - return STATUS_UNSUCCESSFUL; - } -} - -NTSTATUS -ReadPmc( void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - __try - { - ULONGLONG data = __readpmc(*(ULONG*)lpInBuffer); - memcpy((PULONG)lpOutBuffer, &data, 8); - *lpBytesReturned = 8; - return STATUS_SUCCESS; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - *lpBytesReturned = 0; - return STATUS_UNSUCCESSFUL; - } -} - -//----------------------------------------------------------------------------- -// -// IO Port -// -//----------------------------------------------------------------------------- - -NTSTATUS -ReadIoPort( ULONG ioControlCode, - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - ULONG nPort = *(ULONG*)lpInBuffer; - - switch(ioControlCode) - { - case IOCTL_OLS_READ_IO_PORT_BYTE: - *(PUCHAR)lpOutBuffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort); - break; - case IOCTL_OLS_READ_IO_PORT_WORD: - *(PUSHORT)lpOutBuffer = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort); - break; - case IOCTL_OLS_READ_IO_PORT_DWORD: - *(PULONG)lpOutBuffer = READ_PORT_ULONG((PULONG)(ULONG_PTR)nPort); - break; - default: - *lpBytesReturned = 0; - return STATUS_INVALID_PARAMETER; - break; - } - - *lpBytesReturned = nInBufferSize; - return STATUS_SUCCESS; -} - -NTSTATUS -WriteIoPort(ULONG ioControlCode, - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - ULONG nPort; - OLS_WRITE_IO_PORT_INPUT* param; - - param = (OLS_WRITE_IO_PORT_INPUT*)lpInBuffer; - nPort = param->PortNumber; - - switch(ioControlCode) - { - - case IOCTL_OLS_WRITE_IO_PORT_BYTE: - WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort, param->CharData); - break; - case IOCTL_OLS_WRITE_IO_PORT_WORD: - WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort, param->ShortData); - break; - case IOCTL_OLS_WRITE_IO_PORT_DWORD: - WRITE_PORT_ULONG((PULONG)(ULONG_PTR)nPort, param->LongData); - break; - default: - return STATUS_INVALID_PARAMETER; - break; - } - - return STATUS_SUCCESS; -} - -//----------------------------------------------------------------------------- -// -// PCI -// -//----------------------------------------------------------------------------- - -NTSTATUS -ReadPciConfig( void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - OLS_READ_PCI_CONFIG_INPUT *param; - NTSTATUS status; - - if(nInBufferSize != sizeof(OLS_READ_PCI_CONFIG_INPUT)) - { - return STATUS_INVALID_PARAMETER; - } - param = (OLS_READ_PCI_CONFIG_INPUT *)lpInBuffer; - - status = pciConfigRead(param->PciAddress, param->PciOffset, - lpOutBuffer, nOutBufferSize); - - if(status == STATUS_SUCCESS) - { - *lpBytesReturned = nOutBufferSize; - } - else - { - *lpBytesReturned = 0; - } - - return status; -} - -NTSTATUS -WritePciConfig( void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) - -{ - OLS_WRITE_PCI_CONFIG_INPUT *param; - ULONG writeSize; - NTSTATUS status; - - if(nInBufferSize < offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data)) - { - return STATUS_INVALID_PARAMETER; - } - - param = (OLS_WRITE_PCI_CONFIG_INPUT *)lpInBuffer; - writeSize = nInBufferSize - offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data); - - *lpBytesReturned = 0; - - return pciConfigWrite(param->PciAddress, param->PciOffset, - ¶m->Data, writeSize); - -} - -//----------------------------------------------------------------------------- -// -// Support Function -// -//----------------------------------------------------------------------------- - -NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length) -{ - PCI_SLOT_NUMBER slot; - int error; - ULONG busNumber; - - busNumber = PciGetBus(pciAddress); - slot.u.AsULONG = 0; - slot.u.bits.DeviceNumber = PciGetDev(pciAddress); - slot.u.bits.FunctionNumber = PciGetFunc(pciAddress); - error = HalGetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG, - data, offset, length); - - if(error == 0) - { - return OLS_ERROR_PCI_BUS_NOT_EXIST; - } - else if(length != 2 && error == 2) - { - return OLS_ERROR_PCI_NO_DEVICE; - } - else if(length != error) - { - return OLS_ERROR_PCI_READ_CONFIG; - } - - return STATUS_SUCCESS; -} - -NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length) -{ - PCI_SLOT_NUMBER slot; - int error; - ULONG busNumber; - - busNumber = PciGetBus(pciAddress); - - slot.u.AsULONG = 0; - slot.u.bits.DeviceNumber = PciGetDev(pciAddress); - slot.u.bits.FunctionNumber = PciGetFunc(pciAddress); - error = HalSetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG, - data, offset, length); - - if(error != length) - { - return OLS_ERROR_PCI_WRITE_CONFIG; - } - - return STATUS_SUCCESS; -} - - -//----------------------------------------------------------------------------- -// -// Physical Memory -// -//----------------------------------------------------------------------------- - -NTSTATUS -ReadMemory( void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ - OLS_READ_MEMORY_INPUT *param; - ULONG size; - PHYSICAL_ADDRESS address; - PVOID maped; - BOOLEAN error; - - if(nInBufferSize != sizeof(OLS_READ_MEMORY_INPUT)) - { - return STATUS_INVALID_PARAMETER; - } - - param = (OLS_READ_MEMORY_INPUT *)lpInBuffer; - size = param->UnitSize * param->Count; - - if(nOutBufferSize < size) - { - return STATUS_INVALID_PARAMETER; - } - - address.QuadPart = param->Address.QuadPart; - -#ifndef _PHYSICAL_MEMORY_SUPPORT - - if(0x000C0000 > address.QuadPart - || (address.QuadPart + size - 1) > 0x000FFFFF) - { - return STATUS_INVALID_PARAMETER; - } - -#endif - - maped = MmMapIoSpace(address, size, FALSE); - - error = FALSE; - switch(param->UnitSize){ - case 1: - READ_REGISTER_BUFFER_UCHAR(maped, lpOutBuffer, param->Count); - break; - case 2: - READ_REGISTER_BUFFER_USHORT(maped, lpOutBuffer, param->Count); - break; - case 4: - READ_REGISTER_BUFFER_ULONG(maped, lpOutBuffer, param->Count); - break; - default: - error = TRUE; - break; - } - - MmUnmapIoSpace(maped, size); - - if(error) - { - return STATUS_INVALID_PARAMETER; - } - - *lpBytesReturned = nOutBufferSize; - - return STATUS_SUCCESS; -} - -NTSTATUS -WriteMemory(void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned) -{ -#ifdef _PHYSICAL_MEMORY_SUPPORT - - OLS_WRITE_MEMORY_INPUT *param; - ULONG size; - PHYSICAL_ADDRESS address; - PVOID maped; - BOOLEAN error; - - if(nInBufferSize < offsetof(OLS_WRITE_MEMORY_INPUT, Data)) - { - return STATUS_INVALID_PARAMETER; - } - - param = (OLS_WRITE_MEMORY_INPUT *)lpInBuffer; - - size = param->UnitSize * param->Count; - if (nInBufferSize < size + offsetof(OLS_WRITE_MEMORY_INPUT, Data)) - { - return STATUS_INVALID_PARAMETER; - } - - address.QuadPart = param->Address.QuadPart; - - maped = MmMapIoSpace(address, size, FALSE); - - error = FALSE; - switch(param->UnitSize){ - case 1: - WRITE_REGISTER_BUFFER_UCHAR(maped, - (UCHAR*)¶m->Data, param->Count); - break; - case 2: - WRITE_REGISTER_BUFFER_USHORT(maped, - (USHORT*)¶m->Data, param->Count); - break; - case 4: - WRITE_REGISTER_BUFFER_ULONG(maped, - (ULONG*)¶m->Data, param->Count); - break; - default: - error = TRUE; - break; - } - - MmUnmapIoSpace(maped, size); - - if(error) - { - return STATUS_INVALID_PARAMETER; - } - - *lpBytesReturned = 0; - - return STATUS_SUCCESS; - -#else - - *lpBytesReturned = 0; - - return STATUS_INVALID_PARAMETER; - -#endif -} diff --git a/WinRing0/OpenLibSys.h b/WinRing0/OpenLibSys.h deleted file mode 100644 index a92edf7..0000000 --- a/WinRing0/OpenLibSys.h +++ /dev/null @@ -1,131 +0,0 @@ -//----------------------------------------------------------------------------- -// Author : hiyohiyo -// Mail : hiyohiyo@crystalmark.info -// Web : http://openlibsys.org/ -// License : The modified BSD license -// -// Copyright 2007-2008 OpenLibSys.org. All rights reserved. -//----------------------------------------------------------------------------- - -#include -#include -#include "OlsIoctl.h" - -//----------------------------------------------------------------------------- -// -// Device Name -// -//----------------------------------------------------------------------------- - -#define NT_DEVICE_NAME L"\\Device\\WinRing0_1_2_0" -#define DOS_DEVICE_NAME L"\\DosDevices\\WinRing0_1_2_0" - -//----------------------------------------------------------------------------- -// -// Function Prototypes -// -//----------------------------------------------------------------------------- - -NTSTATUS DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath - ); - -NTSTATUS OlsDispatch( - IN PDEVICE_OBJECT pDO, - IN PIRP pIrp - ); - -VOID Unload( - IN PDRIVER_OBJECT DriverObject - ); - -//----------------------------------------------------------------------------- -// -// Function Prototypes for Control Code -// -//----------------------------------------------------------------------------- - -NTSTATUS ReadMsr( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS WriteMsr( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS ReadPmc( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS ReadIoPort( - ULONG ioControlCode, - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS WriteIoPort( - ULONG ioControlCode, - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS ReadPciConfig( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS WritePciConfig( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS ReadMemory( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - -NTSTATUS WriteMemory( - void *lpInBuffer, - ULONG nInBufferSize, - void *lpOutBuffer, - ULONG nOutBufferSize, - ULONG *lpBytesReturned - ); - - -//----------------------------------------------------------------------------- -// -// Support Function Prototypes -// -//----------------------------------------------------------------------------- - -NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length); -NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length); diff --git a/WinRing0/OpenLibSys.rc b/WinRing0/OpenLibSys.rc deleted file mode 100644 index 57df277..0000000 --- a/WinRing0/OpenLibSys.rc +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -#define VER_FILETYPE VFT_DRV -#define VER_FILESUBTYPE VFT2_DRV_SYSTEM - -#define VER_FILEDESCRIPTION_STR "WinRing0" -#define VER_INTERNALNAME_STR "WinRing0.sys" - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1, 2, 0, 5 - PRODUCTVERSION 1, 2, 0, 5 - FILEFLAGSMASK 0x3fL - FILEFLAGS 0x0L - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "041104b0" - BEGIN - VALUE "Comments", "The modified BSD license\0" - VALUE "CompanyName", "OpenLibSys.org\0" - VALUE "FileDescription", "WinRing0\0" - VALUE "FileVersion", "1.2.0.5\0" - VALUE "InternalName", "WinRing0.sys\0" - VALUE "LegalCopyright", "Copyright (C) 2007-2008 OpenLibSys.org. All rights reserved.\0" - VALUE "OriginalFilename", "WinRing0.sys\0" - VALUE "ProductName", "WinRing0\0" - VALUE "ProductVersion", "1.2.0.5\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x411, 1200 - END -END diff --git a/WinRing0/SOURCES b/WinRing0/SOURCES deleted file mode 100644 index 3fa0c3f..0000000 --- a/WinRing0/SOURCES +++ /dev/null @@ -1,7 +0,0 @@ -TARGETNAME=WinRing0 -TARGETPATH=lib -TARGETTYPE=DRIVER - -INCLUDES=..\ - -SOURCES=OpenLibSys.c OpenLibSys.rc