xref: /freebsd/sys/contrib/dev/acpica/components/executer/exregion.c (revision dd21556857e8d40f66bf5ad54754d9d52669ebf7)
1 /******************************************************************************
2  *
3  * Module Name: exregion - ACPI default OpRegion (address space) handlers
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acinterp.h>
155 
156 
157 #define _COMPONENT          ACPI_EXECUTER
158         ACPI_MODULE_NAME    ("exregion")
159 
160 
161 /*******************************************************************************
162  *
163  * FUNCTION:    AcpiExSystemMemorySpaceHandler
164  *
165  * PARAMETERS:  Function            - Read or Write operation
166  *              Address             - Where in the space to read or write
167  *              BitWidth            - Field width in bits (8, 16, or 32)
168  *              Value               - Pointer to in or out value
169  *              HandlerContext      - Pointer to Handler's context
170  *              RegionContext       - Pointer to context specific to the
171  *                                    accessed region
172  *
173  * RETURN:      Status
174  *
175  * DESCRIPTION: Handler for the System Memory address space (Op Region)
176  *
177  ******************************************************************************/
178 
179 ACPI_STATUS
180 AcpiExSystemMemorySpaceHandler (
181     UINT32                  Function,
182     ACPI_PHYSICAL_ADDRESS   Address,
183     UINT32                  BitWidth,
184     UINT64                  *Value,
185     void                    *HandlerContext,
186     void                    *RegionContext)
187 {
188     ACPI_STATUS             Status = AE_OK;
189     void                    *LogicalAddrPtr = NULL;
190     ACPI_MEM_SPACE_CONTEXT  *MemInfo = RegionContext;
191     ACPI_MEM_MAPPING        *Mm = MemInfo->CurMm;
192     UINT32                  Length;
193     ACPI_SIZE               MapLength;
194 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
195     UINT32                  Remainder;
196 #endif
197 
198 
199     ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
200 
201 
202     /* Validate and translate the bit width */
203 
204     switch (BitWidth)
205     {
206     case 8:
207 
208         Length = 1;
209         break;
210 
211     case 16:
212 
213         Length = 2;
214         break;
215 
216     case 32:
217 
218         Length = 4;
219         break;
220 
221     case 64:
222 
223         Length = 8;
224         break;
225 
226     default:
227 
228         ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
229             BitWidth));
230         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
231     }
232 
233 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
234     /*
235      * Hardware does not support non-aligned data transfers, we must verify
236      * the request.
237      */
238     (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder);
239     if (Remainder != 0)
240     {
241         return_ACPI_STATUS (AE_AML_ALIGNMENT);
242     }
243 #endif
244 
245     /*
246      * Does the request fit into the cached memory mapping?
247      * Is 1) Address below the current mapping? OR
248      *    2) Address beyond the current mapping?
249      */
250     if (!Mm || (Address < Mm->PhysicalAddress) ||
251         ((UINT64) Address + Length > (UINT64) Mm->PhysicalAddress + Mm->Length))
252     {
253         /*
254          * The request cannot be resolved by the current memory mapping.
255          *
256          * Look for an existing saved mapping covering the address range
257          * at hand. If found, save it as the current one and carry out
258          * the access.
259          */
260         for (Mm = MemInfo->FirstMm; Mm; Mm = Mm->NextMm)
261         {
262             if (Mm == MemInfo->CurMm)
263             {
264                 continue;
265             }
266 
267             if (Address < Mm->PhysicalAddress)
268             {
269                 continue;
270             }
271 
272             if ((UINT64) Address + Length > (UINT64) Mm->PhysicalAddress + Mm->Length)
273             {
274                 continue;
275             }
276 
277             MemInfo->CurMm = Mm;
278             goto access;
279         }
280 
281         /* Create a new mappings list entry */
282 
283         Mm = ACPI_ALLOCATE_ZEROED(sizeof(*Mm));
284         if (!Mm)
285         {
286             ACPI_ERROR((AE_INFO,
287                 "Unable to save memory mapping at 0x%8.8X%8.8X, size %u",
288                 ACPI_FORMAT_UINT64(Address), Length));
289             return_ACPI_STATUS(AE_NO_MEMORY);
290         }
291 
292         /*
293          * October 2009: Attempt to map from the requested address to the
294          * end of the region. However, we will never map more than one
295          * page, nor will we cross a page boundary.
296          */
297         MapLength = (ACPI_SIZE)
298             ((MemInfo->Address + MemInfo->Length) - Address);
299 
300         if (MapLength > ACPI_DEFAULT_PAGE_SIZE)
301         {
302             MapLength = ACPI_DEFAULT_PAGE_SIZE;
303         }
304 
305         /* Create a new mapping starting at the address given */
306 
307         LogicalAddrPtr = AcpiOsMapMemory(Address, MapLength);
308         if (!LogicalAddrPtr)
309         {
310             ACPI_ERROR ((AE_INFO,
311                 "Could not map memory at 0x%8.8X%8.8X, size %u",
312                 ACPI_FORMAT_UINT64 (Address), (UINT32) MapLength));
313             ACPI_FREE(Mm);
314             return_ACPI_STATUS (AE_NO_MEMORY);
315         }
316 
317         /* Save the physical address and mapping size */
318 
319         Mm->LogicalAddress = LogicalAddrPtr;
320         Mm->PhysicalAddress = Address;
321         Mm->Length = MapLength;
322 
323         /*
324          * Add the new entry to the mappigs list and save it as the
325          * current mapping.
326          */
327         Mm->NextMm = MemInfo->FirstMm;
328         MemInfo->FirstMm = Mm;
329         MemInfo->CurMm = Mm;
330     }
331 
332 access:
333     /*
334      * Generate a logical pointer corresponding to the address we want to
335      * access
336      */
337     LogicalAddrPtr = Mm->LogicalAddress +
338         ((UINT64) Address - (UINT64) Mm->PhysicalAddress);
339 
340     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
341         "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
342         BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
343 
344     /*
345      * Perform the memory read or write
346      *
347      * Note: For machines that do not support non-aligned transfers, the target
348      * address was checked for alignment above. We do not attempt to break the
349      * transfer up into smaller (byte-size) chunks because the AML specifically
350      * asked for a transfer width that the hardware may require.
351      */
352     switch (Function)
353     {
354     case ACPI_READ:
355 
356         *Value = 0;
357         switch (BitWidth)
358         {
359         case 8:
360 
361             *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
362             break;
363 
364         case 16:
365 
366             *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
367             break;
368 
369         case 32:
370 
371             *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
372             break;
373 
374         case 64:
375 
376             *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
377             break;
378 
379         default:
380 
381             /* BitWidth was already validated */
382 
383             break;
384         }
385         break;
386 
387     case ACPI_WRITE:
388 
389         switch (BitWidth)
390         {
391         case 8:
392 
393             ACPI_SET8 (LogicalAddrPtr, *Value);
394             break;
395 
396         case 16:
397 
398             ACPI_SET16 (LogicalAddrPtr, *Value);
399             break;
400 
401         case 32:
402 
403             ACPI_SET32 (LogicalAddrPtr, *Value);
404             break;
405 
406         case 64:
407 
408             ACPI_SET64 (LogicalAddrPtr, *Value);
409             break;
410 
411         default:
412 
413             /* BitWidth was already validated */
414 
415             break;
416         }
417         break;
418 
419     default:
420 
421         Status = AE_BAD_PARAMETER;
422         break;
423     }
424 
425     return_ACPI_STATUS (Status);
426 }
427 
428 
429 /*******************************************************************************
430  *
431  * FUNCTION:    AcpiExSystemIoSpaceHandler
432  *
433  * PARAMETERS:  Function            - Read or Write operation
434  *              Address             - Where in the space to read or write
435  *              BitWidth            - Field width in bits (8, 16, or 32)
436  *              Value               - Pointer to in or out value
437  *              HandlerContext      - Pointer to Handler's context
438  *              RegionContext       - Pointer to context specific to the
439  *                                    accessed region
440  *
441  * RETURN:      Status
442  *
443  * DESCRIPTION: Handler for the System IO address space (Op Region)
444  *
445  ******************************************************************************/
446 
447 ACPI_STATUS
448 AcpiExSystemIoSpaceHandler (
449     UINT32                  Function,
450     ACPI_PHYSICAL_ADDRESS   Address,
451     UINT32                  BitWidth,
452     UINT64                  *Value,
453     void                    *HandlerContext,
454     void                    *RegionContext)
455 {
456     ACPI_STATUS             Status = AE_OK;
457     UINT32                  Value32;
458 
459 
460     ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
461 
462 
463     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
464         "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
465         BitWidth, Function, ACPI_FORMAT_UINT64 (Address)));
466 
467     /* Decode the function parameter */
468 
469     switch (Function)
470     {
471     case ACPI_READ:
472 
473         Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
474                     &Value32, BitWidth);
475         *Value = Value32;
476         break;
477 
478     case ACPI_WRITE:
479 
480         Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
481                     (UINT32) *Value, BitWidth);
482         break;
483 
484     default:
485 
486         Status = AE_BAD_PARAMETER;
487         break;
488     }
489 
490     return_ACPI_STATUS (Status);
491 }
492 
493 
494 /*******************************************************************************
495  *
496  * FUNCTION:    AcpiExPciConfigSpaceHandler
497  *
498  * PARAMETERS:  Function            - Read or Write operation
499  *              Address             - Where in the space to read or write
500  *              BitWidth            - Field width in bits (8, 16, or 32)
501  *              Value               - Pointer to in or out value
502  *              HandlerContext      - Pointer to Handler's context
503  *              RegionContext       - Pointer to context specific to the
504  *                                    accessed region
505  *
506  * RETURN:      Status
507  *
508  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
509  *
510  ******************************************************************************/
511 
512 ACPI_STATUS
513 AcpiExPciConfigSpaceHandler (
514     UINT32                  Function,
515     ACPI_PHYSICAL_ADDRESS   Address,
516     UINT32                  BitWidth,
517     UINT64                  *Value,
518     void                    *HandlerContext,
519     void                    *RegionContext)
520 {
521     ACPI_STATUS             Status = AE_OK;
522     ACPI_PCI_ID             *PciId;
523     UINT16                  PciRegister;
524 
525 
526     ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
527 
528 
529     /*
530      *  The arguments to AcpiOs(Read|Write)PciConfiguration are:
531      *
532      *  PciSegment  is the PCI bus segment range 0-31
533      *  PciBus      is the PCI bus number range 0-255
534      *  PciDevice   is the PCI device number range 0-31
535      *  PciFunction is the PCI device function number
536      *  PciRegister is the Config space register range 0-255 bytes
537      *
538      *  Value - input value for write, output address for read
539      *
540      */
541     PciId       = (ACPI_PCI_ID *) RegionContext;
542     PciRegister = (UINT16) (UINT32) Address;
543 
544     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
545         "Pci-Config %u (%u) Seg(%04x) Bus(%04x) "
546         "Dev(%04x) Func(%04x) Reg(%04x)\n",
547         Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
548         PciId->Function, PciRegister));
549 
550     switch (Function)
551     {
552     case ACPI_READ:
553 
554         *Value = 0;
555         Status = AcpiOsReadPciConfiguration (
556             PciId, PciRegister, Value, BitWidth);
557         break;
558 
559     case ACPI_WRITE:
560 
561         Status = AcpiOsWritePciConfiguration (
562             PciId, PciRegister, *Value, BitWidth);
563         break;
564 
565     default:
566 
567         Status = AE_BAD_PARAMETER;
568         break;
569     }
570 
571     return_ACPI_STATUS (Status);
572 }
573 
574 
575 /*******************************************************************************
576  *
577  * FUNCTION:    AcpiExCmosSpaceHandler
578  *
579  * PARAMETERS:  Function            - Read or Write operation
580  *              Address             - Where in the space to read or write
581  *              BitWidth            - Field width in bits (8, 16, or 32)
582  *              Value               - Pointer to in or out value
583  *              HandlerContext      - Pointer to Handler's context
584  *              RegionContext       - Pointer to context specific to the
585  *                                    accessed region
586  *
587  * RETURN:      Status
588  *
589  * DESCRIPTION: Handler for the CMOS address space (Op Region)
590  *
591  ******************************************************************************/
592 
593 ACPI_STATUS
594 AcpiExCmosSpaceHandler (
595     UINT32                  Function,
596     ACPI_PHYSICAL_ADDRESS   Address,
597     UINT32                  BitWidth,
598     UINT64                  *Value,
599     void                    *HandlerContext,
600     void                    *RegionContext)
601 {
602     ACPI_STATUS             Status = AE_OK;
603 
604 
605     ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
606 
607 
608     return_ACPI_STATUS (Status);
609 }
610 
611 
612 /*******************************************************************************
613  *
614  * FUNCTION:    AcpiExPciBarSpaceHandler
615  *
616  * PARAMETERS:  Function            - Read or Write operation
617  *              Address             - Where in the space to read or write
618  *              BitWidth            - Field width in bits (8, 16, or 32)
619  *              Value               - Pointer to in or out value
620  *              HandlerContext      - Pointer to Handler's context
621  *              RegionContext       - Pointer to context specific to the
622  *                                    accessed region
623  *
624  * RETURN:      Status
625  *
626  * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
627  *
628  ******************************************************************************/
629 
630 ACPI_STATUS
631 AcpiExPciBarSpaceHandler (
632     UINT32                  Function,
633     ACPI_PHYSICAL_ADDRESS   Address,
634     UINT32                  BitWidth,
635     UINT64                  *Value,
636     void                    *HandlerContext,
637     void                    *RegionContext)
638 {
639     ACPI_STATUS             Status = AE_OK;
640 
641 
642     ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
643 
644 
645     return_ACPI_STATUS (Status);
646 }
647 
648 
649 /*******************************************************************************
650  *
651  * FUNCTION:    AcpiExDataTableSpaceHandler
652  *
653  * PARAMETERS:  Function            - Read or Write operation
654  *              Address             - Where in the space to read or write
655  *              BitWidth            - Field width in bits (8, 16, or 32)
656  *              Value               - Pointer to in or out value
657  *              HandlerContext      - Pointer to Handler's context
658  *              RegionContext       - Pointer to context specific to the
659  *                                    accessed region
660  *
661  * RETURN:      Status
662  *
663  * DESCRIPTION: Handler for the Data Table address space (Op Region)
664  *
665  ******************************************************************************/
666 
667 ACPI_STATUS
668 AcpiExDataTableSpaceHandler (
669     UINT32                  Function,
670     ACPI_PHYSICAL_ADDRESS   Address,
671     UINT32                  BitWidth,
672     UINT64                  *Value,
673     void                    *HandlerContext,
674     void                    *RegionContext)
675 {
676     ACPI_DATA_TABLE_MAPPING *Mapping;
677     char                    *Pointer;
678 
679 
680     ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
681 
682 
683     Mapping = (ACPI_DATA_TABLE_MAPPING *) RegionContext;
684     Pointer = ACPI_CAST_PTR (char, Mapping->Pointer) +
685         (Address - ACPI_PTR_TO_PHYSADDR (Mapping->Pointer));
686 
687     /*
688      * Perform the memory read or write. The BitWidth was already
689      * validated.
690      */
691     switch (Function)
692     {
693     case ACPI_READ:
694 
695         memcpy (ACPI_CAST_PTR (char, Value), Pointer, ACPI_DIV_8 (BitWidth));
696         break;
697 
698     case ACPI_WRITE:
699 
700         memcpy (Pointer, ACPI_CAST_PTR (char, Value), ACPI_DIV_8 (BitWidth));
701         break;
702 
703     default:
704 
705         return_ACPI_STATUS (AE_BAD_PARAMETER);
706     }
707 
708     return_ACPI_STATUS (AE_OK);
709 }
710