195b482a8SLen Brown /******************************************************************************* 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: rsmisc - Miscellaneous resource descriptors 495b482a8SLen Brown * 595b482a8SLen Brown ******************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 8*a8357b0cSBob Moore * Copyright (C) 2000 - 2010, Intel Corp. 995b482a8SLen Brown * All rights reserved. 1095b482a8SLen Brown * 1195b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1295b482a8SLen Brown * modification, are permitted provided that the following conditions 1395b482a8SLen Brown * are met: 1495b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1595b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1695b482a8SLen Brown * without modification. 1795b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1895b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 1995b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2095b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2195b482a8SLen Brown * binary redistribution. 2295b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2395b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2495b482a8SLen Brown * from this software without specific prior written permission. 2595b482a8SLen Brown * 2695b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2795b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2895b482a8SLen Brown * Software Foundation. 2995b482a8SLen Brown * 3095b482a8SLen Brown * NO WARRANTY 3195b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3295b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3395b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3495b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3595b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3695b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3795b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3895b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3995b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4095b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4195b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4295b482a8SLen Brown */ 4395b482a8SLen Brown 4495b482a8SLen Brown #include <acpi/acpi.h> 45e2f7a777SLen Brown #include "accommon.h" 46e2f7a777SLen Brown #include "acresrc.h" 4795b482a8SLen Brown 4895b482a8SLen Brown #define _COMPONENT ACPI_RESOURCES 4995b482a8SLen Brown ACPI_MODULE_NAME("rsmisc") 5095b482a8SLen Brown #define INIT_RESOURCE_TYPE(i) i->resource_offset 5195b482a8SLen Brown #define INIT_RESOURCE_LENGTH(i) i->aml_offset 5295b482a8SLen Brown #define INIT_TABLE_LENGTH(i) i->value 5395b482a8SLen Brown #define COMPARE_OPCODE(i) i->resource_offset 5495b482a8SLen Brown #define COMPARE_TARGET(i) i->aml_offset 5595b482a8SLen Brown #define COMPARE_VALUE(i) i->value 5695b482a8SLen Brown /******************************************************************************* 5795b482a8SLen Brown * 5895b482a8SLen Brown * FUNCTION: acpi_rs_convert_aml_to_resource 5995b482a8SLen Brown * 6095b482a8SLen Brown * PARAMETERS: Resource - Pointer to the resource descriptor 6195b482a8SLen Brown * Aml - Where the AML descriptor is returned 6295b482a8SLen Brown * Info - Pointer to appropriate conversion table 6395b482a8SLen Brown * 6495b482a8SLen Brown * RETURN: Status 6595b482a8SLen Brown * 6695b482a8SLen Brown * DESCRIPTION: Convert an external AML resource descriptor to the corresponding 6795b482a8SLen Brown * internal resource descriptor 6895b482a8SLen Brown * 6995b482a8SLen Brown ******************************************************************************/ 7095b482a8SLen Brown acpi_status 7195b482a8SLen Brown acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, 7295b482a8SLen Brown union aml_resource *aml, 7395b482a8SLen Brown struct acpi_rsconvert_info *info) 7495b482a8SLen Brown { 7595b482a8SLen Brown acpi_rs_length aml_resource_length; 7695b482a8SLen Brown void *source; 7795b482a8SLen Brown void *destination; 7895b482a8SLen Brown char *target; 7995b482a8SLen Brown u8 count; 8095b482a8SLen Brown u8 flags_mode = FALSE; 8195b482a8SLen Brown u16 item_count = 0; 8295b482a8SLen Brown u16 temp16 = 0; 8395b482a8SLen Brown 8495b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); 8595b482a8SLen Brown 8695b482a8SLen Brown if (((acpi_size) resource) & 0x3) { 8795b482a8SLen Brown 8895b482a8SLen Brown /* Each internal resource struct is expected to be 32-bit aligned */ 8995b482a8SLen Brown 9095b482a8SLen Brown ACPI_WARNING((AE_INFO, 9195b482a8SLen Brown "Misaligned resource pointer (get): %p Type %2.2X Len %X", 9295b482a8SLen Brown resource, resource->type, resource->length)); 9395b482a8SLen Brown } 9495b482a8SLen Brown 9595b482a8SLen Brown /* Extract the resource Length field (does not include header length) */ 9695b482a8SLen Brown 9795b482a8SLen Brown aml_resource_length = acpi_ut_get_resource_length(aml); 9895b482a8SLen Brown 9995b482a8SLen Brown /* 10095b482a8SLen Brown * First table entry must be ACPI_RSC_INITxxx and must contain the 10195b482a8SLen Brown * table length (# of table entries) 10295b482a8SLen Brown */ 10395b482a8SLen Brown count = INIT_TABLE_LENGTH(info); 10495b482a8SLen Brown 10595b482a8SLen Brown while (count) { 10695b482a8SLen Brown /* 10795b482a8SLen Brown * Source is the external AML byte stream buffer, 10895b482a8SLen Brown * destination is the internal resource descriptor 10995b482a8SLen Brown */ 11095b482a8SLen Brown source = ACPI_ADD_PTR(void, aml, info->aml_offset); 11195b482a8SLen Brown destination = 11295b482a8SLen Brown ACPI_ADD_PTR(void, resource, info->resource_offset); 11395b482a8SLen Brown 11495b482a8SLen Brown switch (info->opcode) { 11595b482a8SLen Brown case ACPI_RSC_INITGET: 11695b482a8SLen Brown /* 11795b482a8SLen Brown * Get the resource type and the initial (minimum) length 11895b482a8SLen Brown */ 11995b482a8SLen Brown ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info)); 12095b482a8SLen Brown resource->type = INIT_RESOURCE_TYPE(info); 12195b482a8SLen Brown resource->length = INIT_RESOURCE_LENGTH(info); 12295b482a8SLen Brown break; 12395b482a8SLen Brown 12495b482a8SLen Brown case ACPI_RSC_INITSET: 12595b482a8SLen Brown break; 12695b482a8SLen Brown 12795b482a8SLen Brown case ACPI_RSC_FLAGINIT: 12895b482a8SLen Brown 12995b482a8SLen Brown flags_mode = TRUE; 13095b482a8SLen Brown break; 13195b482a8SLen Brown 13295b482a8SLen Brown case ACPI_RSC_1BITFLAG: 13395b482a8SLen Brown /* 13495b482a8SLen Brown * Mask and shift the flag bit 13595b482a8SLen Brown */ 13695b482a8SLen Brown ACPI_SET8(destination) = (u8) 13795b482a8SLen Brown ((ACPI_GET8(source) >> info->value) & 0x01); 13895b482a8SLen Brown break; 13995b482a8SLen Brown 14095b482a8SLen Brown case ACPI_RSC_2BITFLAG: 14195b482a8SLen Brown /* 14295b482a8SLen Brown * Mask and shift the flag bits 14395b482a8SLen Brown */ 14495b482a8SLen Brown ACPI_SET8(destination) = (u8) 14595b482a8SLen Brown ((ACPI_GET8(source) >> info->value) & 0x03); 14695b482a8SLen Brown break; 14795b482a8SLen Brown 14895b482a8SLen Brown case ACPI_RSC_COUNT: 14995b482a8SLen Brown 15095b482a8SLen Brown item_count = ACPI_GET8(source); 15195b482a8SLen Brown ACPI_SET8(destination) = (u8) item_count; 15295b482a8SLen Brown 15395b482a8SLen Brown resource->length = resource->length + 15495b482a8SLen Brown (info->value * (item_count - 1)); 15595b482a8SLen Brown break; 15695b482a8SLen Brown 15795b482a8SLen Brown case ACPI_RSC_COUNT16: 15895b482a8SLen Brown 15995b482a8SLen Brown item_count = aml_resource_length; 16095b482a8SLen Brown ACPI_SET16(destination) = item_count; 16195b482a8SLen Brown 16295b482a8SLen Brown resource->length = resource->length + 16395b482a8SLen Brown (info->value * (item_count - 1)); 16495b482a8SLen Brown break; 16595b482a8SLen Brown 16695b482a8SLen Brown case ACPI_RSC_LENGTH: 16795b482a8SLen Brown 16895b482a8SLen Brown resource->length = resource->length + info->value; 16995b482a8SLen Brown break; 17095b482a8SLen Brown 17195b482a8SLen Brown case ACPI_RSC_MOVE8: 17295b482a8SLen Brown case ACPI_RSC_MOVE16: 17395b482a8SLen Brown case ACPI_RSC_MOVE32: 17495b482a8SLen Brown case ACPI_RSC_MOVE64: 17595b482a8SLen Brown /* 17695b482a8SLen Brown * Raw data move. Use the Info value field unless item_count has 17795b482a8SLen Brown * been previously initialized via a COUNT opcode 17895b482a8SLen Brown */ 17995b482a8SLen Brown if (info->value) { 18095b482a8SLen Brown item_count = info->value; 18195b482a8SLen Brown } 18295b482a8SLen Brown acpi_rs_move_data(destination, source, item_count, 18395b482a8SLen Brown info->opcode); 18495b482a8SLen Brown break; 18595b482a8SLen Brown 18695b482a8SLen Brown case ACPI_RSC_SET8: 18795b482a8SLen Brown 18895b482a8SLen Brown ACPI_MEMSET(destination, info->aml_offset, info->value); 18995b482a8SLen Brown break; 19095b482a8SLen Brown 19195b482a8SLen Brown case ACPI_RSC_DATA8: 19295b482a8SLen Brown 19395b482a8SLen Brown target = ACPI_ADD_PTR(char, resource, info->value); 19495b482a8SLen Brown ACPI_MEMCPY(destination, source, ACPI_GET16(target)); 19595b482a8SLen Brown break; 19695b482a8SLen Brown 19795b482a8SLen Brown case ACPI_RSC_ADDRESS: 19895b482a8SLen Brown /* 19995b482a8SLen Brown * Common handler for address descriptor flags 20095b482a8SLen Brown */ 20195b482a8SLen Brown if (!acpi_rs_get_address_common(resource, aml)) { 20295b482a8SLen Brown return_ACPI_STATUS 20395b482a8SLen Brown (AE_AML_INVALID_RESOURCE_TYPE); 20495b482a8SLen Brown } 20595b482a8SLen Brown break; 20695b482a8SLen Brown 20795b482a8SLen Brown case ACPI_RSC_SOURCE: 20895b482a8SLen Brown /* 20995b482a8SLen Brown * Optional resource_source (Index and String) 21095b482a8SLen Brown */ 21195b482a8SLen Brown resource->length += 21295b482a8SLen Brown acpi_rs_get_resource_source(aml_resource_length, 21395b482a8SLen Brown info->value, 21495b482a8SLen Brown destination, aml, NULL); 21595b482a8SLen Brown break; 21695b482a8SLen Brown 21795b482a8SLen Brown case ACPI_RSC_SOURCEX: 21895b482a8SLen Brown /* 21995b482a8SLen Brown * Optional resource_source (Index and String). This is the more 22095b482a8SLen Brown * complicated case used by the Interrupt() macro 22195b482a8SLen Brown */ 22295b482a8SLen Brown target = 22395b482a8SLen Brown ACPI_ADD_PTR(char, resource, 22495b482a8SLen Brown info->aml_offset + (item_count * 4)); 22595b482a8SLen Brown 22695b482a8SLen Brown resource->length += 22795b482a8SLen Brown acpi_rs_get_resource_source(aml_resource_length, 22895b482a8SLen Brown (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); 22995b482a8SLen Brown break; 23095b482a8SLen Brown 23195b482a8SLen Brown case ACPI_RSC_BITMASK: 23295b482a8SLen Brown /* 23395b482a8SLen Brown * 8-bit encoded bitmask (DMA macro) 23495b482a8SLen Brown */ 23595b482a8SLen Brown item_count = 23695b482a8SLen Brown acpi_rs_decode_bitmask(ACPI_GET8(source), 23795b482a8SLen Brown destination); 23895b482a8SLen Brown if (item_count) { 23995b482a8SLen Brown resource->length += (item_count - 1); 24095b482a8SLen Brown } 24195b482a8SLen Brown 24295b482a8SLen Brown target = ACPI_ADD_PTR(char, resource, info->value); 24395b482a8SLen Brown ACPI_SET8(target) = (u8) item_count; 24495b482a8SLen Brown break; 24595b482a8SLen Brown 24695b482a8SLen Brown case ACPI_RSC_BITMASK16: 24795b482a8SLen Brown /* 24895b482a8SLen Brown * 16-bit encoded bitmask (IRQ macro) 24995b482a8SLen Brown */ 25095b482a8SLen Brown ACPI_MOVE_16_TO_16(&temp16, source); 25195b482a8SLen Brown 25295b482a8SLen Brown item_count = 25395b482a8SLen Brown acpi_rs_decode_bitmask(temp16, destination); 25495b482a8SLen Brown if (item_count) { 25595b482a8SLen Brown resource->length += (item_count - 1); 25695b482a8SLen Brown } 25795b482a8SLen Brown 25895b482a8SLen Brown target = ACPI_ADD_PTR(char, resource, info->value); 25995b482a8SLen Brown ACPI_SET8(target) = (u8) item_count; 26095b482a8SLen Brown break; 26195b482a8SLen Brown 26295b482a8SLen Brown case ACPI_RSC_EXIT_NE: 26395b482a8SLen Brown /* 26495b482a8SLen Brown * Control - Exit conversion if not equal 26595b482a8SLen Brown */ 26695b482a8SLen Brown switch (info->resource_offset) { 26795b482a8SLen Brown case ACPI_RSC_COMPARE_AML_LENGTH: 26895b482a8SLen Brown if (aml_resource_length != info->value) { 26995b482a8SLen Brown goto exit; 27095b482a8SLen Brown } 27195b482a8SLen Brown break; 27295b482a8SLen Brown 27395b482a8SLen Brown case ACPI_RSC_COMPARE_VALUE: 27495b482a8SLen Brown if (ACPI_GET8(source) != info->value) { 27595b482a8SLen Brown goto exit; 27695b482a8SLen Brown } 27795b482a8SLen Brown break; 27895b482a8SLen Brown 27995b482a8SLen Brown default: 28095b482a8SLen Brown 28195b482a8SLen Brown ACPI_ERROR((AE_INFO, 28295b482a8SLen Brown "Invalid conversion sub-opcode")); 28395b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 28495b482a8SLen Brown } 28595b482a8SLen Brown break; 28695b482a8SLen Brown 28795b482a8SLen Brown default: 28895b482a8SLen Brown 28995b482a8SLen Brown ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); 29095b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 29195b482a8SLen Brown } 29295b482a8SLen Brown 29395b482a8SLen Brown count--; 29495b482a8SLen Brown info++; 29595b482a8SLen Brown } 29695b482a8SLen Brown 29795b482a8SLen Brown exit: 29895b482a8SLen Brown if (!flags_mode) { 29995b482a8SLen Brown 30095b482a8SLen Brown /* Round the resource struct length up to the next boundary (32 or 64) */ 30195b482a8SLen Brown 30295b482a8SLen Brown resource->length = 30395b482a8SLen Brown (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length); 30495b482a8SLen Brown } 30595b482a8SLen Brown return_ACPI_STATUS(AE_OK); 30695b482a8SLen Brown } 30795b482a8SLen Brown 30895b482a8SLen Brown /******************************************************************************* 30995b482a8SLen Brown * 31095b482a8SLen Brown * FUNCTION: acpi_rs_convert_resource_to_aml 31195b482a8SLen Brown * 31295b482a8SLen Brown * PARAMETERS: Resource - Pointer to the resource descriptor 31395b482a8SLen Brown * Aml - Where the AML descriptor is returned 31495b482a8SLen Brown * Info - Pointer to appropriate conversion table 31595b482a8SLen Brown * 31695b482a8SLen Brown * RETURN: Status 31795b482a8SLen Brown * 31895b482a8SLen Brown * DESCRIPTION: Convert an internal resource descriptor to the corresponding 31995b482a8SLen Brown * external AML resource descriptor. 32095b482a8SLen Brown * 32195b482a8SLen Brown ******************************************************************************/ 32295b482a8SLen Brown 32395b482a8SLen Brown acpi_status 32495b482a8SLen Brown acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, 32595b482a8SLen Brown union aml_resource *aml, 32695b482a8SLen Brown struct acpi_rsconvert_info *info) 32795b482a8SLen Brown { 32895b482a8SLen Brown void *source = NULL; 32995b482a8SLen Brown void *destination; 33095b482a8SLen Brown acpi_rsdesc_size aml_length = 0; 33195b482a8SLen Brown u8 count; 33295b482a8SLen Brown u16 temp16 = 0; 33395b482a8SLen Brown u16 item_count = 0; 33495b482a8SLen Brown 33595b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml); 33695b482a8SLen Brown 33795b482a8SLen Brown /* 33895b482a8SLen Brown * First table entry must be ACPI_RSC_INITxxx and must contain the 33995b482a8SLen Brown * table length (# of table entries) 34095b482a8SLen Brown */ 34195b482a8SLen Brown count = INIT_TABLE_LENGTH(info); 34295b482a8SLen Brown 34395b482a8SLen Brown while (count) { 34495b482a8SLen Brown /* 34595b482a8SLen Brown * Source is the internal resource descriptor, 34695b482a8SLen Brown * destination is the external AML byte stream buffer 34795b482a8SLen Brown */ 34895b482a8SLen Brown source = ACPI_ADD_PTR(void, resource, info->resource_offset); 34995b482a8SLen Brown destination = ACPI_ADD_PTR(void, aml, info->aml_offset); 35095b482a8SLen Brown 35195b482a8SLen Brown switch (info->opcode) { 35295b482a8SLen Brown case ACPI_RSC_INITSET: 35395b482a8SLen Brown 35495b482a8SLen Brown ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info)); 35595b482a8SLen Brown aml_length = INIT_RESOURCE_LENGTH(info); 35695b482a8SLen Brown acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info), 35795b482a8SLen Brown aml_length, aml); 35895b482a8SLen Brown break; 35995b482a8SLen Brown 36095b482a8SLen Brown case ACPI_RSC_INITGET: 36195b482a8SLen Brown break; 36295b482a8SLen Brown 36395b482a8SLen Brown case ACPI_RSC_FLAGINIT: 36495b482a8SLen Brown /* 36595b482a8SLen Brown * Clear the flag byte 36695b482a8SLen Brown */ 36795b482a8SLen Brown ACPI_SET8(destination) = 0; 36895b482a8SLen Brown break; 36995b482a8SLen Brown 37095b482a8SLen Brown case ACPI_RSC_1BITFLAG: 37195b482a8SLen Brown /* 37295b482a8SLen Brown * Mask and shift the flag bit 37395b482a8SLen Brown */ 37495b482a8SLen Brown ACPI_SET8(destination) |= (u8) 37595b482a8SLen Brown ((ACPI_GET8(source) & 0x01) << info->value); 37695b482a8SLen Brown break; 37795b482a8SLen Brown 37895b482a8SLen Brown case ACPI_RSC_2BITFLAG: 37995b482a8SLen Brown /* 38095b482a8SLen Brown * Mask and shift the flag bits 38195b482a8SLen Brown */ 38295b482a8SLen Brown ACPI_SET8(destination) |= (u8) 38395b482a8SLen Brown ((ACPI_GET8(source) & 0x03) << info->value); 38495b482a8SLen Brown break; 38595b482a8SLen Brown 38695b482a8SLen Brown case ACPI_RSC_COUNT: 38795b482a8SLen Brown 38895b482a8SLen Brown item_count = ACPI_GET8(source); 38995b482a8SLen Brown ACPI_SET8(destination) = (u8) item_count; 39095b482a8SLen Brown 39195b482a8SLen Brown aml_length = 39295b482a8SLen Brown (u16) (aml_length + 39395b482a8SLen Brown (info->value * (item_count - 1))); 39495b482a8SLen Brown break; 39595b482a8SLen Brown 39695b482a8SLen Brown case ACPI_RSC_COUNT16: 39795b482a8SLen Brown 39895b482a8SLen Brown item_count = ACPI_GET16(source); 39995b482a8SLen Brown aml_length = (u16) (aml_length + item_count); 40095b482a8SLen Brown acpi_rs_set_resource_length(aml_length, aml); 40195b482a8SLen Brown break; 40295b482a8SLen Brown 40395b482a8SLen Brown case ACPI_RSC_LENGTH: 40495b482a8SLen Brown 40595b482a8SLen Brown acpi_rs_set_resource_length(info->value, aml); 40695b482a8SLen Brown break; 40795b482a8SLen Brown 40895b482a8SLen Brown case ACPI_RSC_MOVE8: 40995b482a8SLen Brown case ACPI_RSC_MOVE16: 41095b482a8SLen Brown case ACPI_RSC_MOVE32: 41195b482a8SLen Brown case ACPI_RSC_MOVE64: 41295b482a8SLen Brown 41395b482a8SLen Brown if (info->value) { 41495b482a8SLen Brown item_count = info->value; 41595b482a8SLen Brown } 41695b482a8SLen Brown acpi_rs_move_data(destination, source, item_count, 41795b482a8SLen Brown info->opcode); 41895b482a8SLen Brown break; 41995b482a8SLen Brown 42095b482a8SLen Brown case ACPI_RSC_ADDRESS: 42195b482a8SLen Brown 42295b482a8SLen Brown /* Set the Resource Type, General Flags, and Type-Specific Flags */ 42395b482a8SLen Brown 42495b482a8SLen Brown acpi_rs_set_address_common(aml, resource); 42595b482a8SLen Brown break; 42695b482a8SLen Brown 42795b482a8SLen Brown case ACPI_RSC_SOURCEX: 42895b482a8SLen Brown /* 42995b482a8SLen Brown * Optional resource_source (Index and String) 43095b482a8SLen Brown */ 43195b482a8SLen Brown aml_length = 43295b482a8SLen Brown acpi_rs_set_resource_source(aml, (acpi_rs_length) 43395b482a8SLen Brown aml_length, source); 43495b482a8SLen Brown acpi_rs_set_resource_length(aml_length, aml); 43595b482a8SLen Brown break; 43695b482a8SLen Brown 43795b482a8SLen Brown case ACPI_RSC_SOURCE: 43895b482a8SLen Brown /* 43995b482a8SLen Brown * Optional resource_source (Index and String). This is the more 44095b482a8SLen Brown * complicated case used by the Interrupt() macro 44195b482a8SLen Brown */ 44295b482a8SLen Brown aml_length = 44395b482a8SLen Brown acpi_rs_set_resource_source(aml, info->value, 44495b482a8SLen Brown source); 44595b482a8SLen Brown acpi_rs_set_resource_length(aml_length, aml); 44695b482a8SLen Brown break; 44795b482a8SLen Brown 44895b482a8SLen Brown case ACPI_RSC_BITMASK: 44995b482a8SLen Brown /* 45095b482a8SLen Brown * 8-bit encoded bitmask (DMA macro) 45195b482a8SLen Brown */ 45295b482a8SLen Brown ACPI_SET8(destination) = (u8) 45395b482a8SLen Brown acpi_rs_encode_bitmask(source, 45495b482a8SLen Brown *ACPI_ADD_PTR(u8, resource, 45595b482a8SLen Brown info->value)); 45695b482a8SLen Brown break; 45795b482a8SLen Brown 45895b482a8SLen Brown case ACPI_RSC_BITMASK16: 45995b482a8SLen Brown /* 46095b482a8SLen Brown * 16-bit encoded bitmask (IRQ macro) 46195b482a8SLen Brown */ 46295b482a8SLen Brown temp16 = acpi_rs_encode_bitmask(source, 46395b482a8SLen Brown *ACPI_ADD_PTR(u8, 46495b482a8SLen Brown resource, 46595b482a8SLen Brown info-> 46695b482a8SLen Brown value)); 46795b482a8SLen Brown ACPI_MOVE_16_TO_16(destination, &temp16); 46895b482a8SLen Brown break; 46995b482a8SLen Brown 47095b482a8SLen Brown case ACPI_RSC_EXIT_LE: 47195b482a8SLen Brown /* 47295b482a8SLen Brown * Control - Exit conversion if less than or equal 47395b482a8SLen Brown */ 47495b482a8SLen Brown if (item_count <= info->value) { 47595b482a8SLen Brown goto exit; 47695b482a8SLen Brown } 47795b482a8SLen Brown break; 47895b482a8SLen Brown 47995b482a8SLen Brown case ACPI_RSC_EXIT_NE: 48095b482a8SLen Brown /* 48195b482a8SLen Brown * Control - Exit conversion if not equal 48295b482a8SLen Brown */ 48395b482a8SLen Brown switch (COMPARE_OPCODE(info)) { 48495b482a8SLen Brown case ACPI_RSC_COMPARE_VALUE: 48595b482a8SLen Brown 48695b482a8SLen Brown if (*ACPI_ADD_PTR(u8, resource, 48795b482a8SLen Brown COMPARE_TARGET(info)) != 48895b482a8SLen Brown COMPARE_VALUE(info)) { 48995b482a8SLen Brown goto exit; 49095b482a8SLen Brown } 49195b482a8SLen Brown break; 49295b482a8SLen Brown 49395b482a8SLen Brown default: 49495b482a8SLen Brown 49595b482a8SLen Brown ACPI_ERROR((AE_INFO, 49695b482a8SLen Brown "Invalid conversion sub-opcode")); 49795b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 49895b482a8SLen Brown } 49995b482a8SLen Brown break; 50095b482a8SLen Brown 50195b482a8SLen Brown case ACPI_RSC_EXIT_EQ: 50295b482a8SLen Brown /* 50395b482a8SLen Brown * Control - Exit conversion if equal 50495b482a8SLen Brown */ 50595b482a8SLen Brown if (*ACPI_ADD_PTR(u8, resource, 50695b482a8SLen Brown COMPARE_TARGET(info)) == 50795b482a8SLen Brown COMPARE_VALUE(info)) { 50895b482a8SLen Brown goto exit; 50995b482a8SLen Brown } 51095b482a8SLen Brown break; 51195b482a8SLen Brown 51295b482a8SLen Brown default: 51395b482a8SLen Brown 51495b482a8SLen Brown ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); 51595b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 51695b482a8SLen Brown } 51795b482a8SLen Brown 51895b482a8SLen Brown count--; 51995b482a8SLen Brown info++; 52095b482a8SLen Brown } 52195b482a8SLen Brown 52295b482a8SLen Brown exit: 52395b482a8SLen Brown return_ACPI_STATUS(AE_OK); 52495b482a8SLen Brown } 52595b482a8SLen Brown 52695b482a8SLen Brown #if 0 52795b482a8SLen Brown /* Previous resource validations */ 52895b482a8SLen Brown 52995b482a8SLen Brown if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) { 53095b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT); 53195b482a8SLen Brown } 53295b482a8SLen Brown 53395b482a8SLen Brown if (resource->data.start_dpf.performance_robustness >= 3) { 53495b482a8SLen Brown return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE); 53595b482a8SLen Brown } 53695b482a8SLen Brown 53795b482a8SLen Brown if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) { 53895b482a8SLen Brown /* 53995b482a8SLen Brown * Only [active_high, edge_sensitive] or [active_low, level_sensitive] 54095b482a8SLen Brown * polarity/trigger interrupts are allowed (ACPI spec, section 54195b482a8SLen Brown * "IRQ Format"), so 0x00 and 0x09 are illegal. 54295b482a8SLen Brown */ 54395b482a8SLen Brown ACPI_ERROR((AE_INFO, 54495b482a8SLen Brown "Invalid interrupt polarity/trigger in resource list, %X", 54595b482a8SLen Brown aml->irq.flags)); 54695b482a8SLen Brown return_ACPI_STATUS(AE_BAD_DATA); 54795b482a8SLen Brown } 54895b482a8SLen Brown 54995b482a8SLen Brown resource->data.extended_irq.interrupt_count = temp8; 55095b482a8SLen Brown if (temp8 < 1) { 55195b482a8SLen Brown 55295b482a8SLen Brown /* Must have at least one IRQ */ 55395b482a8SLen Brown 55495b482a8SLen Brown return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); 55595b482a8SLen Brown } 55695b482a8SLen Brown 55795b482a8SLen Brown if (resource->data.dma.transfer == 0x03) { 55895b482a8SLen Brown ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)")); 55995b482a8SLen Brown return_ACPI_STATUS(AE_BAD_DATA); 56095b482a8SLen Brown } 56195b482a8SLen Brown #endif 562