ReactOS  0.4.15-dev-1203-g0e5a4d5
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 - 2020, 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  ACPI_MEM_MAPPING *Mm = MemInfo->CurMm;
84  UINT32 Length;
85  ACPI_SIZE MapLength;
86  ACPI_SIZE PageBoundaryMapLength;
87 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
89 #endif
90 
91 
92  ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
93 
94 
95  /* Validate and translate the bit width */
96 
97  switch (BitWidth)
98  {
99  case 8:
100 
101  Length = 1;
102  break;
103 
104  case 16:
105 
106  Length = 2;
107  break;
108 
109  case 32:
110 
111  Length = 4;
112  break;
113 
114  case 64:
115 
116  Length = 8;
117  break;
118 
119  default:
120 
121  ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
122  BitWidth));
124  }
125 
126 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
127  /*
128  * Hardware does not support non-aligned data transfers, we must verify
129  * the request.
130  */
132  if (Remainder != 0)
133  {
135  }
136 #endif
137 
138  /*
139  * Does the request fit into the cached memory mapping?
140  * Is 1) Address below the current mapping? OR
141  * 2) Address beyond the current mapping?
142  */
143  if (!Mm || (Address < Mm->PhysicalAddress) ||
144  ((UINT64) Address + Length > (UINT64) Mm->PhysicalAddress + Mm->Length))
145  {
146  /*
147  * The request cannot be resolved by the current memory mapping.
148  *
149  * Look for an existing saved mapping covering the address range
150  * at hand. If found, save it as the current one and carry out
151  * the access.
152  */
153  for (Mm = MemInfo->FirstMm; Mm; Mm = Mm->NextMm)
154  {
155  if (Mm == MemInfo->CurMm)
156  {
157  continue;
158  }
159 
160  if (Address < Mm->PhysicalAddress)
161  {
162  continue;
163  }
164 
165  if ((UINT64) Address + Length > (UINT64) Mm->PhysicalAddress + Mm->Length)
166  {
167  continue;
168  }
169 
170  MemInfo->CurMm = Mm;
171  goto access;
172  }
173 
174  /* Create a new mappings list entry */
175 
176  Mm = ACPI_ALLOCATE_ZEROED(sizeof(*Mm));
177  if (!Mm)
178  {
180  "Unable to save memory mapping at 0x%8.8X%8.8X, size %u",
183  }
184 
185  /*
186  * October 2009: Attempt to map from the requested address to the
187  * end of the region. However, we will never map more than one
188  * page, nor will we cross a page boundary.
189  */
190  MapLength = (ACPI_SIZE)
191  ((MemInfo->Address + MemInfo->Length) - Address);
192 
193  /*
194  * If mapping the entire remaining portion of the region will cross
195  * a page boundary, just map up to the page boundary, do not cross.
196  * On some systems, crossing a page boundary while mapping regions
197  * can cause warnings if the pages have different attributes
198  * due to resource management.
199  *
200  * This has the added benefit of constraining a single mapping to
201  * one page, which is similar to the original code that used a 4k
202  * maximum window.
203  */
204  PageBoundaryMapLength = (ACPI_SIZE)
206  if (PageBoundaryMapLength == 0)
207  {
208  PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE;
209  }
210 
211  if (MapLength > PageBoundaryMapLength)
212  {
213  MapLength = PageBoundaryMapLength;
214  }
215 
216  /* Create a new mapping starting at the address given */
217 
218  LogicalAddrPtr = AcpiOsMapMemory(Address, MapLength);
219  if (!LogicalAddrPtr)
220  {
222  "Could not map memory at 0x%8.8X%8.8X, size %u",
223  ACPI_FORMAT_UINT64 (Address), (UINT32) MapLength));
224  ACPI_FREE(Mm);
226  }
227 
228  /* Save the physical address and mapping size */
229 
230  Mm->LogicalAddress = LogicalAddrPtr;
231  Mm->PhysicalAddress = Address;
232  Mm->Length = MapLength;
233 
234  /*
235  * Add the new entry to the mappigs list and save it as the
236  * current mapping.
237  */
238  Mm->NextMm = MemInfo->FirstMm;
239  MemInfo->FirstMm = Mm;
240  MemInfo->CurMm = Mm;
241  }
242 
243 access:
244  /*
245  * Generate a logical pointer corresponding to the address we want to
246  * access
247  */
248  LogicalAddrPtr = Mm->LogicalAddress +
249  ((UINT64) Address - (UINT64) Mm->PhysicalAddress);
250 
252  "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
253  BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
254 
255  /*
256  * Perform the memory read or write
257  *
258  * Note: For machines that do not support non-aligned transfers, the target
259  * address was checked for alignment above. We do not attempt to break the
260  * transfer up into smaller (byte-size) chunks because the AML specifically
261  * asked for a transfer width that the hardware may require.
262  */
263  switch (Function)
264  {
265  case ACPI_READ:
266 
267  *Value = 0;
268  switch (BitWidth)
269  {
270  case 8:
271 
272  *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
273  break;
274 
275  case 16:
276 
277  *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
278  break;
279 
280  case 32:
281 
282  *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
283  break;
284 
285  case 64:
286 
287  *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
288  break;
289 
290  default:
291 
292  /* BitWidth was already validated */
293 
294  break;
295  }
296  break;
297 
298  case ACPI_WRITE:
299 
300  switch (BitWidth)
301  {
302  case 8:
303 
304  ACPI_SET8 (LogicalAddrPtr, *Value);
305  break;
306 
307  case 16:
308 
309  ACPI_SET16 (LogicalAddrPtr, *Value);
310  break;
311 
312  case 32:
313 
314  ACPI_SET32 (LogicalAddrPtr, *Value);
315  break;
316 
317  case 64:
318 
319  ACPI_SET64 (LogicalAddrPtr, *Value);
320  break;
321 
322  default:
323 
324  /* BitWidth was already validated */
325 
326  break;
327  }
328  break;
329 
330  default:
331 
333  break;
334  }
335 
337 }
338 
339 
340 /*******************************************************************************
341  *
342  * FUNCTION: AcpiExSystemIoSpaceHandler
343  *
344  * PARAMETERS: Function - Read or Write operation
345  * Address - Where in the space to read or write
346  * BitWidth - Field width in bits (8, 16, or 32)
347  * Value - Pointer to in or out value
348  * HandlerContext - Pointer to Handler's context
349  * RegionContext - Pointer to context specific to the
350  * accessed region
351  *
352  * RETURN: Status
353  *
354  * DESCRIPTION: Handler for the System IO address space (Op Region)
355  *
356  ******************************************************************************/
357 
361  ACPI_PHYSICAL_ADDRESS Address,
362  UINT32 BitWidth,
363  UINT64 *Value,
364  void *HandlerContext,
365  void *RegionContext)
366 {
368  UINT32 Value32;
369 
370 
371  ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
372 
373 
375  "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
376  BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
377 
378  /* Decode the function parameter */
379 
380  switch (Function)
381  {
382  case ACPI_READ:
383 
384  Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
385  &Value32, BitWidth);
386  *Value = Value32;
387  break;
388 
389  case ACPI_WRITE:
390 
391  Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
392  (UINT32) *Value, BitWidth);
393  break;
394 
395  default:
396 
398  break;
399  }
400 
402 }
403 
404 
405 /*******************************************************************************
406  *
407  * FUNCTION: AcpiExPciConfigSpaceHandler
408  *
409  * PARAMETERS: Function - Read or Write operation
410  * Address - Where in the space to read or write
411  * BitWidth - Field width in bits (8, 16, or 32)
412  * Value - Pointer to in or out value
413  * HandlerContext - Pointer to Handler's context
414  * RegionContext - Pointer to context specific to the
415  * accessed region
416  *
417  * RETURN: Status
418  *
419  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
420  *
421  ******************************************************************************/
422 
426  ACPI_PHYSICAL_ADDRESS Address,
427  UINT32 BitWidth,
428  UINT64 *Value,
429  void *HandlerContext,
430  void *RegionContext)
431 {
433  ACPI_PCI_ID *PciId;
434  UINT16 PciRegister;
435 
436 
437  ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
438 
439 
440  /*
441  * The arguments to AcpiOs(Read|Write)PciConfiguration are:
442  *
443  * PciSegment is the PCI bus segment range 0-31
444  * PciBus is the PCI bus number range 0-255
445  * PciDevice is the PCI device number range 0-31
446  * PciFunction is the PCI device function number
447  * PciRegister is the Config space register range 0-255 bytes
448  *
449  * Value - input value for write, output address for read
450  *
451  */
452  PciId = (ACPI_PCI_ID *) RegionContext;
453  PciRegister = (UINT16) (UINT32) Address;
454 
456  "Pci-Config %u (%u) Seg(%04x) Bus(%04x) "
457  "Dev(%04x) Func(%04x) Reg(%04x)\n",
458  Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
459  PciId->Function, PciRegister));
460 
461  switch (Function)
462  {
463  case ACPI_READ:
464 
465  *Value = 0;
467  PciId, PciRegister, Value, BitWidth);
468  break;
469 
470  case ACPI_WRITE:
471 
473  PciId, PciRegister, *Value, BitWidth);
474  break;
475 
476  default:
477 
479  break;
480  }
481 
483 }
484 
485 
486 /*******************************************************************************
487  *
488  * FUNCTION: AcpiExCmosSpaceHandler
489  *
490  * PARAMETERS: Function - Read or Write operation
491  * Address - Where in the space to read or write
492  * BitWidth - Field width in bits (8, 16, or 32)
493  * Value - Pointer to in or out value
494  * HandlerContext - Pointer to Handler's context
495  * RegionContext - Pointer to context specific to the
496  * accessed region
497  *
498  * RETURN: Status
499  *
500  * DESCRIPTION: Handler for the CMOS address space (Op Region)
501  *
502  ******************************************************************************/
503 
507  ACPI_PHYSICAL_ADDRESS Address,
508  UINT32 BitWidth,
509  UINT64 *Value,
510  void *HandlerContext,
511  void *RegionContext)
512 {
514 
515 
516  ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
517 
518 
520 }
521 
522 
523 /*******************************************************************************
524  *
525  * FUNCTION: AcpiExPciBarSpaceHandler
526  *
527  * PARAMETERS: Function - Read or Write operation
528  * Address - Where in the space to read or write
529  * BitWidth - Field width in bits (8, 16, or 32)
530  * Value - Pointer to in or out value
531  * HandlerContext - Pointer to Handler's context
532  * RegionContext - Pointer to context specific to the
533  * accessed region
534  *
535  * RETURN: Status
536  *
537  * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
538  *
539  ******************************************************************************/
540 
544  ACPI_PHYSICAL_ADDRESS Address,
545  UINT32 BitWidth,
546  UINT64 *Value,
547  void *HandlerContext,
548  void *RegionContext)
549 {
551 
552 
553  ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
554 
555 
557 }
558 
559 
560 /*******************************************************************************
561  *
562  * FUNCTION: AcpiExDataTableSpaceHandler
563  *
564  * PARAMETERS: Function - Read or Write operation
565  * Address - Where in the space to read or write
566  * BitWidth - Field width in bits (8, 16, or 32)
567  * Value - Pointer to in or out value
568  * HandlerContext - Pointer to Handler's context
569  * RegionContext - Pointer to context specific to the
570  * accessed region
571  *
572  * RETURN: Status
573  *
574  * DESCRIPTION: Handler for the Data Table address space (Op Region)
575  *
576  ******************************************************************************/
577 
581  ACPI_PHYSICAL_ADDRESS Address,
582  UINT32 BitWidth,
583  UINT64 *Value,
584  void *HandlerContext,
585  void *RegionContext)
586 {
587  ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
588 
589 
590  /*
591  * Perform the memory read or write. The BitWidth was already
592  * validated.
593  */
594  switch (Function)
595  {
596  case ACPI_READ:
597 
599  ACPI_DIV_8 (BitWidth));
600  break;
601 
602  case ACPI_WRITE:
603 
605  ACPI_DIV_8 (BitWidth));
606  break;
607 
608  default:
609 
611  }
612 
614 }
#define ACPI_FREE(a)
Definition: actypes.h:386
ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Reg, UINT64 *Value, UINT32 Width)
Definition: osl.c:793
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
_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 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:579
#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:1329
ACPI_SIZE Length
Definition: actypes.h:1339
UINT16 Device
Definition: actypes.h:1330
#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
ACPI_PHYSICAL_ADDRESS PhysicalAddress
Definition: actypes.h:1337
IN UCHAR Value
Definition: halp.h:394
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
#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:1328
#define ACPI_ROUND_UP(value, boundary)
Definition: acmacros.h:242
ACPI_MEM_MAPPING * CurMm
Definition: actypes.h:1348
#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:1347
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1081
ACPI_STATUS AcpiExCmosSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 BitWidth, UINT64 *Value, void *HandlerContext, void *RegionContext)
Definition: exregion.c:505
Status
Definition: gdiplustypes.h:24
#define ACPI_SET32(ptr, val)
Definition: acmacros.h:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ACPI_MEM_MAPPING * FirstMm
Definition: actypes.h:1349
#define ACPI_SET8(ptr, val)
Definition: acmacros.h:61
#define ACPI_DIV_8(a)
Definition: acmacros.h:214
struct acpi_mem_mapping * NextMm
Definition: actypes.h:1340
UINT8 * LogicalAddress
Definition: actypes.h:1338
ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Reg, UINT64 Value, UINT32 Width)
Definition: osl.c:822
#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
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
#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:424
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_AML_ALIGNMENT
Definition: acexcep.h:206
UINT16 Function
Definition: actypes.h:1331
#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:359
#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:542
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3046
#define ACPI_WRITE
Definition: actypes.h:744