ReactOS 0.4.16-dev-2293-g4d8327b
nhlt.cpp
Go to the documentation of this file.
1#include "driver.h"
2#include "nhlt.h"
3#include <acpiioct.h>
4
5DEFINE_GUID(GUID_SST_NHLT,
6 0xA69F886E, 0x6CEB, 0x4594, 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53);
7
10 _In_ WDFDEVICE FxDevice,
11 _In_ ULONG Arg1,
12 _In_ ULONG Arg2,
13 _Out_ WDFMEMORY* outputBufferMemoryArg
14) {
15 ULONG_PTR bytesReturned;
17 WDFMEMORY inputBufferMemory = NULL;
19 PACPI_METHOD_ARGUMENT inputArgument = NULL;
20 ACPI_EVAL_OUTPUT_BUFFER outputHeader;
21 WDFMEMORY outputBufferMemory = NULL;
22 WDF_MEMORY_DESCRIPTOR inputBufferMemoryDescriptor;
23 WDF_MEMORY_DESCRIPTOR outputBufferMemoryDescriptor;
24
25 ULONG inputBufferSize =
26 (ULONG)(
32 );
33
34 status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,
37 inputBufferSize,
38 &inputBufferMemory,
39 (PVOID*)&inputBuffer);
40 if (!NT_SUCCESS(status)) {
41 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "Failed to create input buffer\n");
42 goto end;
43 }
44 RtlZeroMemory(inputBuffer, inputBufferSize);
45
48 inputBuffer->MethodName,
49 sizeof(inputBuffer->MethodName),
50 "_DSM"
51 );
52 if (!NT_SUCCESS(status)) {
53 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "Failed to write method name\n");
54 goto end;
55 }
56
57 inputBuffer->Size = inputBufferSize;
58 inputBuffer->ArgumentCount = 4;
59 inputArgument = inputBuffer->Argument;
60
61 //arg 0
63 &GUID_SST_NHLT,
64 sizeof(GUID_SST_NHLT));
65
66 inputArgument = ACPI_METHOD_NEXT_ARGUMENT(inputArgument);
67 ACPI_METHOD_SET_ARGUMENT_INTEGER(inputArgument, Arg1);
68
69 inputArgument = ACPI_METHOD_NEXT_ARGUMENT(inputArgument);
70 ACPI_METHOD_SET_ARGUMENT_INTEGER(inputArgument, Arg2);
71
72 inputArgument = ACPI_METHOD_NEXT_ARGUMENT(inputArgument);
73 RtlZeroMemory(inputArgument, sizeof(*inputArgument));
74 inputArgument->Type = ACPI_METHOD_ARGUMENT_PACKAGE_EX;
75 inputArgument->DataLength = 0;
76
77 WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputBufferMemoryDescriptor,
78 inputBufferMemory,
79 0);
80 RtlZeroMemory(&outputHeader, sizeof(outputHeader));
81 WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputBufferMemoryDescriptor,
82 &outputHeader,
83 sizeof(outputHeader));
84
85 status = WdfIoTargetSendIoctlSynchronously(WdfDeviceGetIoTarget(FxDevice),
86 NULL,
88 &inputBufferMemoryDescriptor,
89 &outputBufferMemoryDescriptor,
90 NULL,
91 &bytesReturned);
92
95 }
96 else if (!NT_SUCCESS(status)) {
97 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "Failed first ioctl\n");
98 goto end;
99 }
100
101 status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,
102 PagedPool,
104 outputHeader.Length,
105 &outputBufferMemory,
106 (PVOID*)NULL);
107 if (!NT_SUCCESS(status)) {
108 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "Failed to create output buffer\n");
109 goto end;
110 }
111
112 WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputBufferMemoryDescriptor,
113 outputBufferMemory,
114 0);
115 status = WdfIoTargetSendIoctlSynchronously(WdfDeviceGetIoTarget(FxDevice),
116 NULL,
118 &inputBufferMemoryDescriptor,
119 &outputBufferMemoryDescriptor,
120 NULL,
121 &bytesReturned);
122
123 if (!NT_SUCCESS(status)) {
124 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_INIT, "Failed to do 2nd ioctl\n");
125 goto end;
126 }
127
128end:
129 if (inputBufferMemory != NULL) {
130 WdfObjectDelete(inputBufferMemory);
131 inputBufferMemory = NULL;
132 }
133
134 if (!NT_SUCCESS(status)) {
135 if (outputBufferMemory != NULL) {
136 WdfObjectDelete(outputBufferMemory);
137 outputBufferMemory = NULL;
138 }
139 }
140 else {
141 *outputBufferMemoryArg = outputBufferMemory;
142 }
143 return status;
144}
145
147 WDFMEMORY outputBufferMemory;
148 NTSTATUS status = NHLTQuery(FxDevice, NHLTRev1, NHLTSupportQuery, &outputBufferMemory);
149 if (!NT_SUCCESS(status)) {
150 return status;
151 }
152 if (!outputBufferMemory) {
153 return STATUS_NO_MEMORY;
154 }
155
156 PACPI_EVAL_OUTPUT_BUFFER outputBuffer = (PACPI_EVAL_OUTPUT_BUFFER)WdfMemoryGetBuffer(outputBufferMemory, NULL);
157 if (outputBuffer->Count < 1) {
159 goto end;
160 }
161
162 {
163 PACPI_METHOD_ARGUMENT argument = outputBuffer->Argument;
164
165 UCHAR supportedQueries = argument->Data[0];
166
167 if ((supportedQueries & 0x3) == 0) {
169 }
170 }
171
172end:
173 if (outputBufferMemory != NULL) {
174 WdfObjectDelete(outputBufferMemory);
175 outputBufferMemory = NULL;
176 }
177 return status;
178}
179
180void parseACPI(UINT8* res, UINT32 offset, UINT32 sz, UINT64* nhltAddr, UINT64* nhltSz);
181
182NTSTATUS NHLTQueryTableAddress(_In_ WDFDEVICE FxDevice, UINT64 *nhltAddr, UINT64 *nhltSz) {
183 WDFMEMORY outputBufferMemory;
185 if (!NT_SUCCESS(status)) {
186 return status;
187 }
188 if (!outputBufferMemory) {
189 return STATUS_NO_MEMORY;
190 }
191
192 PACPI_EVAL_OUTPUT_BUFFER outputBuffer = (PACPI_EVAL_OUTPUT_BUFFER)WdfMemoryGetBuffer(outputBufferMemory, NULL);
193 if (outputBuffer->Count < 1) {
195 goto end;
196 }
197
198 {
199 PACPI_METHOD_ARGUMENT argument = outputBuffer->Argument;
200
201 UINT8* res = argument->Data;
202 UINT32 sz = argument->DataLength;
203
204 *nhltAddr = 0;
205 *nhltSz = 0;
206 parseACPI(res, 0, sz, nhltAddr, nhltSz);
207 }
208
209 if (nhltAddr == 0 || nhltSz == 0) {
211 }
212
213end:
214 if (outputBufferMemory != NULL) {
215 WdfObjectDelete(outputBufferMemory);
216 outputBufferMemory = NULL;
217 }
218 return status;
219}
220
221//Begin ACPI parser
222
223#define ACPI_RESOURCE_NAME_ADDRESS64 0x8A
224
225/*
226 * LARGE descriptors
227 */
228#define AML_RESOURCE_LARGE_HEADER_COMMON \
229 UINT8 DescriptorType;\
230 UINT16 ResourceLength;
231
232#define AML_RESOURCE_ADDRESS_COMMON \
233 UINT8 ResourceType; \
234 UINT8 Flags; \
235 UINT8 SpecificFlags;
236
237#include <pshpack1.h>
238typedef struct aml_resource_address64
239{
248#include <poppack.h>
249
250void parseACPIMemory64(UINT8* res, UINT32 offset, UINT32 sz, UINT64 *nhltAddr, UINT64 *nhltSz) {
251 if (offset + 3 > sz)
252 return;
253
254 UINT8 opcode = res[offset];
255 if (opcode != ACPI_RESOURCE_NAME_ADDRESS64)
256 return;
257
259
260 *nhltAddr = address64->Minimum;
261 *nhltSz = address64->AddressLength;
262}
263
264void parseACPI(UINT8* res, UINT32 offset, UINT32 sz, UINT64* nhltAddr, UINT64* nhltSz) {
265 if (offset + 3 > sz)
266 return;
267
268 UINT8 opcode = res[offset];
269
270 UINT16 len;
271 memcpy(&len, res + offset + 1, sizeof(UINT16));
272
273 if (opcode == ACPI_RESOURCE_NAME_ADDRESS64)
274 parseACPIMemory64(res, offset, sz, nhltAddr, nhltSz);
275
276 offset += (len + 3);
277 parseACPI(res, offset, sz, nhltAddr, nhltSz);
278}
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:80
#define ACPI_METHOD_NEXT_ARGUMENT(Argument)
Definition: acpiioct.h:159
#define ACPI_METHOD_ARGUMENT_LENGTH(DataLength)
Definition: acpiioct.h:153
#define ACPI_METHOD_SET_ARGUMENT_INTEGER(MethodArgument, IntData)
Definition: acpiioct.h:164
#define IOCTL_ACPI_EVAL_METHOD_EX
Definition: acpiioct.h:199
#define ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, BuffData, BuffLength)
Definition: acpiioct.h:174
#define ACPI_METHOD_ARGUMENT_PACKAGE_EX
Definition: acpiioct.h:34
#define ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE_V1_EX
Definition: acpiioct.h:21
ACPI_EVAL_OUTPUT_BUFFER UNALIGNED * PACPI_EVAL_OUTPUT_BUFFER
Definition: acpiioct.h:99
unsigned short UINT16
Definition: actypes.h:129
unsigned char UINT8
Definition: actypes.h:128
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define SKLHDAUDBUS_POOL_TAG
Definition: driver.h:44
#define SklHdAudBusPrint(dbglevel, fmt,...)
Definition: driver.h:111
#define PagedPool
Definition: env_spec_w32.h:308
GLuint GLuint end
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLintptr offset
Definition: glext.h:5920
GLenum GLsizei len
Definition: glext.h:6722
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define AML_RESOURCE_ADDRESS_COMMON
Definition: nhlt.cpp:232
#define ACPI_RESOURCE_NAME_ADDRESS64
Definition: nhlt.cpp:223
struct aml_resource_address64 AML_RESOURCE_ADDRESS64
void parseACPI(UINT8 *res, UINT32 offset, UINT32 sz, UINT64 *nhltAddr, UINT64 *nhltSz)
Definition: nhlt.cpp:264
#define AML_RESOURCE_LARGE_HEADER_COMMON
Definition: nhlt.cpp:228
NTSTATUS NHLTCheckSupported(_In_ WDFDEVICE FxDevice)
Definition: nhlt.cpp:146
void parseACPIMemory64(UINT8 *res, UINT32 offset, UINT32 sz, UINT64 *nhltAddr, UINT64 *nhltSz)
Definition: nhlt.cpp:250
NTSTATUS NHLTQueryTableAddress(_In_ WDFDEVICE FxDevice, UINT64 *nhltAddr, UINT64 *nhltSz)
Definition: nhlt.cpp:182
@ NHLTRev1
Definition: nhlt.h:2
NHLTQuery
Definition: nhlt.h:5
@ NHLTSupportQuery
Definition: nhlt.h:6
@ NHLTMemoryAddress
Definition: nhlt.h:7
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER
Definition: ntstatus.h:1043
#define STATUS_ACPI_NOT_INITIALIZED
Definition: ntstatus.h:1667
NTSTRSAFEVAPI RtlStringCchPrintfA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1085
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
AML_RESOURCE_LARGE_HEADER_COMMON AML_RESOURCE_ADDRESS_COMMON UINT64 Granularity
Definition: amlresrc.h:356
Definition: ps.c:97
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t UINT32
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
FORCEINLINE VOID WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(_Out_ PWDF_MEMORY_DESCRIPTOR Descriptor, _In_ PVOID Buffer, _In_ ULONG BufferLength)
Definition: wdfmemory.h:102
FORCEINLINE VOID WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(_Out_ PWDF_MEMORY_DESCRIPTOR Descriptor, _In_ WDFMEMORY Memory, _In_opt_ PWDFMEMORY_OFFSET Offsets)
Definition: wdfmemory.h:117
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
unsigned char UCHAR
Definition: xmlstorage.h:181