1/****************************************************************************** 2 * 3 * Module Name: dmextern - Support for External() ASL statements 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/include/acpi.h> 45#include <contrib/dev/acpica/include/accommon.h> 46#include <contrib/dev/acpica/include/amlcode.h> 47#include <contrib/dev/acpica/include/acnamesp.h> 48#include <contrib/dev/acpica/include/acdisasm.h> 49 50 51/* 52 * This module is used for application-level code (iASL disassembler) only. 53 * 54 * It contains the code to create and emit any necessary External() ASL 55 * statements for the module being disassembled. 56 */ 57#define _COMPONENT ACPI_CA_DISASSEMBLER 58 ACPI_MODULE_NAME ("dmextern") 59 60 61/* 62 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL 63 * ObjectTypeKeyword. Used to generate typed external declarations 64 */ 65static const char *AcpiGbl_DmTypeNames[] = 66{ 67 /* 00 */ "", /* Type ANY */ 68 /* 01 */ ", IntObj", 69 /* 02 */ ", StrObj", 70 /* 03 */ ", BuffObj", 71 /* 04 */ ", PkgObj", 72 /* 05 */ ", FieldUnitObj", 73 /* 06 */ ", DeviceObj", 74 /* 07 */ ", EventObj", 75 /* 08 */ ", MethodObj", 76 /* 09 */ ", MutexObj", 77 /* 10 */ ", OpRegionObj", 78 /* 11 */ ", PowerResObj", 79 /* 12 */ ", ProcessorObj", 80 /* 13 */ ", ThermalZoneObj", 81 /* 14 */ ", BuffFieldObj", 82 /* 15 */ ", DDBHandleObj", 83 /* 16 */ "", /* Debug object */ 84 /* 17 */ ", FieldUnitObj", 85 /* 18 */ ", FieldUnitObj", 86 /* 19 */ ", FieldUnitObj" 87}; 88 89 90/* Local prototypes */ 91 92static const char * 93AcpiDmGetObjectTypeName ( 94 ACPI_OBJECT_TYPE Type); 95 96static char * 97AcpiDmNormalizeParentPrefix ( 98 ACPI_PARSE_OBJECT *Op, 99 char *Path); 100 101 102/******************************************************************************* 103 * 104 * FUNCTION: AcpiDmGetObjectTypeName 105 * 106 * PARAMETERS: Type - An ACPI_OBJECT_TYPE 107 * 108 * RETURN: Pointer to a string 109 * 110 * DESCRIPTION: Map an object type to the ASL object type string. 111 * 112 ******************************************************************************/ 113 114static const char * 115AcpiDmGetObjectTypeName ( 116 ACPI_OBJECT_TYPE Type) 117{ 118 119 if (Type == ACPI_TYPE_LOCAL_SCOPE) 120 { 121 Type = ACPI_TYPE_DEVICE; 122 } 123 124 else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) 125 { 126 return (""); 127 } 128 129 return (AcpiGbl_DmTypeNames[Type]); 130} 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiDmNormalizeParentPrefix 136 * 137 * PARAMETERS: Op - Parse op 138 * Path - Path with parent prefix 139 * 140 * RETURN: The full pathname to the object (from the namespace root) 141 * 142 * DESCRIPTION: Returns the full pathname of a path with parent prefix 143 * The caller must free the fullpath returned. 144 * 145 ******************************************************************************/ 146 147static char * 148AcpiDmNormalizeParentPrefix ( 149 ACPI_PARSE_OBJECT *Op, 150 char *Path) 151{ 152 ACPI_NAMESPACE_NODE *Node; 153 char *Fullpath; 154 char *ParentPath; 155 ACPI_SIZE Length;
| 1/****************************************************************************** 2 * 3 * Module Name: dmextern - Support for External() ASL statements 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, 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 <contrib/dev/acpica/include/acpi.h> 45#include <contrib/dev/acpica/include/accommon.h> 46#include <contrib/dev/acpica/include/amlcode.h> 47#include <contrib/dev/acpica/include/acnamesp.h> 48#include <contrib/dev/acpica/include/acdisasm.h> 49 50 51/* 52 * This module is used for application-level code (iASL disassembler) only. 53 * 54 * It contains the code to create and emit any necessary External() ASL 55 * statements for the module being disassembled. 56 */ 57#define _COMPONENT ACPI_CA_DISASSEMBLER 58 ACPI_MODULE_NAME ("dmextern") 59 60 61/* 62 * This table maps ACPI_OBJECT_TYPEs to the corresponding ASL 63 * ObjectTypeKeyword. Used to generate typed external declarations 64 */ 65static const char *AcpiGbl_DmTypeNames[] = 66{ 67 /* 00 */ "", /* Type ANY */ 68 /* 01 */ ", IntObj", 69 /* 02 */ ", StrObj", 70 /* 03 */ ", BuffObj", 71 /* 04 */ ", PkgObj", 72 /* 05 */ ", FieldUnitObj", 73 /* 06 */ ", DeviceObj", 74 /* 07 */ ", EventObj", 75 /* 08 */ ", MethodObj", 76 /* 09 */ ", MutexObj", 77 /* 10 */ ", OpRegionObj", 78 /* 11 */ ", PowerResObj", 79 /* 12 */ ", ProcessorObj", 80 /* 13 */ ", ThermalZoneObj", 81 /* 14 */ ", BuffFieldObj", 82 /* 15 */ ", DDBHandleObj", 83 /* 16 */ "", /* Debug object */ 84 /* 17 */ ", FieldUnitObj", 85 /* 18 */ ", FieldUnitObj", 86 /* 19 */ ", FieldUnitObj" 87}; 88 89 90/* Local prototypes */ 91 92static const char * 93AcpiDmGetObjectTypeName ( 94 ACPI_OBJECT_TYPE Type); 95 96static char * 97AcpiDmNormalizeParentPrefix ( 98 ACPI_PARSE_OBJECT *Op, 99 char *Path); 100 101 102/******************************************************************************* 103 * 104 * FUNCTION: AcpiDmGetObjectTypeName 105 * 106 * PARAMETERS: Type - An ACPI_OBJECT_TYPE 107 * 108 * RETURN: Pointer to a string 109 * 110 * DESCRIPTION: Map an object type to the ASL object type string. 111 * 112 ******************************************************************************/ 113 114static const char * 115AcpiDmGetObjectTypeName ( 116 ACPI_OBJECT_TYPE Type) 117{ 118 119 if (Type == ACPI_TYPE_LOCAL_SCOPE) 120 { 121 Type = ACPI_TYPE_DEVICE; 122 } 123 124 else if (Type > ACPI_TYPE_LOCAL_INDEX_FIELD) 125 { 126 return (""); 127 } 128 129 return (AcpiGbl_DmTypeNames[Type]); 130} 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiDmNormalizeParentPrefix 136 * 137 * PARAMETERS: Op - Parse op 138 * Path - Path with parent prefix 139 * 140 * RETURN: The full pathname to the object (from the namespace root) 141 * 142 * DESCRIPTION: Returns the full pathname of a path with parent prefix 143 * The caller must free the fullpath returned. 144 * 145 ******************************************************************************/ 146 147static char * 148AcpiDmNormalizeParentPrefix ( 149 ACPI_PARSE_OBJECT *Op, 150 char *Path) 151{ 152 ACPI_NAMESPACE_NODE *Node; 153 char *Fullpath; 154 char *ParentPath; 155 ACPI_SIZE Length;
|
| 156 UINT32 Index = 0;
|
156 157
| 157 158
|
158 /* Search upwards in the parse tree until we reach a namespace node */
| 159 if (!Op) 160 { 161 return (NULL); 162 }
|
159
| 163
|
| 164 /* Search upwards in the parse tree until we reach the next namespace node */ 165 166 Op = Op->Common.Parent;
|
160 while (Op) 161 { 162 if (Op->Common.Node) 163 { 164 break; 165 } 166 167 Op = Op->Common.Parent; 168 } 169 170 if (!Op) 171 { 172 return (NULL); 173 } 174 175 /* 176 * Find the actual parent node for the reference: 177 * Remove all carat prefixes from the input path. 178 * There may be multiple parent prefixes (For example, ^^^M000) 179 */ 180 Node = Op->Common.Node; 181 while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) 182 { 183 Node = Node->Parent; 184 Path++; 185 } 186 187 if (!Node) 188 { 189 return (NULL); 190 } 191 192 /* Get the full pathname for the parent node */ 193 194 ParentPath = AcpiNsGetExternalPathname (Node); 195 if (!ParentPath) 196 { 197 return (NULL); 198 } 199 200 Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); 201 if (ParentPath[1]) 202 { 203 /* 204 * If ParentPath is not just a simple '\', increment the length 205 * for the required dot separator (ParentPath.Path) 206 */ 207 Length++;
| 167 while (Op) 168 { 169 if (Op->Common.Node) 170 { 171 break; 172 } 173 174 Op = Op->Common.Parent; 175 } 176 177 if (!Op) 178 { 179 return (NULL); 180 } 181 182 /* 183 * Find the actual parent node for the reference: 184 * Remove all carat prefixes from the input path. 185 * There may be multiple parent prefixes (For example, ^^^M000) 186 */ 187 Node = Op->Common.Node; 188 while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) 189 { 190 Node = Node->Parent; 191 Path++; 192 } 193 194 if (!Node) 195 { 196 return (NULL); 197 } 198 199 /* Get the full pathname for the parent node */ 200 201 ParentPath = AcpiNsGetExternalPathname (Node); 202 if (!ParentPath) 203 { 204 return (NULL); 205 } 206 207 Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); 208 if (ParentPath[1]) 209 { 210 /* 211 * If ParentPath is not just a simple '\', increment the length 212 * for the required dot separator (ParentPath.Path) 213 */ 214 Length++;
|
| 215 216 /* For External() statements, we do not want a leading '\' */ 217 218 if (*ParentPath == AML_ROOT_PREFIX) 219 { 220 Index = 1; 221 }
|
208 } 209 210 Fullpath = ACPI_ALLOCATE_ZEROED (Length); 211 if (!Fullpath) 212 { 213 goto Cleanup; 214 } 215 216 /* 217 * Concatenate parent fullpath and path. For example, 218 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" 219 * 220 * Copy the parent path 221 */
| 222 } 223 224 Fullpath = ACPI_ALLOCATE_ZEROED (Length); 225 if (!Fullpath) 226 { 227 goto Cleanup; 228 } 229 230 /* 231 * Concatenate parent fullpath and path. For example, 232 * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" 233 * 234 * Copy the parent path 235 */
|
222 ACPI_STRCAT (Fullpath, ParentPath);
| 236 ACPI_STRCPY (Fullpath, &ParentPath[Index]);
|
223 224 /* 225 * Add dot separator 226 * (don't need dot if parent fullpath is a single backslash) 227 */ 228 if (ParentPath[1]) 229 { 230 ACPI_STRCAT (Fullpath, "."); 231 } 232 233 /* Copy child path (carat parent prefix(es) were skipped above) */ 234 235 ACPI_STRCAT (Fullpath, Path); 236 237Cleanup: 238 ACPI_FREE (ParentPath); 239 return (Fullpath); 240} 241 242 243/******************************************************************************* 244 * 245 * FUNCTION: AcpiDmAddToExternalFileList 246 * 247 * PARAMETERS: PathList - Single path or list separated by comma 248 * 249 * RETURN: None 250 * 251 * DESCRIPTION: Add external files to global list 252 * 253 ******************************************************************************/ 254 255ACPI_STATUS 256AcpiDmAddToExternalFileList ( 257 char *PathList) 258{ 259 ACPI_EXTERNAL_FILE *ExternalFile; 260 char *Path; 261 char *TmpPath; 262 263 264 if (!PathList) 265 { 266 return (AE_OK); 267 } 268 269 Path = strtok (PathList, ","); 270 271 while (Path) 272 { 273 TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1); 274 if (!TmpPath) 275 { 276 return (AE_NO_MEMORY); 277 } 278 279 ACPI_STRCPY (TmpPath, Path); 280 281 ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); 282 if (!ExternalFile) 283 { 284 ACPI_FREE (TmpPath); 285 return (AE_NO_MEMORY); 286 } 287 288 ExternalFile->Path = TmpPath; 289 290 if (AcpiGbl_ExternalFileList) 291 { 292 ExternalFile->Next = AcpiGbl_ExternalFileList; 293 } 294 295 AcpiGbl_ExternalFileList = ExternalFile; 296 Path = strtok (NULL, ","); 297 } 298 299 return (AE_OK); 300} 301 302 303/******************************************************************************* 304 * 305 * FUNCTION: AcpiDmClearExternalFileList 306 * 307 * PARAMETERS: None 308 * 309 * RETURN: None 310 * 311 * DESCRIPTION: Clear the external file list 312 * 313 ******************************************************************************/ 314 315void 316AcpiDmClearExternalFileList ( 317 void) 318{ 319 ACPI_EXTERNAL_FILE *NextExternal; 320 321 322 while (AcpiGbl_ExternalFileList) 323 { 324 NextExternal = AcpiGbl_ExternalFileList->Next; 325 ACPI_FREE (AcpiGbl_ExternalFileList->Path); 326 ACPI_FREE (AcpiGbl_ExternalFileList); 327 AcpiGbl_ExternalFileList = NextExternal; 328 } 329} 330 331 332/******************************************************************************* 333 * 334 * FUNCTION: AcpiDmAddToExternalList 335 * 336 * PARAMETERS: Op - Current parser Op 337 * Path - Internal (AML) path to the object 338 * Type - ACPI object type to be added 339 * Value - Arg count if adding a Method object 340 * 341 * RETURN: None 342 * 343 * DESCRIPTION: Insert a new name into the global list of Externals which 344 * will in turn be later emitted as an External() declaration 345 * in the disassembled output. 346 * 347 ******************************************************************************/ 348 349void 350AcpiDmAddToExternalList ( 351 ACPI_PARSE_OBJECT *Op, 352 char *Path, 353 UINT8 Type, 354 UINT32 Value) 355{ 356 char *ExternalPath; 357 char *Fullpath = NULL; 358 ACPI_EXTERNAL_LIST *NewExternal; 359 ACPI_EXTERNAL_LIST *NextExternal; 360 ACPI_EXTERNAL_LIST *PrevExternal = NULL; 361 ACPI_STATUS Status; 362 363 364 if (!Path) 365 { 366 return; 367 } 368
| 237 238 /* 239 * Add dot separator 240 * (don't need dot if parent fullpath is a single backslash) 241 */ 242 if (ParentPath[1]) 243 { 244 ACPI_STRCAT (Fullpath, "."); 245 } 246 247 /* Copy child path (carat parent prefix(es) were skipped above) */ 248 249 ACPI_STRCAT (Fullpath, Path); 250 251Cleanup: 252 ACPI_FREE (ParentPath); 253 return (Fullpath); 254} 255 256 257/******************************************************************************* 258 * 259 * FUNCTION: AcpiDmAddToExternalFileList 260 * 261 * PARAMETERS: PathList - Single path or list separated by comma 262 * 263 * RETURN: None 264 * 265 * DESCRIPTION: Add external files to global list 266 * 267 ******************************************************************************/ 268 269ACPI_STATUS 270AcpiDmAddToExternalFileList ( 271 char *PathList) 272{ 273 ACPI_EXTERNAL_FILE *ExternalFile; 274 char *Path; 275 char *TmpPath; 276 277 278 if (!PathList) 279 { 280 return (AE_OK); 281 } 282 283 Path = strtok (PathList, ","); 284 285 while (Path) 286 { 287 TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1); 288 if (!TmpPath) 289 { 290 return (AE_NO_MEMORY); 291 } 292 293 ACPI_STRCPY (TmpPath, Path); 294 295 ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE)); 296 if (!ExternalFile) 297 { 298 ACPI_FREE (TmpPath); 299 return (AE_NO_MEMORY); 300 } 301 302 ExternalFile->Path = TmpPath; 303 304 if (AcpiGbl_ExternalFileList) 305 { 306 ExternalFile->Next = AcpiGbl_ExternalFileList; 307 } 308 309 AcpiGbl_ExternalFileList = ExternalFile; 310 Path = strtok (NULL, ","); 311 } 312 313 return (AE_OK); 314} 315 316 317/******************************************************************************* 318 * 319 * FUNCTION: AcpiDmClearExternalFileList 320 * 321 * PARAMETERS: None 322 * 323 * RETURN: None 324 * 325 * DESCRIPTION: Clear the external file list 326 * 327 ******************************************************************************/ 328 329void 330AcpiDmClearExternalFileList ( 331 void) 332{ 333 ACPI_EXTERNAL_FILE *NextExternal; 334 335 336 while (AcpiGbl_ExternalFileList) 337 { 338 NextExternal = AcpiGbl_ExternalFileList->Next; 339 ACPI_FREE (AcpiGbl_ExternalFileList->Path); 340 ACPI_FREE (AcpiGbl_ExternalFileList); 341 AcpiGbl_ExternalFileList = NextExternal; 342 } 343} 344 345 346/******************************************************************************* 347 * 348 * FUNCTION: AcpiDmAddToExternalList 349 * 350 * PARAMETERS: Op - Current parser Op 351 * Path - Internal (AML) path to the object 352 * Type - ACPI object type to be added 353 * Value - Arg count if adding a Method object 354 * 355 * RETURN: None 356 * 357 * DESCRIPTION: Insert a new name into the global list of Externals which 358 * will in turn be later emitted as an External() declaration 359 * in the disassembled output. 360 * 361 ******************************************************************************/ 362 363void 364AcpiDmAddToExternalList ( 365 ACPI_PARSE_OBJECT *Op, 366 char *Path, 367 UINT8 Type, 368 UINT32 Value) 369{ 370 char *ExternalPath; 371 char *Fullpath = NULL; 372 ACPI_EXTERNAL_LIST *NewExternal; 373 ACPI_EXTERNAL_LIST *NextExternal; 374 ACPI_EXTERNAL_LIST *PrevExternal = NULL; 375 ACPI_STATUS Status; 376 377 378 if (!Path) 379 { 380 return; 381 } 382
|
369 /* Externalize the ACPI path */
| 383 /* 384 * We don't want External() statements to contain a leading '\'. 385 * This prevents duplicate external statements of the form: 386 * 387 * External (\ABCD) 388 * External (ABCD) 389 * 390 * This would cause a compile time error when the disassembled 391 * output file is recompiled. 392 */ 393 if ((*Path == AML_ROOT_PREFIX) && (Path[1])) 394 { 395 Path++; 396 }
|
370
| 397
|
| 398 /* Externalize the ACPI pathname */ 399
|
371 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, 372 NULL, &ExternalPath); 373 if (ACPI_FAILURE (Status)) 374 { 375 return; 376 } 377
| 400 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Path, 401 NULL, &ExternalPath); 402 if (ACPI_FAILURE (Status)) 403 { 404 return; 405 } 406
|
378 /* Get the full pathname from root if "Path" has a parent prefix */ 379
| 407 /* 408 * Get the full pathname from the root if "Path" has one or more 409 * parent prefixes (^). Note: path will not contain a leading '\'. 410 */
|
380 if (*Path == (UINT8) AML_PARENT_PREFIX) 381 { 382 Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath); 383 if (Fullpath) 384 { 385 /* Set new external path */ 386 387 ACPI_FREE (ExternalPath); 388 ExternalPath = Fullpath; 389 } 390 } 391 392 /* Check all existing externals to ensure no duplicates */ 393 394 NextExternal = AcpiGbl_ExternalList; 395 while (NextExternal) 396 { 397 if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) 398 { 399 /* Duplicate method, check that the Value (ArgCount) is the same */ 400 401 if ((NextExternal->Type == ACPI_TYPE_METHOD) && 402 (NextExternal->Value != Value)) 403 { 404 ACPI_ERROR ((AE_INFO, 405 "Argument count mismatch for method %s %u %u", 406 NextExternal->Path, NextExternal->Value, Value)); 407 } 408 409 /* Allow upgrade of type from ANY */ 410 411 else if (NextExternal->Type == ACPI_TYPE_ANY) 412 { 413 NextExternal->Type = Type; 414 NextExternal->Value = Value; 415 } 416 417 ACPI_FREE (ExternalPath); 418 return; 419 } 420 421 NextExternal = NextExternal->Next; 422 } 423 424 /* Allocate and init a new External() descriptor */ 425 426 NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); 427 if (!NewExternal) 428 { 429 ACPI_FREE (ExternalPath); 430 return; 431 } 432 433 NewExternal->Path = ExternalPath; 434 NewExternal->Type = Type; 435 NewExternal->Value = Value; 436 NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); 437 438 /* Was the external path with parent prefix normalized to a fullpath? */ 439 440 if (Fullpath == ExternalPath) 441 { 442 /* Get new internal path */ 443 444 Status = AcpiNsInternalizeName (ExternalPath, &Path); 445 if (ACPI_FAILURE (Status)) 446 { 447 ACPI_FREE (ExternalPath); 448 ACPI_FREE (NewExternal); 449 return; 450 } 451 452 /* Set flag to indicate External->InternalPath need to be freed */ 453 454 NewExternal->Flags |= ACPI_IPATH_ALLOCATED; 455 } 456 457 NewExternal->InternalPath = Path; 458 459 /* Link the new descriptor into the global list, alphabetically ordered */ 460 461 NextExternal = AcpiGbl_ExternalList; 462 while (NextExternal) 463 { 464 if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0) 465 { 466 if (PrevExternal) 467 { 468 PrevExternal->Next = NewExternal; 469 } 470 else 471 { 472 AcpiGbl_ExternalList = NewExternal; 473 } 474 475 NewExternal->Next = NextExternal; 476 return; 477 } 478 479 PrevExternal = NextExternal; 480 NextExternal = NextExternal->Next; 481 } 482 483 if (PrevExternal) 484 { 485 PrevExternal->Next = NewExternal; 486 } 487 else 488 { 489 AcpiGbl_ExternalList = NewExternal; 490 } 491} 492 493 494/******************************************************************************* 495 * 496 * FUNCTION: AcpiDmAddExternalsToNamespace 497 * 498 * PARAMETERS: None 499 * 500 * RETURN: None 501 * 502 * DESCRIPTION: Add all externals to the namespace. Allows externals to be 503 * "resolved". 504 * 505 ******************************************************************************/ 506 507void 508AcpiDmAddExternalsToNamespace ( 509 void) 510{ 511 ACPI_STATUS Status; 512 ACPI_NAMESPACE_NODE *Node; 513 ACPI_OPERAND_OBJECT *ObjDesc; 514 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 515 516 517 while (External) 518 { 519 /* Add the external name (object) into the namespace */ 520 521 Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, 522 ACPI_IMODE_LOAD_PASS1, 523 ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, 524 NULL, &Node); 525 526 if (ACPI_FAILURE (Status)) 527 { 528 ACPI_EXCEPTION ((AE_INFO, Status, 529 "while adding external to namespace [%s]", 530 External->Path)); 531 } 532 533 else switch (External->Type) 534 { 535 case ACPI_TYPE_METHOD: 536 537 /* For methods, we need to save the argument count */ 538 539 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 540 ObjDesc->Method.ParamCount = (UINT8) External->Value; 541 Node->Object = ObjDesc; 542 break; 543 544 case ACPI_TYPE_REGION: 545 546 /* Regions require a region sub-object */ 547 548 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 549 ObjDesc->Region.Node = Node; 550 Node->Object = ObjDesc; 551 break; 552 553 default: 554 break; 555 } 556 557 External = External->Next; 558 } 559} 560 561 562/******************************************************************************* 563 * 564 * FUNCTION: AcpiDmGetExternalMethodCount 565 * 566 * PARAMETERS: None 567 * 568 * RETURN: The number of control method externals in the external list 569 * 570 * DESCRIPTION: Return the number of method externals that have been generated. 571 * If any control method externals have been found, we must 572 * re-parse the entire definition block with the new information 573 * (number of arguments for the methods.) This is limitation of 574 * AML, we don't know the number of arguments from the control 575 * method invocation itself. 576 * 577 ******************************************************************************/ 578 579UINT32 580AcpiDmGetExternalMethodCount ( 581 void) 582{ 583 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 584 UINT32 Count = 0; 585 586 587 while (External) 588 { 589 if (External->Type == ACPI_TYPE_METHOD) 590 { 591 Count++; 592 } 593 594 External = External->Next; 595 } 596 597 return (Count); 598} 599 600 601/******************************************************************************* 602 * 603 * FUNCTION: AcpiDmClearExternalList 604 * 605 * PARAMETERS: None 606 * 607 * RETURN: None 608 * 609 * DESCRIPTION: Free the entire External info list 610 * 611 ******************************************************************************/ 612 613void 614AcpiDmClearExternalList ( 615 void) 616{ 617 ACPI_EXTERNAL_LIST *NextExternal; 618 619 620 while (AcpiGbl_ExternalList) 621 { 622 NextExternal = AcpiGbl_ExternalList->Next; 623 ACPI_FREE (AcpiGbl_ExternalList->Path); 624 ACPI_FREE (AcpiGbl_ExternalList); 625 AcpiGbl_ExternalList = NextExternal; 626 } 627} 628 629 630/******************************************************************************* 631 * 632 * FUNCTION: AcpiDmEmitExternals 633 * 634 * PARAMETERS: None 635 * 636 * RETURN: None 637 * 638 * DESCRIPTION: Emit an External() ASL statement for each of the externals in 639 * the global external info list. 640 * 641 ******************************************************************************/ 642 643void 644AcpiDmEmitExternals ( 645 void) 646{ 647 ACPI_EXTERNAL_LIST *NextExternal; 648 649 650 if (!AcpiGbl_ExternalList) 651 { 652 return; 653 } 654 655 /* 656 * Walk the list of externals (unresolved references) 657 * found during the AML parsing 658 */ 659 while (AcpiGbl_ExternalList) 660 { 661 AcpiOsPrintf (" External (%s%s", 662 AcpiGbl_ExternalList->Path, 663 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 664 665 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 666 { 667 AcpiOsPrintf (") // %u Arguments\n", 668 AcpiGbl_ExternalList->Value); 669 } 670 else 671 { 672 AcpiOsPrintf (")\n"); 673 } 674 675 /* Free this external info block and move on to next external */ 676 677 NextExternal = AcpiGbl_ExternalList->Next; 678 if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) 679 { 680 ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 681 } 682 683 ACPI_FREE (AcpiGbl_ExternalList->Path); 684 ACPI_FREE (AcpiGbl_ExternalList); 685 AcpiGbl_ExternalList = NextExternal; 686 } 687 688 AcpiOsPrintf ("\n"); 689}
| 411 if (*Path == (UINT8) AML_PARENT_PREFIX) 412 { 413 Fullpath = AcpiDmNormalizeParentPrefix (Op, ExternalPath); 414 if (Fullpath) 415 { 416 /* Set new external path */ 417 418 ACPI_FREE (ExternalPath); 419 ExternalPath = Fullpath; 420 } 421 } 422 423 /* Check all existing externals to ensure no duplicates */ 424 425 NextExternal = AcpiGbl_ExternalList; 426 while (NextExternal) 427 { 428 if (!ACPI_STRCMP (ExternalPath, NextExternal->Path)) 429 { 430 /* Duplicate method, check that the Value (ArgCount) is the same */ 431 432 if ((NextExternal->Type == ACPI_TYPE_METHOD) && 433 (NextExternal->Value != Value)) 434 { 435 ACPI_ERROR ((AE_INFO, 436 "Argument count mismatch for method %s %u %u", 437 NextExternal->Path, NextExternal->Value, Value)); 438 } 439 440 /* Allow upgrade of type from ANY */ 441 442 else if (NextExternal->Type == ACPI_TYPE_ANY) 443 { 444 NextExternal->Type = Type; 445 NextExternal->Value = Value; 446 } 447 448 ACPI_FREE (ExternalPath); 449 return; 450 } 451 452 NextExternal = NextExternal->Next; 453 } 454 455 /* Allocate and init a new External() descriptor */ 456 457 NewExternal = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_LIST)); 458 if (!NewExternal) 459 { 460 ACPI_FREE (ExternalPath); 461 return; 462 } 463 464 NewExternal->Path = ExternalPath; 465 NewExternal->Type = Type; 466 NewExternal->Value = Value; 467 NewExternal->Length = (UINT16) ACPI_STRLEN (ExternalPath); 468 469 /* Was the external path with parent prefix normalized to a fullpath? */ 470 471 if (Fullpath == ExternalPath) 472 { 473 /* Get new internal path */ 474 475 Status = AcpiNsInternalizeName (ExternalPath, &Path); 476 if (ACPI_FAILURE (Status)) 477 { 478 ACPI_FREE (ExternalPath); 479 ACPI_FREE (NewExternal); 480 return; 481 } 482 483 /* Set flag to indicate External->InternalPath need to be freed */ 484 485 NewExternal->Flags |= ACPI_IPATH_ALLOCATED; 486 } 487 488 NewExternal->InternalPath = Path; 489 490 /* Link the new descriptor into the global list, alphabetically ordered */ 491 492 NextExternal = AcpiGbl_ExternalList; 493 while (NextExternal) 494 { 495 if (AcpiUtStricmp (NewExternal->Path, NextExternal->Path) < 0) 496 { 497 if (PrevExternal) 498 { 499 PrevExternal->Next = NewExternal; 500 } 501 else 502 { 503 AcpiGbl_ExternalList = NewExternal; 504 } 505 506 NewExternal->Next = NextExternal; 507 return; 508 } 509 510 PrevExternal = NextExternal; 511 NextExternal = NextExternal->Next; 512 } 513 514 if (PrevExternal) 515 { 516 PrevExternal->Next = NewExternal; 517 } 518 else 519 { 520 AcpiGbl_ExternalList = NewExternal; 521 } 522} 523 524 525/******************************************************************************* 526 * 527 * FUNCTION: AcpiDmAddExternalsToNamespace 528 * 529 * PARAMETERS: None 530 * 531 * RETURN: None 532 * 533 * DESCRIPTION: Add all externals to the namespace. Allows externals to be 534 * "resolved". 535 * 536 ******************************************************************************/ 537 538void 539AcpiDmAddExternalsToNamespace ( 540 void) 541{ 542 ACPI_STATUS Status; 543 ACPI_NAMESPACE_NODE *Node; 544 ACPI_OPERAND_OBJECT *ObjDesc; 545 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 546 547 548 while (External) 549 { 550 /* Add the external name (object) into the namespace */ 551 552 Status = AcpiNsLookup (NULL, External->InternalPath, External->Type, 553 ACPI_IMODE_LOAD_PASS1, 554 ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE, 555 NULL, &Node); 556 557 if (ACPI_FAILURE (Status)) 558 { 559 ACPI_EXCEPTION ((AE_INFO, Status, 560 "while adding external to namespace [%s]", 561 External->Path)); 562 } 563 564 else switch (External->Type) 565 { 566 case ACPI_TYPE_METHOD: 567 568 /* For methods, we need to save the argument count */ 569 570 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 571 ObjDesc->Method.ParamCount = (UINT8) External->Value; 572 Node->Object = ObjDesc; 573 break; 574 575 case ACPI_TYPE_REGION: 576 577 /* Regions require a region sub-object */ 578 579 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 580 ObjDesc->Region.Node = Node; 581 Node->Object = ObjDesc; 582 break; 583 584 default: 585 break; 586 } 587 588 External = External->Next; 589 } 590} 591 592 593/******************************************************************************* 594 * 595 * FUNCTION: AcpiDmGetExternalMethodCount 596 * 597 * PARAMETERS: None 598 * 599 * RETURN: The number of control method externals in the external list 600 * 601 * DESCRIPTION: Return the number of method externals that have been generated. 602 * If any control method externals have been found, we must 603 * re-parse the entire definition block with the new information 604 * (number of arguments for the methods.) This is limitation of 605 * AML, we don't know the number of arguments from the control 606 * method invocation itself. 607 * 608 ******************************************************************************/ 609 610UINT32 611AcpiDmGetExternalMethodCount ( 612 void) 613{ 614 ACPI_EXTERNAL_LIST *External = AcpiGbl_ExternalList; 615 UINT32 Count = 0; 616 617 618 while (External) 619 { 620 if (External->Type == ACPI_TYPE_METHOD) 621 { 622 Count++; 623 } 624 625 External = External->Next; 626 } 627 628 return (Count); 629} 630 631 632/******************************************************************************* 633 * 634 * FUNCTION: AcpiDmClearExternalList 635 * 636 * PARAMETERS: None 637 * 638 * RETURN: None 639 * 640 * DESCRIPTION: Free the entire External info list 641 * 642 ******************************************************************************/ 643 644void 645AcpiDmClearExternalList ( 646 void) 647{ 648 ACPI_EXTERNAL_LIST *NextExternal; 649 650 651 while (AcpiGbl_ExternalList) 652 { 653 NextExternal = AcpiGbl_ExternalList->Next; 654 ACPI_FREE (AcpiGbl_ExternalList->Path); 655 ACPI_FREE (AcpiGbl_ExternalList); 656 AcpiGbl_ExternalList = NextExternal; 657 } 658} 659 660 661/******************************************************************************* 662 * 663 * FUNCTION: AcpiDmEmitExternals 664 * 665 * PARAMETERS: None 666 * 667 * RETURN: None 668 * 669 * DESCRIPTION: Emit an External() ASL statement for each of the externals in 670 * the global external info list. 671 * 672 ******************************************************************************/ 673 674void 675AcpiDmEmitExternals ( 676 void) 677{ 678 ACPI_EXTERNAL_LIST *NextExternal; 679 680 681 if (!AcpiGbl_ExternalList) 682 { 683 return; 684 } 685 686 /* 687 * Walk the list of externals (unresolved references) 688 * found during the AML parsing 689 */ 690 while (AcpiGbl_ExternalList) 691 { 692 AcpiOsPrintf (" External (%s%s", 693 AcpiGbl_ExternalList->Path, 694 AcpiDmGetObjectTypeName (AcpiGbl_ExternalList->Type)); 695 696 if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 697 { 698 AcpiOsPrintf (") // %u Arguments\n", 699 AcpiGbl_ExternalList->Value); 700 } 701 else 702 { 703 AcpiOsPrintf (")\n"); 704 } 705 706 /* Free this external info block and move on to next external */ 707 708 NextExternal = AcpiGbl_ExternalList->Next; 709 if (AcpiGbl_ExternalList->Flags & ACPI_IPATH_ALLOCATED) 710 { 711 ACPI_FREE (AcpiGbl_ExternalList->InternalPath); 712 } 713 714 ACPI_FREE (AcpiGbl_ExternalList->Path); 715 ACPI_FREE (AcpiGbl_ExternalList); 716 AcpiGbl_ExternalList = NextExternal; 717 } 718 719 AcpiOsPrintf ("\n"); 720}
|