exfield.c revision 70243
1234285Sdim/****************************************************************************** 2234285Sdim * 3234285Sdim * Module Name: amfield - ACPI AML (p-code) execution - field manipulation 4234285Sdim * $Revision: 75 $ 5234285Sdim * 6234285Sdim *****************************************************************************/ 7234285Sdim 8234285Sdim/****************************************************************************** 9234285Sdim * 10234285Sdim * 1. Copyright Notice 11234285Sdim * 12234285Sdim * Some or all of this work - Copyright (c) 1999, 2000, Intel Corp. 13234285Sdim * All rights reserved. 14234285Sdim * 15234285Sdim * 2. License 16234285Sdim * 17234285Sdim * 2.1. This is your license from Intel Corp. under its intellectual property 18234285Sdim * rights. You may have additional license terms from the party that provided 19251662Sdim * you this software, covering your right to use that party's intellectual 20249423Sdim * property rights. 21251662Sdim * 22234285Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23234285Sdim * copy of the source code appearing in this file ("Covered Code") an 24234285Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25234285Sdim * base code distributed originally by Intel ("Original Intel Code") to copy, 26234285Sdim * make derivatives, distribute, use and display any portion of the Covered 27234285Sdim * Code in any form, with the right to sublicense such rights; and 28234285Sdim * 29263508Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30234285Sdim * license (with the right to sublicense), under only those claims of Intel 31263508Sdim * patents that are infringed by the Original Intel Code, to make, use, sell, 32251662Sdim * offer to sell, and import the Covered Code and derivative works thereof 33251662Sdim * solely to the minimum extent necessary to exercise the above copyright 34234285Sdim * license, and in no event shall the patent license extend to any additions 35234285Sdim * to or modifications of the Original Intel Code. No other license or right 36234285Sdim * is granted directly or by implication, estoppel or otherwise; 37234285Sdim * 38234285Sdim * The above copyright and patent license is granted only if the following 39234285Sdim * conditions are met: 40234285Sdim * 41234285Sdim * 3. Conditions 42234285Sdim * 43234285Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44234285Sdim * Redistribution of source code of any substantial portion of the Covered 45234285Sdim * Code or modification with rights to further distribute source must include 46234285Sdim * the above Copyright Notice, the above License, this list of Conditions, 47234285Sdim * and the following Disclaimer and Export Compliance provision. In addition, 48234285Sdim * Licensee must cause all Covered Code to which Licensee contributes to 49234285Sdim * contain a file documenting the changes Licensee made to create that Covered 50234285Sdim * Code and the date of any change. Licensee must include in that file the 51234285Sdim * documentation of any changes made by any predecessor Licensee. Licensee 52234285Sdim * must include a prominent statement that the modification is derived, 53234285Sdim * directly or indirectly, from Original Intel Code. 54234285Sdim * 55234285Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56234285Sdim * Redistribution of source code of any substantial portion of the Covered 57234285Sdim * Code or modification without rights to further distribute source must 58234285Sdim * include the following Disclaimer and Export Compliance provision in the 59234285Sdim * documentation and/or other materials provided with distribution. In 60234285Sdim * addition, Licensee may not authorize further sublicense of source of any 61234285Sdim * portion of the Covered Code, and must include terms to the effect that the 62234285Sdim * license from Licensee to its licensee is limited to the intellectual 63234285Sdim * property embodied in the software Licensee provides to its licensee, and 64234285Sdim * not to intellectual property embodied in modifications its licensee may 65234285Sdim * make. 66234285Sdim * 67234285Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any 68234285Sdim * substantial portion of the Covered Code or modification must reproduce the 69234285Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance 70234285Sdim * provision in the documentation and/or other materials provided with the 71234285Sdim * distribution. 72249423Sdim * 73249423Sdim * 3.4. Intel retains all right, title, and interest in and to the Original 74249423Sdim * Intel Code. 75249423Sdim * 76234285Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77234285Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or 78234285Sdim * other dealings in products derived from or relating to the Covered Code 79234285Sdim * without prior written authorization from Intel. 80234285Sdim * 81234285Sdim * 4. Disclaimer and Export Compliance 82234285Sdim * 83234285Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84234285Sdim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85234285Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86234285Sdim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87234285Sdim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88234285Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89234285Sdim * PARTICULAR PURPOSE. 90234285Sdim * 91234285Sdim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92234285Sdim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93234285Sdim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94234285Sdim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95234285Sdim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96234285Sdim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97234285Sdim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98234285Sdim * LIMITED REMEDY. 99234285Sdim * 100234285Sdim * 4.3. Licensee shall not export, either directly or indirectly, any of this 101234285Sdim * software or system incorporating such software without first obtaining any 102234285Sdim * required license or other approval from the U. S. Department of Commerce or 103234285Sdim * any other agency or department of the United States Government. In the 104234285Sdim * event Licensee exports any such software from the United States or 105234285Sdim * re-exports any such software from a foreign destination, Licensee shall 106234285Sdim * ensure that the distribution and export/re-export of the software is in 107234285Sdim * compliance with all laws, regulations, orders, or other restrictions of the 108234285Sdim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109234285Sdim * any of its subsidiaries will export/re-export any technical data, process, 110234285Sdim * software, or service, directly or indirectly, to any country for which the 111234285Sdim * United States government or any agency thereof requires an export license, 112234285Sdim * other governmental approval, or letter of assurance, without first obtaining 113234285Sdim * such license, approval or letter. 114234285Sdim * 115234285Sdim *****************************************************************************/ 116234285Sdim 117251662Sdim 118234285Sdim#define __AMFIELD_C__ 119234285Sdim 120234285Sdim#include "acpi.h" 121234285Sdim#include "acdispat.h" 122234285Sdim#include "acinterp.h" 123239462Sdim#include "amlcode.h" 124234285Sdim#include "acnamesp.h" 125234285Sdim#include "achware.h" 126234285Sdim#include "acevents.h" 127234285Sdim 128234285Sdim 129234285Sdim#define _COMPONENT INTERPRETER 130234285Sdim MODULE_NAME ("amfield") 131234285Sdim 132234285Sdim 133234285Sdim/******************************************************************************* 134251662Sdim * 135251662Sdim * FUNCTION: AcpiAmlSetupField 136251662Sdim * 137249423Sdim * PARAMETERS: *ObjDesc - Field to be read or written 138251662Sdim * *RgnDesc - Region containing field 139234285Sdim * FieldBitWidth - Field Width in bits (8, 16, or 32) 140234285Sdim * 141234285Sdim * RETURN: Status 142234285Sdim * 143234285Sdim * DESCRIPTION: Common processing for AcpiAmlReadField and AcpiAmlWriteField 144234285Sdim * 145234285Sdim * ACPI SPECIFICATION REFERENCES: 146234285Sdim * Each of the Type1Opcodes is defined as specified in in-line 147234285Sdim * comments below. For each one, use the following definitions. 148234285Sdim * 149234285Sdim * DefBitField := BitFieldOp SrcBuf BitIdx Destination 150234285Sdim * DefByteField := ByteFieldOp SrcBuf ByteIdx Destination 151234285Sdim * DefCreateField := CreateFieldOp SrcBuf BitIdx NumBits NameString 152234285Sdim * DefDWordField := DWordFieldOp SrcBuf ByteIdx Destination 153234285Sdim * DefWordField := WordFieldOp SrcBuf ByteIdx Destination 154234285Sdim * BitIndex := TermArg=>Integer 155234285Sdim * ByteIndex := TermArg=>Integer 156234285Sdim * Destination := NameString 157234285Sdim * NumBits := TermArg=>Integer 158234285Sdim * SourceBuf := TermArg=>Buffer 159234285Sdim * 160234285Sdim ******************************************************************************/ 161234285Sdim 162234285SdimACPI_STATUS 163234285SdimAcpiAmlSetupField ( 164234285Sdim ACPI_OPERAND_OBJECT *ObjDesc, 165234285Sdim ACPI_OPERAND_OBJECT *RgnDesc, 166234285Sdim UINT32 FieldBitWidth) 167234285Sdim{ 168234285Sdim ACPI_STATUS Status = AE_OK; 169234285Sdim UINT32 FieldByteWidth; 170234285Sdim 171234285Sdim 172234285Sdim FUNCTION_TRACE ("AmlSetupField"); 173234285Sdim 174234285Sdim 175234285Sdim /* Parameter validation */ 176239462Sdim 177239462Sdim if (!ObjDesc || !RgnDesc) 178234285Sdim { 179234285Sdim DEBUG_PRINT (ACPI_ERROR, 180239462Sdim ("AmlSetupField: Internal error - null handle\n")); 181249423Sdim return_ACPI_STATUS (AE_AML_NO_OPERAND); 182251662Sdim } 183249423Sdim 184263508Sdim if (ACPI_TYPE_REGION != RgnDesc->Common.Type) 185263508Sdim { 186263508Sdim DEBUG_PRINT (ACPI_ERROR, 187263508Sdim ("AmlSetupField: Needed Region, found type %x %s\n", 188263508Sdim RgnDesc->Common.Type, AcpiCmGetTypeName (RgnDesc->Common.Type))); 189263508Sdim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 190234285Sdim } 191234285Sdim 192239462Sdim 193239462Sdim /* 194239462Sdim * TBD: [Future] Acpi 2.0 supports Qword fields 195239462Sdim * 196263508Sdim * Init and validate Field width 197239462Sdim * Possible values are 1, 2, 4 198239462Sdim */ 199234285Sdim 200249423Sdim FieldByteWidth = DIV_8 (FieldBitWidth); 201249423Sdim 202249423Sdim if ((FieldBitWidth != 8) && 203251662Sdim (FieldBitWidth != 16) && 204251662Sdim (FieldBitWidth != 32)) 205249423Sdim { 206249423Sdim DEBUG_PRINT (ACPI_ERROR, 207249423Sdim ("AmlSetupField: Internal error - bad width %d\n", FieldBitWidth)); 208249423Sdim return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 209249423Sdim } 210249423Sdim 211249423Sdim 212249423Sdim /* 213251662Sdim * If the Region Address and Length have not been previously evaluated, 214251662Sdim * evaluate them and save the results. 215251662Sdim */ 216234285Sdim if (!(RgnDesc->Region.Flags & AOPOBJ_DATA_VALID)) 217234285Sdim { 218234285Sdim 219234285Sdim Status = AcpiDsGetRegionArguments (RgnDesc); 220234285Sdim if (ACPI_FAILURE (Status)) 221234285Sdim { 222234285Sdim return_ACPI_STATUS (Status); 223234285Sdim } 224 } 225 226 227 if ((ObjDesc->Common.Type == ACPI_TYPE_FIELD_UNIT) && 228 (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))) 229 { 230 /* 231 * Field Buffer and Index have not been previously evaluated, 232 */ 233 DEBUG_PRINT (ACPI_ERROR, ("Uninitialized field!\n")); 234 return_ACPI_STATUS (AE_AML_INTERNAL); 235 } 236 237 if (RgnDesc->Region.Length < 238 (ObjDesc->Field.Offset & ~((UINT32) FieldByteWidth - 1)) + 239 FieldByteWidth) 240 { 241 /* 242 * Offset rounded up to next multiple of field width 243 * exceeds region length, indicate an error 244 */ 245 246 DUMP_STACK_ENTRY (RgnDesc); 247 DUMP_STACK_ENTRY (ObjDesc); 248 249 DEBUG_PRINT (ACPI_ERROR, 250 ("AmlSetupField: Operation at %08lX width %d bits exceeds len %08lX field=%p region=%p\n", 251 ObjDesc->Field.Offset, FieldBitWidth, RgnDesc->Region.Length, 252 ObjDesc, RgnDesc)); 253 254 return_ACPI_STATUS (AE_AML_REGION_LIMIT); 255 } 256 257 return_ACPI_STATUS (AE_OK); 258} 259 260 261/******************************************************************************* 262 * 263 * FUNCTION: AcpiAmlAccessNamedField 264 * 265 * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE 266 * NamedField - Handle for field to be accessed 267 * *Buffer - Value(s) to be read or written 268 * BufferLength - Number of bytes to transfer 269 * 270 * RETURN: Status 271 * 272 * DESCRIPTION: Read or write a named field 273 * 274 ******************************************************************************/ 275 276ACPI_STATUS 277AcpiAmlAccessNamedField ( 278 UINT32 Mode, 279 ACPI_HANDLE NamedField, 280 void *Buffer, 281 UINT32 BufferLength) 282{ 283 ACPI_OPERAND_OBJECT *ObjDesc = NULL; 284 ACPI_STATUS Status = AE_OK; 285 BOOLEAN Locked = FALSE; 286 UINT32 BitGranularity = 0; 287 UINT32 ByteGranularity; 288 UINT32 DatumLength; 289 UINT32 ActualByteLength; 290 UINT32 ByteFieldLength; 291 292 293 FUNCTION_TRACE_PTR ("AmlAccessNamedField", NamedField); 294 295 296 /* Basic data checking */ 297 if ((!NamedField) || (ACPI_READ == Mode && !Buffer)) 298 { 299 DEBUG_PRINT (ACPI_ERROR, 300 ("AcpiAmlAccessNamedField: Internal error - null parameter\n")); 301 return_ACPI_STATUS (AE_AML_INTERNAL); 302 } 303 304 /* Get the attached field object */ 305 306 ObjDesc = AcpiNsGetAttachedObject (NamedField); 307 if (!ObjDesc) 308 { 309 DEBUG_PRINT (ACPI_ERROR, 310 ("AmlAccessNamedField: Internal error - null value pointer\n")); 311 return_ACPI_STATUS (AE_AML_INTERNAL); 312 } 313 314 /* Check the type */ 315 316 if (INTERNAL_TYPE_DEF_FIELD != AcpiNsGetType (NamedField)) 317 { 318 DEBUG_PRINT (ACPI_ERROR, 319 ("AmlAccessNamedField: Name %4.4s type %x is not a defined field\n", 320 &(((ACPI_NAMESPACE_NODE *) NamedField)->Name), 321 AcpiNsGetType (NamedField))); 322 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 323 } 324 325 /* ObjDesc valid and NamedField is a defined field */ 326 327 DEBUG_PRINT (ACPI_INFO, 328 ("AccessNamedField: Obj=%p Type=%x Buf=%p Len=%x\n", 329 ObjDesc, ObjDesc->Common.Type, Buffer, BufferLength)); 330 DEBUG_PRINT (ACPI_INFO, 331 ("AccessNamedField: Mode=%d FieldLen=%d, BitOffset=%d\n", 332 Mode, ObjDesc->FieldUnit.Length, ObjDesc->FieldUnit.BitOffset)); 333 DUMP_ENTRY (NamedField, ACPI_INFO); 334 335 336 /* Double-check that the attached object is also a field */ 337 338 if (INTERNAL_TYPE_DEF_FIELD != ObjDesc->Common.Type) 339 { 340 DEBUG_PRINT (ACPI_ERROR, 341 ("AmlAccessNamedField: Internal error - Name %4.4s type %x does not match value-type %x at %p\n", 342 &(((ACPI_NAMESPACE_NODE *) NamedField)->Name), 343 AcpiNsGetType (NamedField), ObjDesc->Common.Type, ObjDesc)); 344 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 345 } 346 347 348 /* 349 * Granularity was decoded from the field access type 350 * (AnyAcc will be the same as ByteAcc) 351 */ 352 353 BitGranularity = ObjDesc->FieldUnit.Granularity; 354 ByteGranularity = DIV_8 (BitGranularity); 355 356 /* 357 * Check if request is too large for the field, and silently truncate 358 * if necessary 359 */ 360 361 /* TBD: [Errors] should an error be returned in this case? */ 362 363 ByteFieldLength = (UINT32) DIV_8 (ObjDesc->FieldUnit.Length + 7); 364 365 366 ActualByteLength = BufferLength; 367 if (BufferLength > ByteFieldLength) 368 { 369 DEBUG_PRINT (ACPI_INFO, 370 ("AmlAccessNamedField: Byte length %X truncated to %X\n", 371 ActualByteLength, ByteFieldLength)); 372 373 ActualByteLength = ByteFieldLength; 374 } 375 376 /* TBD: should these round down to a power of 2? */ 377 378 if (DIV_8(BitGranularity) > ByteFieldLength) 379 { 380 DEBUG_PRINT (ACPI_INFO, 381 ("AmlAccessNamedField: Bit granularity %X truncated to %X\n", 382 BitGranularity, MUL_8(ByteFieldLength))); 383 384 BitGranularity = MUL_8(ByteFieldLength); 385 } 386 387 if (ByteGranularity > ByteFieldLength) 388 { 389 DEBUG_PRINT (ACPI_INFO, 390 ("AmlAccessNamedField: Byte granularity %X truncated to %X\n", 391 ByteGranularity, ByteFieldLength)); 392 393 ByteGranularity = ByteFieldLength; 394 } 395 396 397 /* Convert byte count to datum count, round up if necessary */ 398 399 DatumLength = (ActualByteLength + (ByteGranularity-1)) / ByteGranularity; 400 401 DEBUG_PRINT (ACPI_INFO, 402 ("ByteLen=%x, DatumLen=%x, BitGran=%x, ByteGran=%x\n", 403 ActualByteLength, DatumLength, BitGranularity, ByteGranularity)); 404 405 406 /* Get the global lock if needed */ 407 408 Locked = AcpiAmlAcquireGlobalLock (ObjDesc->FieldUnit.LockRule); 409 410 411 /* Perform the actual read or write of the buffer */ 412 413 switch (Mode) 414 { 415 case ACPI_READ: 416 417 Status = AcpiAmlReadField (ObjDesc, Buffer, BufferLength, 418 ActualByteLength, DatumLength, 419 BitGranularity, ByteGranularity); 420 break; 421 422 423 case ACPI_WRITE: 424 425 Status = AcpiAmlWriteField (ObjDesc, Buffer, BufferLength, 426 ActualByteLength, DatumLength, 427 BitGranularity, ByteGranularity); 428 break; 429 430 431 default: 432 433 DEBUG_PRINT (ACPI_ERROR, 434 ("AccessNamedField: Unknown I/O Mode: %X\n", Mode)); 435 Status = AE_BAD_PARAMETER; 436 break; 437 } 438 439 440 /* Release global lock if we acquired it earlier */ 441 442 AcpiAmlReleaseGlobalLock (Locked); 443 444 return_ACPI_STATUS (Status); 445} 446 447