diff --git a/OpenRGB.pro b/OpenRGB.pro index d921c9882..2ab0004a1 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -199,7 +199,6 @@ HEADERS += serial_port/find_usb_serial_port.h \ serial_port/serial_port.h \ StringUtils.h \ - super_io/super_io.h \ SuspendResume/SuspendResume.h \ AutoStart/AutoStart.h \ KeyboardLayoutManager/KeyboardLayoutManager.h \ @@ -266,7 +265,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 +328,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 +340,10 @@ 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 \ + i2c_smbus/Windows/i2c_smbus_pawnio.cpp \ + super_io/super_io_pawnio.cpp \ scsiapi/scsiapi_windows.c \ serial_port/find_usb_serial_port_win.cpp \ SuspendResume/SuspendResume_Windows.cpp \ @@ -359,12 +357,12 @@ 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 \ + super_io/super_io_pawnio.h \ wmi/wmi.h \ AutoStart/AutoStart-Windows.h \ SuspendResume/SuspendResume_Windows.h \ @@ -373,17 +371,16 @@ win32:contains(QMAKE_TARGET.arch, x86_64) { 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) { 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 +400,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 +426,12 @@ 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/LpcIO.bin )\" \"$$shell_path($$DESTDIR)\" $$escape_expand(\n\t) first.depends = $(first) copydata export(first.depends) export(copydata.commands) @@ -435,9 +439,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 +463,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 +519,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 +527,7 @@ contains(QMAKE_PLATFORM, linux) { SPDAccessor/SPD5118Accessor_Linux.cpp \ SuspendResume/SuspendResume_Linux_FreeBSD.cpp \ startup/main_Linux_MacOS.cpp \ + super_io/super_io.cpp \ #-------------------------------------------------------------------------------------------# # Set up install paths # @@ -599,6 +603,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 \ @@ -647,6 +652,7 @@ contains(QMAKE_PLATFORM, freebsd) { serial_port/find_usb_serial_port_linux.cpp \ AutoStart/AutoStart-FreeBSD.cpp \ SuspendResume/SuspendResume_Linux_FreeBSD.cpp \ + super_io/super_io.cpp \ SOURCES -= \ Controllers/SeagateController/RGBController_Seagate.cpp \ @@ -749,6 +755,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 \ @@ -760,20 +770,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 \ diff --git a/README.md b/README.md index 772c922ce..ec61606e9 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/dependencies/PawnIO/PawnIOLib.dll b/dependencies/PawnIO/PawnIOLib.dll new file mode 100644 index 000000000..1e79e772f Binary files /dev/null and b/dependencies/PawnIO/PawnIOLib.dll differ diff --git a/dependencies/PawnIO/PawnIOLib.h b/dependencies/PawnIO/PawnIOLib.h new file mode 100644 index 000000000..b1f6b07fb --- /dev/null +++ b/dependencies/PawnIO/PawnIOLib.h @@ -0,0 +1,75 @@ +// PawnIOLib - Library and tooling source to be used with PawnIO. +// Copyright (C) 2023 namazso +// +// 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 diff --git a/dependencies/PawnIO/PawnIOLib.lib b/dependencies/PawnIO/PawnIOLib.lib new file mode 100644 index 000000000..daa76a6f6 Binary files /dev/null and b/dependencies/PawnIO/PawnIOLib.lib differ diff --git a/dependencies/PawnIO/modules/LpcIO.bin b/dependencies/PawnIO/modules/LpcIO.bin new file mode 100644 index 000000000..886f11843 Binary files /dev/null and b/dependencies/PawnIO/modules/LpcIO.bin differ diff --git a/dependencies/PawnIO/modules/SmbusI801.bin b/dependencies/PawnIO/modules/SmbusI801.bin new file mode 100644 index 000000000..8d8282a99 Binary files /dev/null and b/dependencies/PawnIO/modules/SmbusI801.bin differ diff --git a/dependencies/PawnIO/modules/SmbusPIIX4.bin b/dependencies/PawnIO/modules/SmbusPIIX4.bin new file mode 100644 index 000000000..f9ff0dde2 Binary files /dev/null and b/dependencies/PawnIO/modules/SmbusPIIX4.bin differ diff --git a/dependencies/winring0/Win32/WinRing0.dll b/dependencies/winring0/Win32/WinRing0.dll deleted file mode 100644 index 1cd219a8b..000000000 Binary files a/dependencies/winring0/Win32/WinRing0.dll and /dev/null differ diff --git a/dependencies/winring0/Win32/WinRing0.lib b/dependencies/winring0/Win32/WinRing0.lib deleted file mode 100644 index e7adf350a..000000000 Binary files a/dependencies/winring0/Win32/WinRing0.lib and /dev/null differ diff --git a/dependencies/winring0/Win32/WinRing0.sys b/dependencies/winring0/Win32/WinRing0.sys deleted file mode 100644 index feaea414a..000000000 Binary files a/dependencies/winring0/Win32/WinRing0.sys and /dev/null differ diff --git a/dependencies/winring0/include/OlsApi.h b/dependencies/winring0/include/OlsApi.h deleted file mode 100644 index 9f11e6aac..000000000 --- a/dependencies/winring0/include/OlsApi.h +++ /dev/null @@ -1,580 +0,0 @@ -//----------------------------------------------------------------------------- -// Author : hiyohiyo -// Mail : hiyohiyo@crystalmark.info -// 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 \ No newline at end of file diff --git a/dependencies/winring0/x64/WinRing0x64.dll b/dependencies/winring0/x64/WinRing0x64.dll deleted file mode 100644 index 4a48c7a1f..000000000 Binary files a/dependencies/winring0/x64/WinRing0x64.dll and /dev/null differ diff --git a/dependencies/winring0/x64/WinRing0x64.lib b/dependencies/winring0/x64/WinRing0x64.lib deleted file mode 100644 index 0f1697710..000000000 Binary files a/dependencies/winring0/x64/WinRing0x64.lib and /dev/null differ diff --git a/dependencies/winring0/x64/WinRing0x64.sys b/dependencies/winring0/x64/WinRing0x64.sys deleted file mode 100644 index 197c255ad..000000000 Binary files a/dependencies/winring0/x64/WinRing0x64.sys and /dev/null differ diff --git a/i2c_smbus/i2c_smbus_linux.cpp b/i2c_smbus/Linux/i2c_smbus_linux.cpp similarity index 100% rename from i2c_smbus/i2c_smbus_linux.cpp rename to i2c_smbus/Linux/i2c_smbus_linux.cpp diff --git a/i2c_smbus/i2c_smbus_linux.h b/i2c_smbus/Linux/i2c_smbus_linux.h similarity index 100% rename from i2c_smbus/i2c_smbus_linux.h rename to i2c_smbus/Linux/i2c_smbus_linux.h diff --git a/i2c_smbus/i2c_smbus_i801.cpp b/i2c_smbus/MacOS/i2c_smbus_i801.cpp similarity index 77% rename from i2c_smbus/i2c_smbus_i801.cpp rename to i2c_smbus/MacOS/i2c_smbus_i801.cpp index 8b3a18410..d5cd7ce47 100644 --- a/i2c_smbus/i2c_smbus_i801.cpp +++ b/i2c_smbus/MacOS/i2c_smbus_i801.cpp @@ -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(); - } - 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 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 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); diff --git a/i2c_smbus/i2c_smbus_i801.h b/i2c_smbus/MacOS/i2c_smbus_i801.h similarity index 93% rename from i2c_smbus/i2c_smbus_i801.h rename to i2c_smbus/MacOS/i2c_smbus_i801.h index 27bb18ce5..8c06b6177 100644 --- a/i2c_smbus/i2c_smbus_i801.h +++ b/i2c_smbus/MacOS/i2c_smbus_i801.h @@ -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 -#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 }; diff --git a/i2c_smbus/i2c_smbus_nct6775.cpp b/i2c_smbus/MacOS/i2c_smbus_nct6775.cpp similarity index 86% rename from i2c_smbus/i2c_smbus_nct6775.cpp rename to i2c_smbus/MacOS/i2c_smbus_nct6775.cpp index d18674e60..020ca0fad 100644 --- a/i2c_smbus/i2c_smbus_nct6775.cpp +++ b/i2c_smbus/MacOS/i2c_smbus_nct6775.cpp @@ -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(); - } - 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; diff --git a/i2c_smbus/i2c_smbus_nct6775.h b/i2c_smbus/MacOS/i2c_smbus_nct6775.h similarity index 88% rename from i2c_smbus/i2c_smbus_nct6775.h rename to i2c_smbus/MacOS/i2c_smbus_nct6775.h index 651c413ca..127894c32 100644 --- a/i2c_smbus/i2c_smbus_nct6775.h +++ b/i2c_smbus/MacOS/i2c_smbus_nct6775.h @@ -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 -#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 }; diff --git a/i2c_smbus/i2c_smbus_piix4.cpp b/i2c_smbus/MacOS/i2c_smbus_piix4.cpp similarity index 67% rename from i2c_smbus/i2c_smbus_piix4.cpp rename to i2c_smbus/MacOS/i2c_smbus_piix4.cpp index cdd5ce301..ed0482ad1 100644 --- a/i2c_smbus/i2c_smbus_piix4.cpp +++ b/i2c_smbus/MacOS/i2c_smbus_piix4.cpp @@ -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 +#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 -#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(); } -#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(); - } - 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 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); diff --git a/i2c_smbus/i2c_smbus_piix4.h b/i2c_smbus/MacOS/i2c_smbus_piix4.h similarity index 86% rename from i2c_smbus/i2c_smbus_piix4.h rename to i2c_smbus/MacOS/i2c_smbus_piix4.h index bcb2dbdc5..abf5a2852 100644 --- a/i2c_smbus/i2c_smbus_piix4.h +++ b/i2c_smbus/MacOS/i2c_smbus_piix4.h @@ -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 }; diff --git a/i2c_smbus/i2c_smbus_amdadl.cpp b/i2c_smbus/Windows/i2c_smbus_amdadl.cpp similarity index 100% rename from i2c_smbus/i2c_smbus_amdadl.cpp rename to i2c_smbus/Windows/i2c_smbus_amdadl.cpp diff --git a/i2c_smbus/i2c_smbus_amdadl.h b/i2c_smbus/Windows/i2c_smbus_amdadl.h similarity index 100% rename from i2c_smbus/i2c_smbus_amdadl.h rename to i2c_smbus/Windows/i2c_smbus_amdadl.h diff --git a/i2c_smbus/i2c_smbus_nvapi.cpp b/i2c_smbus/Windows/i2c_smbus_nvapi.cpp similarity index 100% rename from i2c_smbus/i2c_smbus_nvapi.cpp rename to i2c_smbus/Windows/i2c_smbus_nvapi.cpp diff --git a/i2c_smbus/i2c_smbus_nvapi.h b/i2c_smbus/Windows/i2c_smbus_nvapi.h similarity index 100% rename from i2c_smbus/i2c_smbus_nvapi.h rename to i2c_smbus/Windows/i2c_smbus_nvapi.h diff --git a/i2c_smbus/Windows/i2c_smbus_pawnio.cpp b/i2c_smbus/Windows/i2c_smbus_pawnio.cpp new file mode 100644 index 000000000..3a1200e09 --- /dev/null +++ b/i2c_smbus/Windows/i2c_smbus_pawnio.cpp @@ -0,0 +1,558 @@ +/*---------------------------------------------------------*\ +| 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 +#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 i2c_smbus_pawnio::using_handle; + +i2c_smbus_pawnio::i2c_smbus_pawnio(HANDLE handle, std::string name) +{ + /*-----------------------------------------------------*\ + | Get driver settings | + \*-----------------------------------------------------*/ + json drivers_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Drivers"); + + /*-----------------------------------------------------*\ + | 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(); + } + + /*-----------------------------------------------------*\ + | Create global SMBus mutex if enabled | + \*-----------------------------------------------------*/ + if(shared_smbus_access) + { + global_smbus_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_SMBUS_MUTEX_NAME); + } + + /*-----------------------------------------------------*\ + | Store bus information | + | TODO: Remove name field once all drivers use the same | + | ioctl names | + \*-----------------------------------------------------*/ + this->handle = handle; + this->name = 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::pawnio_read(u8 addr, char /*read_write*/, u8 command, int size, i2c_smbus_data* data) +{ + SIZE_T return_size; + + switch(size) + { + case I2C_SMBUS_BYTE: + { + const SIZE_T in_size = 1; + ULONG64 in[in_size] = {addr}; + const SIZE_T out_size = 1; + ULONG64 out[out_size]; + + /*---------------------------------------------*\ + | Execute PawnIO read_byte ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_byte").c_str(), in, in_size, out, out_size, &return_size); + data->byte = (u8)out[0]; + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_BYTE_DATA: + { + const SIZE_T in_size = 2; + ULONG64 in[in_size] = {addr, command}; + const SIZE_T out_size = 1; + ULONG64 out[out_size]; + + /*---------------------------------------------*\ + | Execute PawnIO read_byte_data ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_byte_data").c_str(), in, in_size, out, out_size, &return_size); + data->byte = (u8)out[0]; + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_WORD_DATA: + { + const SIZE_T in_size = 2; + ULONG64 in[in_size] = {addr, command}; + const SIZE_T out_size = 1; + ULONG64 out[out_size]; + + /*---------------------------------------------*\ + | Execute PawnIO read_word_data ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_word_data").c_str(), in, in_size, out, out_size, &return_size); + data->word = (u16)out[0]; + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_BLOCK_DATA: + { + const SIZE_T in_size = 2; + ULONG64 in[in_size] = {addr, command}; + + /*---------------------------------------------*\ + | Calculate output data buffer size | + | Pawn only deals with 64-bit cells, divide by | + | 8 to convert bytes to qwords. | + | The first cell is also the length. | + \*---------------------------------------------*/ + const SIZE_T out_size = 1 + (I2C_SMBUS_BLOCK_MAX / 8); + ULONG64 out[out_size]; + + /*---------------------------------------------*\ + | Execute PawnIO read_block_data ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_read_block_data").c_str(), in, in_size, out, out_size, &return_size); + + if(status) + { + return(-EIO); + } + + if(out[0] == 0 || out[0] > I2C_SMBUS_BLOCK_MAX) + { + return(-EPROTO); + } + + /*---------------------------------------------*\ + | Unpack bytes from 64bit Pawn cells | + \*---------------------------------------------*/ + u8 *out_bytes = (u8*)(&out[1]); + memcpy(&data->block[1], out_bytes, out[0]); + + return(0); + } + + default: + return(-EOPNOTSUPP); + } +} + +s32 i2c_smbus_pawnio::pawnio_write(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data) +{ + SIZE_T return_size; + + switch(size) + { + case I2C_SMBUS_QUICK: + { + const SIZE_T in_size = 2; + ULONG64 in[in_size] = {addr, (u8)read_write}; + + /*---------------------------------------------*\ + | Execute PawnIO write_quick ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_quick").c_str(), in, in_size, NULL, 0, &return_size); + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_BYTE: + { + const SIZE_T in_size = 2; + ULONG64 in[in_size] = {addr, data->byte}; + + /*---------------------------------------------*\ + | Execute PawnIO write_byte ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_byte").c_str(), in, in_size, NULL, 0, &return_size); + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_BYTE_DATA: + { + const SIZE_T in_size = 3; + ULONG64 in[in_size] = {addr, command, data->byte}; + + /*---------------------------------------------*\ + | Execute PawnIO write_byte_data ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_byte_data").c_str(), in, in_size, NULL, 0, &return_size); + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_WORD_DATA: + { + const SIZE_T in_size = 3; + ULONG64 in[in_size] = {addr, command, data->word}; + + /*---------------------------------------------*\ + | Execute PawnIO write_word_data ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_word_data").c_str(), in, in_size, NULL, 0, &return_size); + + return(status ? -EIO : 0); + } + + case I2C_SMBUS_BLOCK_DATA: + { + SIZE_T len = data->block[0]; + if(len == 0 || len > I2C_SMBUS_BLOCK_MAX) + { + return -EINVAL; + } + const SIZE_T in_size = 3 + (I2C_SMBUS_BLOCK_MAX/8); + ULONG64 in[3 + (I2C_SMBUS_BLOCK_MAX/8)] = {addr, command, len}; + + /*---------------------------------------------*\ + | Pack bytes into 64bit Pawn cells | + \*---------------------------------------------*/ + u8 *in_bytes = (u8*)&in[3]; + memcpy(in_bytes, &data->block[1], len); + + /*---------------------------------------------*\ + | Execute PawnIO write_block_data ioctl | + \*---------------------------------------------*/ + HRESULT status = pawnio_execute(handle, ("ioctl_" + name + "_write_block_data").c_str(), in, in_size, NULL, 0, &return_size); + + return(status ? -EIO : 0); + } + + default: + return(-EOPNOTSUPP); + } +} + +s32 i2c_smbus_pawnio::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data) +{ + if(global_smbus_access_handle != NULL) + { + WaitForSingleObject(global_smbus_access_handle, INFINITE); + } + + int status = -ENXIO; + + if(read_write && size != I2C_SMBUS_QUICK) { + status = pawnio_read(addr, read_write, command, size, data); + } + else + { + status = pawnio_write(addr, read_write, command, size, data); + } + + 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); +} + +// TODO: Find a better place for this function +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 blob((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + + /*-----------------------------------------------------*\ + | Close the file | + \*-----------------------------------------------------*/ + file.close(); + + /*-----------------------------------------------------*\ + | Load the file into PawnIO | + \*-----------------------------------------------------*/ + status = pawnio_load(handle, reinterpret_cast(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; + HRESULT hres; + Wmi wmi; + HANDLE pawnio_handle; + + /*-----------------------------------------------------*\ + | 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 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, I2C bus detection aborted"); + return(false); + } + + /*-----------------------------------------------------*\ + | For each detected SMBus adapter, try enumerating it | + | as either AMD (piix4) or Intel (i801) | + \*-----------------------------------------------------*/ + 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 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); + + /*---------------------------------------------*\ + | Create bus | + \*---------------------------------------------*/ + if(i2c_smbus_pawnio::start_pawnio("SmbusI801.bin", &pawnio_handle) != S_OK) + { + return(false); + } + + bus = new i2c_smbus_pawnio(pawnio_handle, "i801"); + bus->pci_vendor = ven_id; + bus->pci_device = dev_id; + bus->pci_subsystem_vendor = sbv_id; + bus->pci_subsystem_device = sbd_id; + strncpy(bus->device_name, i["Description"].c_str(), sizeof bus->device_name); + ResourceManager::get()->RegisterI2CBus(bus); + } + + /*-------------------------------------------------*\ + | AMD SMBus adapters use the PIIX4 driver | + \*-------------------------------------------------*/ + else 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); + + /*---------------------------------------------*\ + | Create primary bus | + \*---------------------------------------------*/ + if(i2c_smbus_pawnio::start_pawnio("SmbusPIIX4.bin", &pawnio_handle) != S_OK) + { + return(false); + } + + /*---------------------------------------------*\ + | Select port 0 | + \*---------------------------------------------*/ + piix4_port_sel(pawnio_handle, 0); + + bus = new i2c_smbus_pawnio(pawnio_handle, "piix4"); + bus->pci_vendor = ven_id; + bus->pci_device = dev_id; + bus->pci_subsystem_vendor = sbv_id; + bus->pci_subsystem_device = sbd_id; + strncpy(bus->device_name, i["Description"].c_str(), sizeof bus->device_name); + strncat(bus->device_name, " port 0", sizeof bus->device_name); + ResourceManager::get()->RegisterI2CBus(bus); + + /*---------------------------------------------*\ + | Create secondary bus | + \*---------------------------------------------*/ + if(i2c_smbus_pawnio::start_pawnio("SmbusPIIX4.bin", &pawnio_handle) != S_OK) + { + return(false); + } + + /*---------------------------------------------*\ + | Select port 1 | + \*---------------------------------------------*/ + piix4_port_sel(pawnio_handle, 1); + + bus = new i2c_smbus_pawnio(pawnio_handle, "piix4"); + bus->pci_vendor = ven_id; + bus->pci_device = dev_id; + bus->pci_subsystem_vendor = sbv_id; + bus->pci_subsystem_device = sbd_id; + strncpy(bus->device_name, i["Description"].c_str(), sizeof bus->device_name); + strncat(bus->device_name, " port 1", sizeof bus->device_name); + ResourceManager::get()->RegisterI2CBus(bus); + } + } + + return(true); +} + +REGISTER_I2C_BUS_DETECTOR(i2c_smbus_pawnio_detect); diff --git a/i2c_smbus/Windows/i2c_smbus_pawnio.h b/i2c_smbus/Windows/i2c_smbus_pawnio.h new file mode 100644 index 000000000..1f56f5a1f --- /dev/null +++ b/i2c_smbus/Windows/i2c_smbus_pawnio.h @@ -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 +#include + +#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 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; +}; diff --git a/startup/main_Windows.cpp b/startup/main_Windows.cpp index a812a6796..91c37ecc6 100644 --- a/startup/main_Windows.cpp +++ b/startup/main_Windows.cpp @@ -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 | \*-----------------------------------------------------*/ diff --git a/super_io/super_io.cpp b/super_io/super_io.cpp index b97f389f4..65e6ae984 100644 --- a/super_io/super_io.cpp +++ b/super_io/super_io.cpp @@ -10,11 +10,9 @@ \*---------------------------------------------------------*/ #include "super_io.h" +#include "super_io_pawnio.h" -#ifdef _WIN32 -#include -#include "OlsApi.h" -#elif _MACOSX_X86_X64 +#if _MACOSX_X86_X64 #include "macUSPCIOAccess.h" #else #include @@ -34,7 +32,7 @@ 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); #else @@ -71,7 +69,7 @@ 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); #else @@ -106,7 +104,7 @@ 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); #else diff --git a/super_io/super_io.h b/super_io/super_io.h index 496735c50..b5581c931 100644 --- a/super_io/super_io.h +++ b/super_io/super_io.h @@ -9,6 +9,8 @@ | SPDX-License-Identifier: GPL-2.0-only | \*---------------------------------------------------------*/ +#pragma once + /******************************************************************************************\ * * * Nuvoton Super IO constants * diff --git a/super_io/super_io_pawnio.cpp b/super_io/super_io_pawnio.cpp new file mode 100644 index 000000000..6d4f85ddd --- /dev/null +++ b/super_io/super_io_pawnio.cpp @@ -0,0 +1,120 @@ +/*---------------------------------------------------------*\ +| 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_pawnio.h" + +#include +#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]; +} diff --git a/super_io/super_io_pawnio.h b/super_io/super_io_pawnio.h new file mode 100644 index 000000000..ac4b3b876 --- /dev/null +++ b/super_io/super_io_pawnio.h @@ -0,0 +1,18 @@ +/*---------------------------------------------------------*\ +| super_io_pawnio.h | +| | +| 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 | +\*---------------------------------------------------------*/ + +#pragma once + +void superio_enter(int ioreg); + +void superio_outb(int ioreg, int reg, int val); + +int superio_inb(int ioreg, int reg);