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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/io/acpica/executer/exfldio.c
          +++ new/usr/src/common/acpica/components/executer/exfldio.c
   1    1  /******************************************************************************
   2    2   *
   3    3   * Module Name: exfldio - Aml Field I/O
   4    4   *
   5    5   *****************************************************************************/
   6    6  
   7    7  /*
   8      - * Copyright (C) 2000 - 2011, Intel Corp.
        8 + * Copyright (C) 2000 - 2014, Intel Corp.
   9    9   * All rights reserved.
  10   10   *
  11   11   * Redistribution and use in source and binary forms, with or without
  12   12   * modification, are permitted provided that the following conditions
  13   13   * are met:
  14   14   * 1. Redistributions of source code must retain the above copyright
  15   15   *    notice, this list of conditions, and the following disclaimer,
  16   16   *    without modification.
  17   17   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18   18   *    substantially similar to the "NO WARRANTY" disclaimer below
↓ open down ↓ 60 lines elided ↑ open up ↑
  79   79   *
  80   80   * FUNCTION:    AcpiExSetupRegion
  81   81   *
  82   82   * PARAMETERS:  ObjDesc                 - Field to be read or written
  83   83   *              FieldDatumByteOffset    - Byte offset of this datum within the
  84   84   *                                        parent field
  85   85   *
  86   86   * RETURN:      Status
  87   87   *
  88   88   * DESCRIPTION: Common processing for AcpiExExtractFromField and
  89      - *              AcpiExInsertIntoField.  Initialize the Region if necessary and
       89 + *              AcpiExInsertIntoField. Initialize the Region if necessary and
  90   90   *              validate the request.
  91   91   *
  92   92   ******************************************************************************/
  93   93  
  94   94  static ACPI_STATUS
  95   95  AcpiExSetupRegion (
  96   96      ACPI_OPERAND_OBJECT     *ObjDesc,
  97   97      UINT32                  FieldDatumByteOffset)
  98   98  {
  99   99      ACPI_STATUS             Status = AE_OK;
 100  100      ACPI_OPERAND_OBJECT     *RgnDesc;
      101 +    UINT8                   SpaceId;
 101  102  
 102  103  
 103  104      ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
 104  105  
 105  106  
 106  107      RgnDesc = ObjDesc->CommonField.RegionObj;
 107  108  
 108  109      /* We must have a valid region */
 109  110  
 110  111      if (RgnDesc->Common.Type != ACPI_TYPE_REGION)
 111  112      {
 112  113          ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
 113  114              RgnDesc->Common.Type,
 114  115              AcpiUtGetObjectTypeName (RgnDesc)));
 115  116  
 116  117          return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 117  118      }
 118  119  
      120 +    SpaceId = RgnDesc->Region.SpaceId;
      121 +
      122 +    /* Validate the Space ID */
      123 +
      124 +    if (!AcpiIsValidSpaceId (SpaceId))
      125 +    {
      126 +        ACPI_ERROR ((AE_INFO, "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId));
      127 +        return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
      128 +    }
      129 +
 119  130      /*
 120  131       * If the Region Address and Length have not been previously evaluated,
 121  132       * evaluate them now and save the results.
 122  133       */
 123  134      if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))
 124  135      {
 125  136          Status = AcpiDsGetRegionArguments (RgnDesc);
 126  137          if (ACPI_FAILURE (Status))
 127  138          {
 128  139              return_ACPI_STATUS (Status);
 129  140          }
 130  141      }
 131  142  
 132  143      /*
 133      -     * Exit now for SMBus or IPMI address space, it has a non-linear
      144 +     * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
 134  145       * address space and the request cannot be directly validated
 135  146       */
 136      -    if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
 137      -        RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_IPMI)
      147 +    if (SpaceId == ACPI_ADR_SPACE_SMBUS ||
      148 +        SpaceId == ACPI_ADR_SPACE_GSBUS ||
      149 +        SpaceId == ACPI_ADR_SPACE_IPMI)
 138  150      {
 139  151          /* SMBus or IPMI has a non-linear address space */
 140  152  
 141  153          return_ACPI_STATUS (AE_OK);
 142  154      }
 143  155  
 144  156  #ifdef ACPI_UNDER_DEVELOPMENT
 145  157      /*
 146  158       * If the Field access is AnyAcc, we can now compute the optimal
 147  159       * access (because we know know the length of the parent region)
↓ open down ↓ 1 lines elided ↑ open up ↑
 149  161      if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
 150  162      {
 151  163          if (ACPI_FAILURE (Status))
 152  164          {
 153  165              return_ACPI_STATUS (Status);
 154  166          }
 155  167      }
 156  168  #endif
 157  169  
 158  170      /*
 159      -     * Validate the request.  The entire request from the byte offset for a
      171 +     * Validate the request. The entire request from the byte offset for a
 160  172       * length of one field datum (access width) must fit within the region.
 161  173       * (Region length is specified in bytes)
 162  174       */
 163  175      if (RgnDesc->Region.Length <
 164  176              (ObjDesc->CommonField.BaseByteOffset + FieldDatumByteOffset +
 165  177              ObjDesc->CommonField.AccessByteWidth))
 166  178      {
 167  179          if (AcpiGbl_EnableInterpreterSlack)
 168  180          {
 169  181              /*
↓ open down ↓ 8 lines elided ↑ open up ↑
 178  190                      FieldDatumByteOffset))
 179  191              {
 180  192                  return_ACPI_STATUS (AE_OK);
 181  193              }
 182  194          }
 183  195  
 184  196          if (RgnDesc->Region.Length < ObjDesc->CommonField.AccessByteWidth)
 185  197          {
 186  198              /*
 187  199               * This is the case where the AccessType (AccWord, etc.) is wider
 188      -             * than the region itself.  For example, a region of length one
      200 +             * than the region itself. For example, a region of length one
 189  201               * byte, and a field with Dword access specified.
 190  202               */
 191  203              ACPI_ERROR ((AE_INFO,
 192  204                  "Field [%4.4s] access width (%u bytes) too large for region [%4.4s] (length %u)",
 193  205                  AcpiUtGetNodeName (ObjDesc->CommonField.Node),
 194  206                  ObjDesc->CommonField.AccessByteWidth,
 195  207                  AcpiUtGetNodeName (RgnDesc->Region.Node),
 196  208                  RgnDesc->Region.Length));
 197  209          }
 198  210  
↓ open down ↓ 84 lines elided ↑ open up ↑
 283  295          " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
 284  296          AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 285  297          RgnDesc->Region.SpaceId,
 286  298          ObjDesc->CommonField.AccessByteWidth,
 287  299          ObjDesc->CommonField.BaseByteOffset,
 288  300          FieldDatumByteOffset,
 289  301          ACPI_CAST_PTR (void, (RgnDesc->Region.Address + RegionOffset))));
 290  302  
 291  303      /* Invoke the appropriate AddressSpace/OpRegion handler */
 292  304  
 293      -    Status = AcpiEvAddressSpaceDispatch (RgnDesc, Function, RegionOffset,
      305 +    Status = AcpiEvAddressSpaceDispatch (RgnDesc, ObjDesc,
      306 +                Function, RegionOffset,
 294  307                  ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);
 295  308  
 296  309      if (ACPI_FAILURE (Status))
 297  310      {
 298  311          if (Status == AE_NOT_IMPLEMENTED)
 299  312          {
 300  313              ACPI_ERROR ((AE_INFO,
 301  314                  "Region %s (ID=%u) not implemented",
 302  315                  AcpiUtGetRegionName (RgnDesc->Region.SpaceId),
 303  316                  RgnDesc->Region.SpaceId));
↓ open down ↓ 15 lines elided ↑ open up ↑
 319  332   *
 320  333   * FUNCTION:    AcpiExRegisterOverflow
 321  334   *
 322  335   * PARAMETERS:  ObjDesc                 - Register(Field) to be written
 323  336   *              Value                   - Value to be stored
 324  337   *
 325  338   * RETURN:      TRUE if value overflows the field, FALSE otherwise
 326  339   *
 327  340   * DESCRIPTION: Check if a value is out of range of the field being written.
 328  341   *              Used to check if the values written to Index and Bank registers
 329      - *              are out of range.  Normally, the value is simply truncated
      342 + *              are out of range. Normally, the value is simply truncated
 330  343   *              to fit the field, but this case is most likely a serious
 331  344   *              coding error in the ASL.
 332  345   *
 333  346   ******************************************************************************/
 334  347  
 335  348  static BOOLEAN
 336  349  AcpiExRegisterOverflow (
 337  350      ACPI_OPERAND_OBJECT     *ObjDesc,
 338  351      UINT64                  Value)
 339  352  {
↓ open down ↓ 6 lines elided ↑ open up ↑
 346  359           */
 347  360          return (FALSE);
 348  361      }
 349  362  
 350  363      if (Value >= ((UINT64) 1 << ObjDesc->CommonField.BitLength))
 351  364      {
 352  365          /*
 353  366           * The Value is larger than the maximum value that can fit into
 354  367           * the register.
 355  368           */
      369 +        ACPI_ERROR ((AE_INFO,
      370 +            "Index value 0x%8.8X%8.8X overflows field width 0x%X",
      371 +            ACPI_FORMAT_UINT64 (Value),
      372 +            ObjDesc->CommonField.BitLength));
      373 +
 356  374          return (TRUE);
 357  375      }
 358  376  
 359  377      /* The Value will fit into the field with no truncation */
 360  378  
 361  379      return (FALSE);
 362  380  }
 363  381  
 364  382  
 365  383  /*******************************************************************************
↓ open down ↓ 1 lines elided ↑ open up ↑
 367  385   * FUNCTION:    AcpiExFieldDatumIo
 368  386   *
 369  387   * PARAMETERS:  ObjDesc                 - Field to be read
 370  388   *              FieldDatumByteOffset    - Byte offset of this datum within the
 371  389   *                                        parent field
 372  390   *              Value                   - Where to store value (must be 64 bits)
 373  391   *              ReadWrite               - Read or Write flag
 374  392   *
 375  393   * RETURN:      Status
 376  394   *
 377      - * DESCRIPTION: Read or Write a single datum of a field.  The FieldType is
      395 + * DESCRIPTION: Read or Write a single datum of a field. The FieldType is
 378  396   *              demultiplexed here to handle the different types of fields
 379  397   *              (BufferField, RegionField, IndexField, BankField)
 380  398   *
 381  399   ******************************************************************************/
 382  400  
 383  401  static ACPI_STATUS
 384  402  AcpiExFieldDatumIo (
 385  403      ACPI_OPERAND_OBJECT     *ObjDesc,
 386  404      UINT32                  FieldDatumByteOffset,
 387  405      UINT64                  *Value,
↓ open down ↓ 67 lines elided ↑ open up ↑
 455  473               */
 456  474              ACPI_MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +
 457  475                  ObjDesc->BufferField.BaseByteOffset +
 458  476                  FieldDatumByteOffset,
 459  477                  Value, ObjDesc->CommonField.AccessByteWidth);
 460  478          }
 461  479  
 462  480          Status = AE_OK;
 463  481          break;
 464  482  
 465      -
 466  483      case ACPI_TYPE_LOCAL_BANK_FIELD:
 467      -
 468  484          /*
 469  485           * Ensure that the BankValue is not beyond the capacity of
 470  486           * the register
 471  487           */
 472  488          if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,
 473  489                  (UINT64) ObjDesc->BankField.Value))
 474  490          {
 475  491              return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
 476  492          }
 477  493  
