167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rsmisc - Miscellaneous resource descriptors 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, 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 140151937Sjkim case ACPI_RSC_INITSET: 141151937Sjkim break; 14267754Smsmith 143151937Sjkim case ACPI_RSC_FLAGINIT: 14477424Smsmith 145151937Sjkim FlagsMode = TRUE; 146151937Sjkim break; 14767754Smsmith 148151937Sjkim case ACPI_RSC_1BITFLAG: 149151937Sjkim /* 150151937Sjkim * Mask and shift the flag bit 151151937Sjkim */ 152243347Sjkim ACPI_SET8 (Destination, 153243347Sjkim ((ACPI_GET8 (Source) >> Info->Value) & 0x01)); 154151937Sjkim break; 15567754Smsmith 156151937Sjkim case ACPI_RSC_2BITFLAG: 157151937Sjkim /* 158151937Sjkim * Mask and shift the flag bits 159151937Sjkim */ 160243347Sjkim ACPI_SET8 (Destination, 161243347Sjkim ((ACPI_GET8 (Source) >> Info->Value) & 0x03)); 162151937Sjkim break; 16367754Smsmith 164228110Sjkim case ACPI_RSC_3BITFLAG: 165228110Sjkim /* 166228110Sjkim * Mask and shift the flag bits 167228110Sjkim */ 168243347Sjkim ACPI_SET8 (Destination, 169243347Sjkim ((ACPI_GET8 (Source) >> Info->Value) & 0x07)); 170228110Sjkim break; 171228110Sjkim 172151937Sjkim case ACPI_RSC_COUNT: 17367754Smsmith 174167802Sjkim ItemCount = ACPI_GET8 (Source); 175243347Sjkim ACPI_SET8 (Destination, ItemCount); 17667754Smsmith 177151937Sjkim Resource->Length = Resource->Length + 178151937Sjkim (Info->Value * (ItemCount - 1)); 179151937Sjkim break; 18067754Smsmith 181151937Sjkim case ACPI_RSC_COUNT16: 18267754Smsmith 183151937Sjkim ItemCount = AmlResourceLength; 184243347Sjkim ACPI_SET16 (Destination, ItemCount); 18567754Smsmith 186151937Sjkim Resource->Length = Resource->Length + 187151937Sjkim (Info->Value * (ItemCount - 1)); 188151937Sjkim break; 18967754Smsmith 190228110Sjkim case ACPI_RSC_COUNT_GPIO_PIN: 191228110Sjkim 192228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 193228110Sjkim ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source); 194228110Sjkim 195228110Sjkim Resource->Length = Resource->Length + ItemCount; 196228110Sjkim ItemCount = ItemCount / 2; 197243347Sjkim ACPI_SET16 (Destination, ItemCount); 198228110Sjkim break; 199228110Sjkim 200228110Sjkim case ACPI_RSC_COUNT_GPIO_VEN: 201228110Sjkim 202228110Sjkim ItemCount = ACPI_GET8 (Source); 203243347Sjkim ACPI_SET8 (Destination, ItemCount); 204228110Sjkim 205228110Sjkim Resource->Length = Resource->Length + 206228110Sjkim (Info->Value * ItemCount); 207228110Sjkim break; 208228110Sjkim 209228110Sjkim case ACPI_RSC_COUNT_GPIO_RES: 210228110Sjkim /* 211228110Sjkim * Vendor data is optional (length/offset may both be zero) 212228110Sjkim * Examine vendor data length field first 213228110Sjkim */ 214228110Sjkim Target = ACPI_ADD_PTR (void, Aml, (Info->Value + 2)); 215228110Sjkim if (ACPI_GET16 (Target)) 216228110Sjkim { 217228110Sjkim /* Use vendor offset to get resource source length */ 218228110Sjkim 219228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 220228110Sjkim ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source); 221228110Sjkim } 222228110Sjkim else 223228110Sjkim { 224228110Sjkim /* No vendor data to worry about */ 225228110Sjkim 226228110Sjkim ItemCount = Aml->LargeHeader.ResourceLength + 227228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER) - 228228110Sjkim ACPI_GET16 (Source); 229228110Sjkim } 230228110Sjkim 231228110Sjkim Resource->Length = Resource->Length + ItemCount; 232243347Sjkim ACPI_SET16 (Destination, ItemCount); 233228110Sjkim break; 234228110Sjkim 235228110Sjkim case ACPI_RSC_COUNT_SERIAL_VEN: 236228110Sjkim 237228110Sjkim ItemCount = ACPI_GET16 (Source) - Info->Value; 238228110Sjkim 239228110Sjkim Resource->Length = Resource->Length + ItemCount; 240243347Sjkim ACPI_SET16 (Destination, ItemCount); 241228110Sjkim break; 242228110Sjkim 243228110Sjkim case ACPI_RSC_COUNT_SERIAL_RES: 244228110Sjkim 245228110Sjkim ItemCount = (AmlResourceLength + 246228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER)) - 247228110Sjkim ACPI_GET16 (Source) - Info->Value; 248228110Sjkim 249228110Sjkim Resource->Length = Resource->Length + ItemCount; 250243347Sjkim ACPI_SET16 (Destination, ItemCount); 251228110Sjkim break; 252228110Sjkim 253151937Sjkim case ACPI_RSC_LENGTH: 25467754Smsmith 255151937Sjkim Resource->Length = Resource->Length + Info->Value; 256151937Sjkim break; 25767754Smsmith 258151937Sjkim case ACPI_RSC_MOVE8: 259151937Sjkim case ACPI_RSC_MOVE16: 260151937Sjkim case ACPI_RSC_MOVE32: 261151937Sjkim case ACPI_RSC_MOVE64: 262151937Sjkim /* 263151937Sjkim * Raw data move. Use the Info value field unless ItemCount has 264151937Sjkim * been previously initialized via a COUNT opcode 265151937Sjkim */ 266151937Sjkim if (Info->Value) 267151937Sjkim { 268151937Sjkim ItemCount = Info->Value; 269151937Sjkim } 270167802Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 271151937Sjkim break; 27267754Smsmith 273228110Sjkim case ACPI_RSC_MOVE_GPIO_PIN: 274228110Sjkim 275228110Sjkim /* Generate and set the PIN data pointer */ 276228110Sjkim 277228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 278228110Sjkim (Resource->Length - ItemCount * 2)); 279228110Sjkim *(UINT16 **) Destination = ACPI_CAST_PTR (UINT16, Target); 280228110Sjkim 281228110Sjkim /* Copy the PIN data */ 282228110Sjkim 283228110Sjkim Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source)); 284228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 285228110Sjkim break; 286228110Sjkim 287228110Sjkim case ACPI_RSC_MOVE_GPIO_RES: 288228110Sjkim 289228110Sjkim /* Generate and set the ResourceSource string pointer */ 290228110Sjkim 291228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 292228110Sjkim (Resource->Length - ItemCount)); 293228110Sjkim *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); 294228110Sjkim 295228110Sjkim /* Copy the ResourceSource string */ 296228110Sjkim 297228110Sjkim Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source)); 298228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 299228110Sjkim break; 300228110Sjkim 301228110Sjkim case ACPI_RSC_MOVE_SERIAL_VEN: 302228110Sjkim 303228110Sjkim /* Generate and set the Vendor Data pointer */ 304228110Sjkim 305228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 306228110Sjkim (Resource->Length - ItemCount)); 307228110Sjkim *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); 308228110Sjkim 309228110Sjkim /* Copy the Vendor Data */ 310228110Sjkim 311228110Sjkim Source = ACPI_ADD_PTR (void, Aml, Info->Value); 312228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 313228110Sjkim break; 314228110Sjkim 315228110Sjkim case ACPI_RSC_MOVE_SERIAL_RES: 316228110Sjkim 317228110Sjkim /* Generate and set the ResourceSource string pointer */ 318228110Sjkim 319228110Sjkim Target = (char *) ACPI_ADD_PTR (void, Resource, 320228110Sjkim (Resource->Length - ItemCount)); 321228110Sjkim *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target); 322228110Sjkim 323228110Sjkim /* Copy the ResourceSource string */ 324228110Sjkim 325228110Sjkim Source = ACPI_ADD_PTR (void, Aml, (ACPI_GET16 (Source) + Info->Value)); 326228110Sjkim AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode); 327228110Sjkim break; 328228110Sjkim 329151937Sjkim case ACPI_RSC_SET8: 33067754Smsmith 331151937Sjkim ACPI_MEMSET (Destination, Info->AmlOffset, Info->Value); 332151937Sjkim break; 33367754Smsmith 334151937Sjkim case ACPI_RSC_DATA8: 33567754Smsmith 336167802Sjkim Target = ACPI_ADD_PTR (char, Resource, Info->Value); 337167802Sjkim ACPI_MEMCPY (Destination, Source, ACPI_GET16 (Target)); 338151937Sjkim break; 33967754Smsmith 340151937Sjkim case ACPI_RSC_ADDRESS: 341151937Sjkim /* 342151937Sjkim * Common handler for address descriptor flags 343151937Sjkim */ 344151937Sjkim if (!AcpiRsGetAddressCommon (Resource, Aml)) 345151937Sjkim { 346151937Sjkim return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 347151937Sjkim } 348151937Sjkim break; 34967754Smsmith 350151937Sjkim case ACPI_RSC_SOURCE: 351151937Sjkim /* 352151937Sjkim * Optional ResourceSource (Index and String) 353151937Sjkim */ 354151937Sjkim Resource->Length += 355151937Sjkim AcpiRsGetResourceSource (AmlResourceLength, Info->Value, 356151937Sjkim Destination, Aml, NULL); 357151937Sjkim break; 35867754Smsmith 359151937Sjkim case ACPI_RSC_SOURCEX: 360151937Sjkim /* 361151937Sjkim * Optional ResourceSource (Index and String). This is the more 362151937Sjkim * complicated case used by the Interrupt() macro 363151937Sjkim */ 364228110Sjkim Target = ACPI_ADD_PTR (char, Resource, 365228110Sjkim Info->AmlOffset + (ItemCount * 4)); 36667754Smsmith 367151937Sjkim Resource->Length += 368228110Sjkim AcpiRsGetResourceSource (AmlResourceLength, (ACPI_RS_LENGTH) 369228110Sjkim (((ItemCount - 1) * sizeof (UINT32)) + Info->Value), 370151937Sjkim Destination, Aml, Target); 371151937Sjkim break; 37267754Smsmith 373151937Sjkim case ACPI_RSC_BITMASK: 374151937Sjkim /* 375151937Sjkim * 8-bit encoded bitmask (DMA macro) 376151937Sjkim */ 377167802Sjkim ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination); 378151937Sjkim if (ItemCount) 379151937Sjkim { 380152069Sjkim Resource->Length += (ItemCount - 1); 381151937Sjkim } 38277424Smsmith 383167802Sjkim Target = ACPI_ADD_PTR (char, Resource, Info->Value); 384243347Sjkim ACPI_SET8 (Target, ItemCount); 385151937Sjkim break; 38667754Smsmith 387151937Sjkim case ACPI_RSC_BITMASK16: 388151937Sjkim /* 389151937Sjkim * 16-bit encoded bitmask (IRQ macro) 390151937Sjkim */ 391151937Sjkim ACPI_MOVE_16_TO_16 (&Temp16, Source); 39267754Smsmith 393151937Sjkim ItemCount = AcpiRsDecodeBitmask (Temp16, Destination); 394151937Sjkim if (ItemCount) 395151937Sjkim { 396152069Sjkim Resource->Length += (ItemCount - 1); 397151937Sjkim } 398151937Sjkim 399167802Sjkim Target = ACPI_ADD_PTR (char, Resource, Info->Value); 400243347Sjkim ACPI_SET8 (Target, ItemCount); 401151937Sjkim break; 402151937Sjkim 403151937Sjkim case ACPI_RSC_EXIT_NE: 404151937Sjkim /* 405151937Sjkim * Control - Exit conversion if not equal 406151937Sjkim */ 407151937Sjkim switch (Info->ResourceOffset) 408151937Sjkim { 409151937Sjkim case ACPI_RSC_COMPARE_AML_LENGTH: 410250838Sjkim 411151937Sjkim if (AmlResourceLength != Info->Value) 412151937Sjkim { 413151937Sjkim goto Exit; 414151937Sjkim } 415151937Sjkim break; 416151937Sjkim 417151937Sjkim case ACPI_RSC_COMPARE_VALUE: 418250838Sjkim 419167802Sjkim if (ACPI_GET8 (Source) != Info->Value) 420151937Sjkim { 421151937Sjkim goto Exit; 422151937Sjkim } 423151937Sjkim break; 424151937Sjkim 425151937Sjkim default: 426167802Sjkim 427167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode")); 428151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 429151937Sjkim } 430151937Sjkim break; 431151937Sjkim 432151937Sjkim default: 433151937Sjkim 434167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion opcode")); 435151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 436151937Sjkim } 437151937Sjkim 438151937Sjkim Count--; 439151937Sjkim Info++; 44067754Smsmith } 44167754Smsmith 442151937SjkimExit: 443151937Sjkim if (!FlagsMode) 44467754Smsmith { 445167802Sjkim /* Round the resource struct length up to the next boundary (32 or 64) */ 44667754Smsmith 447167802Sjkim Resource->Length = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length); 44867754Smsmith } 44967754Smsmith return_ACPI_STATUS (AE_OK); 45067754Smsmith} 45167754Smsmith 45267754Smsmith 45367754Smsmith/******************************************************************************* 45467754Smsmith * 455151937Sjkim * FUNCTION: AcpiRsConvertResourceToAml 45667754Smsmith * 457151937Sjkim * PARAMETERS: Resource - Pointer to the resource descriptor 458151937Sjkim * Aml - Where the AML descriptor is returned 459151937Sjkim * Info - Pointer to appropriate conversion table 46067754Smsmith * 46177424Smsmith * RETURN: Status 46267754Smsmith * 463151937Sjkim * DESCRIPTION: Convert an internal resource descriptor to the corresponding 464151937Sjkim * external AML resource descriptor. 46567754Smsmith * 46667754Smsmith ******************************************************************************/ 46767754Smsmith 46867754SmsmithACPI_STATUS 469151937SjkimAcpiRsConvertResourceToAml ( 470151937Sjkim ACPI_RESOURCE *Resource, 471151937Sjkim AML_RESOURCE *Aml, 472151937Sjkim ACPI_RSCONVERT_INFO *Info) 47367754Smsmith{ 474151937Sjkim void *Source = NULL; 475151937Sjkim void *Destination; 476228110Sjkim char *Target; 477151937Sjkim ACPI_RSDESC_SIZE AmlLength = 0; 478151937Sjkim UINT8 Count; 479151937Sjkim UINT16 Temp16 = 0; 480151937Sjkim UINT16 ItemCount = 0; 48167754Smsmith 48267754Smsmith 483167802Sjkim ACPI_FUNCTION_TRACE (RsConvertResourceToAml); 48467754Smsmith 48577424Smsmith 486228110Sjkim if (!Info) 487228110Sjkim { 488228110Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 489228110Sjkim } 490228110Sjkim 49167754Smsmith /* 492151937Sjkim * First table entry must be ACPI_RSC_INITxxx and must contain the 493151937Sjkim * table length (# of table entries) 49467754Smsmith */ 495151937Sjkim Count = INIT_TABLE_LENGTH (Info); 496151937Sjkim 497151937Sjkim while (Count) 49867754Smsmith { 49967754Smsmith /* 500151937Sjkim * Source is the internal resource descriptor, 501151937Sjkim * destination is the external AML byte stream buffer 50267754Smsmith */ 503167802Sjkim Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset); 504167802Sjkim Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset); 50567754Smsmith 506151937Sjkim switch (Info->Opcode) 50767754Smsmith { 508151937Sjkim case ACPI_RSC_INITSET: 50967754Smsmith 510151937Sjkim ACPI_MEMSET (Aml, 0, INIT_RESOURCE_LENGTH (Info)); 511151937Sjkim AmlLength = INIT_RESOURCE_LENGTH (Info); 512151937Sjkim AcpiRsSetResourceHeader (INIT_RESOURCE_TYPE (Info), AmlLength, Aml); 513151937Sjkim break; 51467754Smsmith 515151937Sjkim case ACPI_RSC_INITGET: 516151937Sjkim break; 51767754Smsmith 518151937Sjkim case ACPI_RSC_FLAGINIT: 519151937Sjkim /* 520151937Sjkim * Clear the flag byte 521151937Sjkim */ 522243347Sjkim ACPI_SET8 (Destination, 0); 523151937Sjkim break; 52467754Smsmith 525151937Sjkim case ACPI_RSC_1BITFLAG: 526151937Sjkim /* 527151937Sjkim * Mask and shift the flag bit 528151937Sjkim */ 529243347Sjkim ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) 530243347Sjkim ((ACPI_GET8 (Source) & 0x01) << Info->Value)); 531151937Sjkim break; 53267754Smsmith 533151937Sjkim case ACPI_RSC_2BITFLAG: 534151937Sjkim /* 535151937Sjkim * Mask and shift the flag bits 536151937Sjkim */ 537243347Sjkim ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) 538243347Sjkim ((ACPI_GET8 (Source) & 0x03) << Info->Value)); 539151937Sjkim break; 54067754Smsmith 541228110Sjkim case ACPI_RSC_3BITFLAG: 542228110Sjkim /* 543228110Sjkim * Mask and shift the flag bits 544228110Sjkim */ 545243347Sjkim ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8) 546243347Sjkim ((ACPI_GET8 (Source) & 0x07) << Info->Value)); 547228110Sjkim break; 548228110Sjkim 549151937Sjkim case ACPI_RSC_COUNT: 55077424Smsmith 551167802Sjkim ItemCount = ACPI_GET8 (Source); 552243347Sjkim ACPI_SET8 (Destination, ItemCount); 55367754Smsmith 554167802Sjkim AmlLength = (UINT16) (AmlLength + (Info->Value * (ItemCount - 1))); 555151937Sjkim break; 55667754Smsmith 557151937Sjkim case ACPI_RSC_COUNT16: 55867754Smsmith 559167802Sjkim ItemCount = ACPI_GET16 (Source); 560151937Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 561151937Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 562151937Sjkim break; 56367754Smsmith 564228110Sjkim case ACPI_RSC_COUNT_GPIO_PIN: 565228110Sjkim 566228110Sjkim ItemCount = ACPI_GET16 (Source); 567243347Sjkim ACPI_SET16 (Destination, AmlLength); 568228110Sjkim 569228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount * 2); 570228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 571243347Sjkim ACPI_SET16 (Target, AmlLength); 572228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 573228110Sjkim break; 574228110Sjkim 575228110Sjkim case ACPI_RSC_COUNT_GPIO_VEN: 576228110Sjkim 577228110Sjkim ItemCount = ACPI_GET16 (Source); 578243347Sjkim ACPI_SET16 (Destination, ItemCount); 579228110Sjkim 580228110Sjkim AmlLength = (UINT16) (AmlLength + (Info->Value * ItemCount)); 581228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 582228110Sjkim break; 583228110Sjkim 584228110Sjkim case ACPI_RSC_COUNT_GPIO_RES: 585228110Sjkim 586228110Sjkim /* Set resource source string length */ 587228110Sjkim 588228110Sjkim ItemCount = ACPI_GET16 (Source); 589243347Sjkim ACPI_SET16 (Destination, AmlLength); 590228110Sjkim 591228110Sjkim /* Compute offset for the Vendor Data */ 592228110Sjkim 593228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 594228110Sjkim Target = ACPI_ADD_PTR (void, Aml, Info->Value); 595228110Sjkim 596228110Sjkim /* Set vendor offset only if there is vendor data */ 597228110Sjkim 598228110Sjkim if (Resource->Data.Gpio.VendorLength) 599228110Sjkim { 600243347Sjkim ACPI_SET16 (Target, AmlLength); 601228110Sjkim } 602228110Sjkim 603228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 604228110Sjkim break; 605228110Sjkim 606228110Sjkim case ACPI_RSC_COUNT_SERIAL_VEN: 607228110Sjkim 608228110Sjkim ItemCount = ACPI_GET16 (Source); 609243347Sjkim ACPI_SET16 (Destination, ItemCount + Info->Value); 610228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 611228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 612228110Sjkim break; 613228110Sjkim 614228110Sjkim case ACPI_RSC_COUNT_SERIAL_RES: 615228110Sjkim 616228110Sjkim ItemCount = ACPI_GET16 (Source); 617228110Sjkim AmlLength = (UINT16) (AmlLength + ItemCount); 618228110Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 619228110Sjkim break; 620228110Sjkim 621151937Sjkim case ACPI_RSC_LENGTH: 62267754Smsmith 623151937Sjkim AcpiRsSetResourceLength (Info->Value, Aml); 624151937Sjkim break; 62567754Smsmith 626151937Sjkim case ACPI_RSC_MOVE8: 627151937Sjkim case ACPI_RSC_MOVE16: 628151937Sjkim case ACPI_RSC_MOVE32: 629151937Sjkim case ACPI_RSC_MOVE64: 63077424Smsmith 631151937Sjkim if (Info->Value) 632151937Sjkim { 633151937Sjkim ItemCount = Info->Value; 634151937Sjkim } 635151937Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 636151937Sjkim break; 63767754Smsmith 638228110Sjkim case ACPI_RSC_MOVE_GPIO_PIN: 639228110Sjkim 640228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 641228110Sjkim ACPI_GET16 (Destination)); 642228110Sjkim Source = * (UINT16 **) Source; 643228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 644228110Sjkim break; 645228110Sjkim 646228110Sjkim case ACPI_RSC_MOVE_GPIO_RES: 647228110Sjkim 648228110Sjkim /* Used for both ResourceSource string and VendorData */ 649228110Sjkim 650228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 651228110Sjkim ACPI_GET16 (Destination)); 652228110Sjkim Source = * (UINT8 **) Source; 653228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 654228110Sjkim break; 655228110Sjkim 656228110Sjkim case ACPI_RSC_MOVE_SERIAL_VEN: 657228110Sjkim 658228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 659228110Sjkim (AmlLength - ItemCount)); 660228110Sjkim Source = * (UINT8 **) Source; 661228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 662228110Sjkim break; 663228110Sjkim 664228110Sjkim case ACPI_RSC_MOVE_SERIAL_RES: 665228110Sjkim 666228110Sjkim Destination = (char *) ACPI_ADD_PTR (void, Aml, 667228110Sjkim (AmlLength - ItemCount)); 668228110Sjkim Source = * (UINT8 **) Source; 669228110Sjkim AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode); 670228110Sjkim break; 671228110Sjkim 672151937Sjkim case ACPI_RSC_ADDRESS: 67367754Smsmith 674151937Sjkim /* Set the Resource Type, General Flags, and Type-Specific Flags */ 67567754Smsmith 676151937Sjkim AcpiRsSetAddressCommon (Aml, Resource); 677151937Sjkim break; 67867754Smsmith 679151937Sjkim case ACPI_RSC_SOURCEX: 680151937Sjkim /* 681151937Sjkim * Optional ResourceSource (Index and String) 682151937Sjkim */ 683151937Sjkim AmlLength = AcpiRsSetResourceSource ( 684151937Sjkim Aml, (ACPI_RS_LENGTH) AmlLength, Source); 685151937Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 686151937Sjkim break; 68767754Smsmith 688151937Sjkim case ACPI_RSC_SOURCE: 689151937Sjkim /* 690151937Sjkim * Optional ResourceSource (Index and String). This is the more 691151937Sjkim * complicated case used by the Interrupt() macro 692151937Sjkim */ 693151937Sjkim AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source); 694151937Sjkim AcpiRsSetResourceLength (AmlLength, Aml); 695151937Sjkim break; 69667754Smsmith 697151937Sjkim case ACPI_RSC_BITMASK: 698151937Sjkim /* 699151937Sjkim * 8-bit encoded bitmask (DMA macro) 700151937Sjkim */ 701243347Sjkim ACPI_SET8 (Destination, 702167802Sjkim AcpiRsEncodeBitmask (Source, 703243347Sjkim *ACPI_ADD_PTR (UINT8, Resource, Info->Value))); 704151937Sjkim break; 70567754Smsmith 706151937Sjkim case ACPI_RSC_BITMASK16: 707151937Sjkim /* 708151937Sjkim * 16-bit encoded bitmask (IRQ macro) 709151937Sjkim */ 710167802Sjkim Temp16 = AcpiRsEncodeBitmask (Source, 711167802Sjkim *ACPI_ADD_PTR (UINT8, Resource, Info->Value)); 712151937Sjkim ACPI_MOVE_16_TO_16 (Destination, &Temp16); 713151937Sjkim break; 714151937Sjkim 715151937Sjkim case ACPI_RSC_EXIT_LE: 716151937Sjkim /* 717151937Sjkim * Control - Exit conversion if less than or equal 718151937Sjkim */ 719151937Sjkim if (ItemCount <= Info->Value) 720151937Sjkim { 721151937Sjkim goto Exit; 722151937Sjkim } 723151937Sjkim break; 724151937Sjkim 725151937Sjkim case ACPI_RSC_EXIT_NE: 726151937Sjkim /* 727151937Sjkim * Control - Exit conversion if not equal 728151937Sjkim */ 729151937Sjkim switch (COMPARE_OPCODE (Info)) 730151937Sjkim { 731151937Sjkim case ACPI_RSC_COMPARE_VALUE: 732167802Sjkim 733167802Sjkim if (*ACPI_ADD_PTR (UINT8, Resource, 734167802Sjkim COMPARE_TARGET (Info)) != COMPARE_VALUE (Info)) 735151937Sjkim { 736151937Sjkim goto Exit; 737151937Sjkim } 738151937Sjkim break; 739151937Sjkim 740151937Sjkim default: 741167802Sjkim 742167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode")); 743151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 744151937Sjkim } 745151937Sjkim break; 746151937Sjkim 747193267Sjkim case ACPI_RSC_EXIT_EQ: 748193267Sjkim /* 749193267Sjkim * Control - Exit conversion if equal 750193267Sjkim */ 751193267Sjkim if (*ACPI_ADD_PTR (UINT8, Resource, 752193267Sjkim COMPARE_TARGET (Info)) == COMPARE_VALUE (Info)) 753193267Sjkim { 754193267Sjkim goto Exit; 755193267Sjkim } 756193267Sjkim break; 757193267Sjkim 758151937Sjkim default: 759151937Sjkim 760167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid conversion opcode")); 761151937Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 762151937Sjkim } 763151937Sjkim 764151937Sjkim Count--; 765151937Sjkim Info++; 766151937Sjkim } 767151937Sjkim 768151937SjkimExit: 76967754Smsmith return_ACPI_STATUS (AE_OK); 77067754Smsmith} 77167754Smsmith 772151937Sjkim 773151937Sjkim#if 0 774151937Sjkim/* Previous resource validations */ 775151937Sjkim 776151937Sjkim if (Aml->ExtAddress64.RevisionID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) 777151937Sjkim { 778151937Sjkim return_ACPI_STATUS (AE_SUPPORT); 779151937Sjkim } 780151937Sjkim 781151937Sjkim if (Resource->Data.StartDpf.PerformanceRobustness >= 3) 782151937Sjkim { 783151937Sjkim return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); 784151937Sjkim } 785151937Sjkim 786151937Sjkim if (((Aml->Irq.Flags & 0x09) == 0x00) || 787151937Sjkim ((Aml->Irq.Flags & 0x09) == 0x09)) 788151937Sjkim { 789151937Sjkim /* 790151937Sjkim * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive] 791151937Sjkim * polarity/trigger interrupts are allowed (ACPI spec, section 792151937Sjkim * "IRQ Format"), so 0x00 and 0x09 are illegal. 793151937Sjkim */ 794167802Sjkim ACPI_ERROR ((AE_INFO, 795204773Sjkim "Invalid interrupt polarity/trigger in resource list, 0x%X", 796151937Sjkim Aml->Irq.Flags)); 797151937Sjkim return_ACPI_STATUS (AE_BAD_DATA); 798151937Sjkim } 799151937Sjkim 800151937Sjkim Resource->Data.ExtendedIrq.InterruptCount = Temp8; 801151937Sjkim if (Temp8 < 1) 802151937Sjkim { 803151937Sjkim /* Must have at least one IRQ */ 804151937Sjkim 805151937Sjkim return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 806151937Sjkim } 807151937Sjkim 808151937Sjkim if (Resource->Data.Dma.Transfer == 0x03) 809151937Sjkim { 810167802Sjkim ACPI_ERROR ((AE_INFO, 811167802Sjkim "Invalid DMA.Transfer preference (3)")); 812151937Sjkim return_ACPI_STATUS (AE_BAD_DATA); 813151937Sjkim } 814151937Sjkim#endif 815