Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: tbinstal - ACPI table installation and removal
  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. #include <acpi/acpi.h>
  45. #include "accommon.h"
  46. #include "actables.h"
  47.  
  48. #define _COMPONENT          ACPI_TABLES
  49. ACPI_MODULE_NAME("tbinstal")
  50.  
  51. /* Local prototypes */
  52. static u8
  53. acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
  54.  
  55. /*******************************************************************************
  56.  *
  57.  * FUNCTION:    acpi_tb_compare_tables
  58.  *
  59.  * PARAMETERS:  table_desc          - Table 1 descriptor to be compared
  60.  *              table_index         - Index of table 2 to be compared
  61.  *
  62.  * RETURN:      TRUE if both tables are identical.
  63.  *
  64.  * DESCRIPTION: This function compares a table with another table that has
  65.  *              already been installed in the root table list.
  66.  *
  67.  ******************************************************************************/
  68.  
  69. static u8
  70. acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
  71. {
  72.         acpi_status status = AE_OK;
  73.         u8 is_identical;
  74.         struct acpi_table_header *table;
  75.         u32 table_length;
  76.         u8 table_flags;
  77.  
  78.         status =
  79.             acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
  80.                                   &table, &table_length, &table_flags);
  81.         if (ACPI_FAILURE(status)) {
  82.                 return (FALSE);
  83.         }
  84.  
  85.         /*
  86.          * Check for a table match on the entire table length,
  87.          * not just the header.
  88.          */
  89.         is_identical = (u8)((table_desc->length != table_length ||
  90.                              memcmp(table_desc->pointer, table, table_length)) ?
  91.                             FALSE : TRUE);
  92.  
  93.         /* Release the acquired table */
  94.  
  95.         acpi_tb_release_table(table, table_length, table_flags);
  96.         return (is_identical);
  97. }
  98.  
  99. /*******************************************************************************
  100.  *
  101.  * FUNCTION:    acpi_tb_install_table_with_override
  102.  *
  103.  * PARAMETERS:  new_table_desc          - New table descriptor to install
  104.  *              override                - Whether override should be performed
  105.  *              table_index             - Where the table index is returned
  106.  *
  107.  * RETURN:      None
  108.  *
  109.  * DESCRIPTION: Install an ACPI table into the global data structure. The
  110.  *              table override mechanism is called to allow the host
  111.  *              OS to replace any table before it is installed in the root
  112.  *              table array.
  113.  *
  114.  ******************************************************************************/
  115.  
  116. void
  117. acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc,
  118.                                     u8 override, u32 *table_index)
  119. {
  120.         u32 i;
  121.         acpi_status status;
  122.  
  123.         status = acpi_tb_get_next_table_descriptor(&i, NULL);
  124.         if (ACPI_FAILURE(status)) {
  125.                 return;
  126.         }
  127.  
  128.         /*
  129.          * ACPI Table Override:
  130.          *
  131.          * Before we install the table, let the host OS override it with a new
  132.          * one if desired. Any table within the RSDT/XSDT can be replaced,
  133.          * including the DSDT which is pointed to by the FADT.
  134.          */
  135.         if (override) {
  136.                 acpi_tb_override_table(new_table_desc);
  137.         }
  138.  
  139.         acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i],
  140.                                       new_table_desc->address,
  141.                                       new_table_desc->flags,
  142.                                       new_table_desc->pointer);
  143.  
  144.         acpi_tb_print_table_header(new_table_desc->address,
  145.                                    new_table_desc->pointer);
  146.  
  147.         /* This synchronizes acpi_gbl_dsdt_index */
  148.  
  149.         *table_index = i;
  150.  
  151.         /* Set the global integer width (based upon revision of the DSDT) */
  152.  
  153.         if (i == acpi_gbl_dsdt_index) {
  154.                 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
  155.         }
  156. }
  157.  
  158. /*******************************************************************************
  159.  *
  160.  * FUNCTION:    acpi_tb_install_fixed_table
  161.  *
  162.  * PARAMETERS:  address                 - Physical address of DSDT or FACS
  163.  *              signature               - Table signature, NULL if no need to
  164.  *                                        match
  165.  *              table_index             - Where the table index is returned
  166.  *
  167.  * RETURN:      Status
  168.  *
  169.  * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
  170.  *              structure.
  171.  *
  172.  ******************************************************************************/
  173.  
  174. acpi_status
  175. acpi_tb_install_fixed_table(acpi_physical_address address,
  176.                             char *signature, u32 *table_index)
  177. {
  178.         struct acpi_table_desc new_table_desc;
  179.         acpi_status status;
  180.  
  181.         ACPI_FUNCTION_TRACE(tb_install_fixed_table);
  182.  
  183.         if (!address) {
  184.                 ACPI_ERROR((AE_INFO,
  185.                             "Null physical address for ACPI table [%s]",
  186.                             signature));
  187.                 return (AE_NO_MEMORY);
  188.         }
  189.  
  190.         /* Fill a table descriptor for validation */
  191.  
  192.         status = acpi_tb_acquire_temp_table(&new_table_desc, address,
  193.                                             ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
  194.         if (ACPI_FAILURE(status)) {
  195.                 ACPI_ERROR((AE_INFO,
  196.                             "Could not acquire table length at %8.8X%8.8X",
  197.                             ACPI_FORMAT_UINT64(address)));
  198.                 return_ACPI_STATUS(status);
  199.         }
  200.  
  201.         /* Validate and verify a table before installation */
  202.  
  203.         status = acpi_tb_verify_temp_table(&new_table_desc, signature);
  204.         if (ACPI_FAILURE(status)) {
  205.                 goto release_and_exit;
  206.         }
  207.  
  208.         /* Add the table to the global root table list */
  209.  
  210.         acpi_tb_install_table_with_override(&new_table_desc, TRUE, table_index);
  211.  
  212. release_and_exit:
  213.  
  214.         /* Release the temporary table descriptor */
  215.  
  216.         acpi_tb_release_temp_table(&new_table_desc);
  217.         return_ACPI_STATUS(status);
  218. }
  219.  
  220. /*******************************************************************************
  221.  *
  222.  * FUNCTION:    acpi_tb_install_standard_table
  223.  *
  224.  * PARAMETERS:  address             - Address of the table (might be a virtual
  225.  *                                    address depending on the table_flags)
  226.  *              flags               - Flags for the table
  227.  *              reload              - Whether reload should be performed
  228.  *              override            - Whether override should be performed
  229.  *              table_index         - Where the table index is returned
  230.  *
  231.  * RETURN:      Status
  232.  *
  233.  * DESCRIPTION: This function is called to install an ACPI table that is
  234.  *              neither DSDT nor FACS (a "standard" table.)
  235.  *              When this function is called by "Load" or "LoadTable" opcodes,
  236.  *              or by acpi_load_table() API, the "Reload" parameter is set.
  237.  *              After sucessfully returning from this function, table is
  238.  *              "INSTALLED" but not "VALIDATED".
  239.  *
  240.  ******************************************************************************/
  241.  
  242. acpi_status
  243. acpi_tb_install_standard_table(acpi_physical_address address,
  244.                                u8 flags,
  245.                                u8 reload, u8 override, u32 *table_index)
  246. {
  247.         u32 i;
  248.         acpi_status status = AE_OK;
  249.         struct acpi_table_desc new_table_desc;
  250.  
  251.         ACPI_FUNCTION_TRACE(tb_install_standard_table);
  252.  
  253.         /* Acquire a temporary table descriptor for validation */
  254.  
  255.         status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags);
  256.         if (ACPI_FAILURE(status)) {
  257.                 ACPI_ERROR((AE_INFO,
  258.                             "Could not acquire table length at %8.8X%8.8X",
  259.                             ACPI_FORMAT_UINT64(address)));
  260.                 return_ACPI_STATUS(status);
  261.         }
  262.  
  263.         /*
  264.          * Optionally do not load any SSDTs from the RSDT/XSDT. This can
  265.          * be useful for debugging ACPI problems on some machines.
  266.          */
  267.         if (!reload &&
  268.             acpi_gbl_disable_ssdt_table_install &&
  269.             ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
  270.                 ACPI_INFO((AE_INFO,
  271.                            "Ignoring installation of %4.4s at %8.8X%8.8X",
  272.                            new_table_desc.signature.ascii,
  273.                            ACPI_FORMAT_UINT64(address)));
  274.                 goto release_and_exit;
  275.         }
  276.  
  277.         /* Validate and verify a table before installation */
  278.  
  279.         status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
  280.         if (ACPI_FAILURE(status)) {
  281.                 goto release_and_exit;
  282.         }
  283.  
  284.         if (reload) {
  285.                 /*
  286.                  * Validate the incoming table signature.
  287.                  *
  288.                  * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
  289.                  * 2) We added support for OEMx tables, signature "OEM".
  290.                  * 3) Valid tables were encountered with a null signature, so we just
  291.                  *    gave up on validating the signature, (05/2008).
  292.                  * 4) We encountered non-AML tables such as the MADT, which caused
  293.                  *    interpreter errors and kernel faults. So now, we once again allow
  294.                  *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
  295.                  */
  296.                 if ((new_table_desc.signature.ascii[0] != 0x00) &&
  297.                     (!ACPI_COMPARE_NAME
  298.                      (&new_table_desc.signature, ACPI_SIG_SSDT))
  299.                     && (strncmp(new_table_desc.signature.ascii, "OEM", 3))) {
  300.                         ACPI_BIOS_ERROR((AE_INFO,
  301.                                          "Table has invalid signature [%4.4s] (0x%8.8X), "
  302.                                          "must be SSDT or OEMx",
  303.                                          acpi_ut_valid_acpi_name(new_table_desc.
  304.                                                                  signature.
  305.                                                                  ascii) ?
  306.                                          new_table_desc.signature.
  307.                                          ascii : "????",
  308.                                          new_table_desc.signature.integer));
  309.  
  310.                         status = AE_BAD_SIGNATURE;
  311.                         goto release_and_exit;
  312.                 }
  313.  
  314.                 /* Check if table is already registered */
  315.  
  316.                 for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
  317.                      ++i) {
  318.                         /*
  319.                          * Check for a table match on the entire table length,
  320.                          * not just the header.
  321.                          */
  322.                         if (!acpi_tb_compare_tables(&new_table_desc, i)) {
  323.                                 continue;
  324.                         }
  325.  
  326.                         /*
  327.                          * Note: the current mechanism does not unregister a table if it is
  328.                          * dynamically unloaded. The related namespace entries are deleted,
  329.                          * but the table remains in the root table list.
  330.                          *
  331.                          * The assumption here is that the number of different tables that
  332.                          * will be loaded is actually small, and there is minimal overhead
  333.                          * in just keeping the table in case it is needed again.
  334.                          *
  335.                          * If this assumption changes in the future (perhaps on large
  336.                          * machines with many table load/unload operations), tables will
  337.                          * need to be unregistered when they are unloaded, and slots in the
  338.                          * root table list should be reused when empty.
  339.                          */
  340.                         if (acpi_gbl_root_table_list.tables[i].
  341.                             flags & ACPI_TABLE_IS_LOADED) {
  342.  
  343.                                 /* Table is still loaded, this is an error */
  344.  
  345.                                 status = AE_ALREADY_EXISTS;
  346.                                 goto release_and_exit;
  347.                         } else {
  348.                                 /*
  349.                                  * Table was unloaded, allow it to be reloaded.
  350.                                  * As we are going to return AE_OK to the caller, we should
  351.                                  * take the responsibility of freeing the input descriptor.
  352.                                  * Refill the input descriptor to ensure
  353.                                  * acpi_tb_install_table_with_override() can be called again to
  354.                                  * indicate the re-installation.
  355.                                  */
  356.                                 acpi_tb_uninstall_table(&new_table_desc);
  357.                                 *table_index = i;
  358.                                 return_ACPI_STATUS(AE_OK);
  359.                         }
  360.                 }
  361.         }
  362.  
  363.         /* Add the table to the global root table list */
  364.  
  365.         acpi_tb_install_table_with_override(&new_table_desc, override,
  366.                                             table_index);
  367.  
  368. release_and_exit:
  369.  
  370.         /* Release the temporary table descriptor */
  371.  
  372.         acpi_tb_release_temp_table(&new_table_desc);
  373.         return_ACPI_STATUS(status);
  374. }
  375.  
  376. /*******************************************************************************
  377.  *
  378.  * FUNCTION:    acpi_tb_override_table
  379.  *
  380.  * PARAMETERS:  old_table_desc      - Validated table descriptor to be
  381.  *                                    overridden
  382.  *
  383.  * RETURN:      None
  384.  *
  385.  * DESCRIPTION: Attempt table override by calling the OSL override functions.
  386.  *              Note: If the table is overridden, then the entire new table
  387.  *              is acquired and returned by this function.
  388.  *              Before/after invocation, the table descriptor is in a state
  389.  *              that is "VALIDATED".
  390.  *
  391.  ******************************************************************************/
  392.  
  393. void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
  394. {
  395.         acpi_status status;
  396.         char *override_type;
  397.         struct acpi_table_desc new_table_desc;
  398.         struct acpi_table_header *table;
  399.         acpi_physical_address address;
  400.         u32 length;
  401.  
  402.         /* (1) Attempt logical override (returns a logical address) */
  403.  
  404.         status = acpi_os_table_override(old_table_desc->pointer, &table);
  405.         if (ACPI_SUCCESS(status) && table) {
  406.                 acpi_tb_acquire_temp_table(&new_table_desc,
  407.                                            ACPI_PTR_TO_PHYSADDR(table),
  408.                                            ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL);
  409.                 override_type = "Logical";
  410.                 goto finish_override;
  411.         }
  412.  
  413.         /* (2) Attempt physical override (returns a physical address) */
  414.  
  415.         status = acpi_os_physical_table_override(old_table_desc->pointer,
  416.                                                  &address, &length);
  417.         if (ACPI_SUCCESS(status) && address && length) {
  418.                 acpi_tb_acquire_temp_table(&new_table_desc, address,
  419.                                            ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL);
  420.                 override_type = "Physical";
  421.                 goto finish_override;
  422.         }
  423.  
  424.         return;                 /* There was no override */
  425.  
  426. finish_override:
  427.  
  428.         /* Validate and verify a table before overriding */
  429.  
  430.         status = acpi_tb_verify_temp_table(&new_table_desc, NULL);
  431.         if (ACPI_FAILURE(status)) {
  432.                 return;
  433.         }
  434.  
  435.         ACPI_INFO((AE_INFO, "%4.4s 0x%8.8X%8.8X"
  436.                    " %s table override, new table: 0x%8.8X%8.8X",
  437.                    old_table_desc->signature.ascii,
  438.                    ACPI_FORMAT_UINT64(old_table_desc->address),
  439.                    override_type, ACPI_FORMAT_UINT64(new_table_desc.address)));
  440.  
  441.         /* We can now uninstall the original table */
  442.  
  443.         acpi_tb_uninstall_table(old_table_desc);
  444.  
  445.         /*
  446.          * Replace the original table descriptor and keep its state as
  447.          * "VALIDATED".
  448.          */
  449.         acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address,
  450.                                       new_table_desc.flags,
  451.                                       new_table_desc.pointer);
  452.         acpi_tb_validate_temp_table(old_table_desc);
  453.  
  454.         /* Release the temporary table descriptor */
  455.  
  456.         acpi_tb_release_temp_table(&new_table_desc);
  457. }
  458.  
  459. /*******************************************************************************
  460.  *
  461.  * FUNCTION:    acpi_tb_uninstall_table
  462.  *
  463.  * PARAMETERS:  table_desc          - Table descriptor
  464.  *
  465.  * RETURN:      None
  466.  *
  467.  * DESCRIPTION: Delete one internal ACPI table
  468.  *
  469.  ******************************************************************************/
  470.  
  471. void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
  472. {
  473.  
  474.         ACPI_FUNCTION_TRACE(tb_uninstall_table);
  475.  
  476.         /* Table must be installed */
  477.  
  478.         if (!table_desc->address) {
  479.                 return_VOID;
  480.         }
  481.  
  482.         acpi_tb_invalidate_table(table_desc);
  483.  
  484.         if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
  485.             ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) {
  486.                 ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address));
  487.         }
  488.  
  489.         table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
  490.         return_VOID;
  491. }
  492.