rsmisc.c revision 243347
167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rsmisc - Miscellaneous resource descriptors 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2012, 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 4467754Smsmith#define __RSMISC_C__ 4567754Smsmith 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/acresrc.h> 4967754Smsmith 5077424Smsmith#define _COMPONENT ACPI_RESOURCES 5191116Smsmith ACPI_MODULE_NAME ("rsmisc") 5267754Smsmith 5367754Smsmith 54151937Sjkim#define INIT_RESOURCE_TYPE(i) i->ResourceOffset 55151937Sjkim#define INIT_RESOURCE_LENGTH(i) i->AmlOffset 56151937Sjkim#define INIT_TABLE_LENGTH(i) i->Value 57151937Sjkim 58151937Sjkim#define COMPARE_OPCODE(i) i->ResourceOffset 59151937Sjkim#define COMPARE_TARGET(i) i->AmlOffset 60151937Sjkim#define COMPARE_VALUE(i) i->Value 61151937Sjkim 62151937Sjkim 6367754Smsmith/******************************************************************************* 6467754Smsmith * 65151937Sjkim * FUNCTION: AcpiRsConvertAmlToResource 6667754Smsmith * 67151937Sjkim * PARAMETERS: Resource - Pointer to the resource descriptor 68151937Sjkim * Aml - Where the AML descriptor is returned 69151937Sjkim * Info - Pointer to appropriate conversion table 7067754Smsmith * 7177424Smsmith * RETURN: Status 7267754Smsmith * 73151937Sjkim * DESCRIPTION: Convert an external AML resource descriptor to the corresponding 74151937Sjkim * internal resource descriptor 7567754Smsmith * 7667754Smsmith ******************************************************************************/ 7767754Smsmith 7867754SmsmithACPI_STATUS 79151937SjkimAcpiRsConvertAmlToResource ( 80151937Sjkim ACPI_RESOURCE *Resource, 81151937Sjkim AML_RESOURCE *Aml, 82151937Sjkim ACPI_RSCONVERT_INFO *Info) 8367754Smsmith{ 84151937Sjkim ACPI_RS_LENGTH AmlResourceLength; 85151937Sjkim void *Source; 86151937Sjkim void *Destination; 87151937Sjkim char *Target; 88151937Sjkim UINT8 Count; 89151937Sjkim UINT8 FlagsMode = FALSE; 90151937Sjkim UINT16 ItemCount = 0; 91151937Sjkim UINT16 Temp16 = 0; 9267754Smsmith 9367754Smsmith 94167802Sjkim ACPI_FUNCTION_TRACE (RsConvertAmlToResource); 9567754Smsmith 9677424Smsmith 97228110Sjkim if (!Info) 98228110Sjkim { 99228110Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 100228110Sjkim } 101228110Sjkim 102193267Sjkim if (((ACPI_SIZE) Resource) & 0x3) 103151937Sjkim { 104167802Sjkim /* Each internal resource struct is expected to be 32-bit aligned */ 105167802Sjkim 106167802Sjkim ACPI_WARNING ((AE_INFO, 107204773Sjkim "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u", 108167802Sjkim Resource, Resource->Type, Resource->Length)); 109151937Sjkim } 11067754Smsmith 111151937Sjkim /* Extract the resource Length field (does not include header length) */ 11267754Smsmith 113151937Sjkim AmlResourceLength = AcpiUtGetResourceLength (Aml); 11467754Smsmith 11567754Smsmith /* 116151937Sjkim * First table entry must be ACPI_RSC_INITxxx and must contain the 117151937Sjkim * table length (# of table entries) 11867754Smsmith */ 119151937Sjkim Count = INIT_TABLE_LENGTH (Info); 120151937Sjkim while (Count) 121151937Sjkim { 122151937Sjkim /* 123151937Sjkim * Source is the external AML byte stream buffer, 124151937Sjkim * destination is the internal resource descriptor 125151937Sjkim */ 126167802Sjkim Source = ACPI_ADD_PTR (void, Aml, Info->AmlOffset); 127167802Sjkim Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset); 12867754Smsmith 129151937Sjkim switch (Info->Opcode) 130151937Sjkim { 131151937Sjkim case ACPI_RSC_INITGET: 132151937Sjkim /* 133151937Sjkim * Get the resource type and the initial (minimum) length 134151937Sjkim */ 135151937Sjkim ACPI_MEMSET (Resource, 0, INIT_RESOURCE_LENGTH (Info)); 136151937Sjkim Resource->Type = INIT_RESOURCE_TYPE (Info); 137151937Sjkim Resource->Length = INIT_RESOURCE_LENGTH (Info); 138151937Sjkim break; 13967754Smsmith 14067754Smsmith 141151937Sjkim case ACPI_RSC_INITSET: 142151937Sjkim break; 14367754Smsmith 14467754Smsmith 145151937Sjkim case ACPI_RSC_FLAGINIT: 14677424Smsmith 147151937Sjkim FlagsMode = TRUE; 148151937Sjkim break; 14967754Smsmith 15067754Smsmith 151151937Sjkim case ACPI_RSC_1BITFLAG: 152151937Sjkim /* 153151937Sjkim * Mask and shift the flag bit 154151937Sjkim */ 155243347Sjkim ACPI_SET8 (Destination, 156243347Sjkim ((ACPI_GET8 (Source) >> Info->Value) & 0x01)); 157151937Sjkim break; 15867754Smsmith 15967754Smsmith 160151937Sjkim case ACPI_RSC_2BITFLAG: 161151937Sjkim /* 162151937Sjkim * Mask and shift the flag bits 163151937Sjkim */ 164243347Sjkim ACPI_SET8 (Destination, 165243347Sjkim ((ACPI_GET8 (Source) >> Info->Value) & 0x03)); 166151937Sjkim break; 16767754Smsmith 16867754Smsmith 169228110Sjkim case ACPI_RSC_3BITFLAG: 170228110Sjkim /* 171228110Sjkim * Mask and shift the flag bits 172228110Sjkim */ 173243347Sjkim ACPI_SET8 (Destination, 174243347Sjkim ((ACPI_GET8 (Source) >> Info->Value) & 0x07)); 175228110Sjkim break; 176228110Sjkim 177228110Sjkim 178151937Sjkim case ACPI_RSC_COUNT: 17967754Smsmith 180167802Sjkim ItemCount = ACPI_GET8 (Source); 181243347Sjkim ACPI_SET8 (Destination, ItemCount); 18267754Smsmith 183151937Sjkim Resource->Length = Resource->Length + 184151937Sjkim (Info->Value * (ItemCount - 1)); 185151937Sjkim break; 18667754Smsmith 18777424Smsmith 188151937Sjkim case ACPI_RSC_COUNT16: 18967754Smsmith 190151937Sjkim ItemCount = AmlResourceLength; 191243347Sjkim ACPI_SET16 (Destination, ItemCount); 19267754Smsmith 193151937Sjkim Resource->Length = Resource->Length + 194151937Sjkim (Info->Value * (ItemCount - 1)); 195151937Sjkim break; 19667754Smsmith 19767754Smsmith 198228110Sjkim case ACPI_RSC_COUNT_GPIO_PIN: 199228110Sjkim 200228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 201228110Sjkim ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source); 202228110Sjkim 203228110Sjkim Resource->Length = Resource->Length + ItemCount; 204228110Sjkim ItemCount = ItemCount / 2; 205243347Sjkim ACPI_SET16 (Destination, ItemCount); 206228110Sjkim break; 207228110Sjkim 208228110Sjkim 209228110Sjkim case ACPI_RSC_COUNT_GPIO_VEN: 210228110Sjkim 211228110Sjkim ItemCount = ACPI_GET8 (Source); 212243347Sjkim ACPI_SET8 (Destination, ItemCount); 213228110Sjkim 214228110Sjkim Resource->Length = Resource->Length + 215228110Sjkim (Info->Value * ItemCount); 216228110Sjkim break; 217228110Sjkim 218228110Sjkim 219228110Sjkim case ACPI_RSC_COUNT_GPIO_RES: 220228110Sjkim 221228110Sjkim /* 222228110Sjkim * Vendor data is optional (length/offset may both be zero) 223228110Sjkim * Examine vendor data length field first 224228110Sjkim */ 225228110Sjkim Target = ACPI_ADD_PTR (void, Aml, (Info->Value + 2)); 226228110Sjkim if (ACPI_GET16 (Target)) 227228110Sjkim { 228228110Sjkim /* Use vendor offset to get resource source length */ 229228110Sjkim 230228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 231228110Sjkim ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source); 232228110Sjkim } 233228110Sjkim else 234228110Sjkim { 235228110Sjkim /* No vendor data to worry about */ 236228110Sjkim 237228110Sjkim ItemCount = Aml->LargeHeader.ResourceLength + 238228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER) - 239228110Sjkim ACPI_GET16 (Source); 240228110Sjkim } 241228110Sjkim 242228110Sjkim Resource->Length = Resource->Length + ItemCount; 243243347Sjkim ACPI_SET16 (Destination, ItemCount); 244228110Sjkim break; 245228110Sjkim 246228110Sjkim 247228110Sjkim case ACPI_RSC_COUNT_SERIAL_VEN: 248228110Sjkim 249228110Sjkim ItemCount = ACPI_GET16 (Source) - Info->Value; 250228110Sjkim 251228110Sjkim Resource->Length = Resource->Length + ItemCount; 252243347Sjkim ACPI_SET16 (Destination, ItemCount); 253228110Sjkim break; 254228110Sjkim 255228110Sjkim 256228110Sjkim case ACPI_RSC_COUNT_SERIAL_RES: 257228110Sjkim 258228110Sjkim ItemCount = (AmlResourceLength + 259228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER)) - 260228110Sjkim ACPI_GET16 (Source) - Info->Value; 261228110Sjkim 262228110Sjkim Resource->Length = Resource->Length + ItemCount; 263243347Sjkim ACPI_SET16 (Destination, ItemCount); 264228110Sjkim break; 265228110Sjkim 266228110Sjkim 267151937Sjkim case ACPI_RSC_LENGTH: 26867754Smsmith 269151937Sjkim Resource->Length = Resource->Length + Info->Value; 270151937Sjkim break; 27167754Smsmith 27267754Smsmith 273151937Sjkim case ACPI_RSC_MOVE8: 274151937Sjkim case ACPI_RSC_MOVE16: 275151937Sjkim case ACPI_RSC_MOVE32: 276151937Sjkim case ACPI_RSC_MOVE64: 277151937Sjkim /* 278151937Sjkim * Raw data move. Use the Info value field unless ItemCount has 279151937Sjkim * been previously initialized via a COUNT opcode 280151937Sjkim */ 281151937Sjkim if (Info->Value) 282151937Sjkim { 283151937Sjkim ItemCount = Info->Value; 284151937Sjkim } 285167802Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 286151937Sjkim break; 28767754Smsmith 28867754Smsmith 289228110Sjkim case ACPI_RSC_MOVE_GPIO_PIN: 290228110Sjkim 291228110Sjkim /* Generate and set the PIN data pointer */ 292228110Sjkim 293228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 294228110Sjkim (Resource->Length - ItemCount * 2)); 295228110Sjkim *(UINT16 **) Destination = ACPI_CAST_PTR (UINT16, Target); 296228110Sjkim 297228110Sjkim /* Copy the PIN data */ 298228110Sjkim 299228110Sjkim Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source)); 300228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 301228110Sjkim break; 302228110Sjkim 303228110Sjkim 304228110Sjkim case ACPI_RSC_MOVE_GPIO_RES: 305228110Sjkim 306228110Sjkim /* Generate and set the ResourceSource string pointer */ 307228110Sjkim 308228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 309228110Sjkim (Resource->Length - ItemCount)); 310228110Sjkim *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); 311228110Sjkim 312228110Sjkim /* Copy the ResourceSource string */ 313228110Sjkim 314228110Sjkim Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source)); 315228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 316228110Sjkim break; 317228110Sjkim 318228110Sjkim 319228110Sjkim case ACPI_RSC_MOVE_SERIAL_VEN: 320228110Sjkim 321228110Sjkim /* Generate and set the Vendor Data pointer */ 322228110Sjkim 323228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 324228110Sjkim (Resource->Length - ItemCount)); 325228110Sjkim *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); 326228110Sjkim 327228110Sjkim /* Copy the Vendor Data */ 328228110Sjkim 329228110Sjkim Source = ACPI_ADD_PTR (void, Aml, Info->Value); 330228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 331228110Sjkim break; 332228110Sjkim 333228110Sjkim 334228110Sjkim case ACPI_RSC_MOVE_SERIAL_RES: 335228110Sjkim 336228110Sjkim /* Generate and set the ResourceSource string pointer */ 337228110Sjkim 338228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 339228110Sjkim (Resource->Length - ItemCount)); 340228110Sjkim *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); 341228110Sjkim 342228110Sjkim /* Copy the ResourceSource string */ 343228110Sjkim 344228110Sjkim Source = ACPI_ADD_PTR (void, Aml, (ACPI_GET16 (Source) + Info->Value)); 345228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 346228110Sjkim break; 347228110Sjkim 348228110Sjkim 349151937Sjkim case ACPI_RSC_SET8: 35067754Smsmith 351151937Sjkim ACPI_MEMSET (Destination, Info->AmlOffset, Info->Value); 352151937Sjkim break; 35367754Smsmith 35467754Smsmith 355151937Sjkim case ACPI_RSC_DATA8: 35667754Smsmith 357167802Sjkim Target = ACPI_ADD_PTR (char, Resource, Info->Value); 358167802Sjkim ACPI_MEMCPY (Destination, Source, ACPI_GET16 (Target)); 359151937Sjkim break; 36067754Smsmith 36167754Smsmith 362151937Sjkim case ACPI_RSC_ADDRESS: 363151937Sjkim /* 364151937Sjkim * Common handler for address descriptor flags 365151937Sjkim */ 366151937Sjkim if (!AcpiRsGetAddressCommon (Resource, Aml)) 367151937Sjkim { 368151937Sjkim return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 369151937Sjkim } 370151937Sjkim break; 37167754Smsmith 37267754Smsmith 373151937Sjkim case ACPI_RSC_SOURCE: 374151937Sjkim /* 375151937Sjkim * Optional ResourceSource (Index and String) 376151937Sjkim */ 377151937Sjkim Resource->Length += 378151937Sjkim AcpiRsGetResourceSource (AmlResourceLength, Info->Value, 379151937Sjkim Destination, Aml, NULL); 380151937Sjkim break; 38167754Smsmith 38267754Smsmith 383151937Sjkim case ACPI_RSC_SOURCEX: 384151937Sjkim /* 385151937Sjkim * Optional ResourceSource (Index and String). This is the more 386151937Sjkim * complicated case used by the Interrupt() macro 387151937Sjkim */ 388228110Sjkim Target = ACPI_ADD_PTR (char, Resource, 389228110Sjkim Info->AmlOffset + (ItemCount * 4)); 39067754Smsmith 391151937Sjkim Resource->Length += 392228110Sjkim AcpiRsGetResourceSource (AmlResourceLength, (ACPI_RS_LENGTH) 393228110Sjkim (((ItemCount - 1) * sizeof (UINT32)) + Info->Value), 394151937Sjkim Destination, Aml, Target); 395151937Sjkim break; 39667754Smsmith 39767754Smsmith 398151937Sjkim case ACPI_RSC_BITMASK: 399151937Sjkim /* 400151937Sjkim * 8-bit encoded bitmask (DMA macro) 401151937Sjkim */ 402167802Sjkim ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination); 403151937Sjkim if (ItemCount) 404151937Sjkim { 405152069Sjkim Resource->Length += (ItemCount - 1); 406151937Sjkim } 40777424Smsmith 408167802Sjkim Target = ACPI_ADD_PTR (char, Resource, Info->Value); 409243347Sjkim ACPI_SET8 (Target, ItemCount); 410151937Sjkim break; 41167754Smsmith 41267754Smsmith 413151937Sjkim case ACPI_RSC_BITMASK16: 414151937Sjkim /* 415151937Sjkim * 16-bit encoded bitmask (IRQ macro) 416151937Sjkim */ 417151937Sjkim ACPI_MOVE_16_TO_16 (&Temp16, Source); 41867754Smsmith 419151937Sjkim ItemCount = AcpiRsDecodeBitmask (Temp16, Destination); 420151937Sjkim if (ItemCount) 421151937Sjkim { 422152069Sjkim Resource->Length += (ItemCount - 1); 423151937Sjkim } 424151937Sjkim 425167802Sjkim Target = ACPI_ADD_PTR (char, Resource, Info->Value); 426243347Sjkim ACPI_SET8 (Target, ItemCount); 427151937Sjkim break; 428151937Sjkim 429151937Sjkim 430151937Sjkim case ACPI_RSC_EXIT_NE: 431151937Sjkim /* 432151937Sjkim * Control - Exit conversion if not equal 433151937Sjkim */ 434151937Sjkim switch (Info->ResourceOffset) 435151937Sjkim { 436151937Sjkim case ACPI_RSC_COMPARE_AML_LENGTH: 437151937Sjkim if (AmlResourceLength != Info->Value) 438151937Sjkim { 439151937Sjkim goto Exit; 440151937Sjkim } 441151937Sjkim break; 442151937Sjkim 443151937Sjkim case ACPI_RSC_COMPARE_VALUE: 444167802Sjkim if (ACPI_GET8 (Source) != Info->Value) 445151937Sjkim { 446151937Sjkim goto Exit; 447151937Sjkim } 448151937Sjkim break; 449151937Sjkim 450151937Sjkim default: 451167802Sjkim 452167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode")); 453151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 454151937Sjkim } 455151937Sjkim break; 456151937Sjkim 457151937Sjkim 458151937Sjkim default: 459151937Sjkim 460167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion opcode")); 461151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 462151937Sjkim } 463151937Sjkim 464151937Sjkim Count--; 465151937Sjkim Info++; 46667754Smsmith } 46767754Smsmith 468151937SjkimExit: 469151937Sjkim if (!FlagsMode) 47067754Smsmith { 471167802Sjkim /* Round the resource struct length up to the next boundary (32 or 64) */ 47267754Smsmith 473167802Sjkim Resource->Length = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length); 47467754Smsmith } 47567754Smsmith return_ACPI_STATUS (AE_OK); 47667754Smsmith} 47767754Smsmith 47867754Smsmith 47967754Smsmith/******************************************************************************* 48067754Smsmith * 481151937Sjkim * FUNCTION: AcpiRsConvertResourceToAml 48267754Smsmith * 483151937Sjkim * PARAMETERS: Resource - Pointer to the resource descriptor 484151937Sjkim * Aml - Where the AML descriptor is returned 485151937Sjkim * Info - Pointer to appropriate conversion table 48667754Smsmith * 48777424Smsmith * RETURN: Status 48867754Smsmith * 489151937Sjkim * DESCRIPTION: Convert an internal resource descriptor to the corresponding 490151937Sjkim * external AML resource descriptor. 49167754Smsmith * 49267754Smsmith ******************************************************************************/ 49367754Smsmith 49467754SmsmithACPI_STATUS 495151937SjkimAcpiRsConvertResourceToAml ( 496151937Sjkim ACPI_RESOURCE *Resource, 497151937Sjkim AML_RESOURCE *Aml, 498151937Sjkim ACPI_RSCONVERT_INFO *Info) 49967754Smsmith{ 500151937Sjkim void *Source = NULL; 501151937Sjkim void *Destination; 502228110Sjkim char *Target; 503151937Sjkim ACPI_RSDESC_SIZE AmlLength = 0; 504151937Sjkim UINT8 Count; 505151937Sjkim UINT16 Temp16 = 0; 506151937Sjkim UINT16 ItemCount = 0; 50767754Smsmith 50867754Smsmith 509167802Sjkim ACPI_FUNCTION_TRACE (RsConvertResourceToAml); 51067754Smsmith 51177424Smsmith 512228110Sjkim if (!Info) 513228110Sjkim { 514228110Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 515228110Sjkim } 516228110Sjkim 51767754Smsmith /* 518151937Sjkim * First table entry must be ACPI_RSC_INITxxx and must contain the 519151937Sjkim * table length (# of table entries) 52067754Smsmith */ 521151937Sjkim Count = INIT_TABLE_LENGTH (Info); 522151937Sjkim 523151937Sjkim while (Count) 52467754Smsmith { 52567754Smsmith /* 526151937Sjkim * Source is the internal resource descriptor, 527151937Sjkim * destination is the external AML byte stream buffer 52867754Smsmith */ 529167802Sjkim Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset); 530167802Sjkim Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset); 53167754Smsmith 532151937Sjkim switch (Info->Opcode) 53367754Smsmith { 534151937Sjkim case ACPI_RSC_INITSET: 53567754Smsmith 536151937Sjkim ACPI_MEMSET (Aml, 0, INIT_RESOURCE_LENGTH (Info)); 537151937Sjkim AmlLength = INIT_RESOURCE_LENGTH (Info); 538151937Sjkim AcpiRsSetResourceHeader (INIT_RESOURCE_TYPE (Info), AmlLength, Aml); 539151937Sjkim break; 54067754Smsmith 54167754Smsmith 542151937Sjkim case ACPI_RSC_INITGET: 543151937Sjkim break; 54467754Smsmith 54567754Smsmith 546151937Sjkim case ACPI_RSC_FLAGINIT: 547151937Sjkim /* 548151937Sjkim * Clear the flag byte 549151937Sjkim */ 550243347Sjkim ACPI_SET8 (Destination, 0); 551151937Sjkim break; 55267754Smsmith 55367754Smsmith 554151937Sjkim case ACPI_RSC_1BITFLAG: 555151937Sjkim /* 556151937Sjkim * Mask and shift the flag bit 557151937Sjkim */ 558243347Sjkim ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) 559243347Sjkim ((ACPI_GET8 (Source) & 0x01) << Info->Value)); 560151937Sjkim break; 56167754Smsmith 56267754Smsmith 563151937Sjkim case ACPI_RSC_2BITFLAG: 564151937Sjkim /* 565151937Sjkim * Mask and shift the flag bits 566151937Sjkim */ 567243347Sjkim ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) 568243347Sjkim ((ACPI_GET8 (Source) & 0x03) << Info->Value)); 569151937Sjkim break; 57067754Smsmith 57167754Smsmith 572228110Sjkim case ACPI_RSC_3BITFLAG: 573228110Sjkim /* 574228110Sjkim * Mask and shift the flag bits 575228110Sjkim */ 576243347Sjkim ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) 577243347Sjkim ((ACPI_GET8 (Source) & 0x07) << Info->Value)); 578228110Sjkim break; 579228110Sjkim 580228110Sjkim 581151937Sjkim case ACPI_RSC_COUNT: 58277424Smsmith 583167802Sjkim ItemCount = ACPI_GET8 (Source); 584243347Sjkim ACPI_SET8 (Destination, ItemCount); 58567754Smsmith 586167802Sjkim AmlLength = (UINT16) (AmlLength + (Info->Value * (ItemCount - 1))); 587151937Sjkim break; 58867754Smsmith 58967754Smsmith 590151937Sjkim case ACPI_RSC_COUNT16: 59167754Smsmith 592167802Sjkim ItemCount = ACPI_GET16 (Source); 593151937Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 594151937Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 595151937Sjkim break; 59667754Smsmith 59767754Smsmith 598228110Sjkim case ACPI_RSC_COUNT_GPIO_PIN: 599228110Sjkim 600228110Sjkim ItemCount = ACPI_GET16 (Source); 601243347Sjkim ACPI_SET16 (Destination, AmlLength); 602228110Sjkim 603228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount * 2); 604228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 605243347Sjkim ACPI_SET16 (Target, AmlLength); 606228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 607228110Sjkim break; 608228110Sjkim 609228110Sjkim 610228110Sjkim case ACPI_RSC_COUNT_GPIO_VEN: 611228110Sjkim 612228110Sjkim ItemCount = ACPI_GET16 (Source); 613243347Sjkim ACPI_SET16 (Destination, ItemCount); 614228110Sjkim 615228110Sjkim AmlLength = (UINT16) (AmlLength + (Info->Value * ItemCount)); 616228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 617228110Sjkim break; 618228110Sjkim 619228110Sjkim 620228110Sjkim case ACPI_RSC_COUNT_GPIO_RES: 621228110Sjkim 622228110Sjkim /* Set resource source string length */ 623228110Sjkim 624228110Sjkim ItemCount = ACPI_GET16 (Source); 625243347Sjkim ACPI_SET16 (Destination, AmlLength); 626228110Sjkim 627228110Sjkim /* Compute offset for the Vendor Data */ 628228110Sjkim 629228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 630228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 631228110Sjkim 632228110Sjkim /* Set vendor offset only if there is vendor data */ 633228110Sjkim 634228110Sjkim if (Resource->Data.Gpio.VendorLength) 635228110Sjkim { 636243347Sjkim ACPI_SET16 (Target, AmlLength); 637228110Sjkim } 638228110Sjkim 639228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 640228110Sjkim break; 641228110Sjkim 642228110Sjkim 643228110Sjkim case ACPI_RSC_COUNT_SERIAL_VEN: 644228110Sjkim 645228110Sjkim ItemCount = ACPI_GET16 (Source); 646243347Sjkim ACPI_SET16 (Destination, ItemCount + Info->Value); 647228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 648228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 649228110Sjkim break; 650228110Sjkim 651228110Sjkim 652228110Sjkim case ACPI_RSC_COUNT_SERIAL_RES: 653228110Sjkim 654228110Sjkim ItemCount = ACPI_GET16 (Source); 655228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 656228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 657228110Sjkim break; 658228110Sjkim 659228110Sjkim 660151937Sjkim case ACPI_RSC_LENGTH: 66167754Smsmith 662151937Sjkim AcpiRsSetResourceLength (Info->Value, Aml); 663151937Sjkim break; 66467754Smsmith 66567754Smsmith 666151937Sjkim case ACPI_RSC_MOVE8: 667151937Sjkim case ACPI_RSC_MOVE16: 668151937Sjkim case ACPI_RSC_MOVE32: 669151937Sjkim case ACPI_RSC_MOVE64: 67077424Smsmith 671151937Sjkim if (Info->Value) 672151937Sjkim { 673151937Sjkim ItemCount = Info->Value; 674151937Sjkim } 675151937Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 676151937Sjkim break; 67767754Smsmith 67867754Smsmith 679228110Sjkim case ACPI_RSC_MOVE_GPIO_PIN: 680228110Sjkim 681228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 682228110Sjkim ACPI_GET16 (Destination)); 683228110Sjkim Source = * (UINT16 **) Source; 684228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 685228110Sjkim break; 686228110Sjkim 687228110Sjkim 688228110Sjkim case ACPI_RSC_MOVE_GPIO_RES: 689228110Sjkim 690228110Sjkim /* Used for both ResourceSource string and VendorData */ 691228110Sjkim 692228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 693228110Sjkim ACPI_GET16 (Destination)); 694228110Sjkim Source = * (UINT8 **) Source; 695228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 696228110Sjkim break; 697228110Sjkim 698228110Sjkim 699228110Sjkim case ACPI_RSC_MOVE_SERIAL_VEN: 700228110Sjkim 701228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 702228110Sjkim (AmlLength - ItemCount)); 703228110Sjkim Source = * (UINT8 **) Source; 704228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 705228110Sjkim break; 706228110Sjkim 707228110Sjkim 708228110Sjkim case ACPI_RSC_MOVE_SERIAL_RES: 709228110Sjkim 710228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 711228110Sjkim (AmlLength - ItemCount)); 712228110Sjkim Source = * (UINT8 **) Source; 713228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 714228110Sjkim break; 715228110Sjkim 716228110Sjkim 717151937Sjkim case ACPI_RSC_ADDRESS: 71867754Smsmith 719151937Sjkim /* Set the Resource Type, General Flags, and Type-Specific Flags */ 72067754Smsmith 721151937Sjkim AcpiRsSetAddressCommon (Aml, Resource); 722151937Sjkim break; 72367754Smsmith 72467754Smsmith 725151937Sjkim case ACPI_RSC_SOURCEX: 726151937Sjkim /* 727151937Sjkim * Optional ResourceSource (Index and String) 728151937Sjkim */ 729151937Sjkim AmlLength = AcpiRsSetResourceSource ( 730151937Sjkim Aml, (ACPI_RS_LENGTH) AmlLength, Source); 731151937Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 732151937Sjkim break; 73367754Smsmith 73467754Smsmith 735151937Sjkim case ACPI_RSC_SOURCE: 736151937Sjkim /* 737151937Sjkim * Optional ResourceSource (Index and String). This is the more 738151937Sjkim * complicated case used by the Interrupt() macro 739151937Sjkim */ 740151937Sjkim AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source); 741151937Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 742151937Sjkim break; 74367754Smsmith 74477424Smsmith 745151937Sjkim case ACPI_RSC_BITMASK: 746151937Sjkim /* 747151937Sjkim * 8-bit encoded bitmask (DMA macro) 748151937Sjkim */ 749243347Sjkim ACPI_SET8 (Destination, 750167802Sjkim AcpiRsEncodeBitmask (Source, 751243347Sjkim *ACPI_ADD_PTR (UINT8, Resource, Info->Value))); 752151937Sjkim break; 75367754Smsmith 754151937Sjkim 755151937Sjkim case ACPI_RSC_BITMASK16: 756151937Sjkim /* 757151937Sjkim * 16-bit encoded bitmask (IRQ macro) 758151937Sjkim */ 759167802Sjkim Temp16 = AcpiRsEncodeBitmask (Source, 760167802Sjkim *ACPI_ADD_PTR (UINT8, Resource, Info->Value)); 761151937Sjkim ACPI_MOVE_16_TO_16 (Destination, &Temp16); 762151937Sjkim break; 763151937Sjkim 764151937Sjkim 765151937Sjkim case ACPI_RSC_EXIT_LE: 766151937Sjkim /* 767151937Sjkim * Control - Exit conversion if less than or equal 768151937Sjkim */ 769151937Sjkim if (ItemCount <= Info->Value) 770151937Sjkim { 771151937Sjkim goto Exit; 772151937Sjkim } 773151937Sjkim break; 774151937Sjkim 775151937Sjkim 776151937Sjkim case ACPI_RSC_EXIT_NE: 777151937Sjkim /* 778151937Sjkim * Control - Exit conversion if not equal 779151937Sjkim */ 780151937Sjkim switch (COMPARE_OPCODE (Info)) 781151937Sjkim { 782151937Sjkim case ACPI_RSC_COMPARE_VALUE: 783167802Sjkim 784167802Sjkim if (*ACPI_ADD_PTR (UINT8, Resource, 785167802Sjkim COMPARE_TARGET (Info)) != COMPARE_VALUE (Info)) 786151937Sjkim { 787151937Sjkim goto Exit; 788151937Sjkim } 789151937Sjkim break; 790151937Sjkim 791151937Sjkim default: 792167802Sjkim 793167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode")); 794151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 795151937Sjkim } 796151937Sjkim break; 797151937Sjkim 798151937Sjkim 799193267Sjkim case ACPI_RSC_EXIT_EQ: 800193267Sjkim /* 801193267Sjkim * Control - Exit conversion if equal 802193267Sjkim */ 803193267Sjkim if (*ACPI_ADD_PTR (UINT8, Resource, 804193267Sjkim COMPARE_TARGET (Info)) == COMPARE_VALUE (Info)) 805193267Sjkim { 806193267Sjkim goto Exit; 807193267Sjkim } 808193267Sjkim break; 809193267Sjkim 810193267Sjkim 811151937Sjkim default: 812151937Sjkim 813167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion opcode")); 814151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 815151937Sjkim } 816151937Sjkim 817151937Sjkim Count--; 818151937Sjkim Info++; 819151937Sjkim } 820151937Sjkim 821151937SjkimExit: 82267754Smsmith return_ACPI_STATUS (AE_OK); 82367754Smsmith} 82467754Smsmith 825151937Sjkim 826151937Sjkim#if 0 827151937Sjkim/* Previous resource validations */ 828151937Sjkim 829151937Sjkim if (Aml->ExtAddress64.RevisionID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) 830151937Sjkim { 831151937Sjkim return_ACPI_STATUS (AE_SUPPORT); 832151937Sjkim } 833151937Sjkim 834151937Sjkim if (Resource->Data.StartDpf.PerformanceRobustness >= 3) 835151937Sjkim { 836151937Sjkim return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); 837151937Sjkim } 838151937Sjkim 839151937Sjkim if (((Aml->Irq.Flags & 0x09) == 0x00) || 840151937Sjkim ((Aml->Irq.Flags & 0x09) == 0x09)) 841151937Sjkim { 842151937Sjkim /* 843151937Sjkim * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive] 844151937Sjkim * polarity/trigger interrupts are allowed (ACPI spec, section 845151937Sjkim * "IRQ Format"), so 0x00 and 0x09 are illegal. 846151937Sjkim */ 847167802Sjkim ACPI_ERROR ((AE_INFO, 848204773Sjkim "Invalid interrupt polarity/trigger in resource list, 0x%X", 849151937Sjkim Aml->Irq.Flags)); 850151937Sjkim return_ACPI_STATUS (AE_BAD_DATA); 851151937Sjkim } 852151937Sjkim 853151937Sjkim Resource->Data.ExtendedIrq.InterruptCount = Temp8; 854151937Sjkim if (Temp8 < 1) 855151937Sjkim { 856151937Sjkim /* Must have at least one IRQ */ 857151937Sjkim 858151937Sjkim return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 859151937Sjkim } 860151937Sjkim 861151937Sjkim if (Resource->Data.Dma.Transfer == 0x03) 862151937Sjkim { 863167802Sjkim ACPI_ERROR ((AE_INFO, 864167802Sjkim "Invalid DMA.Transfer preference (3)")); 865151937Sjkim return_ACPI_STATUS (AE_BAD_DATA); 866151937Sjkim } 867151937Sjkim#endif 868