ReactOS 0.4.16-dev-329-g9223134
exserial.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: exserial - FieldUnit support for serial address spaces
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include "acpi.h"
45#include "accommon.h"
46#include "acdispat.h"
47#include "acinterp.h"
48#include "amlcode.h"
49
50
51#define _COMPONENT ACPI_EXECUTER
52 ACPI_MODULE_NAME ("exserial")
53
54
55/*******************************************************************************
56 *
57 * FUNCTION: AcpiExReadGpio
58 *
59 * PARAMETERS: ObjDesc - The named field to read
60 * Buffer - Where the return data is returned
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Read from a named field that references a Generic Serial Bus
65 * field
66 *
67 ******************************************************************************/
68
71 ACPI_OPERAND_OBJECT *ObjDesc,
72 void *Buffer)
73{
75
76
77 ACPI_FUNCTION_TRACE_PTR (ExReadGpio, ObjDesc);
78
79
80 /*
81 * For GPIO (GeneralPurposeIo), the Address will be the bit offset
82 * from the previous Connection() operator, making it effectively a
83 * pin number index. The BitLength is the length of the field, which
84 * is thus the number of pins.
85 */
87 "GPIO FieldRead [FROM]: Pin %u Bits %u\n",
88 ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength));
89
90 /* Lock entire transaction if requested */
91
92 AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
93
94 /* Perform the read */
95
97 ObjDesc, 0, (UINT64 *) Buffer, ACPI_READ);
98
99 AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
101}
102
103
104/*******************************************************************************
105 *
106 * FUNCTION: AcpiExWriteGpio
107 *
108 * PARAMETERS: SourceDesc - Contains data to write. Expect to be
109 * an Integer object.
110 * ObjDesc - The named field
111 * ResultDesc - Where the return value is returned, if any
112 *
113 * RETURN: Status
114 *
115 * DESCRIPTION: Write to a named field that references a General Purpose I/O
116 * field.
117 *
118 ******************************************************************************/
119
122 ACPI_OPERAND_OBJECT *SourceDesc,
123 ACPI_OPERAND_OBJECT *ObjDesc,
124 ACPI_OPERAND_OBJECT **ReturnBuffer)
125{
127 void *Buffer;
128
129
130 ACPI_FUNCTION_TRACE_PTR (ExWriteGpio, ObjDesc);
131
132
133 /*
134 * For GPIO (GeneralPurposeIo), we will bypass the entire field
135 * mechanism and handoff the bit address and bit width directly to
136 * the handler. The Address will be the bit offset
137 * from the previous Connection() operator, making it effectively a
138 * pin number index. The BitLength is the length of the field, which
139 * is thus the number of pins.
140 */
141 if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER)
142 {
144 }
145
147 "GPIO FieldWrite [FROM]: (%s:%X), Value %.8X [TO]: Pin %u Bits %u\n",
148 AcpiUtGetTypeName (SourceDesc->Common.Type),
149 SourceDesc->Common.Type, (UINT32) SourceDesc->Integer.Value,
150 ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength));
151
152 Buffer = &SourceDesc->Integer.Value;
153
154 /* Lock entire transaction if requested */
155
156 AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
157
158 /* Perform the write */
159
161 ObjDesc, 0, (UINT64 *) Buffer, ACPI_WRITE);
162 AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
164}
165
166
167/*******************************************************************************
168 *
169 * FUNCTION: AcpiExReadSerialBus
170 *
171 * PARAMETERS: ObjDesc - The named field to read
172 * ReturnBuffer - Where the return value is returned, if any
173 *
174 * RETURN: Status
175 *
176 * DESCRIPTION: Read from a named field that references a serial bus
177 * (SMBus, IPMI, or GSBus).
178 *
179 ******************************************************************************/
180
183 ACPI_OPERAND_OBJECT *ObjDesc,
184 ACPI_OPERAND_OBJECT **ReturnBuffer)
185{
188 ACPI_OPERAND_OBJECT *BufferDesc;
190 UINT16 AccessorType;
191
192
193 ACPI_FUNCTION_TRACE_PTR (ExReadSerialBus, ObjDesc);
194
195
196 /*
197 * This is an SMBus, GSBus or IPMI read. We must create a buffer to
198 * hold the data and then directly access the region handler.
199 *
200 * Note: SMBus and GSBus protocol value is passed in upper 16-bits
201 * of Function
202 *
203 * Common buffer format:
204 * Status; (Byte 0 of the data buffer)
205 * Length; (Byte 1 of the data buffer)
206 * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer)
207 */
208 switch (ObjDesc->Field.RegionObj->Region.SpaceId)
209 {
211
213 Function = ACPI_READ | (ObjDesc->Field.Attribute << 16);
214 break;
215
217
220 break;
221
223
224 AccessorType = ObjDesc->Field.Attribute;
225 if (AccessorType == AML_FIELD_ATTRIB_RAW_PROCESS_BYTES)
226 {
228 "Invalid direct read using bidirectional write-then-read protocol"));
229
231 }
232
234 if (ACPI_FAILURE (Status))
235 {
237 "Invalid protocol ID for GSBus: 0x%4.4X", AccessorType));
238
240 }
241
242 /* Add header length to get the full size of the buffer */
243
245 Function = ACPI_READ | (AccessorType << 16);
246 break;
247
249
252 break;
253
254 default:
256 }
257
258 /* Create the local transfer buffer that is returned to the caller */
259
261 if (!BufferDesc)
262 {
264 }
265
266 /* Lock entire transaction if requested */
267
268 AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
269
270 /* Call the region handler for the write-then-read */
271
272 Status = AcpiExAccessRegion (ObjDesc, 0,
273 ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer), Function);
274 AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
275
276 *ReturnBuffer = BufferDesc;
278}
279
280
281/*******************************************************************************
282 *
283 * FUNCTION: AcpiExWriteSerialBus
284 *
285 * PARAMETERS: SourceDesc - Contains data to write
286 * ObjDesc - The named field
287 * ReturnBuffer - Where the return value is returned, if any
288 *
289 * RETURN: Status
290 *
291 * DESCRIPTION: Write to a named field that references a serial bus
292 * (SMBus, IPMI, GSBus).
293 *
294 ******************************************************************************/
295
298 ACPI_OPERAND_OBJECT *SourceDesc,
299 ACPI_OPERAND_OBJECT *ObjDesc,
300 ACPI_OPERAND_OBJECT **ReturnBuffer)
301{
305 void *Buffer;
306 ACPI_OPERAND_OBJECT *BufferDesc;
308 UINT16 AccessorType;
309
310
311 ACPI_FUNCTION_TRACE_PTR (ExWriteSerialBus, ObjDesc);
312
313
314 /*
315 * This is an SMBus, GSBus or IPMI write. We will bypass the entire
316 * field mechanism and handoff the buffer directly to the handler.
317 * For these address spaces, the buffer is bidirectional; on a
318 * write, return data is returned in the same buffer.
319 *
320 * Source must be a buffer of sufficient size, these are fixed size:
321 * ACPI_SMBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE.
322 *
323 * Note: SMBus and GSBus protocol type is passed in upper 16-bits
324 * of Function
325 *
326 * Common buffer format:
327 * Status; (Byte 0 of the data buffer)
328 * Length; (Byte 1 of the data buffer)
329 * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer)
330 */
331 if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER)
332 {
334 "SMBus/IPMI/GenericSerialBus write requires "
335 "Buffer, found type %s",
336 AcpiUtGetObjectTypeName (SourceDesc)));
337
339 }
340
341 switch (ObjDesc->Field.RegionObj->Region.SpaceId)
342 {
344
346 Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16);
347 break;
348
350
353 break;
354
356
357 AccessorType = ObjDesc->Field.Attribute;
359 if (ACPI_FAILURE (Status))
360 {
362 "Invalid protocol ID for GSBus: 0x%4.4X", AccessorType));
363
365 }
366
367 /* Add header length to get the full size of the buffer */
368
370 Function = ACPI_WRITE | (AccessorType << 16);
371 break;
372
374
377 break;
378
380
383 break;
384
385 default:
387 }
388
389 /* Create the transfer/bidirectional/return buffer */
390
392 if (!BufferDesc)
393 {
395 }
396
397 /* Copy the input buffer data to the transfer buffer */
398
399 Buffer = BufferDesc->Buffer.Pointer;
400 DataLength = (BufferLength < SourceDesc->Buffer.Length ?
401 BufferLength : SourceDesc->Buffer.Length);
402 memcpy (Buffer, SourceDesc->Buffer.Pointer, DataLength);
403
404 /* Lock entire transaction if requested */
405
406 AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
407
408 /*
409 * Perform the write (returns status and perhaps data in the
410 * same buffer)
411 */
413 ObjDesc, 0, (UINT64 *) Buffer, Function);
414 AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
415
416 *ReturnBuffer = BufferDesc;
418}
unsigned short UINT16
unsigned long long UINT64
unsigned int UINT32
#define AE_AML_PROTOCOL
Definition: acexcep.h:215
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_AML_INVALID_SPACE_ID
Definition: acexcep.h:195
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_DB_BFIELD
Definition: acoutput.h:168
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_ADR_SPACE_IPMI
Definition: actypes.h:868
#define ACPI_ADR_SPACE_PLATFORM_RT
Definition: actypes.h:872
#define ACPI_READ
Definition: actypes.h:751
#define ACPI_TYPE_BUFFER
Definition: actypes.h:690
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_ADR_SPACE_GSBUS
Definition: actypes.h:870
#define ACPI_ADR_SPACE_SMBUS
Definition: actypes.h:865
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define ACPI_ADR_SPACE_FIXED_HARDWARE
Definition: actypes.h:885
#define ACPI_WRITE
Definition: actypes.h:752
const char * AcpiUtGetTypeName(ACPI_OBJECT_TYPE Type)
Definition: utdecode.c:250
const char * AcpiUtGetObjectTypeName(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: utdecode.c:264
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject(ACPI_SIZE BufferSize)
Definition: utobject.c:258
@ AML_FIELD_ATTRIB_RAW_PROCESS_BYTES
Definition: amlcode.h:498
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
Definition: bufpool.h:45
#define ACPI_IPMI_BUFFER_SIZE
Definition: acconfig.h:223
#define ACPI_FFH_INPUT_BUFFER_SIZE
Definition: acconfig.h:230
#define ACPI_SMBUS_BUFFER_SIZE
Definition: acconfig.h:220
#define ACPI_SERIAL_HEADER_SIZE
Definition: acconfig.h:217
#define ACPI_PRM_INPUT_BUFFER_SIZE
Definition: acconfig.h:228
ACPI_STATUS AcpiExGetProtocolBufferLength(UINT32 ProtocolId, UINT32 *ReturnLength)
Definition: exfield.c:111
ACPI_STATUS AcpiExAccessRegion(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 Function)
Definition: exfldio.c:249
ACPI_STATUS AcpiExWriteGpio(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnBuffer)
Definition: exserial.c:121
ACPI_STATUS AcpiExReadSerialBus(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnBuffer)
Definition: exserial.c:182
ACPI_STATUS AcpiExReadGpio(ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer)
Definition: exserial.c:70
ACPI_STATUS AcpiExWriteSerialBus(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnBuffer)
Definition: exserial.c:297
void AcpiExAcquireGlobalLock(UINT32 FieldFlags)
Definition: exutils.c:225
void AcpiExReleaseGlobalLock(UINT32 FieldFlags)
Definition: exutils.c:270
Status
Definition: gdiplustypes.h:25
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
union acpi_operand_object * RegionObj
Definition: acobject.h:346
ACPI_OBJECT_COMMON_HEADER UINT8 SpaceId
Definition: acobject.h:202
ACPI_OBJECT_REGION_FIELD Field
Definition: acobject.h:534
ACPI_OBJECT_REGION Region
Definition: acobject.h:527
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:520
ACPI_OBJECT_COMMON Common
Definition: acobject.h:519
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:533
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:522
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771