Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/io/acpica/hardware/hwxface.c
          +++ new/usr/src/common/acpica/components/hardware/hwxface.c
   1      -
   2    1  /******************************************************************************
   3    2   *
   4    3   * Module Name: hwxface - Public ACPICA hardware interfaces
   5    4   *
   6    5   *****************************************************************************/
   7    6  
   8    7  /*
   9      - * Copyright (C) 2000 - 2011, Intel Corp.
        8 + * Copyright (C) 2000 - 2014, Intel Corp.
  10    9   * All rights reserved.
  11   10   *
  12   11   * Redistribution and use in source and binary forms, with or without
  13   12   * modification, are permitted provided that the following conditions
  14   13   * are met:
  15   14   * 1. Redistributions of source code must retain the above copyright
  16   15   *    notice, this list of conditions, and the following disclaimer,
  17   16   *    without modification.
  18   17   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19   18   *    substantially similar to the "NO WARRANTY" disclaimer below
↓ open down ↓ 15 lines elided ↑ open up ↑
  35   34   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  36   35   * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37   36   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38   37   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39   38   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40   39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41   40   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42   41   * POSSIBILITY OF SUCH DAMAGES.
  43   42   */
  44   43  
       44 +#define EXPORT_ACPI_INTERFACES
       45 +
  45   46  #include "acpi.h"
  46   47  #include "accommon.h"
  47   48  #include "acnamesp.h"
  48   49  
  49   50  #define _COMPONENT          ACPI_HARDWARE
  50   51          ACPI_MODULE_NAME    ("hwxface")
  51   52  
  52   53  
  53   54  /******************************************************************************
  54   55   *
↓ open down ↓ 29 lines elided ↑ open up ↑
  84   85      {
  85   86          return_ACPI_STATUS (AE_NOT_EXIST);
  86   87      }
  87   88  
  88   89      if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
  89   90      {
  90   91          /*
  91   92           * For I/O space, write directly to the OSL. This bypasses the port
  92   93           * validation mechanism, which may block a valid write to the reset
  93   94           * register.
       95 +         *
       96 +         * NOTE:
       97 +         * The ACPI spec requires the reset register width to be 8, so we
       98 +         * hardcode it here and ignore the FADT value. This maintains
       99 +         * compatibility with other ACPI implementations that have allowed
      100 +         * BIOS code with bad register width values to go unnoticed.
  94  101           */
  95  102          Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
  96      -                    AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
      103 +            AcpiGbl_FADT.ResetValue, ACPI_RESET_REGISTER_WIDTH);
  97  104      }
  98  105      else
  99  106      {
 100  107          /* Write the reset value to the reset register */
 101  108  
 102  109          Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
 103  110      }
 104  111  
 105  112      return_ACPI_STATUS (Status);
 106  113  }
