xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/executer/exregion.c (revision e6eaad8615c4734498b9b800847d18bbe62782fa)
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 - 2013, 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 
117 #define __EXREGION_C__
118 
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acinterp.h"
122 
123 
124 #define _COMPONENT          ACPI_EXECUTER
125         ACPI_MODULE_NAME    ("exregion")
126 
127 
128 /*******************************************************************************
129  *
130  * FUNCTION:    AcpiExSystemMemorySpaceHandler
131  *
132  * PARAMETERS:  Function            - Read or Write operation
133  *              Address             - Where in the space to read or write
134  *              BitWidth            - Field width in bits (8, 16, or 32)
135  *              Value               - Pointer to in or out value
136  *              HandlerContext      - Pointer to Handler's context
137  *              RegionContext       - Pointer to context specific to the
138  *                                    accessed region
139  *
140  * RETURN:      Status
141  *
142  * DESCRIPTION: Handler for the System Memory address space (Op Region)
143  *
144  ******************************************************************************/
145 
146 ACPI_STATUS
147 AcpiExSystemMemorySpaceHandler (
148     UINT32                  Function,
149     ACPI_PHYSICAL_ADDRESS   Address,
150     UINT32                  BitWidth,
151     UINT64                  *Value,
152     void                    *HandlerContext,
153     void                    *RegionContext)
154 {
155     ACPI_STATUS             Status = AE_OK;
156     void                    *LogicalAddrPtr = NULL;
157     ACPI_MEM_SPACE_CONTEXT  *MemInfo = RegionContext;
158     UINT32                  Length;
159     ACPI_SIZE               MapLength;
160     ACPI_SIZE               PageBoundaryMapLength;
161 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
162     UINT32                  Remainder;
163 #endif
164 
165 
166     ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
167 
168 
169     /* Validate and translate the bit width */
170 
171     switch (BitWidth)
172     {
173     case 8:
174 
175         Length = 1;
176         break;
177 
178     case 16:
179 
180         Length = 2;
181         break;
182 
183     case 32:
184 
185         Length = 4;
186         break;
187 
188     case 64:
189 
190         Length = 8;
191         break;
192 
193     default:
194 
195         ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
196             BitWidth));
197         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
198     }
199 
200 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
201     /*
202      * Hardware does not support non-aligned data transfers, we must verify
203      * the request.
204      */
205     (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder);
206     if (Remainder != 0)
207     {
208         return_ACPI_STATUS (AE_AML_ALIGNMENT);
209     }
210 #endif
211 
212     /*
213      * Does the request fit into the cached memory mapping?
214      * Is 1) Address below the current mapping? OR
215      *    2) Address beyond the current mapping?
216      */
217     if ((Address < MemInfo->MappedPhysicalAddress) ||
218         (((UINT64) Address + Length) >
219             ((UINT64)
220             MemInfo->MappedPhysicalAddress + MemInfo->MappedLength)))
221     {
222         /*
223          * The request cannot be resolved by the current memory mapping;
224          * Delete the existing mapping and create a new one.
225          */
226         if (MemInfo->MappedLength)
227         {
228             /* Valid mapping, delete it */
229 
230             AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress,
231                 MemInfo->MappedLength);
232         }
233 
234         /*
235          * October 2009: Attempt to map from the requested address to the
236          * end of the region. However, we will never map more than one
237          * page, nor will we cross a page boundary.
238          */
239         MapLength = (ACPI_SIZE)
240             ((MemInfo->Address + MemInfo->Length) - Address);
241 
242         /*
243          * If mapping the entire remaining portion of the region will cross
244          * a page boundary, just map up to the page boundary, do not cross.
245          * On some systems, crossing a page boundary while mapping regions
246          * can cause warnings if the pages have different attributes
247          * due to resource management.
248          *
249          * This has the added benefit of constraining a single mapping to
250          * one page, which is similar to the original code that used a 4k
251          * maximum window.
252          */
253         PageBoundaryMapLength =
254             ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address;
255         if (PageBoundaryMapLength == 0)
256         {
257             PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE;
258         }
259 
260         if (MapLength > PageBoundaryMapLength)
261         {
262             MapLength = PageBoundaryMapLength;
263         }
264 
265         /* Create a new mapping starting at the address given */
266 
267         MemInfo->MappedLogicalAddress = AcpiOsMapMemory (
268             (ACPI_PHYSICAL_ADDRESS) Address, MapLength);
269         if (!MemInfo->MappedLogicalAddress)
270         {
271             ACPI_ERROR ((AE_INFO,
272                 "Could not map memory at 0x%8.8X%8.8X, size %u",
273                 ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength));
274             MemInfo->MappedLength = 0;
275             return_ACPI_STATUS (AE_NO_MEMORY);
276         }
277 
278         /* Save the physical address and mapping size */
279 
280         MemInfo->MappedPhysicalAddress = Address;
281         MemInfo->MappedLength = MapLength;
282     }
283 
284     /*
285      * Generate a logical pointer corresponding to the address we want to
286      * access
287      */
288     LogicalAddrPtr = MemInfo->MappedLogicalAddress +
289         ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress);
290 
291     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
292         "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
293         BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address)));
294 
295     /*
296      * Perform the memory read or write
297      *
298      * Note: For machines that do not support non-aligned transfers, the target
299      * address was checked for alignment above. We do not attempt to break the
300      * transfer up into smaller (byte-size) chunks because the AML specifically
301      * asked for a transfer width that the hardware may require.
302      */
303     switch (Function)
304     {
305     case ACPI_READ:
306 
307         *Value = 0;
308         switch (BitWidth)
309         {
310         case 8:
311 
312             *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
313             break;
314 
315         case 16:
316 
317             *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
318             break;
319 
320         case 32:
321 
322             *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
323             break;
324 
325         case 64:
326 
327             *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
328             break;
329 
330         default:
331 
332             /* BitWidth was already validated */
333 
334             break;
335         }
336         break;
337 
338     case ACPI_WRITE:
339 
340         switch (BitWidth)
341         {
342         case 8:
343 
344             ACPI_SET8 (LogicalAddrPtr, *Value);
345             break;
346 
347         case 16:
348 
349             ACPI_SET16 (LogicalAddrPtr, *Value);
350             break;
351 
352         case 32:
353 
354             ACPI_SET32 (LogicalAddrPtr, *Value);
355             break;
356 
357         case 64:
358 
359             ACPI_SET64 (LogicalAddrPtr, *Value);
360             break;
361 
362         default:
363 
364             /* BitWidth was already validated */
365 
366             break;
367         }
368         break;
369 
370     default:
371 
372         Status = AE_BAD_PARAMETER;
373         break;
374     }
375 
376     return_ACPI_STATUS (Status);
377 }
378 
379 
380 /*******************************************************************************
381  *
382  * FUNCTION:    AcpiExSystemIoSpaceHandler
383  *
384  * PARAMETERS:  Function            - Read or Write operation
385  *              Address             - Where in the space to read or write
386  *              BitWidth            - Field width in bits (8, 16, or 32)
387  *              Value               - Pointer to in or out value
388  *              HandlerContext      - Pointer to Handler's context
389  *              RegionContext       - Pointer to context specific to the
390  *                                    accessed region
391  *
392  * RETURN:      Status
393  *
394  * DESCRIPTION: Handler for the System IO address space (Op Region)
395  *
396  ******************************************************************************/
397 
398 ACPI_STATUS
399 AcpiExSystemIoSpaceHandler (
400     UINT32                  Function,
401     ACPI_PHYSICAL_ADDRESS   Address,
402     UINT32                  BitWidth,
403     UINT64                  *Value,
404     void                    *HandlerContext,
405     void                    *RegionContext)
406 {
407     ACPI_STATUS             Status = AE_OK;
408     UINT32                  Value32;
409 
410 
411     ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
412 
413 
414     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
415         "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
416         BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address)));
417 
418     /* Decode the function parameter */
419 
420     switch (Function)
421     {
422     case ACPI_READ:
423 
424         Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
425                     &Value32, BitWidth);
426         *Value = Value32;
427         break;
428 
429     case ACPI_WRITE:
430 
431         Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
432                     (UINT32) *Value, BitWidth);
433         break;
434 
435     default:
436 
437         Status = AE_BAD_PARAMETER;
438         break;
439     }
440 
441     return_ACPI_STATUS (Status);
442 }
443 
444 
445 /*******************************************************************************
446  *
447  * FUNCTION:    AcpiExPciConfigSpaceHandler
448  *
449  * PARAMETERS:  Function            - Read or Write operation
450  *              Address             - Where in the space to read or write
451  *              BitWidth            - Field width in bits (8, 16, or 32)
452  *              Value               - Pointer to in or out value
453  *              HandlerContext      - Pointer to Handler's context
454  *              RegionContext       - Pointer to context specific to the
455  *                                    accessed region
456  *
457  * RETURN:      Status
458  *
459  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
460  *
461  ******************************************************************************/
462 
463 ACPI_STATUS
464 AcpiExPciConfigSpaceHandler (
465     UINT32                  Function,
466     ACPI_PHYSICAL_ADDRESS   Address,
467     UINT32                  BitWidth,
468     UINT64                  *Value,
469     void                    *HandlerContext,
470     void                    *RegionContext)
471 {
472     ACPI_STATUS             Status = AE_OK;
473     ACPI_PCI_ID             *PciId;
474     UINT16                  PciRegister;
475 
476 
477     ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
478 
479 
480     /*
481      *  The arguments to AcpiOs(Read|Write)PciConfiguration are:
482      *
483      *  PciSegment  is the PCI bus segment range 0-31
484      *  PciBus      is the PCI bus number range 0-255
485      *  PciDevice   is the PCI device number range 0-31
486      *  PciFunction is the PCI device function number
487      *  PciRegister is the Config space register range 0-255 bytes
488      *
489      *  Value - input value for write, output address for read
490      *
491      */
492     PciId       = (ACPI_PCI_ID *) RegionContext;
493     PciRegister = (UINT16) (UINT32) Address;
494 
495     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
496         "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
497         Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
498         PciId->Function, PciRegister));
499 
500     switch (Function)
501     {
502     case ACPI_READ:
503 
504         *Value = 0;
505         Status = AcpiOsReadPciConfiguration (PciId, PciRegister,
506                     Value, BitWidth);
507         break;
508 
509     case ACPI_WRITE:
510 
511         Status = AcpiOsWritePciConfiguration (PciId, PciRegister,
512                     *Value, BitWidth);
513         break;
514 
515     default:
516 
517         Status = AE_BAD_PARAMETER;
518         break;
519     }
520 
521     return_ACPI_STATUS (Status);
522 }
523 
524 
525 /*******************************************************************************
526  *
527  * FUNCTION:    AcpiExCmosSpaceHandler
528  *
529  * PARAMETERS:  Function            - Read or Write operation
530  *              Address             - Where in the space to read or write
531  *              BitWidth            - Field width in bits (8, 16, or 32)
532  *              Value               - Pointer to in or out value
533  *              HandlerContext      - Pointer to Handler's context
534  *              RegionContext       - Pointer to context specific to the
535  *                                    accessed region
536  *
537  * RETURN:      Status
538  *
539  * DESCRIPTION: Handler for the CMOS address space (Op Region)
540  *
541  ******************************************************************************/
542 
543 ACPI_STATUS
544 AcpiExCmosSpaceHandler (
545     UINT32                  Function,
546     ACPI_PHYSICAL_ADDRESS   Address,
547     UINT32                  BitWidth,
548     UINT64                  *Value,
549     void                    *HandlerContext,
550     void                    *RegionContext)
551 {
552     ACPI_STATUS             Status = AE_OK;
553 
554 
555     ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
556 
557 
558     return_ACPI_STATUS (Status);
559 }
560 
561 
562 /*******************************************************************************
563  *
564  * FUNCTION:    AcpiExPciBarSpaceHandler
565  *
566  * PARAMETERS:  Function            - Read or Write operation
567  *              Address             - Where in the space to read or write
568  *              BitWidth            - Field width in bits (8, 16, or 32)
569  *              Value               - Pointer to in or out value
570  *              HandlerContext      - Pointer to Handler's context
571  *              RegionContext       - Pointer to context specific to the
572  *                                    accessed region
573  *
574  * RETURN:      Status
575  *
576  * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
577  *
578  ******************************************************************************/
579 
580 ACPI_STATUS
581 AcpiExPciBarSpaceHandler (
582     UINT32                  Function,
583     ACPI_PHYSICAL_ADDRESS   Address,
584     UINT32                  BitWidth,
585     UINT64                  *Value,
586     void                    *HandlerContext,
587     void                    *RegionContext)
588 {
589     ACPI_STATUS             Status = AE_OK;
590 
591 
592     ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
593 
594 
595     return_ACPI_STATUS (Status);
596 }
597 
598 
599 /*******************************************************************************
600  *
601  * FUNCTION:    AcpiExDataTableSpaceHandler
602  *
603  * PARAMETERS:  Function            - Read or Write operation
604  *              Address             - Where in the space to read or write
605  *              BitWidth            - Field width in bits (8, 16, or 32)
606  *              Value               - Pointer to in or out value
607  *              HandlerContext      - Pointer to Handler's context
608  *              RegionContext       - Pointer to context specific to the
609  *                                    accessed region
610  *
611  * RETURN:      Status
612  *
613  * DESCRIPTION: Handler for the Data Table address space (Op Region)
614  *
615  ******************************************************************************/
616 
617 ACPI_STATUS
618 AcpiExDataTableSpaceHandler (
619     UINT32                  Function,
620     ACPI_PHYSICAL_ADDRESS   Address,
621     UINT32                  BitWidth,
622     UINT64                  *Value,
623     void                    *HandlerContext,
624     void                    *RegionContext)
625 {
626     ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
627 
628 
629     /*
630      * Perform the memory read or write. The BitWidth was already
631      * validated.
632      */
633     switch (Function)
634     {
635     case ACPI_READ:
636 
637         ACPI_MEMCPY (ACPI_CAST_PTR (char, Value), ACPI_PHYSADDR_TO_PTR (Address),
638             ACPI_DIV_8 (BitWidth));
639         break;
640 
641     case ACPI_WRITE:
642 
643         ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
644             ACPI_DIV_8 (BitWidth));
645         break;
646 
647     default:
648 
649         return_ACPI_STATUS (AE_BAD_PARAMETER);
650     }
651 
652     return_ACPI_STATUS (AE_OK);
653 }
654