167754Smsmith/****************************************************************************** 267754Smsmith * 377424Smsmith * Module Name: exnames - interpreter/scanner name load/execute 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 4867754Smsmith 4977424Smsmith#define _COMPONENT ACPI_EXECUTER 5091116Smsmith ACPI_MODULE_NAME ("exnames") 5167754Smsmith 52151937Sjkim/* Local prototypes */ 5367754Smsmith 54151937Sjkimstatic char * 55151937SjkimAcpiExAllocateNameString ( 56151937Sjkim UINT32 PrefixCount, 57151937Sjkim UINT32 NumNameSegs); 5867754Smsmith 59151937Sjkimstatic ACPI_STATUS 60151937SjkimAcpiExNameSegment ( 61151937Sjkim UINT8 **InAmlAddress, 62151937Sjkim char *NameString); 6367754Smsmith 6467754Smsmith 6567754Smsmith/******************************************************************************* 6667754Smsmith * 6777424Smsmith * FUNCTION: AcpiExAllocateNameString 6867754Smsmith * 6967754Smsmith * PARAMETERS: PrefixCount - Count of parent levels. Special cases: 70151937Sjkim * (-1)==root, 0==none 7167754Smsmith * NumNameSegs - count of 4-character name segments 7267754Smsmith * 73241973Sjkim * RETURN: A pointer to the allocated string segment. This segment must 7467754Smsmith * be deleted by the caller. 7567754Smsmith * 7667754Smsmith * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name 7767754Smsmith * string is long enough, and set up prefix if any. 7867754Smsmith * 7967754Smsmith ******************************************************************************/ 8067754Smsmith 81151937Sjkimstatic char * 8277424SmsmithAcpiExAllocateNameString ( 8367754Smsmith UINT32 PrefixCount, 8467754Smsmith UINT32 NumNameSegs) 8567754Smsmith{ 86114237Snjl char *TempPtr; 87114237Snjl char *NameString; 8867754Smsmith UINT32 SizeNeeded; 8967754Smsmith 90167802Sjkim ACPI_FUNCTION_TRACE (ExAllocateNameString); 9167754Smsmith 9267754Smsmith 9367754Smsmith /* 94151937Sjkim * Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix. 9567754Smsmith * Also, one byte for the null terminator. 9667754Smsmith * This may actually be somewhat longer than needed. 9767754Smsmith */ 9891116Smsmith if (PrefixCount == ACPI_UINT32_MAX) 9967754Smsmith { 10067754Smsmith /* Special case for root */ 10167754Smsmith 10267754Smsmith SizeNeeded = 1 + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1; 10367754Smsmith } 10467754Smsmith else 10567754Smsmith { 10667754Smsmith SizeNeeded = PrefixCount + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1; 10767754Smsmith } 10867754Smsmith 10967754Smsmith /* 11067754Smsmith * Allocate a buffer for the name. 11167754Smsmith * This buffer must be deleted by the caller! 11267754Smsmith */ 113167802Sjkim NameString = ACPI_ALLOCATE (SizeNeeded); 11467754Smsmith if (!NameString) 11567754Smsmith { 116167802Sjkim ACPI_ERROR ((AE_INFO, 117204773Sjkim "Could not allocate size %u", SizeNeeded)); 11867754Smsmith return_PTR (NULL); 11967754Smsmith } 12067754Smsmith 12167754Smsmith TempPtr = NameString; 12267754Smsmith 12367754Smsmith /* Set up Root or Parent prefixes if needed */ 12467754Smsmith 12591116Smsmith if (PrefixCount == ACPI_UINT32_MAX) 12667754Smsmith { 12767754Smsmith *TempPtr++ = AML_ROOT_PREFIX; 12867754Smsmith } 12967754Smsmith else 13067754Smsmith { 13167754Smsmith while (PrefixCount--) 13267754Smsmith { 13367754Smsmith *TempPtr++ = AML_PARENT_PREFIX; 13467754Smsmith } 13567754Smsmith } 13667754Smsmith 13767754Smsmith 13867754Smsmith /* Set up Dual or Multi prefixes if needed */ 13967754Smsmith 14067754Smsmith if (NumNameSegs > 2) 14167754Smsmith { 14267754Smsmith /* Set up multi prefixes */ 14367754Smsmith 14467754Smsmith *TempPtr++ = AML_MULTI_NAME_PREFIX_OP; 14567754Smsmith *TempPtr++ = (char) NumNameSegs; 14667754Smsmith } 14767754Smsmith else if (2 == NumNameSegs) 14867754Smsmith { 14967754Smsmith /* Set up dual prefixes */ 15067754Smsmith 15167754Smsmith *TempPtr++ = AML_DUAL_NAME_PREFIX; 15267754Smsmith } 15367754Smsmith 15467754Smsmith /* 15577424Smsmith * Terminate string following prefixes. AcpiExNameSegment() will 15667754Smsmith * append the segment(s) 15767754Smsmith */ 15867754Smsmith *TempPtr = 0; 15967754Smsmith 16067754Smsmith return_PTR (NameString); 16167754Smsmith} 16267754Smsmith 163306536Sjkim 16467754Smsmith/******************************************************************************* 16567754Smsmith * 16677424Smsmith * FUNCTION: AcpiExNameSegment 16767754Smsmith * 168151937Sjkim * PARAMETERS: InAmlAddress - Pointer to the name in the AML code 169151937Sjkim * NameString - Where to return the name. The name is appended 170151937Sjkim * to any existing string to form a namepath 17167754Smsmith * 17267754Smsmith * RETURN: Status 17367754Smsmith * 174151937Sjkim * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream 17567754Smsmith * 17667754Smsmith ******************************************************************************/ 17767754Smsmith 178151937Sjkimstatic ACPI_STATUS 17977424SmsmithAcpiExNameSegment ( 18067754Smsmith UINT8 **InAmlAddress, 181114237Snjl char *NameString) 18267754Smsmith{ 18399679Siwasaki char *AmlAddress = (void *) *InAmlAddress; 18467754Smsmith ACPI_STATUS Status = AE_OK; 18567754Smsmith UINT32 Index; 18699679Siwasaki char CharBuf[5]; 18767754Smsmith 18867754Smsmith 189167802Sjkim ACPI_FUNCTION_TRACE (ExNameSegment); 19067754Smsmith 19167754Smsmith 19267754Smsmith /* 193306536Sjkim * If first character is a digit, then we know that we aren't looking 194306536Sjkim * at a valid name segment 19567754Smsmith */ 19667754Smsmith CharBuf[0] = *AmlAddress; 19767754Smsmith 19867754Smsmith if ('0' <= CharBuf[0] && CharBuf[0] <= '9') 19967754Smsmith { 200167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid leading digit: %c", CharBuf[0])); 20167754Smsmith return_ACPI_STATUS (AE_CTRL_PENDING); 20267754Smsmith } 20367754Smsmith 20482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n")); 20567754Smsmith 20699679Siwasaki for (Index = 0; 207306536Sjkim (Index < ACPI_NAME_SIZE) && (AcpiUtValidNameChar (*AmlAddress, 0)); 20899679Siwasaki Index++) 20967754Smsmith { 21099679Siwasaki CharBuf[Index] = *AmlAddress++; 21199679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", CharBuf[Index])); 21267754Smsmith } 21367754Smsmith 21467754Smsmith 21567754Smsmith /* Valid name segment */ 21667754Smsmith 21799679Siwasaki if (Index == 4) 21867754Smsmith { 21967754Smsmith /* Found 4 valid characters */ 22067754Smsmith 22167754Smsmith CharBuf[4] = '\0'; 22267754Smsmith 22367754Smsmith if (NameString) 22467754Smsmith { 225306536Sjkim strcat (NameString, CharBuf); 22682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 227151937Sjkim "Appended to - %s\n", NameString)); 22867754Smsmith } 22967754Smsmith else 23067754Smsmith { 23182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 232151937Sjkim "No Name string - %s\n", CharBuf)); 23367754Smsmith } 23467754Smsmith } 23599679Siwasaki else if (Index == 0) 23667754Smsmith { 23767754Smsmith /* 23867754Smsmith * First character was not a valid name character, 23967754Smsmith * so we are looking at something other than a name. 24067754Smsmith */ 24182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 24282367Smsmith "Leading character is not alpha: %02Xh (not a name)\n", 24367754Smsmith CharBuf[0])); 24467754Smsmith Status = AE_CTRL_PENDING; 24567754Smsmith } 24667754Smsmith else 24767754Smsmith { 248151937Sjkim /* 249151937Sjkim * Segment started with one or more valid characters, but fewer than 250151937Sjkim * the required 4 251151937Sjkim */ 25267754Smsmith Status = AE_AML_BAD_NAME; 253167802Sjkim ACPI_ERROR ((AE_INFO, 254204773Sjkim "Bad character 0x%02x in name, at %p", 25567754Smsmith *AmlAddress, AmlAddress)); 25667754Smsmith } 25767754Smsmith 258167802Sjkim *InAmlAddress = ACPI_CAST_PTR (UINT8, AmlAddress); 25967754Smsmith return_ACPI_STATUS (Status); 26067754Smsmith} 26167754Smsmith 26267754Smsmith 26367754Smsmith/******************************************************************************* 26467754Smsmith * 26577424Smsmith * FUNCTION: AcpiExGetNameString 26667754Smsmith * 267151937Sjkim * PARAMETERS: DataType - Object type to be associated with this 268151937Sjkim * name 269151937Sjkim * InAmlAddress - Pointer to the namestring in the AML code 270151937Sjkim * OutNameString - Where the namestring is returned 271151937Sjkim * OutNameLength - Length of the returned string 27267754Smsmith * 273151937Sjkim * RETURN: Status, namestring and length 27467754Smsmith * 275151937Sjkim * DESCRIPTION: Extract a full namepath from the AML byte stream, 276151937Sjkim * including any prefixes. 27767754Smsmith * 27867754Smsmith ******************************************************************************/ 27967754Smsmith 28067754SmsmithACPI_STATUS 28177424SmsmithAcpiExGetNameString ( 28291116Smsmith ACPI_OBJECT_TYPE DataType, 28367754Smsmith UINT8 *InAmlAddress, 284114237Snjl char **OutNameString, 28567754Smsmith UINT32 *OutNameLength) 28667754Smsmith{ 28767754Smsmith ACPI_STATUS Status = AE_OK; 28867754Smsmith UINT8 *AmlAddress = InAmlAddress; 289114237Snjl char *NameString = NULL; 29067754Smsmith UINT32 NumSegments; 29167754Smsmith UINT32 PrefixCount = 0; 29267754Smsmith BOOLEAN HasPrefix = FALSE; 29367754Smsmith 29467754Smsmith 295167802Sjkim ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress); 29667754Smsmith 29767754Smsmith 298107325Siwasaki if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType || 299107325Siwasaki ACPI_TYPE_LOCAL_BANK_FIELD == DataType || 300107325Siwasaki ACPI_TYPE_LOCAL_INDEX_FIELD == DataType) 30167754Smsmith { 30277424Smsmith /* Disallow prefixes for types associated with FieldUnit names */ 30367754Smsmith 30477424Smsmith NameString = AcpiExAllocateNameString (0, 1); 30567754Smsmith if (!NameString) 30667754Smsmith { 30767754Smsmith Status = AE_NO_MEMORY; 30867754Smsmith } 30967754Smsmith else 31067754Smsmith { 31177424Smsmith Status = AcpiExNameSegment (&AmlAddress, NameString); 31267754Smsmith } 31367754Smsmith } 31467754Smsmith else 31567754Smsmith { 31667754Smsmith /* 31767754Smsmith * DataType is not a field name. 31867754Smsmith * Examine first character of name for root or parent prefix operators 31967754Smsmith */ 32067754Smsmith switch (*AmlAddress) 32167754Smsmith { 32267754Smsmith case AML_ROOT_PREFIX: 32367754Smsmith 324151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n", 325151937Sjkim AmlAddress)); 32667754Smsmith 32767754Smsmith /* 32867754Smsmith * Remember that we have a RootPrefix -- 32977424Smsmith * see comment in AcpiExAllocateNameString() 33067754Smsmith */ 33191116Smsmith AmlAddress++; 33291116Smsmith PrefixCount = ACPI_UINT32_MAX; 33367754Smsmith HasPrefix = TRUE; 33467754Smsmith break; 33567754Smsmith 33667754Smsmith case AML_PARENT_PREFIX: 33767754Smsmith 33867754Smsmith /* Increment past possibly multiple parent prefixes */ 33967754Smsmith 34067754Smsmith do 34167754Smsmith { 342151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n", 343151937Sjkim AmlAddress)); 34467754Smsmith 34591116Smsmith AmlAddress++; 34691116Smsmith PrefixCount++; 34767754Smsmith 34867754Smsmith } while (*AmlAddress == AML_PARENT_PREFIX); 34991116Smsmith 35067754Smsmith HasPrefix = TRUE; 35167754Smsmith break; 35267754Smsmith 35367754Smsmith default: 35467754Smsmith 35591116Smsmith /* Not a prefix character */ 35691116Smsmith 35767754Smsmith break; 35867754Smsmith } 35967754Smsmith 36067754Smsmith /* Examine first character of name for name segment prefix operator */ 36167754Smsmith 36267754Smsmith switch (*AmlAddress) 36367754Smsmith { 36467754Smsmith case AML_DUAL_NAME_PREFIX: 36567754Smsmith 366151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n", 367151937Sjkim AmlAddress)); 36867754Smsmith 36991116Smsmith AmlAddress++; 37077424Smsmith NameString = AcpiExAllocateNameString (PrefixCount, 2); 37167754Smsmith if (!NameString) 37267754Smsmith { 37367754Smsmith Status = AE_NO_MEMORY; 37467754Smsmith break; 37567754Smsmith } 37667754Smsmith 37767754Smsmith /* Indicate that we processed a prefix */ 37883174Smsmith 37967754Smsmith HasPrefix = TRUE; 38067754Smsmith 38177424Smsmith Status = AcpiExNameSegment (&AmlAddress, NameString); 38267754Smsmith if (ACPI_SUCCESS (Status)) 38367754Smsmith { 38477424Smsmith Status = AcpiExNameSegment (&AmlAddress, NameString); 38567754Smsmith } 38667754Smsmith break; 38767754Smsmith 38867754Smsmith case AML_MULTI_NAME_PREFIX_OP: 38967754Smsmith 390151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n", 391151937Sjkim AmlAddress)); 39267754Smsmith 39367754Smsmith /* Fetch count of segments remaining in name path */ 39467754Smsmith 39591116Smsmith AmlAddress++; 39691116Smsmith NumSegments = *AmlAddress; 39767754Smsmith 398306536Sjkim NameString = AcpiExAllocateNameString ( 399306536Sjkim PrefixCount, NumSegments); 40067754Smsmith if (!NameString) 40167754Smsmith { 40267754Smsmith Status = AE_NO_MEMORY; 40367754Smsmith break; 40467754Smsmith } 40567754Smsmith 40667754Smsmith /* Indicate that we processed a prefix */ 40783174Smsmith 40891116Smsmith AmlAddress++; 40967754Smsmith HasPrefix = TRUE; 41067754Smsmith 41167754Smsmith while (NumSegments && 412151937Sjkim (Status = AcpiExNameSegment (&AmlAddress, NameString)) == 413151937Sjkim AE_OK) 41467754Smsmith { 41591116Smsmith NumSegments--; 41667754Smsmith } 41767754Smsmith 41867754Smsmith break; 41967754Smsmith 42067754Smsmith case 0: 42167754Smsmith 42267754Smsmith /* NullName valid as of 8-12-98 ASL/AML Grammar Update */ 42367754Smsmith 42491116Smsmith if (PrefixCount == ACPI_UINT32_MAX) 42567754Smsmith { 426151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 427151937Sjkim "NameSeg is \"\\\" followed by NULL\n")); 42867754Smsmith } 42967754Smsmith 43067754Smsmith /* Consume the NULL byte */ 43167754Smsmith 43267754Smsmith AmlAddress++; 43377424Smsmith NameString = AcpiExAllocateNameString (PrefixCount, 0); 43467754Smsmith if (!NameString) 43567754Smsmith { 43667754Smsmith Status = AE_NO_MEMORY; 43767754Smsmith break; 43867754Smsmith } 43967754Smsmith 44067754Smsmith break; 44167754Smsmith 44267754Smsmith default: 44367754Smsmith 44467754Smsmith /* Name segment string */ 44567754Smsmith 44677424Smsmith NameString = AcpiExAllocateNameString (PrefixCount, 1); 44767754Smsmith if (!NameString) 44867754Smsmith { 44967754Smsmith Status = AE_NO_MEMORY; 45067754Smsmith break; 45167754Smsmith } 45267754Smsmith 45377424Smsmith Status = AcpiExNameSegment (&AmlAddress, NameString); 45467754Smsmith break; 45591116Smsmith } 45667754Smsmith } 45767754Smsmith 45867754Smsmith if (AE_CTRL_PENDING == Status && HasPrefix) 45967754Smsmith { 46067754Smsmith /* Ran out of segments after processing a prefix */ 46167754Smsmith 462167802Sjkim ACPI_ERROR ((AE_INFO, 463167802Sjkim "Malformed Name at %p", NameString)); 46467754Smsmith Status = AE_AML_BAD_NAME; 46567754Smsmith } 46667754Smsmith 467151937Sjkim if (ACPI_FAILURE (Status)) 468151937Sjkim { 469151937Sjkim if (NameString) 470151937Sjkim { 471167802Sjkim ACPI_FREE (NameString); 472151937Sjkim } 473151937Sjkim return_ACPI_STATUS (Status); 474151937Sjkim } 475151937Sjkim 47667754Smsmith *OutNameString = NameString; 47767754Smsmith *OutNameLength = (UINT32) (AmlAddress - InAmlAddress); 47867754Smsmith 47967754Smsmith return_ACPI_STATUS (Status); 48067754Smsmith} 481