xref: /netbsd-src/sys/external/bsd/acpica/dist/dispatcher/dsinit.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
128c506b8Sjruoho /******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: dsinit - Object initialization namespace walk
428c506b8Sjruoho  *
528c506b8Sjruoho  *****************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "acpi.h"
4528c506b8Sjruoho #include "accommon.h"
4628c506b8Sjruoho #include "acdispat.h"
4728c506b8Sjruoho #include "acnamesp.h"
4828c506b8Sjruoho #include "actables.h"
490b89cdedSchristos #include "acinterp.h"
5028c506b8Sjruoho 
5128c506b8Sjruoho #define _COMPONENT          ACPI_DISPATCHER
5228c506b8Sjruoho         ACPI_MODULE_NAME    ("dsinit")
5328c506b8Sjruoho 
54460301d4Schristos 
5528c506b8Sjruoho /* Local prototypes */
5628c506b8Sjruoho 
5728c506b8Sjruoho static ACPI_STATUS
5828c506b8Sjruoho AcpiDsInitOneObject (
5928c506b8Sjruoho     ACPI_HANDLE             ObjHandle,
6028c506b8Sjruoho     UINT32                  Level,
6128c506b8Sjruoho     void                    *Context,
6228c506b8Sjruoho     void                    **ReturnValue);
6328c506b8Sjruoho 
6428c506b8Sjruoho 
6528c506b8Sjruoho /*******************************************************************************
6628c506b8Sjruoho  *
6728c506b8Sjruoho  * FUNCTION:    AcpiDsInitOneObject
6828c506b8Sjruoho  *
6928c506b8Sjruoho  * PARAMETERS:  ObjHandle       - Node for the object
7028c506b8Sjruoho  *              Level           - Current nesting level
7128c506b8Sjruoho  *              Context         - Points to a init info struct
7228c506b8Sjruoho  *              ReturnValue     - Not used
7328c506b8Sjruoho  *
7428c506b8Sjruoho  * RETURN:      Status
7528c506b8Sjruoho  *
7628c506b8Sjruoho  * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
7728c506b8Sjruoho  *              within the namespace.
7828c506b8Sjruoho  *
7928c506b8Sjruoho  *              Currently, the only objects that require initialization are:
8028c506b8Sjruoho  *              1) Methods
8128c506b8Sjruoho  *              2) Operation Regions
8228c506b8Sjruoho  *
8328c506b8Sjruoho  ******************************************************************************/
8428c506b8Sjruoho 
8528c506b8Sjruoho static ACPI_STATUS
AcpiDsInitOneObject(ACPI_HANDLE ObjHandle,UINT32 Level,void * Context,void ** ReturnValue)8628c506b8Sjruoho AcpiDsInitOneObject (
8728c506b8Sjruoho     ACPI_HANDLE             ObjHandle,
8828c506b8Sjruoho     UINT32                  Level,
8928c506b8Sjruoho     void                    *Context,
9028c506b8Sjruoho     void                    **ReturnValue)
9128c506b8Sjruoho {
9228c506b8Sjruoho     ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
9328c506b8Sjruoho     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
9428c506b8Sjruoho     ACPI_STATUS             Status;
95460301d4Schristos     ACPI_OPERAND_OBJECT     *ObjDesc;
9628c506b8Sjruoho 
9728c506b8Sjruoho 
9828c506b8Sjruoho     ACPI_FUNCTION_ENTRY ();
9928c506b8Sjruoho 
10028c506b8Sjruoho 
10128c506b8Sjruoho     /*
10228c506b8Sjruoho      * We are only interested in NS nodes owned by the table that
10328c506b8Sjruoho      * was just loaded
10428c506b8Sjruoho      */
10528c506b8Sjruoho     if (Node->OwnerId != Info->OwnerId)
10628c506b8Sjruoho     {
10728c506b8Sjruoho         return (AE_OK);
10828c506b8Sjruoho     }
10928c506b8Sjruoho 
11028c506b8Sjruoho     Info->ObjectCount++;
11128c506b8Sjruoho 
11228c506b8Sjruoho     /* And even then, we are only interested in a few object types */
11328c506b8Sjruoho 
114460301d4Schristos     switch (AcpiNsGetType (ObjHandle))
11528c506b8Sjruoho     {
11628c506b8Sjruoho     case ACPI_TYPE_REGION:
11728c506b8Sjruoho 
11828c506b8Sjruoho         Status = AcpiDsInitializeRegion (ObjHandle);
11928c506b8Sjruoho         if (ACPI_FAILURE (Status))
12028c506b8Sjruoho         {
12128c506b8Sjruoho             ACPI_EXCEPTION ((AE_INFO, Status,
12228c506b8Sjruoho                 "During Region initialization %p [%4.4s]",
12328c506b8Sjruoho                 ObjHandle, AcpiUtGetNodeName (ObjHandle)));
12428c506b8Sjruoho         }
12528c506b8Sjruoho 
12628c506b8Sjruoho         Info->OpRegionCount++;
12728c506b8Sjruoho         break;
12828c506b8Sjruoho 
12928c506b8Sjruoho     case ACPI_TYPE_METHOD:
130460301d4Schristos         /*
131460301d4Schristos          * Auto-serialization support. We will examine each method that is
132460301d4Schristos          * NotSerialized to determine if it creates any Named objects. If
133460301d4Schristos          * it does, it will be marked serialized to prevent problems if
134460301d4Schristos          * the method is entered by two or more threads and an attempt is
135460301d4Schristos          * made to create the same named object twice -- which results in
136460301d4Schristos          * an AE_ALREADY_EXISTS exception and method abort.
137460301d4Schristos          */
13828c506b8Sjruoho         Info->MethodCount++;
139460301d4Schristos         ObjDesc = AcpiNsGetAttachedObject (Node);
140460301d4Schristos         if (!ObjDesc)
141460301d4Schristos         {
142460301d4Schristos             break;
143460301d4Schristos         }
144460301d4Schristos 
145460301d4Schristos         /* Ignore if already serialized */
146460301d4Schristos 
147460301d4Schristos         if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
148460301d4Schristos         {
149460301d4Schristos             Info->SerialMethodCount++;
150460301d4Schristos             break;
151460301d4Schristos         }
152460301d4Schristos 
153460301d4Schristos         if (AcpiGbl_AutoSerializeMethods)
154460301d4Schristos         {
155460301d4Schristos             /* Parse/scan method and serialize it if necessary */
156460301d4Schristos 
157460301d4Schristos             AcpiDsAutoSerializeMethod (Node, ObjDesc);
158460301d4Schristos             if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
159460301d4Schristos             {
160460301d4Schristos                 /* Method was just converted to Serialized */
161460301d4Schristos 
162460301d4Schristos                 Info->SerialMethodCount++;
163460301d4Schristos                 Info->SerializedMethodCount++;
164460301d4Schristos                 break;
165460301d4Schristos             }
166460301d4Schristos         }
167460301d4Schristos 
168460301d4Schristos         Info->NonSerialMethodCount++;
16928c506b8Sjruoho         break;
17028c506b8Sjruoho 
17128c506b8Sjruoho     case ACPI_TYPE_DEVICE:
17228c506b8Sjruoho 
17328c506b8Sjruoho         Info->DeviceCount++;
17428c506b8Sjruoho         break;
17528c506b8Sjruoho 
17628c506b8Sjruoho     default:
177ff4a156dSchristos 
17828c506b8Sjruoho         break;
17928c506b8Sjruoho     }
18028c506b8Sjruoho 
18128c506b8Sjruoho     /*
18228c506b8Sjruoho      * We ignore errors from above, and always return OK, since
18328c506b8Sjruoho      * we don't want to abort the walk on a single error.
18428c506b8Sjruoho      */
18528c506b8Sjruoho     return (AE_OK);
18628c506b8Sjruoho }
18728c506b8Sjruoho 
18828c506b8Sjruoho 
18928c506b8Sjruoho /*******************************************************************************
19028c506b8Sjruoho  *
19128c506b8Sjruoho  * FUNCTION:    AcpiDsInitializeObjects
19228c506b8Sjruoho  *
19328c506b8Sjruoho  * PARAMETERS:  TableDesc       - Descriptor for parent ACPI table
19428c506b8Sjruoho  *              StartNode       - Root of subtree to be initialized.
19528c506b8Sjruoho  *
19628c506b8Sjruoho  * RETURN:      Status
19728c506b8Sjruoho  *
19828c506b8Sjruoho  * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
19928c506b8Sjruoho  *              necessary initialization on the objects found therein
20028c506b8Sjruoho  *
20128c506b8Sjruoho  ******************************************************************************/
20228c506b8Sjruoho 
20328c506b8Sjruoho ACPI_STATUS
AcpiDsInitializeObjects(UINT32 TableIndex,ACPI_NAMESPACE_NODE * StartNode)20428c506b8Sjruoho AcpiDsInitializeObjects (
20528c506b8Sjruoho     UINT32                  TableIndex,
20628c506b8Sjruoho     ACPI_NAMESPACE_NODE     *StartNode)
20728c506b8Sjruoho {
20828c506b8Sjruoho     ACPI_STATUS             Status;
20928c506b8Sjruoho     ACPI_INIT_WALK_INFO     Info;
21028c506b8Sjruoho     ACPI_TABLE_HEADER       *Table;
21128c506b8Sjruoho     ACPI_OWNER_ID           OwnerId;
21228c506b8Sjruoho 
21328c506b8Sjruoho 
21428c506b8Sjruoho     ACPI_FUNCTION_TRACE (DsInitializeObjects);
21528c506b8Sjruoho 
21628c506b8Sjruoho 
21728c506b8Sjruoho     Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
21828c506b8Sjruoho     if (ACPI_FAILURE (Status))
21928c506b8Sjruoho     {
22028c506b8Sjruoho         return_ACPI_STATUS (Status);
22128c506b8Sjruoho     }
22228c506b8Sjruoho 
22328c506b8Sjruoho     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
22428c506b8Sjruoho         "**** Starting initialization of namespace objects ****\n"));
22528c506b8Sjruoho 
22628c506b8Sjruoho     /* Set all init info to zero */
22728c506b8Sjruoho 
228c72da027Schristos     memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
22928c506b8Sjruoho 
23028c506b8Sjruoho     Info.OwnerId = OwnerId;
23128c506b8Sjruoho     Info.TableIndex = TableIndex;
23228c506b8Sjruoho 
23328c506b8Sjruoho     /* Walk entire namespace from the supplied root */
23428c506b8Sjruoho 
23528c506b8Sjruoho     /*
23628c506b8Sjruoho      * We don't use AcpiWalkNamespace since we do not want to acquire
23728c506b8Sjruoho      * the namespace reader lock.
23828c506b8Sjruoho      */
23928c506b8Sjruoho     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
2400b89cdedSchristos         ACPI_NS_WALK_NO_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
24128c506b8Sjruoho     if (ACPI_FAILURE (Status))
24228c506b8Sjruoho     {
24328c506b8Sjruoho         ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
24428c506b8Sjruoho     }
24528c506b8Sjruoho 
24628c506b8Sjruoho     Status = AcpiGetTableByIndex (TableIndex, &Table);
24728c506b8Sjruoho     if (ACPI_FAILURE (Status))
24828c506b8Sjruoho     {
24928c506b8Sjruoho         return_ACPI_STATUS (Status);
25028c506b8Sjruoho     }
25128c506b8Sjruoho 
25271e38f1dSchristos     /* DSDT is always the first AML table */
25371e38f1dSchristos 
25494783addSchristos     if (ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_DSDT))
25571e38f1dSchristos     {
25628c506b8Sjruoho         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
257783af925Schristos             "\nACPI table initialization:\n"));
25871e38f1dSchristos     }
25971e38f1dSchristos 
26071e38f1dSchristos     /* Summary of objects initialized */
26171e38f1dSchristos 
26271e38f1dSchristos     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
26371e38f1dSchristos         "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "
26471e38f1dSchristos         "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n",
26571e38f1dSchristos         Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount,
26671e38f1dSchristos         Info.DeviceCount,Info.OpRegionCount, Info.MethodCount,
26771e38f1dSchristos         Info.SerialMethodCount, Info.NonSerialMethodCount,
26871e38f1dSchristos         Info.SerializedMethodCount));
26928c506b8Sjruoho 
270460301d4Schristos     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
271460301d4Schristos         Info.MethodCount, Info.OpRegionCount));
27228c506b8Sjruoho 
27328c506b8Sjruoho     return_ACPI_STATUS (AE_OK);
27428c506b8Sjruoho }
275