forked from Soberia/EmbeddedController
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathec.cpp
114 lines (101 loc) · 3.78 KB
/
ec.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* EC-Access-Tool Copyright(C) 2021, File Modified by: Shubham Paul under 'GPLv3 only'
*
* This program is free software : you can redistribute it and /or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.If not, see < https://www.gnu.org/licenses/>.
*/
//-----------------------------------------------------------------------------
// Author : Soberia
// Web : https://github.com/Soberia
// License : The modified BSD license
//
// Copyright(C) 2021
//-----------------------------------------------------------------------------
#include <map>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <windows.h>
#include "ec.hpp"
EmbeddedController::EmbeddedController(
BYTE scPort,
BYTE dataPort,
BYTE endianness,
UINT16 retry,
UINT16 timeout,
Driver::DriverType driverType
)
: scPort(scPort)
, dataPort(dataPort)
, endianness(endianness)
, retry(retry)
, timeout(timeout)
{
if (driverType == Driver::DriverType::eWinRing0) {
driver = std::make_unique<WinRing0>(L"WinRing0_1_2_0", L"WinRing0x64.sys");
} else {
driver = std::make_unique<RwDrv>(L"rwdrv", L"rwdrv.sys");
}
if (driver->initialize()) {
driverLoaded = TRUE;
}
driverFileExist = driver->driverFileExist;
}
VOID EmbeddedController::close() {
driver->deinitialize();
driverLoaded = FALSE;
}
BOOL EmbeddedController::readByte(BYTE& bRegister, BYTE& value) {
return operation(READ, bRegister, value);
}
BOOL EmbeddedController::writeByte(BYTE& bRegister, BYTE& value) {
return operation(WRITE, bRegister, value);
}
BOOL EmbeddedController::operation(BYTE mode, BYTE& bRegister, BYTE& value) {
BOOL isRead = mode == READ;
BYTE operationType = isRead ? RD_EC : WR_EC;
for (UINT16 i = 0; i < retry; i++) {
if (status(EC_IBF)) { // Wait until IBF is free
driver->writeIoPortByte(scPort, operationType); // Write operation type to the Status/Command port
if (status(EC_IBF)) { // Wait until IBF is free
driver->writeIoPortByte(dataPort, bRegister); // Write register address to the Data port
if (status(EC_IBF)) { // Wait until IBF is free
if (isRead) {
if (status(EC_OBF)) { // Wait until OBF is full
driver->readIoPortByte(dataPort, value); // Read from the Data port
return TRUE;
}
} else {
driver->writeIoPortByte(dataPort, value); // Write to the Data port
return TRUE;
}
}
}
}
}
return FALSE;
}
BOOL EmbeddedController::status(BYTE flag) {
BOOL done = flag == EC_OBF ? 0x01 : 0x00;
for (UINT16 i = 0; i < timeout; i++) {
BYTE result;
driver->readIoPortByte(scPort, result);
// First and second bit of returned value represent
// the status of OBF and IBF flags respectively
if (((done ? ~result : result) & flag) == 0) {
return TRUE;
}
}
return FALSE;
}