1 /****************************************************************************** 2 * 3 * Module Name: aslmaputils - Utilities for the resource descriptor/device maps 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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/acnamesp.h> 51 #include <contrib/dev/acpica/include/amlcode.h> 52 53 /* This module used for application-level code only */ 54 55 #define _COMPONENT ACPI_COMPILER 56 ACPI_MODULE_NAME ("aslmaputils") 57 58 59 /******************************************************************************* 60 * 61 * FUNCTION: MpGetHidFromParseTree 62 * 63 * PARAMETERS: HidNode - Node for a _HID object 64 * 65 * RETURN: An _HID string value. Automatically converts _HID integers 66 * to strings. Never NULL. 67 * 68 * DESCRIPTION: Extract a _HID value from the parse tree, not the namespace. 69 * Used when a fully initialized namespace is not available. 70 * 71 ******************************************************************************/ 72 73 char * 74 MpGetHidFromParseTree ( 75 ACPI_NAMESPACE_NODE *HidNode) 76 { 77 ACPI_PARSE_OBJECT *Op; 78 ACPI_PARSE_OBJECT *Arg; 79 char *HidString; 80 81 82 Op = HidNode->Op; 83 84 switch (Op->Asl.ParseOpcode) 85 { 86 case PARSEOP_NAME: 87 88 Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 89 Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 90 91 switch (Arg->Asl.ParseOpcode) 92 { 93 case PARSEOP_STRING_LITERAL: 94 95 return (Arg->Asl.Value.String); 96 97 case PARSEOP_INTEGER: 98 99 /* Convert EISAID to a string */ 100 101 HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE); 102 AcpiExEisaIdToString (HidString, Arg->Asl.Value.Integer); 103 return (HidString); 104 105 default: 106 107 return ("UNKNOWN"); 108 } 109 110 default: 111 return ("-No HID-"); 112 } 113 } 114 115 116 /******************************************************************************* 117 * 118 * FUNCTION: MpGetHidValue 119 * 120 * PARAMETERS: DeviceNode - Node for parent device 121 * 122 * RETURN: An _HID string value. Automatically converts _HID integers 123 * to strings. Never NULL. 124 * 125 * DESCRIPTION: Extract _HID value from within a device scope. Does not 126 * actually execute a method, just gets the string or integer 127 * value for the _HID. 128 * 129 ******************************************************************************/ 130 131 char * 132 MpGetHidValue ( 133 ACPI_NAMESPACE_NODE *DeviceNode) 134 { 135 ACPI_NAMESPACE_NODE *HidNode; 136 char *HidString; 137 ACPI_STATUS Status; 138 139 140 Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__HID, 141 ACPI_NS_NO_UPSEARCH, &HidNode); 142 if (ACPI_FAILURE (Status)) 143 { 144 goto ErrorExit; 145 } 146 147 /* If only partial namespace, get the _HID from the parse tree */ 148 149 if (!HidNode->Object) 150 { 151 return (MpGetHidFromParseTree (HidNode)); 152 } 153 154 /* Handle the different _HID flavors */ 155 156 switch (HidNode->Type) 157 { 158 case ACPI_TYPE_STRING: 159 160 return (HidNode->Object->String.Pointer); 161 162 case ACPI_TYPE_INTEGER: 163 164 /* Convert EISAID to a string */ 165 166 HidString = UtStringCacheCalloc (ACPI_EISAID_STRING_SIZE); 167 AcpiExEisaIdToString (HidString, HidNode->Object->Integer.Value); 168 return (HidString); 169 170 case ACPI_TYPE_METHOD: 171 172 return ("-Method-"); 173 174 default: 175 176 FlPrintFile (ASL_FILE_MAP_OUTPUT, "BAD HID TYPE: %u", HidNode->Type); 177 break; 178 } 179 180 181 ErrorExit: 182 return ("-No HID-"); 183 } 184 185 186 /******************************************************************************* 187 * 188 * FUNCTION: MpGetHidViaNamestring 189 * 190 * PARAMETERS: DeviceName - Namepath for parent device 191 * 192 * RETURN: _HID string. Never NULL. 193 * 194 * DESCRIPTION: Get a _HID value via a device pathname (instead of just simply 195 * a device node.) 196 * 197 ******************************************************************************/ 198 199 char * 200 MpGetHidViaNamestring ( 201 char *DeviceName) 202 { 203 ACPI_NAMESPACE_NODE *DeviceNode; 204 ACPI_STATUS Status; 205 206 207 Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH, 208 &DeviceNode); 209 if (ACPI_FAILURE (Status)) 210 { 211 goto ErrorExit; 212 } 213 214 return (MpGetHidValue (DeviceNode)); 215 216 217 ErrorExit: 218 return ("-No HID-"); 219 } 220 221 222 /******************************************************************************* 223 * 224 * FUNCTION: MpGetParentDeviceHid 225 * 226 * PARAMETERS: Op - Parse Op to be examined 227 * TargetNode - Where the field node is returned 228 * ParentDeviceName - Where the node path is returned 229 * 230 * RETURN: _HID string. Never NULL. 231 * 232 * DESCRIPTION: Find the parent Device or Scope Op, get the full pathname to 233 * the parent, and get the _HID associated with the parent. 234 * 235 ******************************************************************************/ 236 237 char * 238 MpGetParentDeviceHid ( 239 ACPI_PARSE_OBJECT *Op, 240 ACPI_NAMESPACE_NODE **TargetNode, 241 char **ParentDeviceName) 242 { 243 ACPI_NAMESPACE_NODE *DeviceNode; 244 245 246 /* Find parent Device() or Scope() Op */ 247 248 while (Op && 249 (Op->Asl.AmlOpcode != AML_DEVICE_OP) && 250 (Op->Asl.AmlOpcode != AML_SCOPE_OP)) 251 { 252 Op = Op->Asl.Parent; 253 } 254 255 if (!Op) 256 { 257 FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Parent_Device "); 258 goto ErrorExit; 259 } 260 261 /* Get the full pathname to the device and the _HID */ 262 263 DeviceNode = Op->Asl.Node; 264 if (!DeviceNode) 265 { 266 FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Device_Node "); 267 goto ErrorExit; 268 } 269 270 *ParentDeviceName = AcpiNsGetExternalPathname (DeviceNode); 271 return (MpGetHidValue (DeviceNode)); 272 273 274 ErrorExit: 275 return ("-No HID-"); 276 } 277 278 279 /******************************************************************************* 280 * 281 * FUNCTION: MpGetDdnValue 282 * 283 * PARAMETERS: DeviceName - Namepath for parent device 284 * 285 * RETURN: _DDN description string. NULL on failure. 286 * 287 * DESCRIPTION: Execute the _DDN method for the device. 288 * 289 ******************************************************************************/ 290 291 char * 292 MpGetDdnValue ( 293 char *DeviceName) 294 { 295 ACPI_NAMESPACE_NODE *DeviceNode; 296 ACPI_NAMESPACE_NODE *DdnNode; 297 ACPI_STATUS Status; 298 299 300 Status = AcpiNsGetNode (NULL, DeviceName, ACPI_NS_NO_UPSEARCH, 301 &DeviceNode); 302 if (ACPI_FAILURE (Status)) 303 { 304 goto ErrorExit; 305 } 306 307 Status = AcpiNsGetNode (DeviceNode, METHOD_NAME__DDN, ACPI_NS_NO_UPSEARCH, 308 &DdnNode); 309 if (ACPI_FAILURE (Status)) 310 { 311 goto ErrorExit; 312 } 313 314 if ((DdnNode->Type != ACPI_TYPE_STRING) || 315 !DdnNode->Object) 316 { 317 goto ErrorExit; 318 } 319 320 return (DdnNode->Object->String.Pointer); 321 322 323 ErrorExit: 324 return (NULL); 325 } 326 327 328 /******************************************************************************* 329 * 330 * FUNCTION: MpGetConnectionInfo 331 * 332 * PARAMETERS: Op - Parse Op to be examined 333 * PinIndex - Index into GPIO PinList 334 * TargetNode - Where the field node is returned 335 * TargetName - Where the node path is returned 336 * 337 * RETURN: A substitute _HID string, indicating that the name is actually 338 * a field. NULL if the Op does not refer to a Connection. 339 * 340 * DESCRIPTION: Get the Field Unit that corresponds to the PinIndex after 341 * a Connection() invocation. 342 * 343 ******************************************************************************/ 344 345 char * 346 MpGetConnectionInfo ( 347 ACPI_PARSE_OBJECT *Op, 348 UINT32 PinIndex, 349 ACPI_NAMESPACE_NODE **TargetNode, 350 char **TargetName) 351 { 352 ACPI_PARSE_OBJECT *NextOp; 353 UINT32 i; 354 355 356 /* 357 * Handle Connection() here. Find the next named FieldUnit. 358 * Note: we look at the ParseOpcode for the compiler, look 359 * at the AmlOpcode for the disassembler. 360 */ 361 if ((Op->Asl.AmlOpcode == AML_INT_CONNECTION_OP) || 362 (Op->Asl.ParseOpcode == PARSEOP_CONNECTION)) 363 { 364 /* Find the correct field unit definition */ 365 366 NextOp = Op; 367 for (i = 0; i <= PinIndex;) 368 { 369 NextOp = NextOp->Asl.Next; 370 while (NextOp && 371 (NextOp->Asl.ParseOpcode != PARSEOP_NAMESEG) && 372 (NextOp->Asl.AmlOpcode != AML_INT_NAMEDFIELD_OP)) 373 { 374 NextOp = NextOp->Asl.Next; 375 } 376 377 if (!NextOp) 378 { 379 return ("UNKNOWN"); 380 } 381 382 /* Add length of this field to the current pin index */ 383 384 if (NextOp->Asl.ParseOpcode == PARSEOP_NAMESEG) 385 { 386 i += (UINT32) NextOp->Asl.Child->Asl.Value.Integer; 387 } 388 else /* AML_INT_NAMEDFIELD_OP */ 389 { 390 i += (UINT32) NextOp->Asl.Value.Integer; 391 } 392 } 393 394 /* Return the node and pathname for the field unit */ 395 396 *TargetNode = NextOp->Asl.Node; 397 *TargetName = AcpiNsGetExternalPathname (*TargetNode); 398 return ("-Field-"); 399 } 400 401 return (NULL); 402 } 403