1 /****************************************************************************** 2 * 3 * Module Name: aslmapoutput - Output/emit the resource descriptor/device maps 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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/acapps.h> 47 #include <contrib/dev/acpica/compiler/aslcompiler.h> 48 #include "aslcompiler.y.h" 49 #include <contrib/dev/acpica/include/acinterp.h> 50 #include <contrib/dev/acpica/include/acparser.h> 51 #include <contrib/dev/acpica/include/acnamesp.h> 52 #include <contrib/dev/acpica/include/amlcode.h> 53 54 /* This module used for application-level code only */ 55 56 #define _COMPONENT ACPI_COMPILER 57 ACPI_MODULE_NAME ("aslmapoutput") 58 59 /* Local prototypes */ 60 61 static void 62 MpEmitGpioInfo ( 63 void); 64 65 static void 66 MpEmitSerialInfo ( 67 void); 68 69 static void 70 MpEmitDeviceTree ( 71 void); 72 73 static ACPI_STATUS 74 MpEmitOneDevice ( 75 ACPI_HANDLE ObjHandle, 76 UINT32 NestingLevel, 77 void *Context, 78 void **ReturnValue); 79 80 static void 81 MpXrefDevices ( 82 ACPI_GPIO_INFO *Info); 83 84 static ACPI_STATUS 85 MpNamespaceXrefBegin ( 86 ACPI_PARSE_OBJECT *Op, 87 UINT32 Level, 88 void *Context); 89 90 91 /* Strings used to decode flag bits */ 92 93 const char *DirectionDecode[] = 94 { 95 "Both I/O ", 96 "InputOnly ", 97 "OutputOnly ", 98 "Preserve " 99 }; 100 101 const char *PolarityDecode[] = 102 { 103 "ActiveHigh", 104 "ActiveLow ", 105 "ActiveBoth", 106 "Reserved " 107 }; 108 109 110 /******************************************************************************* 111 * 112 * FUNCTION: MpEmitMappingInfo 113 * 114 * PARAMETERS: None 115 * 116 * RETURN: None 117 * 118 * DESCRIPTION: External interface. 119 * Map file has already been opened. Emit all of the collected 120 * hardware mapping information. Includes: GPIO information, 121 * Serial information, and a dump of the entire ACPI device tree. 122 * 123 ******************************************************************************/ 124 125 void 126 MpEmitMappingInfo ( 127 void) 128 { 129 130 /* Mapfile option enabled? */ 131 132 if (!Gbl_MapfileFlag) 133 { 134 return; 135 } 136 137 if (!Gbl_GpioList) 138 { 139 FlPrintFile (ASL_FILE_MAP_OUTPUT, 140 "\nNo GPIO devices found\n"); 141 } 142 143 if (!Gbl_SerialList) 144 { 145 FlPrintFile (ASL_FILE_MAP_OUTPUT, 146 "\nNo Serial devices found (I2C/SPI/UART)\n"); 147 } 148 149 if (!Gbl_GpioList && !Gbl_SerialList) 150 { 151 return; 152 } 153 154 /* Headers */ 155 156 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\nResource Descriptor Connectivity Map\n"); 157 FlPrintFile (ASL_FILE_MAP_OUTPUT, "------------------------------------\n"); 158 159 /* Emit GPIO and Serial descriptors, then entire ACPI device tree */ 160 161 MpEmitGpioInfo (); 162 MpEmitSerialInfo (); 163 MpEmitDeviceTree (); 164 165 /* Clear the lists - no need to free memory here */ 166 167 Gbl_SerialList = NULL; 168 Gbl_GpioList = NULL; 169 } 170 171 172 /******************************************************************************* 173 * 174 * FUNCTION: MpEmitGpioInfo 175 * 176 * PARAMETERS: None 177 * 178 * RETURN: None 179 * 180 * DESCRIPTION: Emit the info about all GPIO devices found during the 181 * compile or disassembly. 182 * 183 ******************************************************************************/ 184 185 static void 186 MpEmitGpioInfo ( 187 void) 188 { 189 ACPI_GPIO_INFO *Info; 190 char *Type; 191 char *PrevDeviceName = NULL; 192 const char *Direction; 193 const char *Polarity; 194 char *ParentPathname; 195 const char *Description; 196 char *HidString; 197 const AH_DEVICE_ID *HidInfo; 198 199 200 /* Walk the GPIO descriptor list */ 201 202 Info = Gbl_GpioList; 203 while (Info) 204 { 205 HidString = MpGetHidViaNamestring (Info->DeviceName); 206 207 /* Print header info for the controller itself */ 208 209 if (!PrevDeviceName || 210 strcmp (PrevDeviceName, Info->DeviceName)) 211 { 212 FlPrintFile (ASL_FILE_MAP_OUTPUT, 213 "\n\nGPIO Controller: %-8s %-28s", 214 HidString, Info->DeviceName); 215 216 HidInfo = AcpiAhMatchHardwareId (HidString); 217 if (HidInfo) 218 { 219 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s", 220 HidInfo->Description); 221 } 222 223 FlPrintFile (ASL_FILE_MAP_OUTPUT, 224 "\n\nPin Type Direction Polarity" 225 " Dest _HID Destination\n"); 226 } 227 228 PrevDeviceName = Info->DeviceName; 229 230 /* Setup various strings based upon the type (GpioInt or GpioIo) */ 231 232 switch (Info->Type) 233 { 234 case AML_RESOURCE_GPIO_TYPE_INT: 235 236 Type = "GpioInt"; 237 Direction = "-Interrupt-"; 238 Polarity = PolarityDecode[Info->Polarity]; 239 break; 240 241 case AML_RESOURCE_GPIO_TYPE_IO: 242 243 Type = "GpioIo "; 244 Direction = DirectionDecode[Info->Direction]; 245 Polarity = " "; 246 break; 247 248 default: 249 continue; 250 } 251 252 /* Emit the GPIO info */ 253 254 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%4.4X %s %s %s ", 255 Info->PinNumber, Type, Direction, Polarity); 256 257 ParentPathname = NULL; 258 HidString = MpGetConnectionInfo (Info->Op, Info->PinIndex, 259 &Info->TargetNode, &ParentPathname); 260 if (HidString) 261 { 262 /* 263 * This is a Connection() field 264 * Attempt to find all references to the field. 265 */ 266 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s", 267 HidString, ParentPathname); 268 269 MpXrefDevices (Info); 270 } 271 else 272 { 273 /* 274 * For Devices, attempt to get the _HID description string. 275 * Failing that (many _HIDs are not recognized), attempt to 276 * get the _DDN description string. 277 */ 278 HidString = MpGetParentDeviceHid (Info->Op, &Info->TargetNode, 279 &ParentPathname); 280 281 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s", 282 HidString, ParentPathname); 283 284 /* Get the _HID description or _DDN string */ 285 286 HidInfo = AcpiAhMatchHardwareId (HidString); 287 if (HidInfo) 288 { 289 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s", 290 HidInfo->Description); 291 } 292 else if ((Description = MpGetDdnValue (ParentPathname))) 293 { 294 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)", 295 Description); 296 } 297 } 298 299 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n"); 300 ACPI_FREE (ParentPathname); 301 Info = Info->Next; 302 } 303 } 304 305 306 /******************************************************************************* 307 * 308 * FUNCTION: MpEmitSerialInfo 309 * 310 * PARAMETERS: None 311 * 312 * RETURN: None 313 * 314 * DESCRIPTION: Emit the info about all Serial devices found during the 315 * compile or disassembly. 316 * 317 ******************************************************************************/ 318 319 static void 320 MpEmitSerialInfo ( 321 void) 322 { 323 ACPI_SERIAL_INFO *Info; 324 char *Type; 325 char *ParentPathname; 326 char *PrevDeviceName = NULL; 327 char *HidString; 328 const AH_DEVICE_ID *HidInfo; 329 const char *Description; 330 AML_RESOURCE *Resource; 331 332 333 /* Walk the constructed serial descriptor list */ 334 335 Info = Gbl_SerialList; 336 while (Info) 337 { 338 Resource = Info->Resource; 339 switch (Resource->CommonSerialBus.Type) 340 { 341 case AML_RESOURCE_I2C_SERIALBUSTYPE: 342 Type = "I2C "; 343 break; 344 345 case AML_RESOURCE_SPI_SERIALBUSTYPE: 346 Type = "SPI "; 347 break; 348 349 case AML_RESOURCE_UART_SERIALBUSTYPE: 350 Type = "UART"; 351 break; 352 353 default: 354 Type = "UNKN"; 355 break; 356 } 357 358 HidString = MpGetHidViaNamestring (Info->DeviceName); 359 360 /* Print header info for the controller itself */ 361 362 if (!PrevDeviceName || 363 strcmp (PrevDeviceName, Info->DeviceName)) 364 { 365 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\n%s Controller: ", 366 Type); 367 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%-8s %-28s", 368 HidString, Info->DeviceName); 369 370 HidInfo = AcpiAhMatchHardwareId (HidString); 371 if (HidInfo) 372 { 373 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s", 374 HidInfo->Description); 375 } 376 377 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\n"); 378 FlPrintFile (ASL_FILE_MAP_OUTPUT, 379 "Type Address Speed Dest _HID Destination\n"); 380 } 381 382 PrevDeviceName = Info->DeviceName; 383 384 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%s %4.4X %8.8X ", 385 Type, Info->Address, Info->Speed); 386 387 ParentPathname = NULL; 388 HidString = MpGetConnectionInfo (Info->Op, 0, &Info->TargetNode, 389 &ParentPathname); 390 if (HidString) 391 { 392 /* 393 * This is a Connection() field 394 * Attempt to find all references to the field. 395 */ 396 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s", 397 HidString, ParentPathname); 398 } 399 else 400 { 401 /* Normal resource template */ 402 403 HidString = MpGetParentDeviceHid (Info->Op, &Info->TargetNode, 404 &ParentPathname); 405 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s %-28s", 406 HidString, ParentPathname); 407 408 /* Get the _HID description or _DDN string */ 409 410 HidInfo = AcpiAhMatchHardwareId (HidString); 411 if (HidInfo) 412 { 413 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s", 414 HidInfo->Description); 415 } 416 else if ((Description = MpGetDdnValue (ParentPathname))) 417 { 418 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)", 419 Description); 420 } 421 } 422 423 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n"); 424 ACPI_FREE (ParentPathname); 425 Info = Info->Next; 426 } 427 } 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: MpEmitDeviceTree 433 * 434 * PARAMETERS: None 435 * 436 * RETURN: None 437 * 438 * DESCRIPTION: Emit information about all devices within the ACPI namespace. 439 * 440 ******************************************************************************/ 441 442 static void 443 MpEmitDeviceTree ( 444 void) 445 { 446 447 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\nACPI Device Tree\n"); 448 FlPrintFile (ASL_FILE_MAP_OUTPUT, "----------------\n\n"); 449 450 FlPrintFile (ASL_FILE_MAP_OUTPUT, "Device Pathname " 451 "_HID Description\n\n"); 452 453 /* Walk the namespace from the root */ 454 455 (void) AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 456 ACPI_UINT32_MAX, FALSE, MpEmitOneDevice, NULL, NULL, NULL); 457 } 458 459 460 /******************************************************************************* 461 * 462 * FUNCTION: MpEmitOneDevice 463 * 464 * PARAMETERS: ACPI_NAMESPACE_WALK callback 465 * 466 * RETURN: Status 467 * 468 * DESCRIPTION: Emit information about one ACPI device in the namespace. Used 469 * during dump of all device objects within the namespace. 470 * 471 ******************************************************************************/ 472 473 static ACPI_STATUS 474 MpEmitOneDevice ( 475 ACPI_HANDLE ObjHandle, 476 UINT32 NestingLevel, 477 void *Context, 478 void **ReturnValue) 479 { 480 char *DevicePathname; 481 char *DdnString; 482 char *HidString; 483 const AH_DEVICE_ID *HidInfo; 484 485 486 /* Device pathname */ 487 488 DevicePathname = AcpiNsGetExternalPathname ( 489 ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle)); 490 491 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%-32s", DevicePathname); 492 493 /* _HID or _DDN */ 494 495 HidString = MpGetHidValue ( 496 ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle)); 497 FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s", HidString); 498 499 HidInfo = AcpiAhMatchHardwareId (HidString); 500 if (HidInfo) 501 { 502 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s", 503 HidInfo->Description); 504 } 505 else if ((DdnString = MpGetDdnValue (DevicePathname))) 506 { 507 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)", DdnString); 508 } 509 510 FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n"); 511 ACPI_FREE (DevicePathname); 512 return (AE_OK); 513 } 514 515 516 /******************************************************************************* 517 * 518 * FUNCTION: MpXrefDevices 519 * 520 * PARAMETERS: Info - A GPIO Info block 521 * 522 * RETURN: None 523 * 524 * DESCRIPTION: Cross-reference the parse tree and find all references to the 525 * specified GPIO device. 526 * 527 ******************************************************************************/ 528 529 static void 530 MpXrefDevices ( 531 ACPI_GPIO_INFO *Info) 532 { 533 534 /* Walk the entire parse tree */ 535 536 TrWalkParseTree (Gbl_ParseTreeRoot, ASL_WALK_VISIT_DOWNWARD, 537 MpNamespaceXrefBegin, NULL, Info); 538 539 if (!Info->References) 540 { 541 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // **** No references in table"); 542 } 543 } 544 545 546 /******************************************************************************* 547 * 548 * FUNCTION: MpNamespaceXrefBegin 549 * 550 * PARAMETERS: WALK_PARSE_TREE callback 551 * 552 * RETURN: Status 553 * 554 * DESCRIPTION: Walk parse tree callback used to cross-reference GPIO pins. 555 * 556 ******************************************************************************/ 557 558 static ACPI_STATUS 559 MpNamespaceXrefBegin ( 560 ACPI_PARSE_OBJECT *Op, 561 UINT32 Level, 562 void *Context) 563 { 564 ACPI_GPIO_INFO *Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Context); 565 const ACPI_OPCODE_INFO *OpInfo; 566 char *DevicePathname; 567 ACPI_PARSE_OBJECT *ParentOp; 568 char *HidString; 569 570 571 ACPI_FUNCTION_TRACE_PTR (MpNamespaceXrefBegin, Op); 572 573 /* 574 * If this node is the actual declaration of a name 575 * [such as the XXXX name in "Method (XXXX)"], 576 * we are not interested in it here. We only care about names that 577 * are references to other objects within the namespace and the 578 * parent objects of name declarations 579 */ 580 if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) 581 { 582 return (AE_OK); 583 } 584 585 /* We are only interested in opcodes that have an associated name */ 586 587 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 588 589 if ((OpInfo->Flags & AML_NAMED) || 590 (OpInfo->Flags & AML_CREATE)) 591 { 592 return (AE_OK); 593 } 594 595 if ((Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) && 596 (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) && 597 (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)) 598 { 599 return (AE_OK); 600 } 601 602 if (!Op->Asl.Node) 603 { 604 return (AE_OK); 605 } 606 607 ParentOp = Op->Asl.Parent; 608 if (ParentOp->Asl.ParseOpcode == PARSEOP_FIELD) 609 { 610 return (AE_OK); 611 } 612 613 if (Op->Asl.Node == Info->TargetNode) 614 { 615 while (ParentOp && (!ParentOp->Asl.Node)) 616 { 617 ParentOp = ParentOp->Asl.Parent; 618 } 619 620 if (ParentOp) 621 { 622 DevicePathname = AcpiNsGetExternalPathname ( 623 ParentOp->Asl.Node); 624 625 if (!Info->References) 626 { 627 FlPrintFile (ASL_FILE_MAP_OUTPUT, " // References:"); 628 } 629 630 HidString = MpGetHidViaNamestring (DevicePathname); 631 632 FlPrintFile (ASL_FILE_MAP_OUTPUT, " %s [%s]", 633 DevicePathname, HidString); 634 635 Info->References++; 636 637 ACPI_FREE (DevicePathname); 638 } 639 } 640 641 return (AE_OK); 642 } 643