ReactOS  0.4.14-dev-323-g6fe6a88
exregion.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: exregion - ACPI default OpRegion (address space) handlers
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2019, 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 MERCHANTIBILITY 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 "acinterp.h"
47 
48 
49 #define _COMPONENT ACPI_EXECUTER
50  ACPI_MODULE_NAME ("exregion")
51 
52 
53 /*******************************************************************************
54  *
55  * FUNCTION: AcpiExSystemMemorySpaceHandler
56  *
57  * PARAMETERS: Function - Read or Write operation
58  * Address - Where in the space to read or write
59  * BitWidth - Field width in bits (8, 16, or 32)
60  * Value - Pointer to in or out value
61  * HandlerContext - Pointer to Handler's context
62  * RegionContext - Pointer to context specific to the
63  * accessed region
64  *
65  * RETURN: Status
66  *
67  * DESCRIPTION: Handler for the System Memory address space (Op Region)
68  *
69  ******************************************************************************/
70 
74  ACPI_PHYSICAL_ADDRESS Address,
75  UINT32 BitWidth,
76  UINT64 *Value,
77  void *HandlerContext,
78  void *RegionContext)
79 {
81  void *LogicalAddrPtr = NULL;
82  ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext;
83  UINT32 Length;
84  ACPI_SIZE MapLength;
85  ACPI_SIZE PageBoundaryMapLength;
86 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
88 #endif
89 
90 
91  ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
92 
93 
94  /* Validate and translate the bit width */
95 
96  switch (BitWidth)
97  {
98  case 8:
99 
100  Length = 1;
101  break;
102 
103  case 16:
104 
105  Length = 2;
106  break;
107 
108  case 32:
109 
110  Length = 4;
111  break;
112 
113  case 64:
114 
115  Length = 8;
116  break;
117 
118  default:
119 
120  ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
121  BitWidth));
123  }
124 
125 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
126  /*
127  * Hardware does not support non-aligned data transfers, we must verify
128  * the request.
129  */
131  if (Remainder != 0)
132  {
134  }
135 #endif
136 
137  /*
138  * Does the request fit into the cached memory mapping?
139  * Is 1) Address below the current mapping? OR
140  * 2) Address beyond the current mapping?
141  */
142  if ((Address < MemInfo->MappedPhysicalAddress) ||
143  (((UINT64) Address + Length) >
144  ((UINT64)
145  MemInfo->MappedPhysicalAddress + MemInfo->MappedLength)))
146  {
147  /*
148  * The request cannot be resolved by the current memory mapping;
149  * Delete the existing mapping and create a new one.
150  */
151  if (MemInfo->MappedLength)
152  {
153  /* Valid mapping, delete it */
154 
156  MemInfo->MappedLength);
157  }
158 
159  /*
160  * October 2009: Attempt to map from the requested address to the
161  * end of the region. However, we will never map more than one
162  * page, nor will we cross a page boundary.
163  */
164  MapLength = (ACPI_SIZE)
165  ((MemInfo->Address + MemInfo->Length) - Address);
166 
167  /*
168  * If mapping the entire remaining portion of the region will cross
169  * a page boundary, just map up to the page boundary, do not cross.
170  * On some systems, crossing a page boundary while mapping regions
171  * can cause warnings if the pages have different attributes
172  * due to resource management.
173  *
174  * This has the added benefit of constraining a single mapping to
175  * one page, which is similar to the original code that used a 4k
176  * maximum window.
177  */
178  PageBoundaryMapLength = (ACPI_SIZE)
180  if (PageBoundaryMapLength == 0)
181  {
182  PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE;
183  }
184 
185  if (MapLength > PageBoundaryMapLength)
186  {
187  MapLength = PageBoundaryMapLength;
188  }
189 
190  /* Create a new mapping starting at the address given */
191 
192  MemInfo->MappedLogicalAddress = AcpiOsMapMemory (Address, MapLength);
193  if (!MemInfo->MappedLogicalAddress)
194  {
196  "Could not map memory at 0x%8.8X%8.8X, size %u",
197  ACPI_FORMAT_UINT64 (Address), (UINT32) MapLength));
198  MemInfo->MappedLength = 0;
200  }
201 
202  /* Save the physical address and mapping size */
203 
204  MemInfo->MappedPhysicalAddress = Address;
205  MemInfo->MappedLength = MapLength;
206  }
207 
208  /*
209  * Generate a logical pointer corresponding to the address we want to
210  * access
211  */
212  LogicalAddrPtr = MemInfo->MappedLogicalAddress +
213  ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress);
214 
216  "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
217  BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
218 
219  /*
220  * Perform the memory read or write
221  *
222  * Note: For machines that do not support non-aligned transfers, the target
223  * address was checked for alignment above. We do not attempt to break the
224  * transfer up into smaller (byte-size) chunks because the AML specifically
225  * asked for a transfer width that the hardware may require.
226  */
227  switch (Function)
228  {
229  case ACPI_READ:
230 
231  *Value = 0;
232  switch (BitWidth)
233  {
234  case 8:
235 
236  *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
237  break;
238 
239  case 16:
240 
241  *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
242  break;
243 
244  case 32:
245 
246  *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
247  break;
248 
249  case 64:
250 
251  *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
252  break;
253 
254  default:
255 
256  /* BitWidth was already validated */
257 
258  break;
259  }
260  break;
261 
262  case ACPI_WRITE:
263 
264  switch (BitWidth)
265  {
266  case 8:
267 
268  ACPI_SET8 (LogicalAddrPtr, *Value);
269  break;
270 
271  case 16:
272 
273  ACPI_SET16 (LogicalAddrPtr, *Value);
274  break;
275 
276  case 32:
277 
278  ACPI_SET32 (LogicalAddrPtr, *Value);
279  break;
280 
281  case 64:
282 
283  ACPI_SET64 (LogicalAddrPtr, *Value);
284  break;
285 
286  default:
287 
288  /* BitWidth was already validated */
289 
290  break;
291  }
292  break;
293 
294  default:
295 
297  break;
298  }
299 
301 }
302 
303 
304 /*******************************************************************************
305  *
306  * FUNCTION: AcpiExSystemIoSpaceHandler
307  *
308  * PARAMETERS: Function - Read or Write operation
309  * Address - Where in the space to read or write
310  * BitWidth - Field width in bits (8, 16, or 32)
311  * Value - Pointer to in or out value
312  * HandlerContext - Pointer to Handler's context
313  * RegionContext - Pointer to context specific to the
314  * accessed region
315  *
316  * RETURN: Status
317  *
318  * DESCRIPTION: Handler for the System IO address space (Op Region)
319  *
320  ******************************************************************************/
321 
325  ACPI_PHYSICAL_ADDRESS Address,
326  UINT32 BitWidth,
327  UINT64 *Value,
328  void *HandlerContext,
329  void *RegionContext)
330 {
332  UINT32 Value32;
333 
334 
335  ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
336 
337 
339  "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
340  BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
341 
342  /* Decode the function parameter */
343 
344  switch (Function)
345  {
346  case ACPI_READ:
347 
348  Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
349  &Value32, BitWidth);
350  *Value = Value32;
351  break;
352 
353  case ACPI_WRITE:
354 
355  Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
356  (UINT32) *Value, BitWidth);
357  break;
358 
359  default:
360 
362  break;
363  }
364 
366 }
367 
368 
369 /*******************************************************************************
370  *
371  * FUNCTION: AcpiExPciConfigSpaceHandler
372  *
373  * PARAMETERS: Function - Read or Write operation
374  * Address - Where in the space to read or write
375  * BitWidth - Field width in bits (8, 16, or 32)
376  * Value - Pointer to in or out value
377  * HandlerContext - Pointer to Handler's context
378  * RegionContext - Pointer to context specific to the
379  * accessed region
380  *
381  * RETURN: Status
382  *
383  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
384  *
385  ******************************************************************************/
386 
390  ACPI_PHYSICAL_ADDRESS Address,
391  UINT32 BitWidth,
392  UINT64 *Value,
393  void *HandlerContext,
394  void *RegionContext)
395 {
397  ACPI_PCI_ID *PciId;
398  UINT16 PciRegister;
399 
400 
401  ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
402 
403 
404  /*
405  * The arguments to AcpiOs(Read|Write)PciConfiguration are:
406  *
407  * PciSegment is the PCI bus segment range 0-31
408  * PciBus is the PCI bus number range 0-255
409  * PciDevice is the PCI device number range 0-31
410  * PciFunction is the PCI device function number
411  * PciRegister is the Config space register range 0-255 bytes
412  *
413  * Value - input value for write, output address for read
414  *
415  */
416  PciId = (ACPI_PCI_ID *) RegionContext;
417  PciRegister = (UINT16) (UINT32) Address;
418 
420  "Pci-Config %u (%u) Seg(%04x) Bus(%04x) "
421  "Dev(%04x) Func(%04x) Reg(%04x)\n",
422  Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
423  PciId->Function, PciRegister));
424 
425  switch (Function)
426  {
427  case ACPI_READ:
428 
429  *Value = 0;
431  PciId, PciRegister, Value, BitWidth);
432  break;
433 
434  case ACPI_WRITE:
435 
437  PciId, PciRegister, *Value, BitWidth);
438  break;
439 
440  default:
441 
443  break;
444  }
445 
447 }
448 
449 
450 /*******************************************************************************
451  *
452  * FUNCTION: AcpiExCmosSpaceHandler
453  *
454  * PARAMETERS: Function - Read or Write operation
455  * Address - Where in the space to read or write
456  * BitWidth - Field width in bits (8, 16, or 32)
457  * Value - Pointer to in or out value
458  * HandlerContext - Pointer to Handler's context
459  * RegionContext - Pointer to context specific to the
460  * accessed region
461  *
462  * RETURN: Status
463  *
464  * DESCRIPTION: Handler for the CMOS address space (Op Region)
465  *
466  ******************************************************************************/
467 
471  ACPI_PHYSICAL_ADDRESS Address,
472  UINT32 BitWidth,
473  UINT64 *Value,
474  void *HandlerContext,
475  void *RegionContext)
476 {
478 
479 
480  ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
481 
482 
484 }
485 
486 
487 /*******************************************************************************
488  *
489  * FUNCTION: AcpiExPciBarSpaceHandler
490  *
491  * PARAMETERS: Function - Read or Write operation
492  * Address - Where in the space to read or write
493  * BitWidth - Field width in bits (8, 16, or 32)
494  * Value - Pointer to in or out value
495  * HandlerContext - Pointer to Handler's context
496  * RegionContext - Pointer to context specific to the
497  * accessed region
498  *
499  * RETURN: Status
500  *
501  * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
502  *
503  ******************************************************************************/
504 
508  ACPI_PHYSICAL_ADDRESS Address,
509  UINT32 BitWidth,
510  UINT64 *Value,
511  void *HandlerContext,
512  void *RegionContext)
513 {
515 
516 
517  ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
518 
519 
521 }
522 
523 
524 /*******************************************************************************
525  *
526  * FUNCTION: AcpiExDataTableSpaceHandler
527  *
528  * PARAMETERS: Function - Read or Write operation
529  * Address - Where in the space to read or write
530  * BitWidth - Field width in bits (8, 16, or 32)
531  * Value - Pointer to in or out value
532  * HandlerContext - Pointer to Handler's context
533  * RegionContext - Pointer to context specific to the
534  * accessed region
535  *
536  * RETURN: Status
537  *
538  * DESCRIPTION: Handler for the Data Table address space (Op Region)
539  *
540  ******************************************************************************/
541 
545  ACPI_PHYSICAL_ADDRESS Address,
546  UINT32 BitWidth,
547  UINT64 *Value,
548  void *HandlerContext,
549  void *RegionContext)
550 {
551  ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
552 
553 
554  /*
555  * Perform the memory read or write. The BitWidth was already
556  * validated.
557  */
558  switch (Function)
559  {
560  case ACPI_READ:
561 
563  ACPI_DIV_8 (BitWidth));
564  break;
565 
566  case ACPI_WRITE:
567 
569  ACPI_DIV_8 (BitWidth));
570  break;
571 
572  default:
573 
575  }
576 
578 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Reg, UINT64 *Value, UINT32 Width)
Definition: osl.c:793
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ACPI_READ
Definition: actypes.h:742
#define ACPI_GET16(ptr)
Definition: acmacros.h:58
ACPI_STATUS AcpiExDataTableSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:543
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
void * AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
Definition: osl.c:108
#define AE_AML_OPERAND_VALUE
Definition: acexcep.h:183
UINT16 Bus
Definition: actypes.h:1327
UINT16 Device
Definition: actypes.h:1328
#define ACPI_GET8(ptr)
Definition: acmacros.h:57
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiHwReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
Definition: hwvalid.c:237
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
unsigned int UINT32
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
ACPI_STATUS AcpiHwWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
Definition: hwvalid.c:312
#define AE_INFO
Definition: acoutput.h:230
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
ACPI_SIZE MappedLength
Definition: actypes.h:1339
#define ACPI_DEFAULT_PAGE_SIZE
Definition: acconfig.h:132
ACPI_STATUS AcpiUtShortDivide(UINT64 InDividend, UINT32 Divisor, UINT64 *OutQuotient, UINT32 *OutRemainder)
Definition: utmath.c:337
UINT16 Segment
Definition: actypes.h:1326
#define ACPI_ROUND_UP(value, boundary)
Definition: acmacros.h:242
#define ACPI_PHYSADDR_TO_PTR(i)
Definition: actypes.h:555
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
ACPI_PHYSICAL_ADDRESS Address
Definition: actypes.h:1336
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ACPI_STATUS AcpiExCmosSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:469
#define ACPI_SET32(ptr, val)
Definition: acmacros.h:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ACPI_SET8(ptr, val)
Definition: acmacros.h:61
#define ACPI_DIV_8(a)
Definition: acmacros.h:214
ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Reg, UINT64 Value, UINT32 Width)
Definition: osl.c:822
Status
Definition: gdiplustypes.h:24
#define ACPI_DB_INFO
Definition: acoutput.h:153
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_SET64(ptr, val)
Definition: acmacros.h:64
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_GET32(ptr)
Definition: acmacros.h:59
unsigned short UINT16
ACPI_STATUS AcpiExPciConfigSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:388
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_AML_ALIGNMENT
Definition: acexcep.h:206
ACPI_PHYSICAL_ADDRESS MappedPhysicalAddress
Definition: actypes.h:1337
UINT8 * MappedLogicalAddress
Definition: actypes.h:1338
UINT16 Function
Definition: actypes.h:1329
#define ACPI_GET64(ptr)
Definition: acmacros.h:60
unsigned long long UINT64
#define ACPI_SET16(ptr, val)
Definition: acmacros.h:62
ACPI_STATUS AcpiExSystemIoSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:323
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
ACPI_STATUS AcpiExSystemMemorySpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:72
#define AE_OK
Definition: acexcep.h:97
ACPI_STATUS AcpiExPciBarSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:506
void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size)
Definition: osl.c:128
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046
#define ACPI_WRITE
Definition: actypes.h:743