↓ open down ↓ 18 lines elided ↑ open up ↑
 125  132   *      BitOffset and AccessWidth are currently ignored, as there has
 126  133   *          not been a need to implement these.
 127  134   *
 128  135   ******************************************************************************/
 129  136  
 130  137  ACPI_STATUS
 131  138  AcpiRead (
 132  139      UINT64                  *ReturnValue,
 133  140      ACPI_GENERIC_ADDRESS    *Reg)
 134  141  {
 135      -    UINT32                  Value;
      142 +    UINT32                  ValueLo;
      143 +    UINT32                  ValueHi;
 136  144      UINT32                  Width;
 137  145      UINT64                  Address;
 138  146      ACPI_STATUS             Status;
 139  147  
 140  148  
 141  149      ACPI_FUNCTION_NAME (AcpiRead);
 142  150  
 143  151  
 144  152      if (!ReturnValue)
 145  153      {
↓ open down ↓ 1 lines elided ↑ open up ↑
 147  155      }
 148  156  
 149  157      /* Validate contents of the GAS register. Allow 64-bit transfers */
 150  158  
 151  159      Status = AcpiHwValidateRegister (Reg, 64, &Address);
 152  160      if (ACPI_FAILURE (Status))
 153  161      {
 154  162          return (Status);
 155  163      }
 156  164  
 157      -    Width = Reg->BitWidth;
 158      -    if (Width == 64)
 159      -    {
 160      -        Width = 32; /* Break into two 32-bit transfers */
 161      -    }
 162      -
 163      -    /* Initialize entire 64-bit return value to zero */
 164      -
 165      -    *ReturnValue = 0;
 166      -    Value = 0;
 167      -
 168  165      /*
 169      -     * Two address spaces supported: Memory or IO. PCI_Config is
      166 +     * Two address spaces supported: Memory or I/O. PCI_Config is
 170  167       * not supported here because the GAS structure is insufficient
 171  168       */
 172  169      if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 173  170      {
 174  171          Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
 175      -                    Address, &Value, Width);
      172 +                    Address, ReturnValue, Reg->BitWidth);
 176  173          if (ACPI_FAILURE (Status))
 177  174          {
 178  175              return (Status);
 179  176          }
 180      -        *ReturnValue = Value;
 181      -
 182      -        if (Reg->BitWidth == 64)
 183      -        {
 184      -            /* Read the top 32 bits */
 185      -
 186      -            Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
 187      -                        (Address + 4), &Value, 32);
 188      -            if (ACPI_FAILURE (Status))
 189      -            {
 190      -                return (Status);
 191      -            }
 192      -            *ReturnValue |= ((UINT64) Value << 32);
 193      -        }
 194  177      }
 195  178      else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
 196  179      {
      180 +        ValueLo = 0;
      181 +        ValueHi = 0;
      182 +
      183 +        Width = Reg->BitWidth;
      184 +        if (Width == 64)
      185 +        {
      186 +            Width = 32; /* Break into two 32-bit transfers */
      187 +        }
      188 +
 197  189          Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
 198      -                    Address, &Value, Width);
      190 +                    Address, &ValueLo, Width);
 199  191          if (ACPI_FAILURE (Status))
 200  192          {
 201  193              return (Status);
 202  194          }
 203      -        *ReturnValue = Value;
 204  195  
 205  196          if (Reg->BitWidth == 64)
 206  197          {
 207  198              /* Read the top 32 bits */
 208  199  
 209  200              Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
 210      -                        (Address + 4), &Value, 32);
      201 +                        (Address + 4), &ValueHi, 32);
 211  202              if (ACPI_FAILURE (Status))
 212  203              {
 213  204                  return (Status);
 214  205              }
 215      -            *ReturnValue |= ((UINT64) Value << 32);
 216  206          }
      207 +
      208 +        /* Set the return value only if status is AE_OK */
      209 +
      210 +        *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
 217  211      }
 218  212  
 219  213      ACPI_DEBUG_PRINT ((ACPI_DB_IO,
 220  214          "Read:  %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
 221  215          ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
 222  216          ACPI_FORMAT_UINT64 (Address),
 223  217          AcpiUtGetRegionName (Reg->SpaceId)));
 224  218  
 225      -    return (Status);
      219 +    return (AE_OK);
 226  220  }
 227  221  
 228  222  ACPI_EXPORT_SYMBOL (AcpiRead)
 229  223  
 230  224  
 231  225  /******************************************************************************
 232  226   *
 233  227   * FUNCTION:    AcpiWrite
 234  228   *
 235  229   * PARAMETERS:  Value               - Value to be written
↓ open down ↓ 19 lines elided ↑ open up ↑
 255  249  
 256  250  
 257  251      /* Validate contents of the GAS register. Allow 64-bit transfers */
 258  252  
 259  253      Status = AcpiHwValidateRegister (Reg, 64, &Address);
 260  254      if (ACPI_FAILURE (Status))
 261  255      {
 262  256          return (Status);
 263  257      }
 264  258  
 265      -    Width = Reg->BitWidth;
 266      -    if (Width == 64)
 267      -    {
 268      -        Width = 32; /* Break into two 32-bit transfers */
 269      -    }
 270      -
 271  259      /*
 272  260       * Two address spaces supported: Memory or IO. PCI_Config is
 273  261       * not supported here because the GAS structure is insufficient
 274  262       */
 275  263      if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 276  264      {
 277  265          Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
 278      -                    Address, ACPI_LODWORD (Value), Width);
      266 +                    Address, Value, Reg->BitWidth);
 279  267          if (ACPI_FAILURE (Status))
 280  268          {
 281  269              return (Status);
 282  270          }
 283      -
 284      -        if (Reg->BitWidth == 64)
 285      -        {
 286      -            Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
 287      -                        (Address + 4), ACPI_HIDWORD (Value), 32);
 288      -            if (ACPI_FAILURE (Status))
 289      -            {
 290      -                return (Status);
 291      -            }
 292      -        }
 293  271      }
 294  272      else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
 295  273      {
      274 +        Width = Reg->BitWidth;
      275 +        if (Width == 64)
      276 +        {
      277 +            Width = 32; /* Break into two 32-bit transfers */
      278 +        }
      279 +
 296  280          Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
 297  281                      Address, ACPI_LODWORD (Value), Width);
 298  282          if (ACPI_FAILURE (Status))
 299  283          {
 300  284              return (Status);
 301  285          }
 302  286  
 303  287          if (Reg->BitWidth == 64)
 304  288          {
 305  289              Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
↓ open down ↓ 10 lines elided ↑ open up ↑
 316  300          ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
 317  301          ACPI_FORMAT_UINT64 (Address),
 318  302          AcpiUtGetRegionName (Reg->SpaceId)));
 319  303  
 320  304      return (Status);
 321  305  }
 322  306  
 323  307  ACPI_EXPORT_SYMBOL (AcpiWrite)
 324  308  
 325  309  
      310 +#if (!ACPI_REDUCED_HARDWARE)
 326  311  /*******************************************************************************
 327  312   *
 328  313   * FUNCTION:    AcpiReadBitRegister
 329  314   *
 330  315   * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
 331  316   *              ReturnValue     - Value that was read from the register,
 332  317   *                                normalized to bit position zero.
 333  318   *
 334  319   * RETURN:      Status and the value read from the specified Register. Value
 335  320   *              returned is normalized to bit0 (is shifted all the way right)
↓ open down ↓ 58 lines elided ↑ open up ↑
 394  379  
 395  380  ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
 396  381  
 397  382  
 398  383  /*******************************************************************************
 399  384   *
 400  385   * FUNCTION:    AcpiWriteBitRegister
 401  386   *
 402  387   * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
 403  388   *              Value           - Value to write to the register, in bit
 404      - *                                position zero. The bit is automaticallly
      389 + *                                position zero. The bit is automatically
 405  390   *                                shifted to the correct position.
 406  391   *
 407  392   * RETURN:      Status
 408  393   *
 409  394   * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
 410  395   *              since most operations require a read/modify/write sequence.
 411  396   *
 412  397   * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
 413  398   *              PM2 Control.
 414  399   *
↓ open down ↓ 83 lines elided ↑ open up ↑
 498  483  
 499  484  
 500  485  UnlockAndExit:
 501  486  
 502  487      AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
 503  488      return_ACPI_STATUS (Status);
 504  489  }
 505  490  
 506  491  ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
 507  492  
      493 +#endif /* !ACPI_REDUCED_HARDWARE */
 508  494  
      495 +
 509  496  /*******************************************************************************
 510  497   *
 511  498   * FUNCTION:    AcpiGetSleepTypeData
 512  499   *
 513  500   * PARAMETERS:  SleepState          - Numeric sleep state
 514  501   *              *SleepTypeA         - Where SLP_TYPa is returned
 515  502   *              *SleepTypeB         - Where SLP_TYPb is returned
 516  503   *
 517      - * RETURN:      Status - ACPI status
      504 + * RETURN:      Status
 518  505   *
 519      - * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
 520      - *              state.
      506 + * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
      507 + *              sleep state via the appropriate \_Sx object.
 521  508   *
      509 + *  The sleep state package returned from the corresponding \_Sx_ object
      510 + *  must contain at least one integer.
      511 + *
      512 + *  March 2005:
      513 + *  Added support for a package that contains two integers. This
      514 + *  goes against the ACPI specification which defines this object as a
      515 + *  package with one encoded DWORD integer. However, existing practice
      516 + *  by many BIOS vendors is to return a package with 2 or more integer
      517 + *  elements, at least one per sleep type (A/B).
      518 + *
      519 + *  January 2013:
      520 + *  Therefore, we must be prepared to accept a package with either a
      521 + *  single integer or multiple integers.
      522 + *
      523 + *  The single integer DWORD format is as follows:
      524 + *      BYTE 0 - Value for the PM1A SLP_TYP register
      525 + *      BYTE 1 - Value for the PM1B SLP_TYP register
      526 + *      BYTE 2-3 - Reserved
      527 + *
      528 + *  The dual integer format is as follows:
      529 + *      Integer 0 - Value for the PM1A SLP_TYP register
      530 + *      Integer 1 - Value for the PM1A SLP_TYP register
      531 + *
 522  532   ******************************************************************************/
 523  533  
 524  534  ACPI_STATUS
 525  535  AcpiGetSleepTypeData (
 526  536      UINT8                   SleepState,
 527  537      UINT8                   *SleepTypeA,
 528  538      UINT8                   *SleepTypeB)
 529  539  {
 530      -    ACPI_STATUS             Status = AE_OK;
      540 +    ACPI_STATUS             Status;
 531  541      ACPI_EVALUATE_INFO      *Info;
      542 +    ACPI_OPERAND_OBJECT     **Elements;
 532  543  
 533  544  
 534  545      ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
 535  546  
 536  547  
 537  548      /* Validate parameters */
 538  549  
 539  550      if ((SleepState > ACPI_S_STATES_MAX) ||
 540      -        !SleepTypeA ||
 541      -        !SleepTypeB)
      551 +        !SleepTypeA || !SleepTypeB)
 542  552      {
 543  553          return_ACPI_STATUS (AE_BAD_PARAMETER);
 544  554      }
 545  555  
 546  556      /* Allocate the evaluation information block */
 547  557  
 548  558      Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
 549  559      if (!Info)
 550  560      {
 551  561          return_ACPI_STATUS (AE_NO_MEMORY);
 552  562      }
 553  563  
 554      -    Info->Pathname = ACPI_CAST_PTR (char, AcpiGbl_SleepStateNames[SleepState]);
 555      -
 556      -    /* Evaluate the namespace object containing the values for this state */
 557      -
      564 +    /*
      565 +     * Evaluate the \_Sx namespace object containing the register values
      566 +     * for this state
      567 +     */
      568 +    Info->RelativePathname = ACPI_CAST_PTR (
      569 +        char, AcpiGbl_SleepStateNames[SleepState]);
 558  570      Status = AcpiNsEvaluate (Info);
 559  571      if (ACPI_FAILURE (Status))
 560  572      {
 561      -        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 562      -            "%s while evaluating SleepState [%s]\n",
 563      -            AcpiFormatException (Status), Info->Pathname));
 564      -
 565  573          goto Cleanup;
 566  574      }
 567  575  
 568  576      /* Must have a return object */
 569  577  
 570  578      if (!Info->ReturnObject)
 571  579      {
 572  580          ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
 573      -            Info->Pathname));
 574      -        Status = AE_NOT_EXIST;
      581 +            Info->RelativePathname));
      582 +        Status = AE_AML_NO_RETURN_VALUE;
      583 +        goto Cleanup;
 575  584      }
 576  585  
 577      -    /* It must be of type Package */
      586 +    /* Return object must be of type Package */
 578  587  
 579      -    else if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
      588 +    if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
 580  589      {
 581  590          ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
 582  591          Status = AE_AML_OPERAND_TYPE;
      592 +        goto Cleanup1;
 583  593      }
 584  594  
 585  595      /*
 586      -     * The package must have at least two elements. NOTE (March 2005): This
 587      -     * goes against the current ACPI spec which defines this object as a
 588      -     * package with one encoded DWORD element. However, existing practice
 589      -     * by BIOS vendors seems to be to have 2 or more elements, at least
 590      -     * one per sleep type (A/B).
      596 +     * Any warnings about the package length or the object types have
      597 +     * already been issued by the predefined name module -- there is no
      598 +     * need to repeat them here.
 591  599       */
 592      -    else if (Info->ReturnObject->Package.Count < 2)
      600 +    Elements = Info->ReturnObject->Package.Elements;
      601 +    switch (Info->ReturnObject->Package.Count)
 593  602      {
 594      -        ACPI_ERROR ((AE_INFO,
 595      -            "Sleep State return package does not have at least two elements"));
 596      -        Status = AE_AML_NO_OPERAND;
 597      -    }
      603 +    case 0:
 598  604  
 599      -    /* The first two elements must both be of type Integer */
      605 +        Status = AE_AML_PACKAGE_LIMIT;
      606 +        break;
 600  607  
 601      -    else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
 602      -                != ACPI_TYPE_INTEGER) ||
 603      -             ((Info->ReturnObject->Package.Elements[1])->Common.Type
 604      -                != ACPI_TYPE_INTEGER))
 605      -    {
 606      -        ACPI_ERROR ((AE_INFO,
 607      -            "Sleep State return package elements are not both Integers "
 608      -            "(%s, %s)",
 609      -            AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
 610      -            AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
 611      -        Status = AE_AML_OPERAND_TYPE;
 612      -    }
 613      -    else
 614      -    {
 615      -        /* Valid _Sx_ package size, type, and value */
      608 +    case 1:
 616  609  
 617      -        *SleepTypeA = (UINT8)
 618      -            (Info->ReturnObject->Package.Elements[0])->Integer.Value;
 619      -        *SleepTypeB = (UINT8)
 620      -            (Info->ReturnObject->Package.Elements[1])->Integer.Value;
      610 +        if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER)
      611 +        {
      612 +            Status = AE_AML_OPERAND_TYPE;
      613 +            break;
      614 +        }
      615 +
      616 +        /* A valid _Sx_ package with one integer */
      617 +
      618 +        *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
      619 +        *SleepTypeB = (UINT8) (Elements[0]->Integer.Value >> 8);
      620 +        break;
      621 +
      622 +    case 2:
      623 +    default:
      624 +
      625 +        if ((Elements[0]->Common.Type != ACPI_TYPE_INTEGER) ||
      626 +            (Elements[1]->Common.Type != ACPI_TYPE_INTEGER))
      627 +        {
      628 +            Status = AE_AML_OPERAND_TYPE;
      629 +            break;
      630 +        }
      631 +
      632 +        /* A valid _Sx_ package with two integers */
      633 +
      634 +        *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
      635 +        *SleepTypeB = (UINT8) Elements[1]->Integer.Value;
      636 +        break;
 621  637      }
 622  638  
      639 +Cleanup1:
      640 +    AcpiUtRemoveReference (Info->ReturnObject);
      641 +
      642 +Cleanup:
 623  643      if (ACPI_FAILURE (Status))
 624  644      {
 625  645          ACPI_EXCEPTION ((AE_INFO, Status,
 626      -            "While evaluating SleepState [%s], bad Sleep object %p type %s",
 627      -            Info->Pathname, Info->ReturnObject,
 628      -            AcpiUtGetObjectTypeName (Info->ReturnObject)));
      646 +            "While evaluating Sleep State [%s]", Info->RelativePathname));
 629  647      }
 630  648  
 631      -    AcpiUtRemoveReference (Info->ReturnObject);
 632      -
 633      -Cleanup:
 634  649      ACPI_FREE (Info);
 635  650      return_ACPI_STATUS (Status);
 636  651  }
 637  652  
 638  653  ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX