exstoren.c revision 241973
1219185Sadrian/****************************************************************************** 2219185Sadrian * 3219185Sadrian * Module Name: exstoren - AML Interpreter object store support, 4219185Sadrian * Store to Node (namespace object) 5219185Sadrian * 6219185Sadrian *****************************************************************************/ 7219185Sadrian 8219185Sadrian/* 9219185Sadrian * Copyright (C) 2000 - 2012, Intel Corp. 10219185Sadrian * All rights reserved. 11219185Sadrian * 12219185Sadrian * Redistribution and use in source and binary forms, with or without 13219185Sadrian * modification, are permitted provided that the following conditions 14219185Sadrian * are met: 15219185Sadrian * 1. Redistributions of source code must retain the above copyright 16219185Sadrian * notice, this list of conditions, and the following disclaimer, 17219185Sadrian * without modification. 18219185Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19219185Sadrian * substantially similar to the "NO WARRANTY" disclaimer below 20219185Sadrian * ("Disclaimer") and any redistribution must be conditioned upon 21219185Sadrian * including a substantially similar Disclaimer requirement for further 22219185Sadrian * binary redistribution. 23219185Sadrian * 3. Neither the names of the above-listed copyright holders nor the names 24219185Sadrian * of any contributors may be used to endorse or promote products derived 25219185Sadrian * from this software without specific prior written permission. 26219185Sadrian * 27219185Sadrian * Alternatively, this software may be distributed under the terms of the 28219185Sadrian * GNU General Public License ("GPL") version 2 as published by the Free 29219185Sadrian * Software Foundation. 30219185Sadrian * 31219185Sadrian * NO WARRANTY 32219185Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33219185Sadrian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34219185Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35219185Sadrian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36219185Sadrian * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37219185Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38219185Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39219185Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40219185Sadrian * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41219185Sadrian * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42219185Sadrian * POSSIBILITY OF SUCH DAMAGES. 43219185Sadrian */ 44219185Sadrian 45219185Sadrian#define __EXSTOREN_C__ 46219185Sadrian 47219185Sadrian#include <contrib/dev/acpica/include/acpi.h> 48219185Sadrian#include <contrib/dev/acpica/include/accommon.h> 49219185Sadrian#include <contrib/dev/acpica/include/acinterp.h> 50219185Sadrian#include <contrib/dev/acpica/include/amlcode.h> 51219185Sadrian 52219185Sadrian 53219185Sadrian#define _COMPONENT ACPI_EXECUTER 54219185Sadrian ACPI_MODULE_NAME ("exstoren") 55219185Sadrian 56219185Sadrian 57219185Sadrian/******************************************************************************* 58219185Sadrian * 59219185Sadrian * FUNCTION: AcpiExResolveObject 60219185Sadrian * 61219185Sadrian * PARAMETERS: SourceDescPtr - Pointer to the source object 62219185Sadrian * TargetType - Current type of the target 63219185Sadrian * WalkState - Current walk state 64219185Sadrian * 65219185Sadrian * RETURN: Status, resolved object in SourceDescPtr. 66219185Sadrian * 67219185Sadrian * DESCRIPTION: Resolve an object. If the object is a reference, dereference 68219185Sadrian * it and return the actual object in the SourceDescPtr. 69219185Sadrian * 70219185Sadrian ******************************************************************************/ 71219185Sadrian 72219185SadrianACPI_STATUS 73219185SadrianAcpiExResolveObject ( 74219185Sadrian ACPI_OPERAND_OBJECT **SourceDescPtr, 75219185Sadrian ACPI_OBJECT_TYPE TargetType, 76219185Sadrian ACPI_WALK_STATE *WalkState) 77219185Sadrian{ 78219185Sadrian ACPI_OPERAND_OBJECT *SourceDesc = *SourceDescPtr; 79219185Sadrian ACPI_STATUS Status = AE_OK; 80219185Sadrian 81219185Sadrian 82219185Sadrian ACPI_FUNCTION_TRACE (ExResolveObject); 83219185Sadrian 84219185Sadrian 85219185Sadrian /* Ensure we have a Target that can be stored to */ 86219185Sadrian 87219185Sadrian switch (TargetType) 88219185Sadrian { 89219185Sadrian case ACPI_TYPE_BUFFER_FIELD: 90219185Sadrian case ACPI_TYPE_LOCAL_REGION_FIELD: 91219185Sadrian case ACPI_TYPE_LOCAL_BANK_FIELD: 92219185Sadrian case ACPI_TYPE_LOCAL_INDEX_FIELD: 93219185Sadrian /* 94219185Sadrian * These cases all require only Integers or values that 95219185Sadrian * can be converted to Integers (Strings or Buffers) 96219185Sadrian */ 97219185Sadrian 98219185Sadrian case ACPI_TYPE_INTEGER: 99219185Sadrian case ACPI_TYPE_STRING: 100219185Sadrian case ACPI_TYPE_BUFFER: 101219185Sadrian 102219185Sadrian /* 103219185Sadrian * Stores into a Field/Region or into a Integer/Buffer/String 104219185Sadrian * are all essentially the same. This case handles the 105219185Sadrian * "interchangeable" types Integer, String, and Buffer. 106219185Sadrian */ 107219185Sadrian if (SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) 108219185Sadrian { 109219185Sadrian /* Resolve a reference object first */ 110219185Sadrian 111219185Sadrian Status = AcpiExResolveToValue (SourceDescPtr, WalkState); 112219185Sadrian if (ACPI_FAILURE (Status)) 113219185Sadrian { 114219185Sadrian break; 115219185Sadrian } 116219185Sadrian } 117219185Sadrian 118219185Sadrian /* For CopyObject, no further validation necessary */ 119219185Sadrian 120219185Sadrian if (WalkState->Opcode == AML_COPY_OP) 121219185Sadrian { 122219185Sadrian break; 123219185Sadrian } 124219185Sadrian 125219185Sadrian /* Must have a Integer, Buffer, or String */ 126219185Sadrian 127219185Sadrian if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && 128219185Sadrian (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) && 129219185Sadrian (SourceDesc->Common.Type != ACPI_TYPE_STRING) && 130219185Sadrian !((SourceDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 131219185Sadrian (SourceDesc->Reference.Class== ACPI_REFCLASS_TABLE))) 132219185Sadrian { 133219185Sadrian /* Conversion successful but still not a valid type */ 134219185Sadrian 135219185Sadrian ACPI_ERROR ((AE_INFO, 136219185Sadrian "Cannot assign type %s to %s (must be type Int/Str/Buf)", 137219185Sadrian AcpiUtGetObjectTypeName (SourceDesc), 138219185Sadrian AcpiUtGetTypeName (TargetType))); 139219185Sadrian Status = AE_AML_OPERAND_TYPE; 140219185Sadrian } 141219185Sadrian break; 142219185Sadrian 143219185Sadrian 144219185Sadrian case ACPI_TYPE_LOCAL_ALIAS: 145219185Sadrian case ACPI_TYPE_LOCAL_METHOD_ALIAS: 146219185Sadrian 147219185Sadrian /* 148219185Sadrian * All aliases should have been resolved earlier, during the 149219185Sadrian * operand resolution phase. 150219185Sadrian */ 151219185Sadrian ACPI_ERROR ((AE_INFO, "Store into an unresolved Alias object")); 152219185Sadrian Status = AE_AML_INTERNAL; 153219185Sadrian break; 154219185Sadrian 155219185Sadrian 156219185Sadrian case ACPI_TYPE_PACKAGE: 157219185Sadrian default: 158219185Sadrian 159219185Sadrian /* 160219185Sadrian * All other types than Alias and the various Fields come here, 161219185Sadrian * including the untyped case - ACPI_TYPE_ANY. 162219185Sadrian */ 163219185Sadrian break; 164219185Sadrian } 165219185Sadrian 166219185Sadrian return_ACPI_STATUS (Status); 167219185Sadrian} 168219185Sadrian 169219185Sadrian 170219185Sadrian/******************************************************************************* 171219185Sadrian * 172219185Sadrian * FUNCTION: AcpiExStoreObjectToObject 173219185Sadrian * 174219185Sadrian * PARAMETERS: SourceDesc - Object to store 175219185Sadrian * DestDesc - Object to receive a copy of the source 176219185Sadrian * NewDesc - New object if DestDesc is obsoleted 177219185Sadrian * WalkState - Current walk state 178219185Sadrian * 179219185Sadrian * RETURN: Status 180219185Sadrian * 181219185Sadrian * DESCRIPTION: "Store" an object to another object. This may include 182219185Sadrian * converting the source type to the target type (implicit 183219185Sadrian * conversion), and a copy of the value of the source to 184219185Sadrian * the target. 185219185Sadrian * 186219185Sadrian * The Assignment of an object to another (not named) object 187219185Sadrian * is handled here. 188219185Sadrian * The Source passed in will replace the current value (if any) 189219185Sadrian * with the input value. 190219185Sadrian * 191219185Sadrian * When storing into an object the data is converted to the 192219185Sadrian * target object type then stored in the object. This means 193219185Sadrian * that the target object type (for an initialized target) will 194219185Sadrian * not be changed by a store operation. 195219185Sadrian * 196219185Sadrian * This module allows destination types of Number, String, 197219185Sadrian * Buffer, and Package. 198219185Sadrian * 199219185Sadrian * Assumes parameters are already validated. NOTE: SourceDesc 200219185Sadrian * resolution (from a reference object) must be performed by 201219185Sadrian * the caller if necessary. 202219185Sadrian * 203219185Sadrian ******************************************************************************/ 204219185Sadrian 205219185SadrianACPI_STATUS 206219185SadrianAcpiExStoreObjectToObject ( 207219185Sadrian ACPI_OPERAND_OBJECT *SourceDesc, 208219185Sadrian ACPI_OPERAND_OBJECT *DestDesc, 209219185Sadrian ACPI_OPERAND_OBJECT **NewDesc, 210219185Sadrian ACPI_WALK_STATE *WalkState) 211219185Sadrian{ 212219185Sadrian ACPI_OPERAND_OBJECT *ActualSrcDesc; 213219185Sadrian ACPI_STATUS Status = AE_OK; 214219185Sadrian 215219185Sadrian 216219185Sadrian ACPI_FUNCTION_TRACE_PTR (ExStoreObjectToObject, SourceDesc); 217219185Sadrian 218219185Sadrian 219219185Sadrian ActualSrcDesc = SourceDesc; 220219185Sadrian if (!DestDesc) 221219185Sadrian { 222219185Sadrian /* 223219185Sadrian * There is no destination object (An uninitialized node or 224219185Sadrian * package element), so we can simply copy the source object 225219185Sadrian * creating a new destination object 226219185Sadrian */ 227219185Sadrian Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, NewDesc, WalkState); 228219185Sadrian return_ACPI_STATUS (Status); 229219185Sadrian } 230219185Sadrian 231219185Sadrian if (SourceDesc->Common.Type != DestDesc->Common.Type) 232219185Sadrian { 233219185Sadrian /* 234219185Sadrian * The source type does not match the type of the destination. 235219185Sadrian * Perform the "implicit conversion" of the source to the current type 236219185Sadrian * of the target as per the ACPI specification. 237219185Sadrian * 238219185Sadrian * If no conversion performed, ActualSrcDesc = SourceDesc. 239219185Sadrian * Otherwise, ActualSrcDesc is a temporary object to hold the 240219185Sadrian * converted object. 241219185Sadrian */ 242219185Sadrian Status = AcpiExConvertToTargetType (DestDesc->Common.Type, 243219185Sadrian SourceDesc, &ActualSrcDesc, WalkState); 244219185Sadrian if (ACPI_FAILURE (Status)) 245219185Sadrian { 246219185Sadrian return_ACPI_STATUS (Status); 247219185Sadrian } 248219185Sadrian 249219185Sadrian if (SourceDesc == ActualSrcDesc) 250219185Sadrian { 251219185Sadrian /* 252219185Sadrian * No conversion was performed. Return the SourceDesc as the 253219185Sadrian * new object. 254219185Sadrian */ 255219185Sadrian *NewDesc = SourceDesc; 256219185Sadrian return_ACPI_STATUS (AE_OK); 257219185Sadrian } 258219185Sadrian } 259219185Sadrian 260219185Sadrian /* 261219185Sadrian * We now have two objects of identical types, and we can perform a 262219185Sadrian * copy of the *value* of the source object. 263219185Sadrian */ 264219185Sadrian switch (DestDesc->Common.Type) 265219185Sadrian { 266219185Sadrian case ACPI_TYPE_INTEGER: 267219185Sadrian 268219185Sadrian DestDesc->Integer.Value = ActualSrcDesc->Integer.Value; 269219185Sadrian 270219185Sadrian /* Truncate value if we are executing from a 32-bit ACPI table */ 271219185Sadrian 272219185Sadrian AcpiExTruncateFor32bitTable (DestDesc); 273219185Sadrian break; 274219185Sadrian 275219185Sadrian case ACPI_TYPE_STRING: 276219185Sadrian 277219185Sadrian Status = AcpiExStoreStringToString (ActualSrcDesc, DestDesc); 278219185Sadrian break; 279219185Sadrian 280219185Sadrian case ACPI_TYPE_BUFFER: 281219185Sadrian 282219185Sadrian Status = AcpiExStoreBufferToBuffer (ActualSrcDesc, DestDesc); 283219185Sadrian break; 284219185Sadrian 285219185Sadrian case ACPI_TYPE_PACKAGE: 286219185Sadrian 287219185Sadrian Status = AcpiUtCopyIobjectToIobject (ActualSrcDesc, &DestDesc, 288219185Sadrian WalkState); 289219185Sadrian break; 290219185Sadrian 291219185Sadrian default: 292219185Sadrian /* 293219185Sadrian * All other types come here. 294219185Sadrian */ 295219185Sadrian ACPI_WARNING ((AE_INFO, "Store into type %s not implemented", 296219185Sadrian AcpiUtGetObjectTypeName (DestDesc))); 297219185Sadrian 298219185Sadrian Status = AE_NOT_IMPLEMENTED; 299219185Sadrian break; 300219185Sadrian } 301219185Sadrian 302219185Sadrian if (ActualSrcDesc != SourceDesc) 303219185Sadrian { 304219185Sadrian /* Delete the intermediate (temporary) source object */ 305219185Sadrian 306219185Sadrian AcpiUtRemoveReference (ActualSrcDesc); 307219185Sadrian } 308219185Sadrian 309219185Sadrian *NewDesc = DestDesc; 310219185Sadrian return_ACPI_STATUS (Status); 311219185Sadrian} 312219185Sadrian