↓ open down ↓ 9 lines elided ↑ open up ↑
 487  503              return_ACPI_STATUS (Status);
 488  504          }
 489  505  
 490  506          /*
 491  507           * Now that the Bank has been selected, fall through to the
 492  508           * RegionField case and write the datum to the Operation Region
 493  509           */
 494  510  
 495  511          /*lint -fallthrough */
 496  512  
 497      -
 498  513      case ACPI_TYPE_LOCAL_REGION_FIELD:
 499  514          /*
 500  515           * For simple RegionFields, we just directly access the owning
 501  516           * Operation Region.
 502  517           */
 503  518          Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,
 504  519                      ReadWrite);
 505  520          break;
 506  521  
 507      -
 508  522      case ACPI_TYPE_LOCAL_INDEX_FIELD:
 509      -
 510      -
 511  523          /*
 512  524           * Ensure that the IndexValue is not beyond the capacity of
 513  525           * the register
 514  526           */
 515  527          if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,
 516  528                  (UINT64) ObjDesc->IndexField.Value))
 517  529          {
 518  530              return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
 519  531          }
 520  532  
↓ open down ↓ 29 lines elided ↑ open up ↑
 550  562  
 551  563              ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 552  564                  "Write to Data Register: Value %8.8X%8.8X\n",
 553  565                  ACPI_FORMAT_UINT64 (*Value)));
 554  566  
 555  567              Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,
 556  568                          Value, sizeof (UINT64));
 557  569          }
 558  570          break;
 559  571  
 560      -
 561  572      default:
 562  573  
 563  574          ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
 564  575              ObjDesc->Common.Type));
 565  576          Status = AE_AML_INTERNAL;
 566  577          break;
 567  578      }
 568  579  
 569  580      if (ACPI_SUCCESS (Status))
 570  581      {
↓ open down ↓ 170 lines elided ↑ open up ↑
 741  752      }
 742  753  
 743  754      ACPI_MEMSET (Buffer, 0, BufferLength);
 744  755      AccessBitWidth = ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth);
 745  756  
 746  757      /* Handle the simple case here */
 747  758  
 748  759      if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
 749  760          (ObjDesc->CommonField.BitLength == AccessBitWidth))
 750  761      {
 751      -        Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
      762 +        if (BufferLength >= sizeof (UINT64))
      763 +        {
      764 +            Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
      765 +        }
      766 +        else
      767 +        {
      768 +            /* Use RawDatum (UINT64) to handle buffers < 64 bits */
      769 +
      770 +            Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ);
      771 +            ACPI_MEMCPY (Buffer, &RawDatum, BufferLength);
      772 +        }
      773 +
 752  774          return_ACPI_STATUS (Status);
 753  775      }
 754  776  
 755  777  /* TBD: Move to common setup code */
 756  778  
 757  779      /* Field algorithm is limited to sizeof(UINT64), truncate if needed */
 758  780  
 759  781      if (ObjDesc->CommonField.AccessByteWidth > sizeof (UINT64))
 760  782      {
 761  783          ObjDesc->CommonField.AccessByteWidth = sizeof (UINT64);
↓ open down ↓ 119 lines elided ↑ open up ↑
 881  903      ACPI_FUNCTION_TRACE (ExInsertIntoField);
 882  904  
 883  905  
 884  906      /* Validate input buffer */
 885  907  
 886  908      NewBuffer = NULL;
 887  909      RequiredLength = ACPI_ROUND_BITS_UP_TO_BYTES (
 888  910                          ObjDesc->CommonField.BitLength);
 889  911      /*
 890  912       * We must have a buffer that is at least as long as the field
 891      -     * we are writing to.  This is because individual fields are
      913 +     * we are writing to. This is because individual fields are
 892  914       * indivisible and partial writes are not supported -- as per
 893  915       * the ACPI specification.
 894  916       */
 895  917      if (BufferLength < RequiredLength)
 896  918      {
 897  919          /* We need to create a new buffer */
 898  920  
 899  921          NewBuffer = ACPI_ALLOCATE_ZEROED (RequiredLength);
 900  922          if (!NewBuffer)
 901  923          {
 902  924              return_ACPI_STATUS (AE_NO_MEMORY);
 903  925          }
 904  926  
 905  927          /*
 906  928           * Copy the original data to the new buffer, starting
 907      -         * at Byte zero.  All unused (upper) bytes of the
      929 +         * at Byte zero. All unused (upper) bytes of the
 908  930           * buffer will be 0.
 909  931           */
 910  932          ACPI_MEMCPY ((char *) NewBuffer, (char *) Buffer, BufferLength);
 911  933          Buffer = NewBuffer;
 912  934          BufferLength = RequiredLength;
 913  935      }
 914  936  
 915  937  /* TBD: Move to common setup code */
 916  938  
 917  939      /* Algo is limited to sizeof(UINT64), so cut the AccessByteWidth */
↓ open down ↓ 108 lines elided ↑ open up ↑
1026 1048  
1027 1049  Exit:
1028 1050      /* Free temporary buffer if we used one */
1029 1051  
1030 1052      if (NewBuffer)
1031 1053      {
1032 1054          ACPI_FREE (NewBuffer);
1033 1055      }
1034 1056      return_ACPI_STATUS (Status);
1035 1057  }
1036      -
1037      -
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX