Home | History | Annotate | Line # | Download | only in executer
      1 /******************************************************************************
      2  *
      3  * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2025, 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 
     87  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
     88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     89  * PARTICULAR PURPOSE.
     90  *
     91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
     97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     98  * LIMITED REMEDY.
     99  *
    100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    101  * software or system incorporating such software without first obtaining any
    102  * required license or other approval from the U. S. Department of Commerce or
    103  * any other agency or department of the United States Government. In the
    104  * event Licensee exports any such software from the United States or
    105  * re-exports any such software from a foreign destination, Licensee shall
    106  * ensure that the distribution and export/re-export of the software is in
    107  * compliance with all laws, regulations, orders, or other restrictions of the
    108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    109  * any of its subsidiaries will export/re-export any technical data, process,
    110  * software, or service, directly or indirectly, to any country for which the
    111  * United States government or any agency thereof requires an export license,
    112  * other governmental approval, or letter of assurance, without first obtaining
    113  * such license, approval or letter.
    114  *
    115  *****************************************************************************
    116  *
    117  * Alternatively, you may choose to be licensed under the terms of the
    118  * following license:
    119  *
    120  * Redistribution and use in source and binary forms, with or without
    121  * modification, are permitted provided that the following conditions
    122  * are met:
    123  * 1. Redistributions of source code must retain the above copyright
    124  *    notice, this list of conditions, and the following disclaimer,
    125  *    without modification.
    126  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    127  *    substantially similar to the "NO WARRANTY" disclaimer below
    128  *    ("Disclaimer") and any redistribution must be conditioned upon
    129  *    including a substantially similar Disclaimer requirement for further
    130  *    binary redistribution.
    131  * 3. Neither the names of the above-listed copyright holders nor the names
    132  *    of any contributors may be used to endorse or promote products derived
    133  *    from this software without specific prior written permission.
    134  *
    135  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    136  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    137  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    138  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    139  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    140  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    141  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    142  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    143  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    144  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    145  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    146  *
    147  * Alternatively, you may choose to be licensed under the terms of the
    148  * GNU General Public License ("GPL") version 2 as published by the Free
    149  * Software Foundation.
    150  *
    151  *****************************************************************************/
    152 
    153 #include "acpi.h"
    154 #include "accommon.h"
    155 #include "acinterp.h"
    156 #include "acnamesp.h"
    157 #include "actables.h"
    158 #include "acdispat.h"
    159 #include "acevents.h"
    160 #include "amlcode.h"
    161 
    162 
    163 #define _COMPONENT          ACPI_EXECUTER
    164         ACPI_MODULE_NAME    ("exconfig")
    165 
    166 /* Local prototypes */
    167 
    168 static ACPI_STATUS
    169 AcpiExAddTable (
    170     UINT32                  TableIndex,
    171     ACPI_OPERAND_OBJECT     **DdbHandle);
    172 
    173 static ACPI_STATUS
    174 AcpiExRegionRead (
    175     ACPI_OPERAND_OBJECT     *ObjDesc,
    176     UINT32                  Length,
    177     UINT8                   *Buffer);
    178 
    179 
    180 /*******************************************************************************
    181  *
    182  * FUNCTION:    AcpiExAddTable
    183  *
    184  * PARAMETERS:  Table               - Pointer to raw table
    185  *              ParentNode          - Where to load the table (scope)
    186  *              DdbHandle           - Where to return the table handle.
    187  *
    188  * RETURN:      Status
    189  *
    190  * DESCRIPTION: Common function to Install and Load an ACPI table with a
    191  *              returned table handle.
    192  *
    193  ******************************************************************************/
    194 
    195 static ACPI_STATUS
    196 AcpiExAddTable (
    197     UINT32                  TableIndex,
    198     ACPI_OPERAND_OBJECT     **DdbHandle)
    199 {
    200     ACPI_OPERAND_OBJECT     *ObjDesc;
    201 
    202 
    203     ACPI_FUNCTION_TRACE (ExAddTable);
    204 
    205 
    206     /* Create an object to be the table handle */
    207 
    208     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
    209     if (!ObjDesc)
    210     {
    211         return_ACPI_STATUS (AE_NO_MEMORY);
    212     }
    213 
    214     /* Init the table handle */
    215 
    216     ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
    217     ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE;
    218     ObjDesc->Reference.Value = TableIndex;
    219     *DdbHandle = ObjDesc;
    220     return_ACPI_STATUS (AE_OK);
    221 }
    222 
    223 
    224 /*******************************************************************************
    225  *
    226  * FUNCTION:    AcpiExLoadTableOp
    227  *
    228  * PARAMETERS:  WalkState           - Current state with operands
    229  *              ReturnDesc          - Where to store the return object
    230  *
    231  * RETURN:      Status
    232  *
    233  * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
    234  *
    235  ******************************************************************************/
    236 
    237 ACPI_STATUS
    238 AcpiExLoadTableOp (
    239     ACPI_WALK_STATE         *WalkState,
    240     ACPI_OPERAND_OBJECT     **ReturnDesc)
    241 {
    242     ACPI_STATUS             Status;
    243     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    244     ACPI_NAMESPACE_NODE     *ParentNode;
    245     ACPI_NAMESPACE_NODE     *StartNode;
    246     ACPI_NAMESPACE_NODE     *ParameterNode = NULL;
    247     ACPI_OPERAND_OBJECT     *ReturnObj;
    248     ACPI_OPERAND_OBJECT     *DdbHandle;
    249     UINT32                  TableIndex;
    250 
    251 
    252     ACPI_FUNCTION_TRACE (ExLoadTableOp);
    253 
    254 
    255     /* Create the return object */
    256 
    257     ReturnObj = AcpiUtCreateIntegerObject ((UINT64) 0);
    258     if (!ReturnObj)
    259     {
    260         return_ACPI_STATUS (AE_NO_MEMORY);
    261     }
    262 
    263     *ReturnDesc = ReturnObj;
    264 
    265     /* Find the ACPI table in the RSDT/XSDT */
    266 
    267     AcpiExExitInterpreter ();
    268     Status = AcpiTbFindTable (
    269         Operand[0]->String.Pointer,
    270         Operand[1]->String.Pointer,
    271         Operand[2]->String.Pointer, &TableIndex);
    272     AcpiExEnterInterpreter ();
    273     if (ACPI_FAILURE (Status))
    274     {
    275         if (Status != AE_NOT_FOUND)
    276         {
    277             return_ACPI_STATUS (Status);
    278         }
    279 
    280         /* Table not found, return an Integer=0 and AE_OK */
    281 
    282         return_ACPI_STATUS (AE_OK);
    283     }
    284 
    285     /* Default nodes */
    286 
    287     StartNode = WalkState->ScopeInfo->Scope.Node;
    288     ParentNode = AcpiGbl_RootNode;
    289 
    290     /* RootPath (optional parameter) */
    291 
    292     if (Operand[3]->String.Length > 0)
    293     {
    294         /*
    295          * Find the node referenced by the RootPathString. This is the
    296          * location within the namespace where the table will be loaded.
    297          */
    298         Status = AcpiNsGetNodeUnlocked (StartNode,
    299             Operand[3]->String.Pointer, ACPI_NS_SEARCH_PARENT,
    300             &ParentNode);
    301         if (ACPI_FAILURE (Status))
    302         {
    303             return_ACPI_STATUS (Status);
    304         }
    305     }
    306 
    307     /* ParameterPath (optional parameter) */
    308 
    309     if (Operand[4]->String.Length > 0)
    310     {
    311         if ((Operand[4]->String.Pointer[0] != AML_ROOT_PREFIX) &&
    312             (Operand[4]->String.Pointer[0] != AML_PARENT_PREFIX))
    313         {
    314             /*
    315              * Path is not absolute, so it will be relative to the node
    316              * referenced by the RootPathString (or the NS root if omitted)
    317              */
    318             StartNode = ParentNode;
    319         }
    320 
    321         /* Find the node referenced by the ParameterPathString */
    322 
    323         Status = AcpiNsGetNodeUnlocked (StartNode,
    324             Operand[4]->String.Pointer, ACPI_NS_SEARCH_PARENT,
    325             &ParameterNode);
    326         if (ACPI_FAILURE (Status))
    327         {
    328             return_ACPI_STATUS (Status);
    329         }
    330     }
    331 
    332     /* Load the table into the namespace */
    333 
    334     ACPI_INFO (("Dynamic OEM Table Load:"));
    335     AcpiExExitInterpreter ();
    336     Status = AcpiTbLoadTable (TableIndex, ParentNode);
    337     AcpiExEnterInterpreter ();
    338     if (ACPI_FAILURE (Status))
    339     {
    340         return_ACPI_STATUS (Status);
    341     }
    342 
    343     Status = AcpiExAddTable (TableIndex, &DdbHandle);
    344     if (ACPI_FAILURE (Status))
    345     {
    346         return_ACPI_STATUS (Status);
    347     }
    348 
    349     /* Complete the initialization/resolution of new objects */
    350 
    351     AcpiExExitInterpreter();
    352     AcpiNsInitializeObjects();
    353     AcpiExEnterInterpreter();
    354 
    355     /* Parameter Data (optional) */
    356 
    357     if (ParameterNode)
    358     {
    359         /* Store the parameter data into the optional parameter object */
    360 
    361         Status = AcpiExStore (Operand[5],
    362             ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode), WalkState);
    363         if (ACPI_FAILURE (Status))
    364         {
    365             (void) AcpiExUnloadTable (DdbHandle);
    366 
    367             AcpiUtRemoveReference (DdbHandle);
    368             return_ACPI_STATUS (Status);
    369         }
    370     }
    371 
    372     /* Remove the reference to DdbHandle created by AcpiExAddTable above */
    373 
    374     AcpiUtRemoveReference (DdbHandle);
    375 
    376     /* Return -1 (non-zero) indicates success */
    377 
    378     ReturnObj->Integer.Value = 0xFFFFFFFFFFFFFFFF;
    379     return_ACPI_STATUS (Status);
    380 }
    381 
    382 
    383 /*******************************************************************************
    384  *
    385  * FUNCTION:    AcpiExRegionRead
    386  *
    387  * PARAMETERS:  ObjDesc         - Region descriptor
    388  *              Length          - Number of bytes to read
    389  *              Buffer          - Pointer to where to put the data
    390  *
    391  * RETURN:      Status
    392  *
    393  * DESCRIPTION: Read data from an operation region. The read starts from the
    394  *              beginning of the region.
    395  *
    396  ******************************************************************************/
    397 
    398 static ACPI_STATUS
    399 AcpiExRegionRead (
    400     ACPI_OPERAND_OBJECT     *ObjDesc,
    401     UINT32                  Length,
    402     UINT8                   *Buffer)
    403 {
    404     ACPI_STATUS             Status;
    405     UINT64                  Value;
    406     UINT32                  RegionOffset = 0;
    407     UINT32                  i;
    408 
    409 
    410     /* Bytewise reads */
    411 
    412     for (i = 0; i < Length; i++)
    413     {
    414         Status = AcpiEvAddressSpaceDispatch (ObjDesc, NULL, ACPI_READ,
    415             RegionOffset, 8, &Value);
    416         if (ACPI_FAILURE (Status))
    417         {
    418             return (Status);
    419         }
    420 
    421         *Buffer = (UINT8) Value;
    422         Buffer++;
    423         RegionOffset++;
    424     }
    425 
    426     return (AE_OK);
    427 }
    428 
    429 
    430 /*******************************************************************************
    431  *
    432  * FUNCTION:    AcpiExLoadOp
    433  *
    434  * PARAMETERS:  ObjDesc         - Region or Buffer/Field where the table will be
    435  *                                obtained
    436  *              Target          - Where the status of the load will be stored
    437  *              WalkState       - Current state
    438  *
    439  * RETURN:      Status
    440  *
    441  * DESCRIPTION: Load an ACPI table from a field or operation region
    442  *
    443  * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer
    444  *       objects before this code is reached.
    445  *
    446  *       If source is an operation region, it must refer to SystemMemory, as
    447  *       per the ACPI specification.
    448  *
    449  ******************************************************************************/
    450 
    451 ACPI_STATUS
    452 AcpiExLoadOp (
    453     ACPI_OPERAND_OBJECT     *ObjDesc,
    454     ACPI_OPERAND_OBJECT     *Target,
    455     ACPI_WALK_STATE         *WalkState)
    456 {
    457     ACPI_OPERAND_OBJECT     *DdbHandle;
    458     ACPI_TABLE_HEADER       *TableHeader;
    459     ACPI_TABLE_HEADER       *Table;
    460     UINT32                  TableIndex;
    461     ACPI_STATUS             Status;
    462     UINT32                  Length;
    463 
    464 
    465     ACPI_FUNCTION_TRACE (ExLoadOp);
    466 
    467 
    468     if (Target->Common.DescriptorType == ACPI_DESC_TYPE_NAMED)
    469     {
    470         Target = AcpiNsGetAttachedObject (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Target));
    471     }
    472     if (Target->Common.Type != ACPI_TYPE_INTEGER)
    473     {
    474         ACPI_ERROR ((AE_INFO, "Type not integer: %X", Target->Common.Type));
    475         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    476     }
    477 
    478     Target->Integer.Value = 0;
    479 
    480     /* Source Object can be either an OpRegion or a Buffer/Field */
    481 
    482     switch (ObjDesc->Common.Type)
    483     {
    484     case ACPI_TYPE_REGION:
    485 
    486         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    487             "Load table from Region %p\n", ObjDesc));
    488 
    489         /* Region must be SystemMemory (from ACPI spec) */
    490 
    491         if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
    492         {
    493             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    494         }
    495 
    496         /*
    497          * If the Region Address and Length have not been previously
    498          * evaluated, evaluate them now and save the results.
    499          */
    500         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
    501         {
    502             Status = AcpiDsGetRegionArguments (ObjDesc);
    503             if (ACPI_FAILURE (Status))
    504             {
    505                 return_ACPI_STATUS (Status);
    506             }
    507         }
    508 
    509         /* Get the table header first so we can get the table length */
    510 
    511         TableHeader = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
    512         if (!TableHeader)
    513         {
    514             return_ACPI_STATUS (AE_NO_MEMORY);
    515         }
    516 
    517         Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
    518             ACPI_CAST_PTR (UINT8, TableHeader));
    519         Length = TableHeader->Length;
    520         ACPI_FREE (TableHeader);
    521 
    522         if (ACPI_FAILURE (Status))
    523         {
    524             return_ACPI_STATUS (Status);
    525         }
    526 
    527         /* Must have at least an ACPI table header */
    528 
    529         if (Length < sizeof (ACPI_TABLE_HEADER))
    530         {
    531             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    532         }
    533 
    534         /*
    535          * The original implementation simply mapped the table, with no copy.
    536          * However, the memory region is not guaranteed to remain stable and
    537          * we must copy the table to a local buffer. For example, the memory
    538          * region is corrupted after suspend on some machines. Dynamically
    539          * loaded tables are usually small, so this overhead is minimal.
    540          *
    541          * The latest implementation (5/2009) does not use a mapping at all.
    542          * We use the low-level operation region interface to read the table
    543          * instead of the obvious optimization of using a direct mapping.
    544          * This maintains a consistent use of operation regions across the
    545          * entire subsystem. This is important if additional processing must
    546          * be performed in the (possibly user-installed) operation region
    547          * handler. For example, AcpiExec and ASLTS depend on this.
    548          */
    549 
    550         /* Allocate a buffer for the table */
    551 
    552         Table = ACPI_ALLOCATE (Length);
    553         if (!Table)
    554         {
    555             return_ACPI_STATUS (AE_NO_MEMORY);
    556         }
    557 
    558         /* Read the entire table */
    559 
    560         Status = AcpiExRegionRead (ObjDesc, Length,
    561             ACPI_CAST_PTR (UINT8, Table));
    562         if (ACPI_FAILURE (Status))
    563         {
    564             ACPI_FREE (Table);
    565             return_ACPI_STATUS (Status);
    566         }
    567         break;
    568 
    569     case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */
    570 
    571         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    572             "Load table from Buffer or Field %p\n", ObjDesc));
    573 
    574         /* Must have at least an ACPI table header */
    575 
    576         if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
    577         {
    578             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    579         }
    580 
    581         /* Get the actual table length from the table header */
    582 
    583         TableHeader = ACPI_CAST_PTR (
    584             ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
    585         Length = TableHeader->Length;
    586 
    587         /* Table cannot extend beyond the buffer */
    588 
    589         if (Length > ObjDesc->Buffer.Length)
    590         {
    591             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
    592         }
    593         if (Length < sizeof (ACPI_TABLE_HEADER))
    594         {
    595             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    596         }
    597 
    598         /*
    599          * Copy the table from the buffer because the buffer could be
    600          * modified or even deleted in the future
    601          */
    602         Table = ACPI_ALLOCATE (Length);
    603         if (!Table)
    604         {
    605             return_ACPI_STATUS (AE_NO_MEMORY);
    606         }
    607 
    608         memcpy (Table, TableHeader, Length);
    609         break;
    610 
    611     default:
    612 
    613         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    614     }
    615 
    616     /* Install the new table into the local data structures */
    617 
    618     ACPI_INFO (("Dynamic OEM Table Load:"));
    619     AcpiExExitInterpreter ();
    620     Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table),
    621         ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table, TRUE, &TableIndex);
    622     AcpiExEnterInterpreter ();
    623     if (ACPI_FAILURE (Status))
    624     {
    625         /* Delete allocated table buffer */
    626 
    627         ACPI_FREE (Table);
    628         return_ACPI_STATUS (Status);
    629     }
    630 
    631     /*
    632      * Add the table to the namespace.
    633      *
    634      * Note: Load the table objects relative to the root of the namespace.
    635      * This appears to go against the ACPI specification, but we do it for
    636      * compatibility with other ACPI implementations.
    637      */
    638     Status = AcpiExAddTable (TableIndex, &DdbHandle);
    639     if (ACPI_FAILURE (Status))
    640     {
    641         return_ACPI_STATUS (Status);
    642     }
    643 
    644     /* Complete the initialization/resolution of new objects */
    645 
    646     AcpiExExitInterpreter ();
    647     AcpiNsInitializeObjects ();
    648     AcpiExEnterInterpreter ();
    649 
    650     /* Remove the reference to DdbHandle created by AcpiExAddTable above */
    651 
    652     AcpiUtRemoveReference (DdbHandle);
    653 
    654     /* Return -1 (non-zero) indicates success */
    655 
    656     Target->Integer.Value = 0xFFFFFFFFFFFFFFFF;
    657     return_ACPI_STATUS (Status);
    658 }
    659 
    660 
    661 /*******************************************************************************
    662  *
    663  * FUNCTION:    AcpiExUnloadTable
    664  *
    665  * PARAMETERS:  DdbHandle           - Handle to a previously loaded table
    666  *
    667  * RETURN:      Status
    668  *
    669  * DESCRIPTION: Unload an ACPI table
    670  *
    671  ******************************************************************************/
    672 
    673 ACPI_STATUS
    674 AcpiExUnloadTable (
    675     ACPI_OPERAND_OBJECT     *DdbHandle)
    676 {
    677     ACPI_STATUS             Status = AE_OK;
    678     ACPI_OPERAND_OBJECT     *TableDesc = DdbHandle;
    679     UINT32                  TableIndex;
    680 
    681 
    682     ACPI_FUNCTION_TRACE (ExUnloadTable);
    683 
    684 
    685     /*
    686      * Temporarily emit a warning so that the ASL for the machine can be
    687      * hopefully obtained. This is to say that the Unload() operator is
    688      * extremely rare if not completely unused.
    689      */
    690     ACPI_WARNING ((AE_INFO,
    691         "Received request to unload an ACPI table"));
    692 
    693     /*
    694      * May 2018: Unload is no longer supported for the following reasons:
    695      * 1) A correct implementation on some hosts may not be possible.
    696      * 2) Other ACPI implementations do not correctly/fully support it.
    697      * 3) It requires host device driver support which does not exist.
    698      *    (To properly support namespace unload out from underneath.)
    699      * 4) This AML operator has never been seen in the field.
    700      */
    701     ACPI_EXCEPTION ((AE_INFO, AE_NOT_IMPLEMENTED,
    702         "AML Unload operator is not supported"));
    703 
    704     /*
    705      * Validate the handle
    706      * Although the handle is partially validated in AcpiExReconfiguration()
    707      * when it calls AcpiExResolveOperands(), the handle is more completely
    708      * validated here.
    709      *
    710      * Handle must be a valid operand object of type reference. Also, the
    711      * DdbHandle must still be marked valid (table has not been previously
    712      * unloaded)
    713      */
    714     if ((!DdbHandle) ||
    715         (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
    716         (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
    717         (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
    718     {
    719         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    720     }
    721 
    722     /* Get the table index from the DdbHandle */
    723 
    724     TableIndex = TableDesc->Reference.Value;
    725 
    726     /*
    727      * Release the interpreter lock so that the table lock won't have
    728      * strict order requirement against it.
    729      */
    730     AcpiExExitInterpreter ();
    731     Status = AcpiTbUnloadTable (TableIndex);
    732     AcpiExEnterInterpreter ();
    733 
    734     /*
    735      * Invalidate the handle. We do this because the handle may be stored
    736      * in a named object and may not be actually deleted until much later.
    737      */
    738     if (ACPI_SUCCESS (Status))
    739     {
    740         DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
    741     }
    742     return_ACPI_STATUS (Status);
    743 }
    744