mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-23 23:37:48 -05:00
Replace WinRing0 with PawnIO for SMBus and Super-IO access on Windows
Commits squashed, files cleaned up, and rebased by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
committed by
Adam Honse
parent
66c9691c87
commit
977269dfe6
69
OpenRGB.pro
69
OpenRGB.pro
@@ -198,7 +198,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 \
|
||||
@@ -265,7 +264,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 \
|
||||
@@ -329,10 +327,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
|
||||
@@ -340,11 +339,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 \
|
||||
@@ -358,12 +356,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 \
|
||||
@@ -372,17 +370,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 \
|
||||
@@ -402,6 +399,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 #
|
||||
#-----------------------------------------------------------------------------------------------#
|
||||
@@ -423,10 +425,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)
|
||||
@@ -434,9 +438,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)
|
||||
|
||||
@@ -461,14 +462,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 += \
|
||||
@@ -515,7 +518,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 \
|
||||
@@ -523,6 +526,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 #
|
||||
@@ -598,6 +602,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 \
|
||||
@@ -646,6 +651,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 \
|
||||
@@ -748,6 +754,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 \
|
||||
@@ -759,20 +769,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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
BIN
dependencies/PawnIO/PawnIOLib.dll
vendored
Normal file
BIN
dependencies/PawnIO/PawnIOLib.dll
vendored
Normal file
Binary file not shown.
75
dependencies/PawnIO/PawnIOLib.h
vendored
Normal file
75
dependencies/PawnIO/PawnIOLib.h
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// PawnIOLib - Library and tooling source to be used with PawnIO.
|
||||
// Copyright (C) 2023 namazso <admin@namazso.eu>
|
||||
//
|
||||
// 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
|
||||
BIN
dependencies/PawnIO/PawnIOLib.lib
vendored
Normal file
BIN
dependencies/PawnIO/PawnIOLib.lib
vendored
Normal file
Binary file not shown.
BIN
dependencies/PawnIO/modules/LpcIO.bin
vendored
Normal file
BIN
dependencies/PawnIO/modules/LpcIO.bin
vendored
Normal file
Binary file not shown.
BIN
dependencies/PawnIO/modules/SmbusI801.bin
vendored
Normal file
BIN
dependencies/PawnIO/modules/SmbusI801.bin
vendored
Normal file
Binary file not shown.
BIN
dependencies/PawnIO/modules/SmbusPIIX4.bin
vendored
Normal file
BIN
dependencies/PawnIO/modules/SmbusPIIX4.bin
vendored
Normal file
Binary file not shown.
BIN
dependencies/winring0/Win32/WinRing0.dll
vendored
BIN
dependencies/winring0/Win32/WinRing0.dll
vendored
Binary file not shown.
BIN
dependencies/winring0/Win32/WinRing0.lib
vendored
BIN
dependencies/winring0/Win32/WinRing0.lib
vendored
Binary file not shown.
BIN
dependencies/winring0/Win32/WinRing0.sys
vendored
BIN
dependencies/winring0/Win32/WinRing0.sys
vendored
Binary file not shown.
580
dependencies/winring0/include/OlsApi.h
vendored
580
dependencies/winring0/include/OlsApi.h
vendored
@@ -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
|
||||
BIN
dependencies/winring0/x64/WinRing0x64.dll
vendored
BIN
dependencies/winring0/x64/WinRing0x64.dll
vendored
Binary file not shown.
BIN
dependencies/winring0/x64/WinRing0x64.lib
vendored
BIN
dependencies/winring0/x64/WinRing0x64.lib
vendored
Binary file not shown.
BIN
dependencies/winring0/x64/WinRing0x64.sys
vendored
BIN
dependencies/winring0/x64/WinRing0x64.sys
vendored
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;
|
||||
@@ -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
|
||||
};
|
||||
558
i2c_smbus/Windows/i2c_smbus_pawnio.cpp
Normal file
558
i2c_smbus/Windows/i2c_smbus_pawnio.cpp
Normal file
@@ -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 <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)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| 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<bool>();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| 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<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;
|
||||
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<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, 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);
|
||||
42
i2c_smbus/Windows/i2c_smbus_pawnio.h
Normal file
42
i2c_smbus/Windows/i2c_smbus_pawnio.h
Normal 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;
|
||||
};
|
||||
262
main.cpp
Normal file
262
main.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| main.cpp |
|
||||
| |
|
||||
| Entry point for the OpenRGB application |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "NetworkServer.h"
|
||||
#include "LogManager.h"
|
||||
#include "cli.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <thread>
|
||||
|
||||
#ifdef _MACOSX_X86_X64
|
||||
#include "macUSPCIOAccess.h"
|
||||
io_connect_t macUSPCIO_driver_connection;
|
||||
#endif
|
||||
|
||||
#include "OpenRGBDialog.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "macutils.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <csignal>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* InitializeTimerResolutionThreadFunction (Win32) *
|
||||
* *
|
||||
* On Windows, the default timer resolution is 15.6ms. For higher accuracy delays, *
|
||||
* the timer resolution should be set to a shorter interval. The shortest interval *
|
||||
* that can be set is 0.5ms. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
#ifdef _WIN32
|
||||
void InitializeTimerResolutionThreadFunction()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| NtSetTimerResolution function pointer type |
|
||||
\*-----------------------------------------------------*/
|
||||
typedef unsigned int NTSTATUS;
|
||||
typedef NTSTATUS (*NTSETTIMERRESOLUTION)(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION = 4, |
|
||||
| isn't defined in Win10 headers |
|
||||
\*-----------------------------------------------------*/
|
||||
PROCESS_POWER_THROTTLING_STATE PowerThrottlingState { PROCESS_POWER_THROTTLING_CURRENT_VERSION, 4, 0 };
|
||||
|
||||
ULONG CurrentResolution;
|
||||
HMODULE NtDllHandle;
|
||||
NTSETTIMERRESOLUTION NtSetTimerResolution;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Load ntdll.dll and get pointer to NtSetTimerResolution|
|
||||
\*-----------------------------------------------------*/
|
||||
NtDllHandle = LoadLibrary("ntdll.dll");
|
||||
NtSetTimerResolution = (NTSETTIMERRESOLUTION)GetProcAddress(NtDllHandle, "NtSetTimerResolution");
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Windows 11 requires |
|
||||
| PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION |
|
||||
\*-----------------------------------------------------*/
|
||||
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, &PowerThrottlingState, sizeof(PowerThrottlingState));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Call NtSetTimerResolution to set timer resolution to |
|
||||
| 0.5ms every 500ms |
|
||||
\*-----------------------------------------------------*/
|
||||
while(1)
|
||||
{
|
||||
NtSetTimerResolution(5000, TRUE, &CurrentResolution);
|
||||
|
||||
std::this_thread::sleep_for(500ms);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void WaitWhileServerOnline(NetworkServer* srv)
|
||||
{
|
||||
while (srv->GetOnline())
|
||||
{
|
||||
std::this_thread::sleep_for(1s);
|
||||
};
|
||||
}
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* Linux signal handler *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
#ifdef __linux__
|
||||
void sigHandler(int s)
|
||||
{
|
||||
std::signal(s, SIG_DFL);
|
||||
qApp->quit();
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* main *
|
||||
* *
|
||||
* Main function. Detects busses and Aura controllers, then opens the main window *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int exitval = EXIT_SUCCESS;
|
||||
#ifdef _WIN32
|
||||
/*-----------------------------------------------------*\
|
||||
| Windows only - Attach console output |
|
||||
\*-----------------------------------------------------*/
|
||||
if (AttachConsole(ATTACH_PARENT_PROCESS))
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| We are running under some terminal context; |
|
||||
| otherwise leave the GUI and CRT alone |
|
||||
\*-------------------------------------------------*/
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Windows only - Start timer resolution correction |
|
||||
| thread |
|
||||
\*-----------------------------------------------------*/
|
||||
std::thread * InitializeTimerResolutionThread;
|
||||
InitializeTimerResolutionThread = new std::thread(InitializeTimerResolutionThreadFunction);
|
||||
InitializeTimerResolutionThread->detach();
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Mac x86/x64 only - Install SMBus Driver macUSPCIO |
|
||||
\*-----------------------------------------------------*/
|
||||
#ifdef _MACOSX_X86_X64
|
||||
InitMacUSPCIODriver();
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Process command line arguments before detection |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int ret_flags = cli_pre_detection(argc, argv);
|
||||
|
||||
ResourceManager::get()->Initialize(
|
||||
!(ret_flags & RET_FLAG_NO_AUTO_CONNECT),
|
||||
!(ret_flags & RET_FLAG_NO_DETECT),
|
||||
ret_flags & RET_FLAG_START_SERVER,
|
||||
ret_flags & RET_FLAG_CLI_POST_DETECTION);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If the command line parser indicates that the GUI |
|
||||
| should run, or if there were no command line |
|
||||
| arguments, start the GUI. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(ret_flags & RET_FLAG_START_GUI)
|
||||
{
|
||||
LOG_TRACE("[main] initializing GUI");
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Enable high DPI scaling support |
|
||||
\*-------------------------------------------------*/
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Enable high DPI fractional scaling support on |
|
||||
| Windows |
|
||||
\*-------------------------------------------------*/
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && defined(Q_OS_WIN)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
|
||||
QApplication a(argc, argv);
|
||||
QGuiApplication::setDesktopFileName("org.openrgb.OpenRGB");
|
||||
LOG_TRACE("[main] QApplication created");
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Main UI widget |
|
||||
\*-------------------------------------------------*/
|
||||
OpenRGBDialog dlg;
|
||||
LOG_TRACE("[main] Dialog created");
|
||||
|
||||
if(ret_flags & RET_FLAG_I2C_TOOLS)
|
||||
{
|
||||
dlg.AddI2CToolsPage();
|
||||
}
|
||||
|
||||
if(ret_flags & RET_FLAG_START_MINIMIZED)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/*---------------------------------------------*\
|
||||
| Show the window always, even if it will |
|
||||
| immediately be hidden. On Windows, events |
|
||||
| are not delivered to nativeEventFilter (for |
|
||||
| SuspendResume) until the window has been |
|
||||
| shown once. |
|
||||
\*---------------------------------------------*/
|
||||
dlg.showMinimized();
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
MacUtils::ToggleApplicationDocklessState(false);
|
||||
#endif
|
||||
dlg.hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
dlg.show();
|
||||
}
|
||||
|
||||
LOG_TRACE("[main] Ready to exec() the dialog");
|
||||
#ifdef __linux__
|
||||
std::signal(SIGINT, sigHandler);
|
||||
std::signal(SIGTERM, sigHandler);
|
||||
#endif
|
||||
exitval = a.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| If no GUI is needed, we let the background |
|
||||
| threads run as long as they need, but we need to |
|
||||
| AT LEAST wait for initialization to finish |
|
||||
\*-------------------------------------------------*/
|
||||
ResourceManager::get()->WaitForInitialization();
|
||||
|
||||
if(ret_flags & RET_FLAG_START_SERVER)
|
||||
{
|
||||
NetworkServer* server = ResourceManager::get()->GetServer();
|
||||
|
||||
if(!server->GetOnline())
|
||||
{
|
||||
exitval = EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitWhileServerOnline(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
ResourceManager::get()->Cleanup();
|
||||
#ifdef _MACOSX_X86_X64
|
||||
CloseMacUSPCIODriver();
|
||||
#endif
|
||||
LOG_TRACE("OpenRGB finishing with exit code %d", exitval);
|
||||
return exitval;
|
||||
}
|
||||
@@ -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 |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
@@ -10,11 +10,9 @@
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "super_io.h"
|
||||
#include "super_io_pawnio.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include "OlsApi.h"
|
||||
#elif _MACOSX_X86_X64
|
||||
#if _MACOSX_X86_X64
|
||||
#include "macUSPCIOAccess.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
@@ -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
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* Nuvoton Super IO constants *
|
||||
|
||||
120
super_io/super_io_pawnio.cpp
Normal file
120
super_io/super_io_pawnio.cpp
Normal file
@@ -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 <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];
|
||||
}
|
||||
18
super_io/super_io_pawnio.h
Normal file
18
super_io/super_io_pawnio.h
Normal file
@@ -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);
|
||||
Reference in New Issue
Block a user