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