-
Notifications
You must be signed in to change notification settings - Fork 223
/
Copy pathkern_vsmcapi.hpp
328 lines (294 loc) · 12.4 KB
/
kern_vsmcapi.hpp
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
//
// kern_vsmcapi.hpp
// VirtualSMC
//
// Copyright © 2018 vit9696. All rights reserved.
//
#ifndef kern_vsmcapi_hpp
#define kern_vsmcapi_hpp
#include <Headers/kern_util.hpp>
#include <VirtualSMCSDK/kern_smcinfo.hpp>
#include <VirtualSMCSDK/kern_keyvalue.hpp>
#include <IOKit/IOService.h>
namespace VirtualSMCAPI {
/**
* SMC device service name. Please be aware that the same name is used for any (including physical) SMC device.
*/
static constexpr const char *ServiceName = "APP0001";
/**
* Main communication platform function interface.
* Takes plugin IOService and VirtualSMCPlugin as arguments. No modifications to struct contents are allowed once it is submitted.
* Virtual key functions may be invoked asynchronously from inside IOSimpleLock context, so they should be designed
* with the help of lock-free algorithms.
*/
static constexpr const char *SubmitPlugin = "VirtualSMCSubmitPlugin";
/**
* A total maximum of allowed plugins for installation.
*/
static constexpr size_t PluginMax = 16;
/**
* Accepted plugin API (and ABI) compatibility
*/
static constexpr size_t Version = 1;
/**
* Sorted key storage containing pairs of keys and values.
*/
using KeyStorage = evector<VirtualSMCKeyValue&, VirtualSMCKeyValue::deleter>;
/**
* Main description structure submitted by a plugin. Must be unchanged and never deallocated after submission.
*/
struct Plugin {
const char *product; // Product name (e.g. xStringify(PRODUCT_NAME))
size_t version; // Product version (e.g. parseModuleVersion(xStringify(MODULE_VERSION)))
size_t apiver; // Product API compatibility (i.e. VirtualSMCAPIVersion)
// Please note, that storage vectors MUST be sorted. Otherwise the behaviour is undefined.
KeyStorage data, dataHidden;
};
/**
* Register plugin handler for plugin loading
*
* @param handler function to handle the notification
* @param context function context
*
* @result notifier (must be released) or nullptr
*/
EXPORT IONotifier *registerHandler(IOServiceMatchingNotificationHandler handler, void *context);
/**
* Asynchronous event poster, which may be used for submitting plugin events.
* Note, this may only be used after SubmitPlugin.
*
* @param code event code to post
* @param data data to include in the interrupt
* @param dataSize size of the supplied data
*
* @return true on success
*/
EXPORT bool postInterrupt(SMC_EVENT_CODE code, const void *data=nullptr, uint32_t dataSize=0);
/**
* Obtain emulated SMC device info to determine used keys and their format.
* Note, this may only be used within SubmitPlugin or afterwards.
*
* @param info device info object to be copied to
*
* @return true on success
*/
EXPORT bool getDeviceInfo(SMCInfo &info);
/**
* Adds a key with given value to a key storage.
* Does nothing if given value is nullptr.
*
* @param key an SMC key
* @param data a key storage to add the key to
* @param val an SMC value for the given key
*
* @return true on success
*/
EXPORT bool addKey(SMC_KEY key, KeyStorage &data, VirtualSMCValue *val);
/**
* Initializes the given value with the appropriate data. Creates new value if nullptr passed as thisValue.
*
* @param smcData a pointer to SMC_DATA to be used for the value.
* @param smcDataSize a size of given SMC_DATA. Cannot be 0.
* @param smcKeyType a key type to init value with.
* @param thisValue a pointer to VirtualSMCValue. Must always be heap-based, don't use address take operator (&). If nullptr passed an instance of VirtualSMCValue will be created for you. Defaults to nullptr.
* @param smcKeyAttrs a key attributes as SMC_KEY_ATTRIBUTES flags. Defaults to SMC_KEY_ATTRIBUTE_READ.
* @param serializeLevel a serialize level needed. Defaults to SerializeLevel::None.
*
* @return thisValue either passed or created new on success, nullptr if something went wrong.
*/
EXPORT VirtualSMCValue *valueWithData(const SMC_DATA *smcData, SMC_DATA_SIZE smcDataSize, SMC_KEY_TYPE smcKeyType, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None);
/**
* Decode Apple SP signed fixed point fractional format
*
* @param type encoding type, e.g. SmcKeyTypeSp78
* @param value value as it is read from SMC_DATA field
*
* @return floating point value
*/
EXPORT double decodeSp(uint32_t type, uint16_t value);
/**
* Encode Apple SP signed fixed point fractional format
*
* @param type encoding type, e.g. SmcKeyTypeSp78
* @param value source value
*
* @return value as it is to be written to SMC_DATA field
*/
EXPORT uint16_t encodeSp(uint32_t type, double value);
/**
* Decode Apple FP unsigned fixed point fractional format
*
* @param type encoding type, e.g. SmcKeyTypeFp88
* @param value value as it is read from SMC_DATA field
*
* @return floating point value
*/
EXPORT double decodeFp(uint32_t type, uint16_t value);
/**
* Encode Apple FP unsigned fixed point fractional format
*
* @param type encoding type, e.g. SmcKeyTypeFp88
* @param value source value
*
* @return value as it is to be written to SMC_DATA field
*/
EXPORT uint16_t encodeFp(uint32_t type, double value);
/**
* Decode Apple FP signed integral number
*
* @param type encoding type, e.g. SmcKeyTypeSp78
* @param value value as it is read from SMC_DATA field
*
* @return floating point value
*/
EXPORT int16_t decodeIntSp(uint32_t type, uint16_t value);
/**
* Encode Apple FP signed integral number
*
* @param type encoding type, e.g. SmcKeyTypeSp78
* @param value source value
*
* @return value as it is to be written to SMC_DATA field
*/
EXPORT uint16_t encodeIntSp(uint32_t type, int16_t value);
/**
* Decode Apple FP unsigned integral number
*
* @param type encoding type, e.g. SmcKeyTypeFpe2
* @param value value as it is read from SMC_DATA field
*
* @return floating point value
*/
EXPORT uint16_t decodeIntFp(uint32_t type, uint16_t value);
/**
* Encode Apple FP unsigned integral number
*
* @param type encoding type, e.g. SmcKeyTypeFpe2
* @param value source value
*
* @return value as it is to be written to SMC_DATA field
*/
EXPORT uint16_t encodeIntFp(uint32_t type, uint16_t value);
/**
* Decode Apple float fractional format
*
* @param value value as it is read from SMC_DATA field
*
* @return floating point value
*/
inline float decodeFlt(uint32_t value) {
union { uint32_t u32; float f; } v {value};
return v.f;
}
/**
* Encode Apple float fractional format
*
* @param value source value
*
* @return value as it is to be written to SMC_DATA field
*/
inline uint32_t encodeFlt(float value) {
union { float f; uint32_t u32; } v {value};
return v.u32;
}
/**
* A convenient method for initializing flag type key value.
*
* @param flagValue a boolean true or false.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithFlag(bool flagValue, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
return valueWithData(reinterpret_cast<const SMC_DATA *>(&flagValue), sizeof(bool), SmcKeyTypeFlag, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing Uint8 type key value.
*
* @param uint8Value an integer of 0..255 range.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithUint8(uint8_t uint8Value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
return valueWithData(reinterpret_cast<const SMC_DATA *>(&uint8Value), sizeof(uint8_t), SmcKeyTypeUint8, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing Sint8 type key value.
*
* @param sint8Value an integer of -128..127 range.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithSint8(int8_t sint8Value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
return valueWithData(reinterpret_cast<const SMC_DATA *>(&sint8Value), sizeof(uint8_t), SmcKeyTypeSint8, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing Sint16 type key value.
*
* @param int16Value an integer of -32767..32768 range.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithSint16(int16_t int16Value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
int16_t t = OSSwapHostToBigInt16(int16Value);
return valueWithData(reinterpret_cast<const SMC_DATA *>(&t), sizeof(int16_t), SmcKeyTypeSint16, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing Uint16 type key value.
*
* @param uint16Value an integer of 0..65535 range.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithUint16(uint16_t uint16Value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
uint16_t t = OSSwapHostToBigInt16(uint16Value);
return valueWithData(reinterpret_cast<const SMC_DATA *>(&t), sizeof(uint16_t), SmcKeyTypeUint16, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing Sint32 type key value.
*
* @param int32Value an integer of –2147483648..2147483647 range.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithSint32(int32_t int32Value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
int32_t t = OSSwapHostToBigInt32(int32Value);
return valueWithData(reinterpret_cast<const SMC_DATA *>(&t), sizeof(int32_t), SmcKeyTypeSint32, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing uint32_t type key value.
*
* @param uint32Value an integer of 0..4294967295 range.
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithUint32(uint32_t uint32Value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
uint32_t t = OSSwapHostToBigInt32(uint32Value);
return valueWithData(reinterpret_cast<const SMC_DATA *>(&t), sizeof(uint32_t), SmcKeyTypeUint32, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing spXX key value
*
* @param value floating point value
* @param type Apple sp type (see encodeSp)
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithSp(double value, SMC_KEY_TYPE spType, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
auto e = encodeSp(spType, value);
return valueWithData(reinterpret_cast<SMC_DATA *>(&e), sizeof(e), spType, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing fpXX key value
*
* @param value floating point value
* @param type Apple fp type (see encodeFp)
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithFp(double value, SMC_KEY_TYPE fpType, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
auto e = encodeFp(fpType, value);
return valueWithData(reinterpret_cast<SMC_DATA *>(&e), sizeof(e), fpType, thisValue, smcKeyAttrs, serializeLevel);
}
/**
* A convenient method for initializing flt key value
*
* @param value floating point value
* @see VirtualSMCAPI::valueWithData
*/
inline VirtualSMCValue *valueWithFlt(float value, VirtualSMCValue *thisValue = nullptr, SMC_KEY_ATTRIBUTES smcKeyAttrs = SMC_KEY_ATTRIBUTE_READ, SerializeLevel serializeLevel = SerializeLevel::None) {
auto e = encodeFlt(value);
return valueWithData(reinterpret_cast<SMC_DATA *>(&e), sizeof(e), SmcKeyTypeFloat, thisValue, smcKeyAttrs, serializeLevel);
}
}
#endif /* kern_vsmcapi_hpp */