linux/drivers/acpi/acpica/rsaddr.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 * Module Name: rsaddr - Address resource descriptors (16/32/64)
   4 *
   5 ******************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2012, Intel Corp.
   9 * All rights reserved.
  10 *
  11 * Redistribution and use in source and binary forms, with or without
  12 * modification, are permitted provided that the following conditions
  13 * are met:
  14 * 1. Redistributions of source code must retain the above copyright
  15 *    notice, this list of conditions, and the following disclaimer,
  16 *    without modification.
  17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18 *    substantially similar to the "NO WARRANTY" disclaimer below
  19 *    ("Disclaimer") and any redistribution must be conditioned upon
  20 *    including a substantially similar Disclaimer requirement for further
  21 *    binary redistribution.
  22 * 3. Neither the names of the above-listed copyright holders nor the names
  23 *    of any contributors may be used to endorse or promote products derived
  24 *    from this software without specific prior written permission.
  25 *
  26 * Alternatively, this software may be distributed under the terms of the
  27 * GNU General Public License ("GPL") version 2 as published by the Free
  28 * Software Foundation.
  29 *
  30 * NO WARRANTY
  31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41 * POSSIBILITY OF SUCH DAMAGES.
  42 */
  43
  44#include <acpi/acpi.h>
  45#include "accommon.h"
  46#include "acresrc.h"
  47
  48#define _COMPONENT          ACPI_RESOURCES
  49ACPI_MODULE_NAME("rsaddr")
  50
  51/*******************************************************************************
  52 *
  53 * acpi_rs_convert_address16 - All WORD (16-bit) address resources
  54 *
  55 ******************************************************************************/
  56struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {
  57        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
  58         ACPI_RS_SIZE(struct acpi_resource_address16),
  59         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},
  60
  61        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
  62         sizeof(struct aml_resource_address16),
  63         0},
  64
  65        /* Resource Type, General Flags, and Type-Specific Flags */
  66
  67        {ACPI_RSC_ADDRESS, 0, 0, 0},
  68
  69        /*
  70         * These fields are contiguous in both the source and destination:
  71         * Address Granularity
  72         * Address Range Minimum
  73         * Address Range Maximum
  74         * Address Translation Offset
  75         * Address Length
  76         */
  77        {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity),
  78         AML_OFFSET(address16.granularity),
  79         5},
  80
  81        /* Optional resource_source (Index and String) */
  82
  83        {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),
  84         0,
  85         sizeof(struct aml_resource_address16)}
  86};
  87
  88/*******************************************************************************
  89 *
  90 * acpi_rs_convert_address32 - All DWORD (32-bit) address resources
  91 *
  92 ******************************************************************************/
  93
  94struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {
  95        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
  96         ACPI_RS_SIZE(struct acpi_resource_address32),
  97         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},
  98
  99        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
 100         sizeof(struct aml_resource_address32),
 101         0},
 102
 103        /* Resource Type, General Flags, and Type-Specific Flags */
 104
 105        {ACPI_RSC_ADDRESS, 0, 0, 0},
 106
 107        /*
 108         * These fields are contiguous in both the source and destination:
 109         * Address Granularity
 110         * Address Range Minimum
 111         * Address Range Maximum
 112         * Address Translation Offset
 113         * Address Length
 114         */
 115        {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity),
 116         AML_OFFSET(address32.granularity),
 117         5},
 118
 119        /* Optional resource_source (Index and String) */
 120
 121        {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),
 122         0,
 123         sizeof(struct aml_resource_address32)}
 124};
 125
 126/*******************************************************************************
 127 *
 128 * acpi_rs_convert_address64 - All QWORD (64-bit) address resources
 129 *
 130 ******************************************************************************/
 131
 132struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {
 133        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
 134         ACPI_RS_SIZE(struct acpi_resource_address64),
 135         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},
 136
 137        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
 138         sizeof(struct aml_resource_address64),
 139         0},
 140
 141        /* Resource Type, General Flags, and Type-Specific Flags */
 142
 143        {ACPI_RSC_ADDRESS, 0, 0, 0},
 144
 145        /*
 146         * These fields are contiguous in both the source and destination:
 147         * Address Granularity
 148         * Address Range Minimum
 149         * Address Range Maximum
 150         * Address Translation Offset
 151         * Address Length
 152         */
 153        {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity),
 154         AML_OFFSET(address64.granularity),
 155         5},
 156
 157        /* Optional resource_source (Index and String) */
 158
 159        {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),
 160         0,
 161         sizeof(struct aml_resource_address64)}
 162};
 163
 164/*******************************************************************************
 165 *
 166 * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources
 167 *
 168 ******************************************************************************/
 169
 170struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {
 171        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
 172         ACPI_RS_SIZE(struct acpi_resource_extended_address64),
 173         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},
 174
 175        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
 176         sizeof(struct aml_resource_extended_address64),
 177         0},
 178
 179        /* Resource Type, General Flags, and Type-Specific Flags */
 180
 181        {ACPI_RSC_ADDRESS, 0, 0, 0},
 182
 183        /* Revision ID */
 184
 185        {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_ID),
 186         AML_OFFSET(ext_address64.revision_ID),
 187         1},
 188        /*
 189         * These fields are contiguous in both the source and destination:
 190         * Address Granularity
 191         * Address Range Minimum
 192         * Address Range Maximum
 193         * Address Translation Offset
 194         * Address Length
 195         * Type-Specific Attribute
 196         */
 197        {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity),
 198         AML_OFFSET(ext_address64.granularity),
 199         6}
 200};
 201
 202/*******************************************************************************
 203 *
 204 * acpi_rs_convert_general_flags - Flags common to all address descriptors
 205 *
 206 ******************************************************************************/
 207
 208static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {
 209        {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),
 210         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},
 211
 212        /* Resource Type (Memory, Io, bus_number, etc.) */
 213
 214        {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),
 215         AML_OFFSET(address.resource_type),
 216         1},
 217
 218        /* General flags - Consume, Decode, min_fixed, max_fixed */
 219
 220        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),
 221         AML_OFFSET(address.flags),
 222         0},
 223
 224        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),
 225         AML_OFFSET(address.flags),
 226         1},
 227
 228        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),
 229         AML_OFFSET(address.flags),
 230         2},
 231
 232        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),
 233         AML_OFFSET(address.flags),
 234         3}
 235};
 236
 237/*******************************************************************************
 238 *
 239 * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors
 240 *
 241 ******************************************************************************/
 242
 243static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {
 244        {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
 245         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},
 246
 247        /* Memory-specific flags */
 248
 249        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),
 250         AML_OFFSET(address.specific_flags),
 251         0},
 252
 253        {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),
 254         AML_OFFSET(address.specific_flags),
 255         1},
 256
 257        {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),
 258         AML_OFFSET(address.specific_flags),
 259         3},
 260
 261        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),
 262         AML_OFFSET(address.specific_flags),
 263         5}
 264};
 265
 266/*******************************************************************************
 267 *
 268 * acpi_rs_convert_io_flags - Flags common to I/O address descriptors
 269 *
 270 ******************************************************************************/
 271
 272static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {
 273        {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
 274         ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},
 275
 276        /* I/O-specific flags */
 277
 278        {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),
 279         AML_OFFSET(address.specific_flags),
 280         0},
 281
 282        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),
 283         AML_OFFSET(address.specific_flags),
 284         4},
 285
 286        {ACPI_RSC_1BITFLAG,
 287         ACPI_RS_OFFSET(data.address.info.io.translation_type),
 288         AML_OFFSET(address.specific_flags),
 289         5}
 290};
 291
 292/*******************************************************************************
 293 *
 294 * FUNCTION:    acpi_rs_get_address_common
 295 *
 296 * PARAMETERS:  resource            - Pointer to the internal resource struct
 297 *              aml                 - Pointer to the AML resource descriptor
 298 *
 299 * RETURN:      TRUE if the resource_type field is OK, FALSE otherwise
 300 *
 301 * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
 302 *              to an internal resource descriptor
 303 *
 304 ******************************************************************************/
 305
 306u8
 307acpi_rs_get_address_common(struct acpi_resource *resource,
 308                           union aml_resource *aml)
 309{
 310        ACPI_FUNCTION_ENTRY();
 311
 312        /* Validate the Resource Type */
 313
 314        if ((aml->address.resource_type > 2)
 315            && (aml->address.resource_type < 0xC0)) {
 316                return (FALSE);
 317        }
 318
 319        /* Get the Resource Type and General Flags */
 320
 321        (void)acpi_rs_convert_aml_to_resource(resource, aml,
 322                                              acpi_rs_convert_general_flags);
 323
 324        /* Get the Type-Specific Flags (Memory and I/O descriptors only) */
 325
 326        if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
 327                (void)acpi_rs_convert_aml_to_resource(resource, aml,
 328                                                      acpi_rs_convert_mem_flags);
 329        } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
 330                (void)acpi_rs_convert_aml_to_resource(resource, aml,
 331                                                      acpi_rs_convert_io_flags);
 332        } else {
 333                /* Generic resource type, just grab the type_specific byte */
 334
 335                resource->data.address.info.type_specific =
 336                    aml->address.specific_flags;
 337        }
 338
 339        return (TRUE);
 340}
 341
 342/*******************************************************************************
 343 *
 344 * FUNCTION:    acpi_rs_set_address_common
 345 *
 346 * PARAMETERS:  aml                 - Pointer to the AML resource descriptor
 347 *              resource            - Pointer to the internal resource struct
 348 *
 349 * RETURN:      None
 350 *
 351 * DESCRIPTION: Convert common flag fields from a resource descriptor to an
 352 *              AML descriptor
 353 *
 354 ******************************************************************************/
 355
 356void
 357acpi_rs_set_address_common(union aml_resource *aml,
 358                           struct acpi_resource *resource)
 359{
 360        ACPI_FUNCTION_ENTRY();
 361
 362        /* Set the Resource Type and General Flags */
 363
 364        (void)acpi_rs_convert_resource_to_aml(resource, aml,
 365                                              acpi_rs_convert_general_flags);
 366
 367        /* Set the Type-Specific Flags (Memory and I/O descriptors only) */
 368
 369        if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
 370                (void)acpi_rs_convert_resource_to_aml(resource, aml,
 371                                                      acpi_rs_convert_mem_flags);
 372        } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
 373                (void)acpi_rs_convert_resource_to_aml(resource, aml,
 374                                                      acpi_rs_convert_io_flags);
 375        } else {
 376                /* Generic resource type, just copy the type_specific byte */
 377
 378                aml->address.specific_flags =
 379                    resource->data.address.info.type_specific;
 380        }
 381}
 382