Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:02

0001 /******************************************************************************
0002  *
0003  * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086 
0087  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0089  * PARTICULAR PURPOSE.
0090  *
0091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0098  * LIMITED REMEDY.
0099  *
0100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0101  * software or system incorporating such software without first obtaining any
0102  * required license or other approval from the U. S. Department of Commerce or
0103  * any other agency or department of the United States Government. In the
0104  * event Licensee exports any such software from the United States or
0105  * re-exports any such software from a foreign destination, Licensee shall
0106  * ensure that the distribution and export/re-export of the software is in
0107  * compliance with all laws, regulations, orders, or other restrictions of the
0108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0109  * any of its subsidiaries will export/re-export any technical data, process,
0110  * software, or service, directly or indirectly, to any country for which the
0111  * United States government or any agency thereof requires an export license,
0112  * other governmental approval, or letter of assurance, without first obtaining
0113  * such license, approval or letter.
0114  *
0115  *****************************************************************************
0116  *
0117  * Alternatively, you may choose to be licensed under the terms of the
0118  * following license:
0119  *
0120  * Redistribution and use in source and binary forms, with or without
0121  * modification, are permitted provided that the following conditions
0122  * are met:
0123  * 1. Redistributions of source code must retain the above copyright
0124  *    notice, this list of conditions, and the following disclaimer,
0125  *    without modification.
0126  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0127  *    substantially similar to the "NO WARRANTY" disclaimer below
0128  *    ("Disclaimer") and any redistribution must be conditioned upon
0129  *    including a substantially similar Disclaimer requirement for further
0130  *    binary redistribution.
0131  * 3. Neither the names of the above-listed copyright holders nor the names
0132  *    of any contributors may be used to endorse or promote products derived
0133  *    from this software without specific prior written permission.
0134  *
0135  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0136  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0137  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0138  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0139  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0140  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0141  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0142  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0143  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0144  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0145  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0146  *
0147  * Alternatively, you may choose to be licensed under the terms of the
0148  * GNU General Public License ("GPL") version 2 as published by the Free
0149  * Software Foundation.
0150  *
0151  *****************************************************************************/
0152 
0153 #include "acpi.h"
0154 #include "accommon.h"
0155 #include "acinterp.h"
0156 #include "acnamesp.h"
0157 #include "actables.h"
0158 #include "acdispat.h"
0159 #include "acevents.h"
0160 #include "amlcode.h"
0161 
0162 
0163 #define _COMPONENT          ACPI_EXECUTER
0164         ACPI_MODULE_NAME    ("exconfig")
0165 
0166 /* Local prototypes */
0167 
0168 static ACPI_STATUS
0169 AcpiExAddTable (
0170     UINT32                  TableIndex,
0171     ACPI_OPERAND_OBJECT     **DdbHandle);
0172 
0173 static ACPI_STATUS
0174 AcpiExRegionRead (
0175     ACPI_OPERAND_OBJECT     *ObjDesc,
0176     UINT32                  Length,
0177     UINT8                   *Buffer);
0178 
0179 
0180 /*******************************************************************************
0181  *
0182  * FUNCTION:    AcpiExAddTable
0183  *
0184  * PARAMETERS:  Table               - Pointer to raw table
0185  *              ParentNode          - Where to load the table (scope)
0186  *              DdbHandle           - Where to return the table handle.
0187  *
0188  * RETURN:      Status
0189  *
0190  * DESCRIPTION: Common function to Install and Load an ACPI table with a
0191  *              returned table handle.
0192  *
0193  ******************************************************************************/
0194 
0195 static ACPI_STATUS
0196 AcpiExAddTable (
0197     UINT32                  TableIndex,
0198     ACPI_OPERAND_OBJECT     **DdbHandle)
0199 {
0200     ACPI_OPERAND_OBJECT     *ObjDesc;
0201 
0202 
0203     ACPI_FUNCTION_TRACE (ExAddTable);
0204 
0205 
0206     /* Create an object to be the table handle */
0207 
0208     ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
0209     if (!ObjDesc)
0210     {
0211         return_ACPI_STATUS (AE_NO_MEMORY);
0212     }
0213 
0214     /* Init the table handle */
0215 
0216     ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
0217     ObjDesc->Reference.Class = ACPI_REFCLASS_TABLE;
0218     ObjDesc->Reference.Value = TableIndex;
0219     *DdbHandle = ObjDesc;
0220     return_ACPI_STATUS (AE_OK);
0221 }
0222 
0223 
0224 /*******************************************************************************
0225  *
0226  * FUNCTION:    AcpiExLoadTableOp
0227  *
0228  * PARAMETERS:  WalkState           - Current state with operands
0229  *              ReturnDesc          - Where to store the return object
0230  *
0231  * RETURN:      Status
0232  *
0233  * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
0234  *
0235  ******************************************************************************/
0236 
0237 ACPI_STATUS
0238 AcpiExLoadTableOp (
0239     ACPI_WALK_STATE         *WalkState,
0240     ACPI_OPERAND_OBJECT     **ReturnDesc)
0241 {
0242     ACPI_STATUS             Status;
0243     ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
0244     ACPI_NAMESPACE_NODE     *ParentNode;
0245     ACPI_NAMESPACE_NODE     *StartNode;
0246     ACPI_NAMESPACE_NODE     *ParameterNode = NULL;
0247     ACPI_OPERAND_OBJECT     *ReturnObj;
0248     ACPI_OPERAND_OBJECT     *DdbHandle;
0249     UINT32                  TableIndex;
0250 
0251 
0252     ACPI_FUNCTION_TRACE (ExLoadTableOp);
0253 
0254 
0255     /* Create the return object */
0256 
0257     ReturnObj = AcpiUtCreateIntegerObject ((UINT64) 0);
0258     if (!ReturnObj)
0259     {
0260         return_ACPI_STATUS (AE_NO_MEMORY);
0261     }
0262 
0263     *ReturnDesc = ReturnObj;
0264 
0265     /* Find the ACPI table in the RSDT/XSDT */
0266 
0267     AcpiExExitInterpreter ();
0268     Status = AcpiTbFindTable (
0269         Operand[0]->String.Pointer,
0270         Operand[1]->String.Pointer,
0271         Operand[2]->String.Pointer, &TableIndex);
0272     AcpiExEnterInterpreter ();
0273     if (ACPI_FAILURE (Status))
0274     {
0275         if (Status != AE_NOT_FOUND)
0276         {
0277             return_ACPI_STATUS (Status);
0278         }
0279 
0280         /* Table not found, return an Integer=0 and AE_OK */
0281 
0282         return_ACPI_STATUS (AE_OK);
0283     }
0284 
0285     /* Default nodes */
0286 
0287     StartNode = WalkState->ScopeInfo->Scope.Node;
0288     ParentNode = AcpiGbl_RootNode;
0289 
0290     /* RootPath (optional parameter) */
0291 
0292     if (Operand[3]->String.Length > 0)
0293     {
0294         /*
0295          * Find the node referenced by the RootPathString. This is the
0296          * location within the namespace where the table will be loaded.
0297          */
0298         Status = AcpiNsGetNodeUnlocked (StartNode,
0299             Operand[3]->String.Pointer, ACPI_NS_SEARCH_PARENT,
0300             &ParentNode);
0301         if (ACPI_FAILURE (Status))
0302         {
0303             return_ACPI_STATUS (Status);
0304         }
0305     }
0306 
0307     /* ParameterPath (optional parameter) */
0308 
0309     if (Operand[4]->String.Length > 0)
0310     {
0311         if ((Operand[4]->String.Pointer[0] != AML_ROOT_PREFIX) &&
0312             (Operand[4]->String.Pointer[0] != AML_PARENT_PREFIX))
0313         {
0314             /*
0315              * Path is not absolute, so it will be relative to the node
0316              * referenced by the RootPathString (or the NS root if omitted)
0317              */
0318             StartNode = ParentNode;
0319         }
0320 
0321         /* Find the node referenced by the ParameterPathString */
0322 
0323         Status = AcpiNsGetNodeUnlocked (StartNode,
0324             Operand[4]->String.Pointer, ACPI_NS_SEARCH_PARENT,
0325             &ParameterNode);
0326         if (ACPI_FAILURE (Status))
0327         {
0328             return_ACPI_STATUS (Status);
0329         }
0330     }
0331 
0332     /* Load the table into the namespace */
0333 
0334     ACPI_INFO (("Dynamic OEM Table Load:"));
0335     AcpiExExitInterpreter ();
0336     Status = AcpiTbLoadTable (TableIndex, ParentNode);
0337     AcpiExEnterInterpreter ();
0338     if (ACPI_FAILURE (Status))
0339     {
0340         return_ACPI_STATUS (Status);
0341     }
0342 
0343     Status = AcpiExAddTable (TableIndex, &DdbHandle);
0344     if (ACPI_FAILURE (Status))
0345     {
0346         return_ACPI_STATUS (Status);
0347     }
0348 
0349     /* Complete the initialization/resolution of new objects */
0350 
0351     AcpiExExitInterpreter();
0352     AcpiNsInitializeObjects();
0353     AcpiExEnterInterpreter();
0354 
0355     /* Parameter Data (optional) */
0356 
0357     if (ParameterNode)
0358     {
0359         /* Store the parameter data into the optional parameter object */
0360 
0361         Status = AcpiExStore (Operand[5],
0362             ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParameterNode), WalkState);
0363         if (ACPI_FAILURE (Status))
0364         {
0365             (void) AcpiExUnloadTable (DdbHandle);
0366 
0367             AcpiUtRemoveReference (DdbHandle);
0368             return_ACPI_STATUS (Status);
0369         }
0370     }
0371 
0372     /* Remove the reference to DdbHandle created by AcpiExAddTable above */
0373 
0374     AcpiUtRemoveReference (DdbHandle);
0375 
0376     /* Return -1 (non-zero) indicates success */
0377 
0378     ReturnObj->Integer.Value = 0xFFFFFFFFFFFFFFFF;
0379     return_ACPI_STATUS (Status);
0380 }
0381 
0382 
0383 /*******************************************************************************
0384  *
0385  * FUNCTION:    AcpiExRegionRead
0386  *
0387  * PARAMETERS:  ObjDesc         - Region descriptor
0388  *              Length          - Number of bytes to read
0389  *              Buffer          - Pointer to where to put the data
0390  *
0391  * RETURN:      Status
0392  *
0393  * DESCRIPTION: Read data from an operation region. The read starts from the
0394  *              beginning of the region.
0395  *
0396  ******************************************************************************/
0397 
0398 static ACPI_STATUS
0399 AcpiExRegionRead (
0400     ACPI_OPERAND_OBJECT     *ObjDesc,
0401     UINT32                  Length,
0402     UINT8                   *Buffer)
0403 {
0404     ACPI_STATUS             Status;
0405     UINT64                  Value;
0406     UINT32                  RegionOffset = 0;
0407     UINT32                  i;
0408 
0409 
0410     /* Bytewise reads */
0411 
0412     for (i = 0; i < Length; i++)
0413     {
0414         Status = AcpiEvAddressSpaceDispatch (ObjDesc, NULL, ACPI_READ,
0415             RegionOffset, 8, &Value);
0416         if (ACPI_FAILURE (Status))
0417         {
0418             return (Status);
0419         }
0420 
0421         *Buffer = (UINT8) Value;
0422         Buffer++;
0423         RegionOffset++;
0424     }
0425 
0426     return (AE_OK);
0427 }
0428 
0429 
0430 /*******************************************************************************
0431  *
0432  * FUNCTION:    AcpiExLoadOp
0433  *
0434  * PARAMETERS:  ObjDesc         - Region or Buffer/Field where the table will be
0435  *                                obtained
0436  *              Target          - Where the status of the load will be stored
0437  *              WalkState       - Current state
0438  *
0439  * RETURN:      Status
0440  *
0441  * DESCRIPTION: Load an ACPI table from a field or operation region
0442  *
0443  * NOTE: Region Fields (Field, BankField, IndexFields) are resolved to buffer
0444  *       objects before this code is reached.
0445  *
0446  *       If source is an operation region, it must refer to SystemMemory, as
0447  *       per the ACPI specification.
0448  *
0449  ******************************************************************************/
0450 
0451 ACPI_STATUS
0452 AcpiExLoadOp (
0453     ACPI_OPERAND_OBJECT     *ObjDesc,
0454     ACPI_OPERAND_OBJECT     *Target,
0455     ACPI_WALK_STATE         *WalkState)
0456 {
0457     ACPI_OPERAND_OBJECT     *DdbHandle;
0458     ACPI_TABLE_HEADER       *TableHeader;
0459     ACPI_TABLE_HEADER       *Table;
0460     UINT32                  TableIndex;
0461     ACPI_STATUS             Status;
0462     UINT32                  Length;
0463 
0464 
0465     ACPI_FUNCTION_TRACE (ExLoadOp);
0466 
0467 
0468     if (Target->Common.DescriptorType == ACPI_DESC_TYPE_NAMED)
0469     {
0470         Target = AcpiNsGetAttachedObject (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Target));
0471     }
0472     if (Target->Common.Type != ACPI_TYPE_INTEGER)
0473     {
0474         ACPI_ERROR ((AE_INFO, "Type not integer: %X", Target->Common.Type));
0475         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
0476     }
0477 
0478     Target->Integer.Value = 0;
0479 
0480     /* Source Object can be either an OpRegion or a Buffer/Field */
0481 
0482     switch (ObjDesc->Common.Type)
0483     {
0484     case ACPI_TYPE_REGION:
0485 
0486         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
0487             "Load table from Region %p\n", ObjDesc));
0488 
0489         /* Region must be SystemMemory (from ACPI spec) */
0490 
0491         if (ObjDesc->Region.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY)
0492         {
0493             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
0494         }
0495 
0496         /*
0497          * If the Region Address and Length have not been previously
0498          * evaluated, evaluate them now and save the results.
0499          */
0500         if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
0501         {
0502             Status = AcpiDsGetRegionArguments (ObjDesc);
0503             if (ACPI_FAILURE (Status))
0504             {
0505                 return_ACPI_STATUS (Status);
0506             }
0507         }
0508 
0509         /* Get the table header first so we can get the table length */
0510 
0511         TableHeader = ACPI_ALLOCATE (sizeof (ACPI_TABLE_HEADER));
0512         if (!TableHeader)
0513         {
0514             return_ACPI_STATUS (AE_NO_MEMORY);
0515         }
0516 
0517         Status = AcpiExRegionRead (ObjDesc, sizeof (ACPI_TABLE_HEADER),
0518             ACPI_CAST_PTR (UINT8, TableHeader));
0519         Length = TableHeader->Length;
0520         ACPI_FREE (TableHeader);
0521 
0522         if (ACPI_FAILURE (Status))
0523         {
0524             return_ACPI_STATUS (Status);
0525         }
0526 
0527         /* Must have at least an ACPI table header */
0528 
0529         if (Length < sizeof (ACPI_TABLE_HEADER))
0530         {
0531             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
0532         }
0533 
0534         /*
0535          * The original implementation simply mapped the table, with no copy.
0536          * However, the memory region is not guaranteed to remain stable and
0537          * we must copy the table to a local buffer. For example, the memory
0538          * region is corrupted after suspend on some machines. Dynamically
0539          * loaded tables are usually small, so this overhead is minimal.
0540          *
0541          * The latest implementation (5/2009) does not use a mapping at all.
0542          * We use the low-level operation region interface to read the table
0543          * instead of the obvious optimization of using a direct mapping.
0544          * This maintains a consistent use of operation regions across the
0545          * entire subsystem. This is important if additional processing must
0546          * be performed in the (possibly user-installed) operation region
0547          * handler. For example, AcpiExec and ASLTS depend on this.
0548          */
0549 
0550         /* Allocate a buffer for the table */
0551 
0552         Table = ACPI_ALLOCATE (Length);
0553         if (!Table)
0554         {
0555             return_ACPI_STATUS (AE_NO_MEMORY);
0556         }
0557 
0558         /* Read the entire table */
0559 
0560         Status = AcpiExRegionRead (ObjDesc, Length,
0561             ACPI_CAST_PTR (UINT8, Table));
0562         if (ACPI_FAILURE (Status))
0563         {
0564             ACPI_FREE (Table);
0565             return_ACPI_STATUS (Status);
0566         }
0567         break;
0568 
0569     case ACPI_TYPE_BUFFER: /* Buffer or resolved RegionField */
0570 
0571         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
0572             "Load table from Buffer or Field %p\n", ObjDesc));
0573 
0574         /* Must have at least an ACPI table header */
0575 
0576         if (ObjDesc->Buffer.Length < sizeof (ACPI_TABLE_HEADER))
0577         {
0578             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
0579         }
0580 
0581         /* Get the actual table length from the table header */
0582 
0583         TableHeader = ACPI_CAST_PTR (
0584             ACPI_TABLE_HEADER, ObjDesc->Buffer.Pointer);
0585         Length = TableHeader->Length;
0586 
0587         /* Table cannot extend beyond the buffer */
0588 
0589         if (Length > ObjDesc->Buffer.Length)
0590         {
0591             return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
0592         }
0593         if (Length < sizeof (ACPI_TABLE_HEADER))
0594         {
0595             return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
0596         }
0597 
0598         /*
0599          * Copy the table from the buffer because the buffer could be
0600          * modified or even deleted in the future
0601          */
0602         Table = ACPI_ALLOCATE (Length);
0603         if (!Table)
0604         {
0605             return_ACPI_STATUS (AE_NO_MEMORY);
0606         }
0607 
0608         memcpy (Table, TableHeader, Length);
0609         break;
0610 
0611     default:
0612 
0613         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
0614     }
0615 
0616     /* Install the new table into the local data structures */
0617 
0618     ACPI_INFO (("Dynamic OEM Table Load:"));
0619     AcpiExExitInterpreter ();
0620     Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table),
0621         ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, Table, TRUE, &TableIndex);
0622     AcpiExEnterInterpreter ();
0623     if (ACPI_FAILURE (Status))
0624     {
0625         /* Delete allocated table buffer */
0626 
0627         ACPI_FREE (Table);
0628         return_ACPI_STATUS (Status);
0629     }
0630 
0631     /*
0632      * Add the table to the namespace.
0633      *
0634      * Note: Load the table objects relative to the root of the namespace.
0635      * This appears to go against the ACPI specification, but we do it for
0636      * compatibility with other ACPI implementations.
0637      */
0638     Status = AcpiExAddTable (TableIndex, &DdbHandle);
0639     if (ACPI_FAILURE (Status))
0640     {
0641         return_ACPI_STATUS (Status);
0642     }
0643 
0644     /* Complete the initialization/resolution of new objects */
0645 
0646     AcpiExExitInterpreter ();
0647     AcpiNsInitializeObjects ();
0648     AcpiExEnterInterpreter ();
0649 
0650     /* Remove the reference to DdbHandle created by AcpiExAddTable above */
0651 
0652     AcpiUtRemoveReference (DdbHandle);
0653 
0654     /* Return -1 (non-zero) indicates success */
0655 
0656     Target->Integer.Value = 0xFFFFFFFFFFFFFFFF;
0657     return_ACPI_STATUS (Status);
0658 }
0659 
0660 
0661 /*******************************************************************************
0662  *
0663  * FUNCTION:    AcpiExUnloadTable
0664  *
0665  * PARAMETERS:  DdbHandle           - Handle to a previously loaded table
0666  *
0667  * RETURN:      Status
0668  *
0669  * DESCRIPTION: Unload an ACPI table
0670  *
0671  ******************************************************************************/
0672 
0673 ACPI_STATUS
0674 AcpiExUnloadTable (
0675     ACPI_OPERAND_OBJECT     *DdbHandle)
0676 {
0677     ACPI_STATUS             Status = AE_OK;
0678     ACPI_OPERAND_OBJECT     *TableDesc = DdbHandle;
0679     UINT32                  TableIndex;
0680 
0681 
0682     ACPI_FUNCTION_TRACE (ExUnloadTable);
0683 
0684 
0685     /*
0686      * Temporarily emit a warning so that the ASL for the machine can be
0687      * hopefully obtained. This is to say that the Unload() operator is
0688      * extremely rare if not completely unused.
0689      */
0690     ACPI_WARNING ((AE_INFO,
0691         "Received request to unload an ACPI table"));
0692 
0693     /*
0694      * May 2018: Unload is no longer supported for the following reasons:
0695      * 1) A correct implementation on some hosts may not be possible.
0696      * 2) Other ACPI implementations do not correctly/fully support it.
0697      * 3) It requires host device driver support which does not exist.
0698      *    (To properly support namespace unload out from underneath.)
0699      * 4) This AML operator has never been seen in the field.
0700      */
0701     ACPI_EXCEPTION ((AE_INFO, AE_NOT_IMPLEMENTED,
0702         "AML Unload operator is not supported"));
0703 
0704     /*
0705      * Validate the handle
0706      * Although the handle is partially validated in AcpiExReconfiguration()
0707      * when it calls AcpiExResolveOperands(), the handle is more completely
0708      * validated here.
0709      *
0710      * Handle must be a valid operand object of type reference. Also, the
0711      * DdbHandle must still be marked valid (table has not been previously
0712      * unloaded)
0713      */
0714     if ((!DdbHandle) ||
0715         (ACPI_GET_DESCRIPTOR_TYPE (DdbHandle) != ACPI_DESC_TYPE_OPERAND) ||
0716         (DdbHandle->Common.Type != ACPI_TYPE_LOCAL_REFERENCE) ||
0717         (!(DdbHandle->Common.Flags & AOPOBJ_DATA_VALID)))
0718     {
0719         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
0720     }
0721 
0722     /* Get the table index from the DdbHandle */
0723 
0724     TableIndex = TableDesc->Reference.Value;
0725 
0726     /*
0727      * Release the interpreter lock so that the table lock won't have
0728      * strict order requirement against it.
0729      */
0730     AcpiExExitInterpreter ();
0731     Status = AcpiTbUnloadTable (TableIndex);
0732     AcpiExEnterInterpreter ();
0733 
0734     /*
0735      * Invalidate the handle. We do this because the handle may be stored
0736      * in a named object and may not be actually deleted until much later.
0737      */
0738     if (ACPI_SUCCESS (Status))
0739     {
0740         DdbHandle->Common.Flags &= ~AOPOBJ_DATA_VALID;
0741     }
0742     return_ACPI_STATUS (Status);
0743 }