Compare commits

...
42 changed files with 703 additions and 1085 deletions
@@ -277,7 +277,7 @@ void DetectENESMBusMotherboardControllers(std::vector<i2c_smbus_interface*> &bus
// Add ENE (ASUS Aura) motherboard controllers
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
if(busses[bus]->pci_subsystem_vendor == ASUS_SUB_VEN || busses[bus]->pci_subsystem_vendor == 0)
if(busses[bus]->pci_subsystem_vendor == ASUS_SUB_VEN || busses[bus]->pci_subsystem_vendor == 0 || busses[bus]->pci_subsystem_vendor == 0xFFFF)
{
for (unsigned int address_list_idx = 0; address_list_idx < AURA_MOBO_ADDRESS_COUNT; address_list_idx++)
{
+3 -3
View File
@@ -10,9 +10,9 @@ SMBus is generally not meant to be accessed by user applications, but RGB softwa
## Windows
* On Windows, OpenRGB uses the [WinRing0](https://github.com/GermanAizek/WinRing0) driver to access the SMBus interface.
* **You must run the application as Administrator the first time to allow WinRing0 to set up. It can be run as a normal user afterwards**
* Early versions of OpenRGB used [InpOut32](https://www.highrez.co.uk/downloads/inpout32/). This is no longer needed and should be removed to avoid warnings by some anti-cheat software. You can uninstall Inpout32 by following the instructions [here](https://gitlab.com/CalcProgrammer1/OpenRGB/-/issues/669#note_461054255).
* On Windows, OpenRGB uses the [PawnIO](https://pawnio.eu/) driver to access the SMBus interface. You must install PawnIO by downloading and running its installer prior to using OpenRGB.
* **You must run the application as Administrator in order for PawnIO to be able to access SMBus. OpenRGB may be installed as a background service that runs with Administrator permissions.**
* Early versions of OpenRGB used [WinRing0](https://github.com/GermanAizek/WinRing0) and even earlier versions used [InpOut32](https://www.highrez.co.uk/downloads/inpout32/). These drivers are no longer used and should be removed to avoid warnings by anti-cheat and anti-virus software. You can uninstall Inpout32 by following the instructions [here](https://gitlab.com/CalcProgrammer1/OpenRGB/-/issues/669#note_461054255).
## Linux
+48 -29
View File
@@ -26,7 +26,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#-----------------------------------------------------------------------------------------------#
MAJOR = 0
MINOR = 9
SUFFIX = 1.0rc2wr0
SUFFIX = 1.0rc2
SHORTHASH = $$system("git rev-parse --short=7 HEAD")
LASTTAG = "release_"$$MAJOR"."$$MINOR
@@ -198,8 +198,8 @@ HEADERS +=
scsiapi/scsiapi.h \
serial_port/find_usb_serial_port.h \
serial_port/serial_port.h \
StringUtils.h \
super_io/super_io.h \
StringUtils.h \
SuspendResume/SuspendResume.h \
AutoStart/AutoStart.h \
KeyboardLayoutManager/KeyboardLayoutManager.h \
@@ -266,7 +266,6 @@ SOURCES +=
net_port/net_port.cpp \
serial_port/serial_port.cpp \
StringUtils.cpp \
super_io/super_io.cpp \
AutoStart/AutoStart.cpp \
KeyboardLayoutManager/KeyboardLayoutManager.cpp \
RGBController/RGBController.cpp \
@@ -330,10 +329,11 @@ win32:QMAKE_CXXFLAGS += /utf-8
win32:INCLUDEPATH += \
dependencies/display-library/include \
dependencies/hidapi-win/include \
dependencies/winring0/include \
dependencies/libusb-1.0.27/include \
dependencies/mbedtls-3.2.1/include \
dependencies/NVFC \
dependencies/PawnIO \
i2c_smbus/Windows \
wmi/ \
win32:SOURCES += $$CONTROLLER_CPP_WINDOWS
@@ -341,11 +341,8 @@ win32:SOURCES += $$CONTROLLER_CPP_WINDOWS
win32:SOURCES += \
dependencies/hueplusplus-1.2.0/src/WinHttpHandler.cpp \
dependencies/NVFC/nvapi.cpp \
i2c_smbus/i2c_smbus_amdadl.cpp \
i2c_smbus/i2c_smbus_i801.cpp \
i2c_smbus/i2c_smbus_nct6775.cpp \
i2c_smbus/i2c_smbus_nvapi.cpp \
i2c_smbus/i2c_smbus_piix4.cpp \
i2c_smbus/Windows/i2c_smbus_amdadl.cpp \
i2c_smbus/Windows/i2c_smbus_nvapi.cpp \
scsiapi/scsiapi_windows.c \
serial_port/find_usb_serial_port_win.cpp \
SuspendResume/SuspendResume_Windows.cpp \
@@ -359,31 +356,36 @@ win32:HEADERS +=
dependencies/display-library/include/adl_defines.h \
dependencies/display-library/include/adl_sdk.h \
dependencies/display-library/include/adl_structures.h \
dependencies/winring0/include/OlsApi.h \
dependencies/NVFC/nvapi.h \
i2c_smbus/i2c_smbus_i801.h \
i2c_smbus/i2c_smbus_nct6775.h \
i2c_smbus/i2c_smbus_nvapi.h \
i2c_smbus/i2c_smbus_piix4.h \
dependencies/PawnIO/PawnIOLib.h \
i2c_smbus/Windows/i2c_smbus_amdadl.h \
i2c_smbus/Windows/i2c_smbus_nvapi.h \
i2c_smbus/Windows/i2c_smbus_pawnio.h \
wmi/wmi.h \
AutoStart/AutoStart-Windows.h \
SuspendResume/SuspendResume_Windows.h \
win32:contains(QMAKE_TARGET.arch, x86_64) {
win32:SOURCES += \
i2c_smbus/Windows/i2c_smbus_pawnio.cpp \
super_io/super_io_pawnio.cpp \
LIBS += \
-lws2_32 \
-liphlpapi \
-L"$$PWD/dependencies/winring0/x64/" -lWinRing0x64 \
-L"$$PWD/dependencies/libusb-1.0.27/VS2019/MS64/dll" -llibusb-1.0 \
-L"$$PWD/dependencies/hidapi-win/x64/" -lhidapi \
-L"$$PWD/dependencies/mbedtls-3.2.1/lib/x64/" -lmbedcrypto -lmbedtls -lmbedx509 \
-L"$$PWD/dependencies/PawnIO/" -lPawnIOLib \
}
win32:contains(QMAKE_TARGET.arch, x86) {
win32:SOURCES += \
super_io/super_io.cpp \
LIBS += \
-lws2_32 \
-liphlpapi \
-L"$$PWD/dependencies/winring0/Win32/" -lWinRing0 \
-L"$$PWD/dependencies/libusb-1.0.27/VS2019/MS32/dll" -llibusb-1.0 \
-L"$$PWD/dependencies/hidapi-win/x86/" -lhidapi \
-L"$$PWD/dependencies/mbedtls-3.2.1/lib/x86/" -lmbedcrypto -lmbedtls -lmbedx509 \
@@ -403,6 +405,11 @@ win32:DEFINES +=
win32:RC_ICONS += \
qt/OpenRGB.ico
win32:DISTFILES += \
dependencies/PawnIO/modules/SmbusPIIX4.bin \
dependencies/PawnIO/modules/SmbusI801.bin \
dependencies/PawnIO/modules/LpcIO.bin
#-----------------------------------------------------------------------------------------------#
# Windows GitLab CI Configuration #
#-----------------------------------------------------------------------------------------------#
@@ -424,10 +431,13 @@ win32:UI_DIR = _intermediate_$$DESTDIR/.ui
#-----------------------------------------------------------------------------------------------#
win32:contains(QMAKE_TARGET.arch, x86_64) {
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/x64/WinRing0x64.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/x64/WinRing0x64.sys )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/libusb-1.0.27/VS2019/MS64/dll/libusb-1.0.dll)\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/hidapi-win/x64/hidapi.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/PawnIOLib.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/SmbusPIIX4.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/SmbusI801.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/SmbusNCT6793.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/PawnIO/modules/LpcIO.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
@@ -435,9 +445,6 @@ win32:contains(QMAKE_TARGET.arch, x86_64) {
}
win32:contains(QMAKE_TARGET.arch, x86) {
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/Win32/WinRing0.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/Win32/WinRing0.sys )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/winring0/x64/WinRing0x64.sys )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/libusb-1.0.27/VS2019/MS32/dll/libusb-1.0.dll)\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
copydata.commands += $(COPY_FILE) \"$$shell_path($$PWD/dependencies/hidapi-win/x86/hidapi.dll )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t)
@@ -462,14 +469,16 @@ contains(QMAKE_PLATFORM, linux) {
HEADERS += \
dependencies/NVFC/nvapi.h \
i2c_smbus/i2c_smbus_linux.h \
i2c_smbus/Linux/i2c_smbus_linux.h \
AutoStart/AutoStart-Linux.h \
SPDAccessor/EE1004Accessor_Linux.h \
SPDAccessor/SPD5118Accessor_Linux.h \
SuspendResume/SuspendResume_Linux_FreeBSD.h \
super_io/super_io.h \
INCLUDEPATH += \
dependencies/NVFC \
i2c_smbus/Linux \
/usr/include/mbedtls/ \
LIBS += \
@@ -516,7 +525,7 @@ contains(QMAKE_PLATFORM, linux) {
SOURCES += \
dependencies/hueplusplus-1.2.0/src/LinHttpHandler.cpp \
dependencies/NVFC/nvapi.cpp \
i2c_smbus/i2c_smbus_linux.cpp \
i2c_smbus/Linux/i2c_smbus_linux.cpp \
scsiapi/scsiapi_linux.c \
serial_port/find_usb_serial_port_linux.cpp \
AutoStart/AutoStart-Linux.cpp \
@@ -524,6 +533,7 @@ contains(QMAKE_PLATFORM, linux) {
SPDAccessor/SPD5118Accessor_Linux.cpp \
SuspendResume/SuspendResume_Linux_FreeBSD.cpp \
startup/main_FreeBSD_Linux_MacOS.cpp \
super_io/super_io.cpp \
#-------------------------------------------------------------------------------------------#
# Set up install paths #
@@ -599,6 +609,7 @@ contains(QMAKE_PLATFORM, freebsd) {
HEADERS += \
AutoStart/AutoStart-FreeBSD.h \
SuspendResume/SuspendResume_Linux_FreeBSD.h \
super_io/super_io.h \
HEADERS -= \
Controllers/SeagateController/RGBController_Seagate.h \
@@ -648,6 +659,7 @@ contains(QMAKE_PLATFORM, freebsd) {
AutoStart/AutoStart-FreeBSD.cpp \
SuspendResume/SuspendResume_Linux_FreeBSD.cpp \
startup/main_FreeBSD_Linux_MacOS.cpp \
super_io/super_io.cpp \
SOURCES -= \
Controllers/SeagateController/RGBController_Seagate.cpp \
@@ -750,6 +762,10 @@ macx:contains(QMAKE_HOST.arch, arm64) {
SOURCES += \
scsiapi/scsiapi_macos.c \
super_io/super_io.cpp \
HEADERS += \
super_io/super_io.h \
LIBS += \
-L/opt/homebrew/lib \
@@ -761,20 +777,23 @@ macx:contains(QMAKE_HOST.arch, arm64) {
macx:contains(QMAKE_HOST.arch, x86_64) {
INCLUDEPATH += \
dependencies/macUSPCIO \
i2c_smbus/MacOS \
/usr/local/include \
/usr/local/homebrew/include \
SOURCES += \
i2c_smbus/i2c_smbus_i801.cpp \
i2c_smbus/i2c_smbus_nct6775.cpp \
i2c_smbus/i2c_smbus_piix4.cpp \
i2c_smbus/MacOS/i2c_smbus_i801.cpp \
i2c_smbus/MacOS/i2c_smbus_nct6775.cpp \
i2c_smbus/MacOS/i2c_smbus_piix4.cpp \
scsiapi/scsiapi_macos.c \
super_io/super_io.cpp \
HEADERS += \
dependencies/macUSPCIO/macUSPCIOAccess.h \
i2c_smbus/i2c_smbus_i801.h \
i2c_smbus/i2c_smbus_nct6775.h \
i2c_smbus/i2c_smbus_piix4.h \
i2c_smbus/MacOS/i2c_smbus_i801.h \
i2c_smbus/MacOS/i2c_smbus_nct6775.h \
i2c_smbus/MacOS/i2c_smbus_piix4.h \
super_io/super_io.h \
LIBS += \
-L/usr/local/lib \
+1 -2
View File
@@ -132,8 +132,7 @@ This project interacts directly with hardware using reverse engineered protocols
## Projects Used
* OpenRGB directly relies upon these projects.
* WinRing0: https://openlibsys.org/
* PawnIO: https://pawnio.eu/
* libusb: https://github.com/libusb/libusb
* hidapi: https://github.com/libusb/hidapi
* libe131: https://github.com/hhromic/libe131
+2 -2
View File
@@ -38,8 +38,8 @@ const char* I2C_ERR_WIN = QT_TRANSLATE_NOOP("ResourceManager",
"<p>One or more I2C or SMBus interfaces failed to initialize.</p>"
"<p><b>RGB DRAM modules, some motherboards' onboard RGB lighting, and RGB Graphics Cards, will not be available in OpenRGB</b> without I2C or SMBus.</p>"
"<h4>How to fix this:</h4>"
"<p>On Windows, this is usually caused by a failure to load the WinRing0 driver.</p>"
"<p>You must run OpenRGB as administrator at least once to allow WinRing0 to set up.</p>"
"<p>On Windows, this is usually caused by a failure to load the PawnIO driver.</p>"
"<p>You must first install <a href='https://pawnio.eu/'>PawnIO</a>, then you must OpenRGB as administrator in order to access these devices.</p>"
"<p>See <a href='https://help.openrgb.org/'>help.openrgb.org</a> for additional troubleshooting steps if you keep seeing this message.<br></p>"
"<h3>If you are not using internal RGB on a desktop this message is not important to you.</h3>");
const char* I2C_ERR_LINUX = QT_TRANSLATE_NOOP("ResourceManager",
Binary file not shown.
+75
View File
@@ -0,0 +1,75 @@
// PawnIOLib - Library and tooling source to be used with PawnIO.
// Copyright (C) 2023 namazso <[email protected]>
//
// 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
#ifndef PAWNIOLIB_LIBRARY_H
#define PAWNIOLIB_LIBRARY_H
#ifdef PawnIOLib_EXPORTS
#define PAWNIO_EXPORT __declspec(dllexport)
#else
#define PAWNIO_EXPORT __declspec(dllimport)
#endif
#define PAWNIOAPI EXTERN_C PAWNIO_EXPORT HRESULT STDAPICALLTYPE
/// Get PawnIOLib version.
///
/// @p version A pointer to a ULONG which receives the version.
/// @return A HRESULT.
PAWNIOAPI pawnio_version(PULONG version);
/// Open a PawnIO executor.
///
/// @p handle A handle to the executor, or NULL.
/// @return A HRESULT.
PAWNIOAPI pawnio_open(PHANDLE handle);
/// Load a PawnIO blob.
///
/// @p handle Handle from @c pawnio_open.
/// @p blob Blob to load.
/// @p size Size of blob.
/// @return A HRESULT.
PAWNIOAPI pawnio_load(HANDLE handle, const UCHAR* blob, SIZE_T size);
/// Executes a function from the loaded blob.
///
/// @p handle Handle from @c pawnio_open.
/// @p name Function name to execute.
/// @p in Input buffer.
/// @p in_size Input buffer count.
/// @p out Output buffer.
/// @p out_size Output buffer count.
/// @p return_size Entries written in out_size.
/// @return A HRESULT.
PAWNIOAPI pawnio_execute(
HANDLE handle,
PCSTR name,
const ULONG64* in,
SIZE_T in_size,
PULONG64 out,
SIZE_T out_size,
PSIZE_T return_size
);
/// Close a PawnIO executor.
///
/// @p handle Handle from @c pawnio_open.
/// @return A HRESULT.
PAWNIOAPI pawnio_close(HANDLE handle);
#endif //PAWNIOLIB_LIBRARY_H
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-580
View File
@@ -1,580 +0,0 @@
//-----------------------------------------------------------------------------
// Author : hiyohiyo
// Mail : [email protected]
// Web : http://openlibsys.org/
// License : The modified BSD license
//
// Copyright 2007-2009 OpenLibSys.org. All rights reserved.
//-----------------------------------------------------------------------------
// for WinRing0 1.3.x
#pragma once
/******************************************************************************
**
** DLL Information
**
******************************************************************************/
//-----------------------------------------------------------------------------
// GetDllStatus
//-----------------------------------------------------------------------------
DWORD // DLL Status, defined OLS_DLL_****
WINAPI GetDllStatus();
//-----------------------------------------------------------------------------
// GetDllVersion
//-----------------------------------------------------------------------------
DWORD // DLL Version, defined OLS_VERSION
WINAPI GetDllVersion(
PBYTE major, // major version
PBYTE minor, // minor version
PBYTE revision, // revision
PBYTE release // release/build
);
//-----------------------------------------------------------------------------
// GetDriverVersion
//-----------------------------------------------------------------------------
DWORD // Device Driver Version, defined OLS_DRIVER_VERSION
WINAPI GetDriverVersion(
PBYTE major, // major version
PBYTE minor, // minor version
PBYTE revision, // revision
PBYTE release // release/build
);
//-----------------------------------------------------------------------------
// GetDriverType
//-----------------------------------------------------------------------------
DWORD // Device Driver Type, defined OLS_DRIVER_TYPE_****
WINAPI GetDriverType();
//-----------------------------------------------------------------------------
// InitializeOls
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI InitializeOls();
//-----------------------------------------------------------------------------
// DeinitializeOls
//-----------------------------------------------------------------------------
VOID WINAPI DeinitializeOls();
/******************************************************************************
**
** CPU
**
******************************************************************************/
//-----------------------------------------------------------------------------
// IsCpuid
//-----------------------------------------------------------------------------
BOOL // TRUE: support CPUID instruction, FALSE: not support CPUID instruction
WINAPI IsCpuid();
//-----------------------------------------------------------------------------
// IsMsr
//-----------------------------------------------------------------------------
BOOL // TRUE: support MSR(Model-Specific Register), FALSE: not support MSR
WINAPI IsMsr();
//-----------------------------------------------------------------------------
// IsTsc
//-----------------------------------------------------------------------------
BOOL // TRUE: support TSC(Time Stamp Counter), FALSE: not support TSC
WINAPI IsTsc();
//-----------------------------------------------------------------------------
// Rdmsr
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Rdmsr(
DWORD index, // MSR index
PDWORD eax, // bit 0-31
PDWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// RdmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdmsrTx(
DWORD index, // MSR index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// RdmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdmsrPx(
DWORD index, // MSR index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Wrmsr
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Wrmsr(
DWORD index, // MSR index
DWORD eax, // bit 0-31
DWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// WrmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WrmsrTx(
DWORD index, // MSR index
DWORD eax, // bit 0-31
DWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// WrmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WrmsrPx(
DWORD index, // MSR index
DWORD eax, // bit 0-31
DWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Rdpmc
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Rdpmc(
DWORD index, // PMC index
PDWORD eax, // bit 0-31
PDWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// RdmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdpmcTx(
DWORD index, // PMC index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// RdmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdpmcPx(
DWORD index, // PMC index
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Cpuid
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Cpuid(
DWORD index, // CPUID index
PDWORD eax,
PDWORD ebx,
PDWORD ecx,
PDWORD edx
);
//-----------------------------------------------------------------------------
// CpuidTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI CpuidTx(
DWORD index, // CPUID index
PDWORD eax,
PDWORD ebx,
PDWORD ecx,
PDWORD edx,
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// CpuidPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI CpuidPx(
DWORD index, // CPUID index
PDWORD eax,
PDWORD ebx,
PDWORD ecx,
PDWORD edx,
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Rdtsc
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Rdtsc(
PDWORD eax, // bit 0-31
PDWORD edx // bit 32-63
);
//-----------------------------------------------------------------------------
// RdmsrTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdtscTx(
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// RdmsrPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI RdtscPx(
PDWORD eax, // bit 0-31
PDWORD edx, // bit 32-63
DWORD_PTR processAffinityMask
);
//-----------------------------------------------------------------------------
// Hlt
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI Hlt();
//-----------------------------------------------------------------------------
// HltTx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI HltTx(
DWORD_PTR threadAffinityMask
);
//-----------------------------------------------------------------------------
// HltPx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI HltTx(
DWORD_PTR processAffinityMask
);
/******************************************************************************
**
** I/O
**
******************************************************************************/
//-----------------------------------------------------------------------------
// ReadIoPortByte
//-----------------------------------------------------------------------------
BYTE // Read Value
WINAPI ReadIoPortByte(
WORD port // I/O port address
);
//-----------------------------------------------------------------------------
// ReadIoPortWord
//-----------------------------------------------------------------------------
WORD // Read Value
WINAPI ReadIoPortWord(
WORD port // I/O port address
);
//-----------------------------------------------------------------------------
// ReadIoPortDword
//-----------------------------------------------------------------------------
DWORD // Read Value
WINAPI ReadIoPortDword(
WORD port // I/O port address
);
//-----------------------------------------------------------------------------
// ReadIoPortByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadIoPortByteEx(
WORD port, // I/O port address
PBYTE value // Read Value
);
//-----------------------------------------------------------------------------
// ReadIoPortWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadIoPortWordEx(
WORD port, // I/O port address
PWORD value // Read Value
);
//-----------------------------------------------------------------------------
// ReadIoPortDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadIoPortDwordEx(
WORD port, // I/O port address
PDWORD value // Read Value
);
//-----------------------------------------------------------------------------
// WriteIoPortByte
//-----------------------------------------------------------------------------
VOID
WINAPI WriteIoPortByte(
WORD port, // I/O port address
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortDword
//-----------------------------------------------------------------------------
VOID
WINAPI WriteIoPortDword(
WORD port, // I/O port address
DWORD value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortWord
//-----------------------------------------------------------------------------
VOID
WINAPI WriteIoPortWord(
WORD port, // I/O port address
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WriteIoPortByteEx(
WORD port, // I/O port address
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WriteIoPortWordEx(
WORD port, // I/O port address
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WriteIoPortDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WriteIoPortDwordEx(
WORD port, // I/O port address
DWORD value // Write Value
);
/******************************************************************************
**
** PCI
**
******************************************************************************/
// pciAddress
// 0- 2: Function Number
// 3- 7: Device Number
// 8-15: PCI Bus Number
// 16-31: Reserved
// 0xFFFFFFFF : Error
//-----------------------------------------------------------------------------
// SetPciMaxBusNo
//-----------------------------------------------------------------------------
VOID
WINAPI SetPciMaxBusIndex(
BYTE max // Max PCI Bus to Scan
);
//-----------------------------------------------------------------------------
// ReadPciConfigByte
//-----------------------------------------------------------------------------
BYTE // Read Value
WINAPI ReadPciConfigByte(
DWORD pciAddress, // PCI Device Address
BYTE regAddress // Configuration Address 0-255
);
//-----------------------------------------------------------------------------
// ReadPciConfigWord
//-----------------------------------------------------------------------------
WORD // Read Value
WINAPI ReadPciConfigWord(
DWORD pciAddress, // PCI Device Address
BYTE regAddress // Configuration Address 0-255
);
//-----------------------------------------------------------------------------
// ReadPciConfigDword
//-----------------------------------------------------------------------------
DWORD // Read Value
WINAPI ReadPciConfigDword(
DWORD pciAddress, // PCI Device Address
BYTE regAddress // Configuration Address 0-255
);
//-----------------------------------------------------------------------------
// ReadPciConfigByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadPciConfigByteEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
PBYTE value // Read Value
);
//-----------------------------------------------------------------------------
// ReadPciConfigWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadPciConfigWordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
PWORD value // Read Value
);
//-----------------------------------------------------------------------------
// ReadPciConfigDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI ReadPciConfigDwordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
PDWORD value // Read Value
);
//-----------------------------------------------------------------------------
// WritePciConfigByte
//-----------------------------------------------------------------------------
VOID
WINAPI WritePciConfigByte(
DWORD pciAddress, // PCI Device Address
BYTE regAddress, // Configuration Address 0-255
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigWord
//-----------------------------------------------------------------------------
VOID
WINAPI WritePciConfigWord(
DWORD pciAddress, // PCI Device Address
BYTE regAddress, // Configuration Address 0-255
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigDword
//-----------------------------------------------------------------------------
VOID
WINAPI WritePciConfigDword(
DWORD pciAddress, // PCI Device Address
BYTE regAddress, // Configuration Address 0-255
DWORD value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigByteEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WritePciConfigByteEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
BYTE value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigWordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WritePciConfigWordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
WORD value // Write Value
);
//-----------------------------------------------------------------------------
// WritePciConfigDwordEx
//-----------------------------------------------------------------------------
BOOL // TRUE: success, FALSE: failure
WINAPI WritePciConfigDwordEx(
DWORD pciAddress, // PCI Device Address
DWORD regAddress, // Configuration Address 0-whatever
DWORD value // Write Value
);
//-----------------------------------------------------------------------------
// FindPciDeviceById
//-----------------------------------------------------------------------------
DWORD // pciAddress, 0xFFFFFFFF: failure
WINAPI FindPciDeviceById(
WORD vendorId, // Vendor ID
WORD deviceId, // Device ID
BYTE index // Index
);
//-----------------------------------------------------------------------------
// FindPciDeviceByClass
//-----------------------------------------------------------------------------
DWORD // pciAddress, 0xFFFFFFFF: failure
WINAPI FindPciDeviceByClass(
BYTE baseClass, // Base Class
BYTE subClass, // Sub Class
BYTE programIf, // Program Interface
BYTE index // Index
);
/******************************************************************************
**
** Memory (Special API)
**
******************************************************************************/
#ifdef _PHYSICAL_MEMORY_SUPPORT
//-----------------------------------------------------------------------------
// ReadDmiMemory
//-----------------------------------------------------------------------------
DWORD // Read size(byte), 0: failure
WINAPI ReadDmiMemory(
PBYTE buffer, // Buffer
DWORD count, // Count
DWORD unitSize // Unit Size (BYTE, WORD, DWORD)
);
//-----------------------------------------------------------------------------
// ReadPhysicalMemory
//-----------------------------------------------------------------------------
DWORD // Read size(byte), 0: failure
WINAPI ReadPhysicalMemory(
DWORD_PTR address, // Physical Memory Address
PBYTE buffer, // Buffer
DWORD count, // Count
DWORD unitSize // Unit Size (BYTE, WORD, DWORD)
);
//-----------------------------------------------------------------------------
// WritePhysicalMemory
//-----------------------------------------------------------------------------
DWORD // Write size(byte), 0: failure
WINAPI WritePhysicalMemory(
DWORD_PTR address, // Physical Memory Address
PBYTE buffer, // Buffer
DWORD count, // Count
DWORD unitSize // Unit Size (BYTE, WORD, DWORD)
);
#endif
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_i801.cpp |
| |
| i801 SMBUS driver for Windows |
| i801 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 29 Jan 2019 |
| Portions based on Linux source code |
@@ -10,47 +10,22 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "macUSPCIOAccess.h"
#include "Detector.h"
#include "i2c_smbus_i801.h"
#include "ResourceManager.h"
#ifdef _WIN32
#include "OlsApi.h"
#include "wmi.h"
#elif _MACOSX_X86_X64
#include "macUSPCIOAccess.h"
#endif
#include "LogManager.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
using namespace std::chrono_literals;
i2c_smbus_i801::i2c_smbus_i801()
{
#ifdef _WIN32
json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers");
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
#endif
}
i2c_smbus_i801::~i2c_smbus_i801()
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
#endif
}
/* Return negative errno on error. */
@@ -519,22 +494,8 @@ int i2c_smbus_i801::i801_wait_intr()
s32 i2c_smbus_i801::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
#endif
s32 result = i801_access(addr, read_write, command, size, data);
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
#endif
return result;
}
@@ -543,103 +504,6 @@ s32 i2c_smbus_i801::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/, u8
return -1;
}
#ifdef _WIN32
bool i2c_smbus_i801_detect()
{
if(!InitializeOls() || GetDllStatus())
{
LOG_INFO("WinRing0 is not loaded, i801 I2C bus detection aborted");
return(false);
}
i2c_smbus_interface * bus;
HRESULT hres;
Wmi wmi;
// Query WMI for Win32_PnPSignedDriver entries with names matching "SMBUS" or "SM BUS"
// These devices may be browsed under Device Manager -> System Devices
std::vector<QueryObj> q_res_PnPSignedDriver;
hres = wmi.query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'", q_res_PnPSignedDriver);
if (hres)
{
LOG_INFO("WMI query failed, i801 I2C bus detection aborted");
return(false);
}
// For each detected SMBus adapter, try enumerating it as either AMD or Intel
for (QueryObj &i : q_res_PnPSignedDriver)
{
// Intel SMBus controllers do show I/O resources in Device Manager
// Analysis of many Intel boards has shown that Intel SMBus adapter I/O space varies between boards
// We can query Win32_PnPAllocatedResource entries and look up the PCI device ID to find the allocated I/O space
// Intel SMBus adapters use the i801 driver
if ((i["Manufacturer"].find("Intel") != std::string::npos)
|| (i["Manufacturer"].find("INTEL") != std::string::npos))
{
std::string rgx1 = ".+" + q_res_PnPSignedDriver[0]["DeviceID"].substr(4, 33) + ".+";
AdditionalFilters filters;
filters.emplace("Dependent", rgx1);
filters.emplace("Antecedent", ".*Port.*");
std::vector<QueryObj> q_res_PNPAllocatedResource;
hres = wmi.query("SELECT * FROM Win32_PnPAllocatedResource", q_res_PNPAllocatedResource, &filters);
std::regex rgx2(".*StartingAddress=\"(\\d+)\".*");
std::smatch matches;
// Query the StartingAddress for the matching device ID and use it to enumerate the bus
if (!q_res_PNPAllocatedResource.empty() && std::regex_search(q_res_PNPAllocatedResource[0]["Antecedent"], matches, rgx2))
{
unsigned int IORangeStart = std::stoi(matches[1].str());
std::string pnp_str = i["DeviceID"];
std::size_t ven_loc = pnp_str.find("VEN_");
std::size_t dev_loc = pnp_str.find("DEV_");
std::size_t sub_loc = pnp_str.find("SUBSYS_");
std::string ven_str = pnp_str.substr(ven_loc + 4, 4);
std::string dev_str = pnp_str.substr(dev_loc + 4, 4);
std::string sbv_str = pnp_str.substr(sub_loc + 11, 4);
std::string sbd_str = pnp_str.substr(sub_loc + 7, 4);
int ven_id = (int)std::stoul(ven_str, nullptr, 16);
int dev_id = (int)std::stoul(dev_str, nullptr, 16);
int sbv_id = (int)std::stoul(sbv_str, nullptr, 16);
int sbd_id = (int)std::stoul(sbd_str, nullptr, 16);
DWORD pciAddress = FindPciDeviceById(ven_id, dev_id, 0);
if(pciAddress == 0xFFFFFFFF)
{
continue;
}
uint8_t host_config = (uint8_t)ReadPciConfigWord(pciAddress, SMBHSTCFG);
if ((host_config & SMBHSTCFG_HST_EN) == 0)
{
continue;
}
bus = new i2c_smbus_i801();
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strcpy(bus->device_name, i["Description"].c_str());
((i2c_smbus_i801 *)bus)->i801_smba = IORangeStart;
ResourceManager::get()->RegisterI2CBus(bus);
}
}
}
return(true);
}
#elif _MACOSX_X86_X64
bool i2c_smbus_i801_detect()
{
if(!GetMacUSPCIODriverStatus())
@@ -675,6 +539,4 @@ bool i2c_smbus_i801_detect()
return(true);
}
#endif
REGISTER_I2C_BUS_DETECTOR(i2c_smbus_i801_detect);
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_i801.h |
| |
| i801 SMBUS driver for Windows |
| i801 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 29 Jan 2019 |
| Portions based on Linux source code |
@@ -14,10 +14,6 @@
#include "i2c_smbus.h"
#ifdef _WIN32
#include <Windows.h>
#endif
/* BIT shifting macro */
#define BIT(x) ( 1 << x )
@@ -87,10 +83,6 @@
#define SMBHSTCFG 0x040
#define SMBHSTCFG_HST_EN BIT(0)
#ifdef _WIN32
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
#endif
class i2c_smbus_i801 : public i2c_smbus_interface
{
public:
@@ -109,8 +101,4 @@ private:
int i801_wait_intr();
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
#ifdef _WIN32
HANDLE global_smbus_access_handle = NULL;
#endif
};
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_nct6775.cpp |
| |
| Nuvoton NCT67xx SMBUS driver for Windows |
| Nuvoton NCT67xx SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 19 May 2019 |
| |
@@ -9,14 +9,11 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "macUSPCIOAccess.h"
#include "Detector.h"
#include "i2c_smbus_nct6775.h"
#include "LogManager.h"
#ifdef _WIN32
#include "OlsApi.h"
#elif _MACOSX_X86_X64
#include "macUSPCIOAccess.h"
#endif
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "super_io.h"
@@ -25,29 +22,10 @@ using namespace std::chrono_literals;
i2c_smbus_nct6775::i2c_smbus_nct6775()
{
#ifdef _WIN32
json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers");
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
#endif
}
i2c_smbus_nct6775::~i2c_smbus_nct6775()
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
#endif
}
s32 i2c_smbus_nct6775::nct6775_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data)
@@ -223,22 +201,8 @@ s32 i2c_smbus_nct6775::nct6775_access(u16 addr, char read_write, u8 command, int
s32 i2c_smbus_nct6775::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
#endif
s32 result = nct6775_access(addr, read_write, command, size, data);
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
#endif
return result;
}
@@ -249,19 +213,11 @@ s32 i2c_smbus_nct6775::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/,
bool i2c_smbus_nct6775_detect()
{
#ifdef _WIN32
if(!InitializeOls() || GetDllStatus())
{
LOG_INFO("WinRing0 is not loaded, nct6775 I2C bus detection aborted");
return(false);
}
#elif _MACOSX_X86_X64
if(!GetMacUSPCIODriverStatus())
{
LOG_INFO("macUSPCIO is not loaded, nct6775 I2C bus detection aborted");
return(false);
}
#endif
i2c_smbus_interface* bus;
int sioaddr = 0x2E;
@@ -276,12 +232,12 @@ bool i2c_smbus_nct6775_detect()
case SIO_NCT6793_ID:
case SIO_NCT6796_ID:
case SIO_NCT6798_ID:
// Create new nct6775 bus and zero out the PCI ID information
// Create new nct6775 bus and invalidate the PCI ID information
bus = new i2c_smbus_nct6775();
bus->pci_vendor = 0;
bus->pci_device = 0;
bus->pci_subsystem_vendor = 0;
bus->pci_subsystem_device = 0;
bus->pci_vendor = 0xFFFF;
bus->pci_device = 0xFFFF;
bus->pci_subsystem_vendor = 0xFFFF;
bus->pci_subsystem_device = 0xFFFF;
// Set logical device register to get SMBus base address
superio_outb(sioaddr, SIO_REG_LOGDEV, SIO_LOGDEV_SMBUS);
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_nct6775.h |
| |
| Nuvoton NCT67xx SMBUS driver for Windows |
| Nuvoton NCT67xx SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 19 May 2019 |
| |
@@ -12,9 +12,6 @@
#pragma once
#include "i2c_smbus.h"
#ifdef _WIN32
#include <Windows.h>
#endif
#define SMBHSTDAT (0 + nct6775_smba)
#define SMBBLKSZ (1 + nct6775_smba)
@@ -50,10 +47,6 @@
/* Other settings */
#define NCT6775_MAX_RETRIES 400
#ifdef _WIN32
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
#endif
class i2c_smbus_nct6775: public i2c_smbus_interface
{
public:
@@ -65,8 +58,4 @@ private:
s32 nct6775_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
#ifdef _WIN32
HANDLE global_smbus_access_handle = NULL;
#endif
};
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_piix4.cpp |
| |
| PIIX4 SMBUS driver for Windows |
| PIIX4 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 08 Aug 2018 |
| Portions based on Linux source code |
@@ -10,17 +10,13 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <unistd.h>
#include "macUSPCIOAccess.h"
#include "Detector.h"
#include "i2c_smbus_piix4.h"
#include "LogManager.h"
#ifdef _WIN32
#include "OlsApi.h"
#include "wmi.h"
#elif _MACOSX_X86_X64
#include <unistd.h>
#include "macUSPCIOAccess.h"
#include "pci_ids.h"
#endif
#include "ResourceManager.h"
#include "SettingsManager.h"
@@ -33,43 +29,12 @@ i2c_smbus_piix4::i2c_smbus_piix4()
{
amd_smbus_reduce_cpu = drivers_settings["amd_smbus_reduce_cpu"].get<bool>();
}
#ifdef _WIN32
if(amd_smbus_reduce_cpu)
{
delay_timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_MANUAL_RESET | CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
if(delay_timer == NULL) // high resolution timer not supported
{
delay_timer = CreateWaitableTimer(NULL, TRUE, NULL); // create regular timer instead
}
}
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
#else
delay_timer = amd_smbus_reduce_cpu;
#endif
}
i2c_smbus_piix4::~i2c_smbus_piix4()
{
#ifdef _WIN32
if(delay_timer != NULL)
{
CloseHandle(delay_timer);
}
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
#endif
}
//Logic adapted from piix4_transaction() in i2c-piix4.c
@@ -105,21 +70,8 @@ int i2c_smbus_piix4::piix4_transaction()
| if this bit is set. Note that there may be moderate latency before the transaction begins and the Host Busy bit |
| gets set. |
\*---------------------------------------------------------------------------------------------------------------*/
#ifdef _WIN32
if(delay_timer != NULL)
{
LARGE_INTEGER retry_delay;
retry_delay.QuadPart = RETRY_DELAY_US * -10;
temp = 0;
do
{
SetWaitableTimer(delay_timer, &retry_delay, 0, NULL, NULL, FALSE);
WaitForSingleObject(delay_timer, INFINITE);
temp = ReadIoPortByte(SMBHSTSTS);
}
while((++timeout < MAX_TIMEOUT) && ((temp & 0x03) != 0x02));
}
#else
if(delay_timer)
{
do
@@ -129,7 +81,6 @@ int i2c_smbus_piix4::piix4_transaction()
}
while((++timeout < MAX_TIMEOUT) && ((temp & 0x03) != 0x02));
}
#endif
else
{
std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);
@@ -282,22 +233,8 @@ s32 i2c_smbus_piix4::piix4_access(u16 addr, char read_write, u8 command, int siz
s32 i2c_smbus_piix4::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
#endif
s32 result = piix4_access(addr, read_write, command, size, data);
#ifdef _WIN32
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
#endif
return result;
}
@@ -305,79 +242,7 @@ s32 i2c_smbus_piix4::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/, u
{
return -1;
}
#ifdef _WIN32
bool i2c_smbus_piix4_detect()
{
if(!InitializeOls() || GetDllStatus())
{
LOG_INFO("WinRing0 is not loaded, piix4 I2C bus detection aborted");
return(false);
}
i2c_smbus_interface * bus;
HRESULT hres;
Wmi wmi;
// Query WMI for Win32_PnPSignedDriver entries with names matching "SMBUS" or "SM BUS"
// These devices may be browsed under Device Manager -> System Devices
std::vector<QueryObj> q_res_PnPSignedDriver;
hres = wmi.query("SELECT * FROM Win32_PnPSignedDriver WHERE Description LIKE '%SMBUS%' OR Description LIKE '%SM BUS%'", q_res_PnPSignedDriver);
if (hres)
{
LOG_INFO("WMI query failed, piix4 I2C bus detection aborted");
return(false);
}
// For each detected SMBus adapter, try enumerating it as either AMD or Intel
for (QueryObj &i : q_res_PnPSignedDriver)
{
// AMD SMBus controllers do not show any I/O resources allocated in Device Manager
// Analysis of many AMD boards has shown that AMD SMBus controllers have two adapters with fixed I/O spaces at 0x0B00 and 0x0B20
// AMD SMBus adapters use the PIIX4 driver
if (i["Manufacturer"].find("Advanced Micro Devices, Inc") != std::string::npos)
{
std::string pnp_str = i["DeviceID"];
std::size_t ven_loc = pnp_str.find("VEN_");
std::size_t dev_loc = pnp_str.find("DEV_");
std::size_t sub_loc = pnp_str.find("SUBSYS_");
std::string ven_str = pnp_str.substr(ven_loc + 4, 4);
std::string dev_str = pnp_str.substr(dev_loc + 4, 4);
std::string sbv_str = pnp_str.substr(sub_loc + 11, 4);
std::string sbd_str = pnp_str.substr(sub_loc + 7, 4);
int ven_id = (int)std::stoul(ven_str, nullptr, 16);
int dev_id = (int)std::stoul(dev_str, nullptr, 16);
int sbv_id = (int)std::stoul(sbv_str, nullptr, 16);
int sbd_id = (int)std::stoul(sbd_str, nullptr, 16);
bus = new i2c_smbus_piix4();
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
strcpy(bus->device_name, i["Description"].c_str());
strcat(bus->device_name, " at 0x0B00");
((i2c_smbus_piix4 *)bus)->piix4_smba = 0x0B00;
ResourceManager::get()->RegisterI2CBus(bus);
bus = new i2c_smbus_piix4();
bus->pci_vendor = ven_id;
bus->pci_device = dev_id;
bus->pci_subsystem_vendor = sbv_id;
bus->pci_subsystem_device = sbd_id;
((i2c_smbus_piix4 *)bus)->piix4_smba = 0x0B20;
strcpy(bus->device_name, i["Description"].c_str());
strcat(bus->device_name, " at 0x0B20");
ResourceManager::get()->RegisterI2CBus(bus);
}
}
return(true);
}
#elif _MACOSX_X86_X64
bool i2c_smbus_piix4_detect()
{
if(!GetMacUSPCIODriverStatus())
@@ -419,6 +284,5 @@ bool i2c_smbus_piix4_detect()
return(true);
}
#endif
REGISTER_I2C_BUS_DETECTOR(i2c_smbus_piix4_detect);
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| i2c_smbus_piix4.h |
| |
| PIIX4 SMBUS driver for Windows |
| PIIX4 SMBUS driver for MacOS |
| |
| Adam Honse (CalcProgrammer1) 08 Aug 2018 |
| Portions based on Linux source code |
@@ -13,9 +13,6 @@
#pragma once
#include "i2c_smbus.h"
#ifdef _WIN32
#include "windows.h"
#endif
// PIIX4 SMBus address offsets
#define SMBHSTSTS (0 + piix4_smba)
@@ -41,10 +38,6 @@
#define PIIX4_WORD_DATA 0x0C
#define PIIX4_BLOCK_DATA 0x14
#ifdef _WIN32
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
#endif
class i2c_smbus_piix4 : public i2c_smbus_interface
{
public:
@@ -57,10 +50,6 @@ private:
s32 piix4_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
#ifdef _WIN32
HANDLE delay_timer = NULL;
HANDLE global_smbus_access_handle = NULL;
#else
bool delay_timer;
#endif
};
+346
View File
@@ -0,0 +1,346 @@
/*---------------------------------------------------------*\
| i2c_smbus_pawnio.cpp |
| |
| PawnIO SMBUS driver for Windows |
| |
| Stephen Horvath (Steve-Tech) 04 May 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include <string>
#include "Detector.h"
#include "i2c_smbus_pawnio.h"
#include "LogManager.h"
#include "PawnIOLib.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "wmi.h"
std::unordered_map<std::string, int> i2c_smbus_pawnio::using_handle;
i2c_smbus_pawnio::i2c_smbus_pawnio(HANDLE handle, std::string name)
{
/*-----------------------------------------------------*\
| Store bus information |
| TODO: Remove name field once all drivers use the same |
| ioctl names |
\*-----------------------------------------------------*/
this->handle = handle;
this->name = name;
/*-----------------------------------------------------*\
| Get driver settings |
\*-----------------------------------------------------*/
json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers");
/*-----------------------------------------------------*\
| Get bus information |
\*-----------------------------------------------------*/
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {0};
const SIZE_T out_size = 3;
ULONG64 out[out_size];
SIZE_T return_size;
HRESULT status;
status = pawnio_execute(handle, "ioctl_identity", in, in_size, out, out_size, &return_size);
if(!status)
{
this->pci_vendor = (out[2] & 0x000000000000FFFF);
this->pci_device = (out[2] & 0x00000000FFFF0000) >> 16;
this->pci_subsystem_vendor = (out[2] & 0x0000FFFF0000FFFF) >> 32;
this->pci_subsystem_device = (out[2] & 0xFFFF000000000000) >> 48;
char name_str[9];
name_str[0] = (out[0] & 0x00000000000000FF);
name_str[1] = (out[0] & 0x000000000000FF00) >> 8;
name_str[2] = (out[0] & 0x0000000000FF0000) >> 16;
name_str[3] = (out[0] & 0x00000000FF000000) >> 24;
name_str[4] = (out[0] & 0x000000FF00000000) >> 32;
name_str[5] = (out[0] & 0x0000FF0000000000) >> 40;
name_str[6] = (out[0] & 0x00FF000000000000) >> 48;
name_str[7] = (out[0] & 0xFF00000000000000) >> 56;
name_str[8] = 0;
strncpy( this->device_name, name_str, 512 );
}
/*-----------------------------------------------------*\
| Get shared SMBus access setting |
\*-----------------------------------------------------*/
bool shared_smbus_access = true;
if(drivers_settings.contains("shared_smbus_access"))
{
shared_smbus_access = drivers_settings["shared_smbus_access"].get<bool>();
}
/*-----------------------------------------------------*\
| Create global SMBus mutex if enabled |
\*-----------------------------------------------------*/
if(shared_smbus_access)
{
global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME);
}
using_handle[name]++;
}
i2c_smbus_pawnio::~i2c_smbus_pawnio()
{
/*-----------------------------------------------------*\
| Close global SMBus mutex |
\*-----------------------------------------------------*/
if(global_smbus_access_handle != NULL)
{
CloseHandle(global_smbus_access_handle);
}
/*-----------------------------------------------------*\
| TODO: find a way to do this without name field |
\*-----------------------------------------------------*/
if(--using_handle[name] == 0 && pawnio_close(handle))
{
LOG_ERROR("PawnIO failed to close");
}
}
s32 i2c_smbus_pawnio::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data)
{
/*-----------------------------------------------------*\
| Lock SMBus mutex |
\*-----------------------------------------------------*/
if(global_smbus_access_handle != NULL)
{
WaitForSingleObject(global_smbus_access_handle, INFINITE);
}
/*-----------------------------------------------------*\
| Pack input data |
\*-----------------------------------------------------*/
const SIZE_T in_size = 9;
ULONG64 in[in_size];
const SIZE_T out_size = 5;
ULONG64 out[out_size];
SIZE_T return_size;
HRESULT status;
in[0] = addr;
in[1] = read_write;
in[2] = command;
in[3] = size;
if(data != NULL)
{
memcpy( &in[4], data, sizeof(i2c_smbus_data));
}
/*-----------------------------------------------------*\
| Perform SMBus transfer |
\*-----------------------------------------------------*/
status = pawnio_execute(handle, "ioctl_smbus_xfer", in, in_size, out, out_size, &return_size);
/*-----------------------------------------------------*\
| Unpack output data |
\*-----------------------------------------------------*/
if(data != NULL)
{
memcpy( data, &out[0], sizeof(i2c_smbus_data));
}
/*-----------------------------------------------------*\
| Unlock SMBus mutex |
\*-----------------------------------------------------*/
if(global_smbus_access_handle != NULL)
{
ReleaseMutex(global_smbus_access_handle);
}
return(status);
}
s32 i2c_smbus_pawnio::i2c_xfer(u8 /*addr*/, char /*read_write*/, int* /*size*/, u8* /*data*/)
{
return(-1);
}
HRESULT i2c_smbus_pawnio::start_pawnio(std::string filename, PHANDLE phandle)
{
char exePath[MAX_PATH];
HANDLE handle;
HRESULT status;
/*-----------------------------------------------------*\
| Open PawnIO driver |
\*-----------------------------------------------------*/
status = pawnio_open(phandle);
/*-----------------------------------------------------*\
| Check result |
\*-----------------------------------------------------*/
if(status)
{
if(status == E_ACCESSDENIED)
{
LOG_ERROR("Permission Denied, PawnIO initialization aborted");
}
else
{
LOG_ERROR("Could not open PawnIO, PawnIO initialization aborted");
}
return(status);
}
handle = *phandle;
/*-----------------------------------------------------*\
| Get the path of the executable |
\*-----------------------------------------------------*/
if(!GetModuleFileNameA(NULL, exePath, MAX_PATH))
{
LOG_ERROR("Failed to get executable path, PawnIO initialization aborted");
return E_FAIL;
}
/*-----------------------------------------------------*\
| Construct the path to `filename` in the executable's |
| directory |
\*-----------------------------------------------------*/
std::filesystem::path exeDir = std::filesystem::path(exePath).parent_path();
std::filesystem::path filePath = exeDir / filename;
/*-----------------------------------------------------*\
| Check if the file exists |
\*-----------------------------------------------------*/
if(!std::filesystem::exists(filePath))
{
LOG_ERROR("Failed to find %s in the executable's directory, PawnIO initialization aborted", filename.c_str());
return(E_FAIL);
}
/*-----------------------------------------------------*\
| Open the file |
\*-----------------------------------------------------*/
std::ifstream file(filePath, std::ios::binary);
if(!file.is_open())
{
LOG_ERROR("Failed to open %s, PawnIO initialization aborted", filename.c_str());
return(E_FAIL);
}
/*-----------------------------------------------------*\
| Read the contents of the file into a vector of bytes |
\*-----------------------------------------------------*/
std::vector<char> blob((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
/*-----------------------------------------------------*\
| Close the file |
\*-----------------------------------------------------*/
file.close();
/*-----------------------------------------------------*\
| Load the file into PawnIO |
\*-----------------------------------------------------*/
status = pawnio_load(handle, reinterpret_cast<const UCHAR*>(blob.data()), blob.size());
/*-----------------------------------------------------*\
| Check if the load was successful |
\*-----------------------------------------------------*/
if(status)
{
LOG_ERROR("Failed to load %s, PawnIO initialization aborted", filename.c_str());
return(status);
}
/*-----------------------------------------------------*\
| Log a message and return OK if PawnIO successfully |
| opened |
\*-----------------------------------------------------*/
LOG_INFO("PawnIO initialized");
return(S_OK);
}
s32 piix4_port_sel(HANDLE pawnio_handle, s32 port)
{
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {(ULONG64)port};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
SIZE_T return_size;
HRESULT status;
/*-----------------------------------------------------*\
| Execute PIIX4 port_sel ioctl |
\*-----------------------------------------------------*/
status = pawnio_execute(pawnio_handle, "ioctl_piix4_port_sel", in, in_size, out, 1, &return_size);
return(status ? -EIO : 0);
}
bool i2c_smbus_pawnio_detect()
{
ULONG dll_version;
if(pawnio_version(&dll_version))
{
LOG_INFO("PawnIO is not loaded, PawnIO I2C bus detection aborted");
return(false);
}
i2c_smbus_interface * bus;
HANDLE pawnio_handle;
/*-----------------------------------------------------*\
| Try to load Intel (i801) SMBus driver |
\*-----------------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusI801.bin", &pawnio_handle) == S_OK)
{
bus = new i2c_smbus_pawnio(pawnio_handle, "i801");
ResourceManager::get()->RegisterI2CBus(bus);
}
/*-----------------------------------------------------*\
| Try to load AMD (PIIX4) SMBus driver - primary bus |
\*-----------------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusPIIX4.bin", &pawnio_handle) == S_OK)
{
/*-------------------------------------------------*\
| Select port 0 |
\*-------------------------------------------------*/
piix4_port_sel(pawnio_handle, 0);
bus = new i2c_smbus_pawnio(pawnio_handle, "piix4");
ResourceManager::get()->RegisterI2CBus(bus);
}
/*-----------------------------------------------------*\
| Try to load AMD (PIIX4 SMBus driver - secondary bus |
\*-----------------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusPIIX4.bin", &pawnio_handle) == S_OK)
{
/*--------------------------------------------------*\
| Select port 1 |
\*-------------------------------------------------*/
piix4_port_sel(pawnio_handle, 1);
bus = new i2c_smbus_pawnio(pawnio_handle, "piix4");
ResourceManager::get()->RegisterI2CBus(bus);
}
/*-----------------------------------------------------*\
| Try to load Nuvoton (NCT6793) SMBus driver |
\*-----------------------------------------------------*/
if(i2c_smbus_pawnio::start_pawnio("SmbusNCT6793.bin", &pawnio_handle) == S_OK)
{
bus = new i2c_smbus_pawnio(pawnio_handle, "NCT6793");
ResourceManager::get()->RegisterI2CBus(bus);
}
return(true);
}
REGISTER_I2C_BUS_DETECTOR(i2c_smbus_pawnio_detect);
+42
View File
@@ -0,0 +1,42 @@
/*---------------------------------------------------------*\
| i2c_smbus_piix4_pawnio.h |
| |
| PawnIO PIIX4 SMBUS driver for Windows |
| |
| Stephen Horvath (Steve-Tech) 21 Apr 2025 |
| Based on original OpenRGB PIIX4 source code |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <unordered_map>
#include "windows.h"
#include "i2c_smbus.h"
#define GLOBAL_SMBUS_MUTEX_NAME "Global\\Access_SMBUS.HTP.Method"
class i2c_smbus_pawnio : public i2c_smbus_interface
{
public:
static std::unordered_map<std::string, int> using_handle;
i2c_smbus_pawnio(HANDLE handle, std::string name);
~i2c_smbus_pawnio();
static HRESULT start_pawnio(std::string filename, PHANDLE phandle);
private:
s32 pawnio_read(u8 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 pawnio_write(u8 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
HANDLE global_smbus_access_handle;
std::string name;
HANDLE handle;
};
+3
View File
@@ -62,6 +62,9 @@ std::string i2c_detect(i2c_smbus_interface * bus, int mode)
case MODE_READ:
res = bus->i2c_smbus_read_byte(slave_addr);
break;
case MODE_READ_DATA:
res = bus->i2c_smbus_read_byte_data(slave_addr, 0);
break;
default:
if ((i + j >= 0x30 && i + j <= 0x37)
|| (i + j >= 0x50 && i + j <= 0x5F))
+5 -4
View File
@@ -11,10 +11,11 @@
#include <string>
#include "i2c_smbus.h"
#define MODE_AUTO 0
#define MODE_QUICK 1
#define MODE_READ 2
#define MODE_FUNC 3
#define MODE_AUTO 0
#define MODE_QUICK 1
#define MODE_READ 2
#define MODE_READ_DATA 3
#define MODE_FUNC 4
std::string i2c_detect(i2c_smbus_interface * bus, int mode);
+1
View File
@@ -966,6 +966,7 @@
#define IF_MOBO_SMBUS(ven, dev) \
if((ven == 0) || \
((ven == 0xFFFF) && (dev == 0xFFFF)) || \
((ven == AMD_VEN) && (dev == AMD_FCH_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_ICH10_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_SUNRISE_POINT_H_SMBUS_DEV)) || \
@@ -46,6 +46,7 @@ OpenRGBSystemInfoPage::OpenRGBSystemInfoPage(std::vector<i2c_smbus_interface *>&
ui->SMBusDetectionModeBox->addItem("Auto");
ui->SMBusDetectionModeBox->addItem("Quick");
ui->SMBusDetectionModeBox->addItem("Read");
ui->SMBusDetectionModeBox->addItem("Read Data");
ui->SMBusDetectionModeBox->setCurrentIndex(0);
}
@@ -104,6 +105,10 @@ void OpenRGBSystemInfoPage::on_DetectButton_clicked()
case 2:
ui->SMBusDataText->setPlainText(i2c_detect(bus, MODE_READ).c_str());
break;
case 3:
ui->SMBusDataText->setPlainText(i2c_detect(bus, MODE_READ_DATA).c_str());
break;
}
}
}
+2 -2
View File
@@ -12,12 +12,12 @@ import os
#############################################
# OpenRGB version #
#############################################
version = "1.0rc2wr0"
version = "1.0rc2"
#############################################
# Git version (tag, branch, or commit) #
#############################################
git_id = "release_candidate_1.0rc2wr0"
git_id = "release_candidate_1.0rc2"
command = "git rev-list -n 1 " + git_id
print(command)
-82
View File
@@ -519,83 +519,6 @@ static void WaitWhileServerOnline(NetworkServer* srv)
};
}
/*---------------------------------------------------------*\
| InstallWinRing0 |
| |
| Install SMBus Driver WinRing0, If not already installed |
| (Win32) |
\*---------------------------------------------------------*/
void InstallWinRing0()
{
/*-----------------------------------------------------*\
| Driver final location usually |
| C:\windows\system32\drivers\WinRing0x64.sys |
\*-----------------------------------------------------*/
TCHAR winring0_install_location[MAX_PATH];
uint system_path_length = GetSystemDirectory(winring0_install_location, MAX_PATH);
std::string winring0_filename = "WinRing0.sys";
BOOL bIsWow64 = false;
#if _WIN64
winring0_filename = "WinRing0x64.sys";
#else
BOOL (*fnIsWow64Process)(HANDLE, PBOOL) = (BOOL (__cdecl *)(HANDLE, PBOOL))GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if (fnIsWow64Process)
{
fnIsWow64Process(GetCurrentProcess(),&bIsWow64);
}
if(bIsWow64)
{
winring0_filename = "WinRing0x64.sys";
}
#endif
std::strncat(winring0_install_location, "\\drivers\\", MAX_PATH - system_path_length - 1);
std::strncat(winring0_install_location, winring0_filename.c_str(), MAX_PATH - system_path_length - 10);
std::string driver_name = winring0_filename.substr(0, winring0_filename.size() - 4); // driver name: WinRing0 or WinRing0x64
SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (manager)
{
PVOID wow64_fsredirection_OldValue = NULL;
if(bIsWow64)
{
Wow64DisableWow64FsRedirection(&wow64_fsredirection_OldValue);
}
if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(winring0_install_location) && GetLastError()==ERROR_FILE_NOT_FOUND)
{
char module_path_buffer[MAX_PATH];
GetModuleFileNameA(NULL, module_path_buffer, MAX_PATH);
std::string::size_type exe_loc = std::string(module_path_buffer).find_last_of("\\/");
std::string driver_source_path = std::string(module_path_buffer).substr(0, exe_loc + 1) + winring0_filename;
CopyFile(driver_source_path.c_str(), winring0_install_location, true);
}
if(bIsWow64)
{
Wow64RevertWow64FsRedirection(wow64_fsredirection_OldValue);
}
SC_HANDLE service = OpenService(manager, driver_name.c_str(), SERVICE_ALL_ACCESS);
if(!service)
{
std::string service_sys_path = "System32\\Drivers\\" + winring0_filename;
service = CreateService(manager,
driver_name.c_str(),
driver_name.c_str(),
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
service_sys_path.c_str(),
NULL,
NULL,
NULL,
NULL,
NULL);
}
CloseServiceHandle(service);
CloseServiceHandle(manager);
}
}
/*---------------------------------------------------------*\
| common_main |
| |
@@ -631,11 +554,6 @@ static int common_main(int argc, char* argv[])
InitializeTimerResolutionThread = new std::thread(InitializeTimerResolutionThreadFunction);
InitializeTimerResolutionThread->detach();
/*-----------------------------------------------------*\
| Install SMBus Driver WinRing0 |
\*-----------------------------------------------------*/
InstallWinRing0();
/*-----------------------------------------------------*\
| Initialize ResourceManager |
\*-----------------------------------------------------*/
+27 -7
View File
@@ -11,11 +11,9 @@
#include "super_io.h"
#ifdef _WIN32
#include <Windows.h>
#include "OlsApi.h"
#elif _MACOSX_X86_X64
#if defined(_MACOSX_X86_X64)
#include "macUSPCIOAccess.h"
#elif defined(_WIN32)
#else
#include <unistd.h>
#include <sys/types.h>
@@ -34,9 +32,16 @@ int dev_port_fd;
void superio_enter(int ioreg)
{
#if defined(WIN32) || defined(_MACOSX_X86_X64)
#if defined(_MACOSX_X86_X64)
WriteIoPortByte(ioreg, 0x87);
WriteIoPortByte(ioreg, 0x87);
#elif defined(_WIN32)
/*-----------------------------------------------------*\
| This function is not defined for Windows |
| For 64-bit Windows, super_io_pawnio.cpp is used |
| instead. For 32-bit Windows, this function provides|
| a nonfunctional stub implementation. |
\*-----------------------------------------------------*/
#else
unsigned char temp = 0x87;
dev_port_fd = open("/dev/port", O_RDWR, "rw");
@@ -71,9 +76,16 @@ void superio_enter(int ioreg)
void superio_outb(int ioreg, int reg, int val)
{
#if defined(WIN32) || defined(_MACOSX_X86_X64)
#if defined(_MACOSX_X86_X64)
WriteIoPortByte(ioreg, reg);
WriteIoPortByte(ioreg + 1, val);
#elif defined(_WIN32)
/*-----------------------------------------------------*\
| This function is not defined for Windows |
| For 64-bit Windows, super_io_pawnio.cpp is used |
| instead. For 32-bit Windows, this function provides|
| a nonfunctional stub implementation. |
\*-----------------------------------------------------*/
#else
dev_port_fd = open("/dev/port", O_RDWR, "rw");
@@ -106,9 +118,17 @@ void superio_outb(int ioreg, int reg, int val)
int superio_inb(int ioreg, int reg)
{
#if defined(WIN32) || defined(_MACOSX_X86_X64)
#if defined(_MACOSX_X86_X64)
WriteIoPortByte(ioreg, reg);
return ReadIoPortByte(ioreg + 1);
#elif defined(_WIN32)
/*-----------------------------------------------------*\
| This function is not defined for Windows |
| For 64-bit Windows, super_io_pawnio.cpp is used |
| instead. For 32-bit Windows, this function provides|
| a nonfunctional stub implementation. |
\*-----------------------------------------------------*/
return -1;
#else
unsigned char temp = 0;
dev_port_fd = open("/dev/port", O_RDWR, "rw");
+2
View File
@@ -9,6 +9,8 @@
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#pragma once
/******************************************************************************************\
* *
* Nuvoton Super IO constants *
+119
View File
@@ -0,0 +1,119 @@
/*---------------------------------------------------------*\
| super_io_pawnio.cpp |
| |
| Functions for interfacing with Super-IO using PawnIO |
| |
| Stephen Horvath (Steve-Tech) 05 May 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
\*---------------------------------------------------------*/
#include "super_io.h"
#include <Windows.h>
#include "PawnIOLib.h"
#include "i2c_smbus_pawnio.h"
static HANDLE pawnio_handle = NULL;
static int pawnio_chip_type = 0;
static int addr_to_pawnio(int addr)
{
switch (addr)
{
case 0x2E:
return 0;
case 0x4E:
return 1;
default:
return -1;
}
}
/******************************************************************************************\
* *
* pawnio_superio_enter *
* *
* Put the Super IO chip into Extended Function Mode *
* *
\******************************************************************************************/
void superio_enter(int ioreg)
{
HRESULT status;
SIZE_T return_size;
if (pawnio_handle == NULL)
{
status = i2c_smbus_pawnio::start_pawnio("superio", &pawnio_handle);
if (status != S_OK)
{
// TODO: Figure out how to handle errors
return;
}
}
if (pawnio_chip_type == 0)
{
int in_reg = addr_to_pawnio(ioreg);
if (in_reg == -1) {
return;
}
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {(ULONG64)in_reg};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
status = pawnio_execute(pawnio_handle, "ioctl_detect", in, in_size, out, out_size, &return_size);
if (status != S_OK || out[0] == 0)
{
return;
}
pawnio_chip_type = (int)out[0];
}
pawnio_execute(pawnio_handle, "ioctl_enter", NULL, 0, NULL, 0, &return_size);
}
/******************************************************************************************\
* *
* pawnio_superio_outb *
* *
* Write a byte to the Super IO configuration register *
* *
\******************************************************************************************/
void superio_outb([[maybe_unused]] int ioreg, int reg, int val)
{
const SIZE_T in_size = 2;
ULONG64 in[in_size] = {(ULONG64)reg, (ULONG64)val};
SIZE_T return_size;
pawnio_execute(pawnio_handle, "ioctl_write", in, in_size, NULL, 0, &return_size);
}
/******************************************************************************************\
* *
* pawnio_superio_inb *
* *
* Read a byte from the Super IO configuration register *
* *
\******************************************************************************************/
int superio_inb([[maybe_unused]] int ioreg, int reg)
{
const SIZE_T in_size = 1;
ULONG64 in[in_size] = {(ULONG64)reg};
const SIZE_T out_size = 1;
ULONG64 out[out_size];
SIZE_T return_size;
HRESULT status = pawnio_execute(pawnio_handle, "ioctl_read", in, in_size, out, out_size, &return_size);
if (status != S_OK)
{
return -1;
}
return (int)out[0];
}