Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: hwxface - Public ACPICA hardware interfaces
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, 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. #define EXPORT_ACPI_INTERFACES
  45.  
  46. #include <acpi/acpi.h>
  47. #include "accommon.h"
  48. #include "acnamesp.h"
  49.  
  50. #define _COMPONENT          ACPI_HARDWARE
  51. ACPI_MODULE_NAME("hwxface")
  52.  
  53. /******************************************************************************
  54.  *
  55.  * FUNCTION:    acpi_reset
  56.  *
  57.  * PARAMETERS:  None
  58.  *
  59.  * RETURN:      Status
  60.  *
  61.  * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
  62.  *              support reset register in PCI config space, this must be
  63.  *              handled separately.
  64.  *
  65.  ******************************************************************************/
  66. acpi_status acpi_reset(void)
  67. {
  68.         struct acpi_generic_address *reset_reg;
  69.         acpi_status status;
  70.  
  71.         ACPI_FUNCTION_TRACE(acpi_reset);
  72.  
  73.         reset_reg = &acpi_gbl_FADT.reset_register;
  74.  
  75.         /* Check if the reset register is supported */
  76.  
  77.         if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
  78.             !reset_reg->address) {
  79.                 return_ACPI_STATUS(AE_NOT_EXIST);
  80.         }
  81.  
  82.         if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
  83.                 /*
  84.                  * For I/O space, write directly to the OSL. This bypasses the port
  85.                  * validation mechanism, which may block a valid write to the reset
  86.                  * register.
  87.                  *
  88.                  * NOTE:
  89.                  * The ACPI spec requires the reset register width to be 8, so we
  90.                  * hardcode it here and ignore the FADT value. This maintains
  91.                  * compatibility with other ACPI implementations that have allowed
  92.                  * BIOS code with bad register width values to go unnoticed.
  93.                  */
  94.                 status =
  95.                     acpi_os_write_port((acpi_io_address) reset_reg->address,
  96.                                        acpi_gbl_FADT.reset_value,
  97.                                        ACPI_RESET_REGISTER_WIDTH);
  98.         } else {
  99.                 /* Write the reset value to the reset register */
  100.  
  101.                 status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg);
  102.         }
  103.  
  104.         return_ACPI_STATUS(status);
  105. }
  106.  
  107. ACPI_EXPORT_SYMBOL(acpi_reset)
  108.  
  109. /******************************************************************************
  110.  *
  111.  * FUNCTION:    acpi_read
  112.  *
  113.  * PARAMETERS:  value               - Where the value is returned
  114.  *              reg                 - GAS register structure
  115.  *
  116.  * RETURN:      Status
  117.  *
  118.  * DESCRIPTION: Read from either memory or IO space.
  119.  *
  120.  * LIMITATIONS: <These limitations also apply to acpi_write>
  121.  *      bit_width must be exactly 8, 16, 32, or 64.
  122.  *      space_ID must be system_memory or system_IO.
  123.  *      bit_offset and access_width are currently ignored, as there has
  124.  *          not been a need to implement these.
  125.  *
  126.  ******************************************************************************/
  127. acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
  128. {
  129.         u32 value_lo;
  130.         u32 value_hi;
  131.         u32 width;
  132.         u64 address;
  133.         acpi_status status;
  134.  
  135.         ACPI_FUNCTION_NAME(acpi_read);
  136.  
  137.         if (!return_value) {
  138.                 return (AE_BAD_PARAMETER);
  139.         }
  140.  
  141.         /* Validate contents of the GAS register. Allow 64-bit transfers */
  142.  
  143.         status = acpi_hw_validate_register(reg, 64, &address);
  144.         if (ACPI_FAILURE(status)) {
  145.                 return (status);
  146.         }
  147.  
  148.         /*
  149.          * Two address spaces supported: Memory or I/O. PCI_Config is
  150.          * not supported here because the GAS structure is insufficient
  151.          */
  152.         if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
  153.                 status = acpi_os_read_memory((acpi_physical_address)
  154.                                              address, return_value,
  155.                                              reg->bit_width);
  156.                 if (ACPI_FAILURE(status)) {
  157.                         return (status);
  158.                 }
  159.         } else {                /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
  160.  
  161.                 value_lo = 0;
  162.                 value_hi = 0;
  163.  
  164.                 width = reg->bit_width;
  165.                 if (width == 64) {
  166.                         width = 32;     /* Break into two 32-bit transfers */
  167.                 }
  168.  
  169.                 status = acpi_hw_read_port((acpi_io_address)
  170.                                            address, &value_lo, width);
  171.                 if (ACPI_FAILURE(status)) {
  172.                         return (status);
  173.                 }
  174.  
  175.                 if (reg->bit_width == 64) {
  176.  
  177.                         /* Read the top 32 bits */
  178.  
  179.                         status = acpi_hw_read_port((acpi_io_address)
  180.                                                    (address + 4), &value_hi,
  181.                                                    32);
  182.                         if (ACPI_FAILURE(status)) {
  183.                                 return (status);
  184.                         }
  185.                 }
  186.  
  187.                 /* Set the return value only if status is AE_OK */
  188.  
  189.                 *return_value = (value_lo | ((u64)value_hi << 32));
  190.         }
  191.  
  192.         ACPI_DEBUG_PRINT((ACPI_DB_IO,
  193.                           "Read:  %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
  194.                           ACPI_FORMAT_UINT64(*return_value), reg->bit_width,
  195.                           ACPI_FORMAT_UINT64(address),
  196.                           acpi_ut_get_region_name(reg->space_id)));
  197.  
  198.         return (AE_OK);
  199. }
  200.  
  201. ACPI_EXPORT_SYMBOL(acpi_read)
  202.  
  203. /******************************************************************************
  204.  *
  205.  * FUNCTION:    acpi_write
  206.  *
  207.  * PARAMETERS:  value               - Value to be written
  208.  *              reg                 - GAS register structure
  209.  *
  210.  * RETURN:      Status
  211.  *
  212.  * DESCRIPTION: Write to either memory or IO space.
  213.  *
  214.  ******************************************************************************/
  215. acpi_status acpi_write(u64 value, struct acpi_generic_address *reg)
  216. {
  217.         u32 width;
  218.         u64 address;
  219.         acpi_status status;
  220.  
  221.         ACPI_FUNCTION_NAME(acpi_write);
  222.  
  223.         /* Validate contents of the GAS register. Allow 64-bit transfers */
  224.  
  225.         status = acpi_hw_validate_register(reg, 64, &address);
  226.         if (ACPI_FAILURE(status)) {
  227.                 return (status);
  228.         }
  229.  
  230.         /*
  231.          * Two address spaces supported: Memory or IO. PCI_Config is
  232.          * not supported here because the GAS structure is insufficient
  233.          */
  234.         if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
  235.                 status = acpi_os_write_memory((acpi_physical_address)
  236.                                               address, value, reg->bit_width);
  237.                 if (ACPI_FAILURE(status)) {
  238.                         return (status);
  239.                 }
  240.         } else {                /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
  241.  
  242.                 width = reg->bit_width;
  243.                 if (width == 64) {
  244.                         width = 32;     /* Break into two 32-bit transfers */
  245.                 }
  246.  
  247.                 status = acpi_hw_write_port((acpi_io_address)
  248.                                             address, ACPI_LODWORD(value),
  249.                                             width);
  250.                 if (ACPI_FAILURE(status)) {
  251.                         return (status);
  252.                 }
  253.  
  254.                 if (reg->bit_width == 64) {
  255.                         status = acpi_hw_write_port((acpi_io_address)
  256.                                                     (address + 4),
  257.                                                     ACPI_HIDWORD(value), 32);
  258.                         if (ACPI_FAILURE(status)) {
  259.                                 return (status);
  260.                         }
  261.                 }
  262.         }
  263.  
  264.         ACPI_DEBUG_PRINT((ACPI_DB_IO,
  265.                           "Wrote: %8.8X%8.8X width %2d   to %8.8X%8.8X (%s)\n",
  266.                           ACPI_FORMAT_UINT64(value), reg->bit_width,
  267.                           ACPI_FORMAT_UINT64(address),
  268.                           acpi_ut_get_region_name(reg->space_id)));
  269.  
  270.         return (status);
  271. }
  272.  
  273. ACPI_EXPORT_SYMBOL(acpi_write)
  274.  
  275. #if (!ACPI_REDUCED_HARDWARE)
  276. /*******************************************************************************
  277.  *
  278.  * FUNCTION:    acpi_read_bit_register
  279.  *
  280.  * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
  281.  *              return_value    - Value that was read from the register,
  282.  *                                normalized to bit position zero.
  283.  *
  284.  * RETURN:      Status and the value read from the specified Register. Value
  285.  *              returned is normalized to bit0 (is shifted all the way right)
  286.  *
  287.  * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
  288.  *
  289.  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
  290.  *              PM2 Control.
  291.  *
  292.  * Note: The hardware lock is not required when reading the ACPI bit registers
  293.  *       since almost all of them are single bit and it does not matter that
  294.  *       the parent hardware register can be split across two physical
  295.  *       registers. The only multi-bit field is SLP_TYP in the PM1 control
  296.  *       register, but this field does not cross an 8-bit boundary (nor does
  297.  *       it make much sense to actually read this field.)
  298.  *
  299.  ******************************************************************************/
  300. acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
  301. {
  302.         struct acpi_bit_register_info *bit_reg_info;
  303.         u32 register_value;
  304.         u32 value;
  305.         acpi_status status;
  306.  
  307.         ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
  308.  
  309.         /* Get the info structure corresponding to the requested ACPI Register */
  310.  
  311.         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
  312.         if (!bit_reg_info) {
  313.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  314.         }
  315.  
  316.         /* Read the entire parent register */
  317.  
  318.         status = acpi_hw_register_read(bit_reg_info->parent_register,
  319.                                        &register_value);
  320.         if (ACPI_FAILURE(status)) {
  321.                 return_ACPI_STATUS(status);
  322.         }
  323.  
  324.         /* Normalize the value that was read, mask off other bits */
  325.  
  326.         value = ((register_value & bit_reg_info->access_bit_mask)
  327.                  >> bit_reg_info->bit_position);
  328.  
  329.         ACPI_DEBUG_PRINT((ACPI_DB_IO,
  330.                           "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
  331.                           register_id, bit_reg_info->parent_register,
  332.                           register_value, value));
  333.  
  334.         *return_value = value;
  335.         return_ACPI_STATUS(AE_OK);
  336. }
  337.  
  338. ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
  339.  
  340. /*******************************************************************************
  341.  *
  342.  * FUNCTION:    acpi_write_bit_register
  343.  *
  344.  * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
  345.  *              value           - Value to write to the register, in bit
  346.  *                                position zero. The bit is automatically
  347.  *                                shifted to the correct position.
  348.  *
  349.  * RETURN:      Status
  350.  *
  351.  * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
  352.  *              since most operations require a read/modify/write sequence.
  353.  *
  354.  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
  355.  *              PM2 Control.
  356.  *
  357.  * Note that at this level, the fact that there may be actually two
  358.  * hardware registers (A and B - and B may not exist) is abstracted.
  359.  *
  360.  ******************************************************************************/
  361. acpi_status acpi_write_bit_register(u32 register_id, u32 value)
  362. {
  363.         struct acpi_bit_register_info *bit_reg_info;
  364.         acpi_cpu_flags lock_flags;
  365.         u32 register_value;
  366.         acpi_status status = AE_OK;
  367.  
  368.         ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
  369.  
  370.         /* Get the info structure corresponding to the requested ACPI Register */
  371.  
  372.         bit_reg_info = acpi_hw_get_bit_register_info(register_id);
  373.         if (!bit_reg_info) {
  374.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  375.         }
  376.  
  377.         lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
  378.  
  379.         /*
  380.          * At this point, we know that the parent register is one of the
  381.          * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
  382.          */
  383.         if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
  384.                 /*
  385.                  * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
  386.                  *
  387.                  * Perform a register read to preserve the bits that we are not
  388.                  * interested in
  389.                  */
  390.                 status = acpi_hw_register_read(bit_reg_info->parent_register,
  391.                                                &register_value);
  392.                 if (ACPI_FAILURE(status)) {
  393.                         goto unlock_and_exit;
  394.                 }
  395.  
  396.                 /*
  397.                  * Insert the input bit into the value that was just read
  398.                  * and write the register
  399.                  */
  400.                 ACPI_REGISTER_INSERT_VALUE(register_value,
  401.                                            bit_reg_info->bit_position,
  402.                                            bit_reg_info->access_bit_mask,
  403.                                            value);
  404.  
  405.                 status = acpi_hw_register_write(bit_reg_info->parent_register,
  406.                                                 register_value);
  407.         } else {
  408.                 /*
  409.                  * 2) Case for PM1 Status
  410.                  *
  411.                  * The Status register is different from the rest. Clear an event
  412.                  * by writing 1, writing 0 has no effect. So, the only relevant
  413.                  * information is the single bit we're interested in, all others
  414.                  * should be written as 0 so they will be left unchanged.
  415.                  */
  416.                 register_value = ACPI_REGISTER_PREPARE_BITS(value,
  417.                                                             bit_reg_info->
  418.                                                             bit_position,
  419.                                                             bit_reg_info->
  420.                                                             access_bit_mask);
  421.  
  422.                 /* No need to write the register if value is all zeros */
  423.  
  424.                 if (register_value) {
  425.                         status =
  426.                             acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
  427.                                                    register_value);
  428.                 }
  429.         }
  430.  
  431.         ACPI_DEBUG_PRINT((ACPI_DB_IO,
  432.                           "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
  433.                           register_id, bit_reg_info->parent_register, value,
  434.                           register_value));
  435.  
  436. unlock_and_exit:
  437.  
  438.         acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
  439.         return_ACPI_STATUS(status);
  440. }
  441.  
  442. ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
  443. #endif                          /* !ACPI_REDUCED_HARDWARE */
  444. /*******************************************************************************
  445.  *
  446.  * FUNCTION:    acpi_get_sleep_type_data
  447.  *
  448.  * PARAMETERS:  sleep_state         - Numeric sleep state
  449.  *              *sleep_type_a        - Where SLP_TYPa is returned
  450.  *              *sleep_type_b        - Where SLP_TYPb is returned
  451.  *
  452.  * RETURN:      Status
  453.  *
  454.  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
  455.  *              sleep state via the appropriate \_Sx object.
  456.  *
  457.  *  The sleep state package returned from the corresponding \_Sx_ object
  458.  *  must contain at least one integer.
  459.  *
  460.  *  March 2005:
  461.  *  Added support for a package that contains two integers. This
  462.  *  goes against the ACPI specification which defines this object as a
  463.  *  package with one encoded DWORD integer. However, existing practice
  464.  *  by many BIOS vendors is to return a package with 2 or more integer
  465.  *  elements, at least one per sleep type (A/B).
  466.  *
  467.  *  January 2013:
  468.  *  Therefore, we must be prepared to accept a package with either a
  469.  *  single integer or multiple integers.
  470.  *
  471.  *  The single integer DWORD format is as follows:
  472.  *      BYTE 0 - Value for the PM1A SLP_TYP register
  473.  *      BYTE 1 - Value for the PM1B SLP_TYP register
  474.  *      BYTE 2-3 - Reserved
  475.  *
  476.  *  The dual integer format is as follows:
  477.  *      Integer 0 - Value for the PM1A SLP_TYP register
  478.  *      Integer 1 - Value for the PM1A SLP_TYP register
  479.  *
  480.  ******************************************************************************/
  481. acpi_status
  482. acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
  483. {
  484.         acpi_status status;
  485.         struct acpi_evaluate_info *info;
  486.         union acpi_operand_object **elements;
  487.  
  488.         ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
  489.  
  490.         /* Validate parameters */
  491.  
  492.         if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
  493.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  494.         }
  495.  
  496.         /* Allocate the evaluation information block */
  497.  
  498.         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
  499.         if (!info) {
  500.                 return_ACPI_STATUS(AE_NO_MEMORY);
  501.         }
  502.  
  503.         /*
  504.          * Evaluate the \_Sx namespace object containing the register values
  505.          * for this state
  506.          */
  507.         info->relative_pathname =
  508.             ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
  509.         status = acpi_ns_evaluate(info);
  510.         if (ACPI_FAILURE(status)) {
  511.                 goto cleanup;
  512.         }
  513.  
  514.         /* Must have a return object */
  515.  
  516.         if (!info->return_object) {
  517.                 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
  518.                             info->relative_pathname));
  519.                 status = AE_AML_NO_RETURN_VALUE;
  520.                 goto cleanup;
  521.         }
  522.  
  523.         /* Return object must be of type Package */
  524.  
  525.         if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
  526.                 ACPI_ERROR((AE_INFO,
  527.                             "Sleep State return object is not a Package"));
  528.                 status = AE_AML_OPERAND_TYPE;
  529.                 goto cleanup1;
  530.         }
  531.  
  532.         /*
  533.          * Any warnings about the package length or the object types have
  534.          * already been issued by the predefined name module -- there is no
  535.          * need to repeat them here.
  536.          */
  537.         elements = info->return_object->package.elements;
  538.         switch (info->return_object->package.count) {
  539.         case 0:
  540.  
  541.                 status = AE_AML_PACKAGE_LIMIT;
  542.                 break;
  543.  
  544.         case 1:
  545.  
  546.                 if (elements[0]->common.type != ACPI_TYPE_INTEGER) {
  547.                         status = AE_AML_OPERAND_TYPE;
  548.                         break;
  549.                 }
  550.  
  551.                 /* A valid _Sx_ package with one integer */
  552.  
  553.                 *sleep_type_a = (u8)elements[0]->integer.value;
  554.                 *sleep_type_b = (u8)(elements[0]->integer.value >> 8);
  555.                 break;
  556.  
  557.         case 2:
  558.         default:
  559.  
  560.                 if ((elements[0]->common.type != ACPI_TYPE_INTEGER) ||
  561.                     (elements[1]->common.type != ACPI_TYPE_INTEGER)) {
  562.                         status = AE_AML_OPERAND_TYPE;
  563.                         break;
  564.                 }
  565.  
  566.                 /* A valid _Sx_ package with two integers */
  567.  
  568.                 *sleep_type_a = (u8)elements[0]->integer.value;
  569.                 *sleep_type_b = (u8)elements[1]->integer.value;
  570.                 break;
  571.         }
  572.  
  573. cleanup1:
  574.         acpi_ut_remove_reference(info->return_object);
  575.  
  576. cleanup:
  577.         if (ACPI_FAILURE(status)) {
  578.                 ACPI_EXCEPTION((AE_INFO, status,
  579.                                 "While evaluating Sleep State [%s]",
  580.                                 info->relative_pathname));
  581.         }
  582.  
  583.         ACPI_FREE(info);
  584.         return_ACPI_STATUS(status);
  585. }
  586.  
  587. ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data)
  588.