ReactOS  0.4.15-dev-3203-gacde1e0
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 - 2021, 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 
216  case ACPI_ADR_SPACE_IPMI:
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 
260  BufferDesc = AcpiUtCreateBufferObject (BufferLength);
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 
349  case ACPI_ADR_SPACE_IPMI:
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 
379  default:
381  }
382 
383  /* Create the transfer/bidirectional/return buffer */
384 
385  BufferDesc = AcpiUtCreateBufferObject (BufferLength);
386  if (!BufferDesc)
387  {
389  }
390 
391  /* Copy the input buffer data to the transfer buffer */
392 
393  Buffer = BufferDesc->Buffer.Pointer;
394  DataLength = (BufferLength < SourceDesc->Buffer.Length ?
395  BufferLength : SourceDesc->Buffer.Length);
396  memcpy (Buffer, SourceDesc->Buffer.Pointer, DataLength);
397 
398  /* Lock entire transaction if requested */
399 
400  AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
401 
402  /*
403  * Perform the write (returns status and perhaps data in the
404  * same buffer)
405  */
407  ObjDesc, 0, (UINT64 *) Buffer, Function);
408  AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags);
409 
410  *ReturnBuffer = BufferDesc;
412 }
#define ACPI_DB_BFIELD
Definition: acoutput.h:168
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
void AcpiExReleaseGlobalLock(UINT32 FieldFlags)
Definition: exutils.c:270
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
#define ACPI_READ
Definition: actypes.h:743
#define AE_NO_MEMORY
Definition: acexcep.h:112
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define ACPI_TYPE_BUFFER
Definition: actypes.h:682
#define ACPI_TYPE_INTEGER
Definition: actypes.h:680
#define ACPI_SERIAL_HEADER_SIZE
Definition: acconfig.h:217
ACPI_OBJECT_FIELD_COMMON CommonField
Definition: acobject.h:532
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject(ACPI_SIZE BufferSize)
Definition: utobject.c:258
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiExWriteGpio(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnBuffer)
Definition: exserial.c:121
ACPI_OBJECT_COMMON_HEADER UINT8 SpaceId
Definition: acobject.h:202
ACPI_STATUS AcpiExReadSerialBus(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnBuffer)
Definition: exserial.c:182
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
unsigned int UINT32
#define AE_AML_INVALID_SPACE_ID
Definition: acexcep.h:195
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define AE_INFO
Definition: acoutput.h:230
void AcpiExAcquireGlobalLock(UINT32 FieldFlags)
Definition: exutils.c:225
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
Definition: bufpool.h:45
#define ACPI_PRM_INPUT_BUFFER_SIZE
Definition: acconfig.h:228
ACPI_OBJECT_REGION Region
Definition: acobject.h:526
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
Status
Definition: gdiplustypes.h:24
ACPI_STATUS AcpiExWriteSerialBus(ACPI_OPERAND_OBJECT *SourceDesc, ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ReturnBuffer)
Definition: exserial.c:297
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:521
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_ADR_SPACE_IPMI
Definition: actypes.h:859
#define ACPI_ADR_SPACE_GSBUS
Definition: actypes.h:861
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:519
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
union acpi_operand_object * RegionObj
Definition: acobject.h:345
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
ACPI_OBJECT_COMMON Common
Definition: acobject.h:518
unsigned short UINT16
const char * AcpiUtGetTypeName(ACPI_OBJECT_TYPE Type)
Definition: utdecode.c:250
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
ACPI_STATUS AcpiExGetProtocolBufferLength(UINT32 ProtocolId, UINT32 *ReturnLength)
Definition: exfield.c:111
ACPI_STATUS AcpiExReadGpio(ACPI_OPERAND_OBJECT *ObjDesc, void *Buffer)
Definition: exserial.c:70
#define ACPI_ADR_SPACE_PLATFORM_RT
Definition: actypes.h:863
ACPI_OBJECT_REGION_FIELD Field
Definition: acobject.h:533
#define ACPI_ADR_SPACE_SMBUS
Definition: actypes.h:856
#define ACPI_SMBUS_BUFFER_SIZE
Definition: acconfig.h:220
unsigned long long UINT64
ACPI_STATUS AcpiExAccessRegion(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 FieldDatumByteOffset, UINT64 *Value, UINT32 Function)
Definition: exfldio.c:249
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
const char * AcpiUtGetObjectTypeName(ACPI_OPERAND_OBJECT *ObjDesc)
Definition: utdecode.c:264
#define AE_AML_PROTOCOL
Definition: acexcep.h:215
#define ACPI_IPMI_BUFFER_SIZE
Definition: acconfig.h:223
#define ACPI_WRITE
Definition: actypes.h:744