1 /****************************************************************************** 2 * 3 * Module Name: dsinit - Object initialization namespace walk 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acdispat.h" 47 #include "acnamesp.h" 48 #include "actables.h" 49 #include "acinterp.h" 50 51 #define _COMPONENT ACPI_DISPATCHER 52 ACPI_MODULE_NAME ("dsinit") 53 54 55 /* Local prototypes */ 56 57 static ACPI_STATUS 58 AcpiDsInitOneObject ( 59 ACPI_HANDLE ObjHandle, 60 UINT32 Level, 61 void *Context, 62 void **ReturnValue); 63 64 65 /******************************************************************************* 66 * 67 * FUNCTION: AcpiDsInitOneObject 68 * 69 * PARAMETERS: ObjHandle - Node for the object 70 * Level - Current nesting level 71 * Context - Points to a init info struct 72 * ReturnValue - Not used 73 * 74 * RETURN: Status 75 * 76 * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object 77 * within the namespace. 78 * 79 * Currently, the only objects that require initialization are: 80 * 1) Methods 81 * 2) Operation Regions 82 * 83 ******************************************************************************/ 84 85 static ACPI_STATUS 86 AcpiDsInitOneObject ( 87 ACPI_HANDLE ObjHandle, 88 UINT32 Level, 89 void *Context, 90 void **ReturnValue) 91 { 92 ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context; 93 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 94 ACPI_STATUS Status; 95 ACPI_OPERAND_OBJECT *ObjDesc; 96 97 98 ACPI_FUNCTION_ENTRY (); 99 100 101 /* 102 * We are only interested in NS nodes owned by the table that 103 * was just loaded 104 */ 105 if (Node->OwnerId != Info->OwnerId) 106 { 107 return (AE_OK); 108 } 109 110 Info->ObjectCount++; 111 112 /* And even then, we are only interested in a few object types */ 113 114 switch (AcpiNsGetType (ObjHandle)) 115 { 116 case ACPI_TYPE_REGION: 117 118 Status = AcpiDsInitializeRegion (ObjHandle); 119 if (ACPI_FAILURE (Status)) 120 { 121 ACPI_EXCEPTION ((AE_INFO, Status, 122 "During Region initialization %p [%4.4s]", 123 ObjHandle, AcpiUtGetNodeName (ObjHandle))); 124 } 125 126 Info->OpRegionCount++; 127 break; 128 129 case ACPI_TYPE_METHOD: 130 /* 131 * Auto-serialization support. We will examine each method that is 132 * NotSerialized to determine if it creates any Named objects. If 133 * it does, it will be marked serialized to prevent problems if 134 * the method is entered by two or more threads and an attempt is 135 * made to create the same named object twice -- which results in 136 * an AE_ALREADY_EXISTS exception and method abort. 137 */ 138 Info->MethodCount++; 139 ObjDesc = AcpiNsGetAttachedObject (Node); 140 if (!ObjDesc) 141 { 142 break; 143 } 144 145 /* Ignore if already serialized */ 146 147 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) 148 { 149 Info->SerialMethodCount++; 150 break; 151 } 152 153 if (AcpiGbl_AutoSerializeMethods) 154 { 155 /* Parse/scan method and serialize it if necessary */ 156 157 AcpiDsAutoSerializeMethod (Node, ObjDesc); 158 if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) 159 { 160 /* Method was just converted to Serialized */ 161 162 Info->SerialMethodCount++; 163 Info->SerializedMethodCount++; 164 break; 165 } 166 } 167 168 Info->NonSerialMethodCount++; 169 break; 170 171 case ACPI_TYPE_DEVICE: 172 173 Info->DeviceCount++; 174 break; 175 176 default: 177 178 break; 179 } 180 181 /* 182 * We ignore errors from above, and always return OK, since 183 * we don't want to abort the walk on a single error. 184 */ 185 return (AE_OK); 186 } 187 188 189 /******************************************************************************* 190 * 191 * FUNCTION: AcpiDsInitializeObjects 192 * 193 * PARAMETERS: TableDesc - Descriptor for parent ACPI table 194 * StartNode - Root of subtree to be initialized. 195 * 196 * RETURN: Status 197 * 198 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any 199 * necessary initialization on the objects found therein 200 * 201 ******************************************************************************/ 202 203 ACPI_STATUS 204 AcpiDsInitializeObjects ( 205 UINT32 TableIndex, 206 ACPI_NAMESPACE_NODE *StartNode) 207 { 208 ACPI_STATUS Status; 209 ACPI_INIT_WALK_INFO Info; 210 ACPI_TABLE_HEADER *Table; 211 ACPI_OWNER_ID OwnerId; 212 213 214 ACPI_FUNCTION_TRACE (DsInitializeObjects); 215 216 217 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 218 if (ACPI_FAILURE (Status)) 219 { 220 return_ACPI_STATUS (Status); 221 } 222 223 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 224 "**** Starting initialization of namespace objects ****\n")); 225 226 /* Set all init info to zero */ 227 228 memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO)); 229 230 Info.OwnerId = OwnerId; 231 Info.TableIndex = TableIndex; 232 233 /* Walk entire namespace from the supplied root */ 234 235 /* 236 * We don't use AcpiWalkNamespace since we do not want to acquire 237 * the namespace reader lock. 238 */ 239 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, 240 ACPI_NS_WALK_NO_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); 241 if (ACPI_FAILURE (Status)) 242 { 243 ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); 244 } 245 246 Status = AcpiGetTableByIndex (TableIndex, &Table); 247 if (ACPI_FAILURE (Status)) 248 { 249 return_ACPI_STATUS (Status); 250 } 251 252 /* DSDT is always the first AML table */ 253 254 if (ACPI_COMPARE_NAMESEG (Table->Signature, ACPI_SIG_DSDT)) 255 { 256 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 257 "\nACPI table initialization:\n")); 258 } 259 260 /* Summary of objects initialized */ 261 262 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 263 "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, " 264 "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n", 265 Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount, 266 Info.DeviceCount,Info.OpRegionCount, Info.MethodCount, 267 Info.SerialMethodCount, Info.NonSerialMethodCount, 268 Info.SerializedMethodCount)); 269 270 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n", 271 Info.MethodCount, Info.OpRegionCount)); 272 273 return_ACPI_STATUS (AE_OK); 274 } 275