-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for sending hda-verbs from user-space (#614)
- Loading branch information
1 parent
09a0177
commit 61e2bbf
Showing
13 changed files
with
974 additions
and
39 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// ALCUserClient.cpp | ||
// AppleALC | ||
// | ||
// Created by Nick on 10/14/20. | ||
// Copyright © 2020 vit9696. All rights reserved. | ||
// | ||
|
||
#include <IOKit/IOLib.h> | ||
|
||
#include "ALCUserClient.hpp" | ||
|
||
OSDefineMetaClassAndStructors(ALCUserClient, IOUserClient); | ||
|
||
const IOExternalMethodDispatch ALCUserClient::sMethods[kNumberOfMethods] = { | ||
{ //kMethodExecuteVerb | ||
reinterpret_cast<IOExternalMethodAction>(&ALCUserClient::methodExecuteVerb), // Method pointer | ||
3, // Num of scalar input values | ||
0, // Num of struct input values | ||
1, // Num of scalar output values | ||
0 // Num of struct output values | ||
} | ||
}; | ||
|
||
IOReturn ALCUserClient::externalMethod(uint32_t selector, IOExternalMethodArguments* arguments, IOExternalMethodDispatch* dispatch, OSObject* target, void* reference) { | ||
if (selector >= kNumberOfMethods) | ||
return kIOReturnUnsupported; | ||
|
||
dispatch = const_cast<IOExternalMethodDispatch*>(&sMethods[selector]); | ||
|
||
target = mProvider; | ||
reference = NULL; | ||
|
||
return super::externalMethod(selector, arguments, dispatch, target, reference); | ||
} | ||
|
||
bool ALCUserClient::initWithTask(task_t owningTask, void* securityToken, UInt32 type, OSDictionary* properties) { | ||
if (!owningTask) | ||
return false; | ||
|
||
if (!super::initWithTask(owningTask, securityToken, type)) | ||
return false; | ||
|
||
mTask = owningTask; | ||
mProvider = NULL; | ||
|
||
return true; | ||
} | ||
|
||
bool ALCUserClient::start(IOService* provider) { | ||
bool success; | ||
|
||
mProvider = OSDynamicCast(ALCUserClientProvider, provider); | ||
success = (mProvider != NULL); | ||
|
||
if (success) | ||
success = super::start(provider); | ||
|
||
return success; | ||
} | ||
|
||
IOReturn ALCUserClient::clientClose() { | ||
if (!isInactive()) | ||
terminate(); | ||
|
||
return kIOReturnSuccess; | ||
} | ||
|
||
IOReturn ALCUserClient::methodExecuteVerb(ALCUserClientProvider* target, void* ref, IOExternalMethodArguments* args) { | ||
uint16_t nid, verb, params; | ||
|
||
nid = static_cast<uint16_t>(args->scalarInput[0]); | ||
verb = static_cast<uint16_t>(args->scalarInput[1]); | ||
params = static_cast<uint16_t>(args->scalarInput[2]); | ||
|
||
args->scalarOutput[0] = target->sendHdaCommand(nid, verb, params); | ||
return kIOReturnSuccess; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// | ||
// ALCUserClient.hpp | ||
// AppleALC | ||
// | ||
// Created by Nick on 10/14/20. | ||
// Copyright © 2020 vit9696. All rights reserved. | ||
// | ||
|
||
#ifndef ALCUserClient_hpp | ||
#define ALCUserClient_hpp | ||
|
||
#include <IOKit/IOService.h> | ||
#include <IOKit/IOUserClient.h> | ||
|
||
#include "../UserKernelShared.h" | ||
#include "../ALCUserClientProvider/ALCUserClientProvider.hpp" | ||
|
||
class ALCUserClient : public IOUserClient { | ||
typedef IOUserClient super; | ||
OSDeclareDefaultStructors(ALCUserClient); | ||
|
||
private: | ||
ALCUserClientProvider* mProvider { nullptr }; | ||
task_t mTask; | ||
static const IOExternalMethodDispatch sMethods[kNumberOfMethods]; | ||
|
||
public: | ||
virtual bool start(IOService* provider) override; | ||
|
||
virtual bool initWithTask(task_t owningTask, void* securityToken, | ||
UInt32 type, OSDictionary* properties) override; | ||
|
||
virtual IOReturn clientClose() override; | ||
virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments* arguments, | ||
IOExternalMethodDispatch* dispatch, OSObject* target, | ||
void* reference) override; | ||
|
||
protected: | ||
static IOReturn methodExecuteVerb(ALCUserClientProvider* target, void* ref, | ||
IOExternalMethodArguments* args); | ||
}; | ||
|
||
#endif /* ALCUserClient_hpp */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// | ||
// ALCUserClientProvider.cpp | ||
// AppleALC | ||
// | ||
// Created by Nick on 10/14/20. | ||
// Copyright © 2020 vit9696. All rights reserved. | ||
// | ||
|
||
#include "ALCUserClientProvider.hpp" | ||
|
||
OSDefineMetaClassAndStructors(ALCUserClientProvider, IOService); | ||
|
||
bool ALCUserClientProvider::start(IOService* provider) { | ||
if (!super::start(provider)) | ||
return false; | ||
|
||
auto matchingDict = IOService::nameMatching(kIOHDACodecDevice); | ||
if (!matchingDict) { | ||
DBGLOG("client", "Failed to allocate matching dictionary"); | ||
return false; | ||
} | ||
|
||
mHDACodecDevice = IOService::waitForMatchingService(matchingDict, 100000000); // Wait for 0.1s | ||
matchingDict->release(); | ||
|
||
if (!mHDACodecDevice) | ||
{ | ||
DBGLOG("client", "Timeout in waiting for IOHDACodecDevice, will retry"); | ||
return false; | ||
} | ||
|
||
// We are ready for verbs | ||
DBGLOG("client", "ALCUserClient is ready for hda-verbs"); | ||
setProperty("ReadyForALCVerbs", kOSBooleanTrue); | ||
readyForVerbs = true; | ||
|
||
// Publish the service | ||
registerService(); | ||
|
||
return true; | ||
} | ||
|
||
void ALCUserClientProvider::stop(IOService* provider) { | ||
super::stop(provider); | ||
|
||
OSSafeReleaseNULL(mHDACodecDevice); | ||
} | ||
|
||
uint64_t ALCUserClientProvider::sendHdaCommand(uint16_t nid, uint16_t verb, uint16_t param) { | ||
if (!readyForVerbs) | ||
{ | ||
DBGLOG("client", "Provider not ready to accept hda-verb commands"); | ||
return kIOReturnError; | ||
} | ||
|
||
auto sharedAlc = AlcEnabler::getShared(); | ||
|
||
if (!sharedAlc) { | ||
DBGLOG("client", "Unable to get shared AlcEnabler instance"); | ||
return kIOReturnError; | ||
} | ||
|
||
UInt ret = 0; | ||
sharedAlc->IOHDACodecDevice_executeVerb(reinterpret_cast<void*>(mHDACodecDevice), nid, verb, param, &ret, true); | ||
DBGLOG("client", "Send HDA command nid=0x%X, verb=0x%X, param=0x%X, result=0x%08x", nid, verb, param, ret); | ||
|
||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// | ||
// ALCUserClientProvider.hpp | ||
// AppleALC | ||
// | ||
// Created by Nick on 10/14/20. | ||
// Copyright © 2020 vit9696. All rights reserved. | ||
// | ||
|
||
#ifndef ALCUserClientProvider_hpp | ||
#define ALCUserClientProvider_hpp | ||
|
||
#define kIOHDACodecDevice "IOHDACodecDevice" | ||
|
||
#include<IOKit/IOService.h> | ||
#include <IOKit/IOUserClient.h> | ||
|
||
#include "../kern_alc.hpp" | ||
|
||
class ALCUserClientProvider : public IOService { | ||
typedef IOService super; | ||
OSDeclareDefaultStructors(ALCUserClientProvider); | ||
|
||
private: | ||
IOService* mHDACodecDevice { nullptr }; | ||
bool readyForVerbs { false }; | ||
|
||
public: | ||
virtual bool start(IOService* provider) override; | ||
virtual void stop(IOService* provider) override; | ||
|
||
/** | ||
* Called by user-client to set the codec verbs | ||
* | ||
* @param nid Node ID | ||
* @param verb The hda-verb command to send (as defined in hdaverb.h) | ||
* @param param The parameters for the verb | ||
* | ||
* @return kIOReturnSuccess on successful execution | ||
*/ | ||
virtual uint64_t sendHdaCommand(uint16_t nid, uint16_t verb, uint16_t param); | ||
}; | ||
|
||
#endif /* ALCUserClientProvider_hpp */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// | ||
// UserKernelShared.h | ||
// AppleALC | ||
// | ||
// Created by Nick on 10/14/20. | ||
// Copyright © 2020 vit9696. All rights reserved. | ||
// | ||
|
||
#ifndef UserKernelShared_h | ||
#define UserKernelShared_h | ||
|
||
enum { | ||
kMethodExecuteVerb, | ||
|
||
kNumberOfMethods // Must be last | ||
}; | ||
|
||
#endif /* UserKernelShared_h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.