Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: tbxface - ACPI table-oriented external 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 "actables.h"
  49.  
  50. #define _COMPONENT          ACPI_TABLES
  51. ACPI_MODULE_NAME("tbxface")
  52.  
  53. /*******************************************************************************
  54.  *
  55.  * FUNCTION:    acpi_allocate_root_table
  56.  *
  57.  * PARAMETERS:  initial_table_count - Size of initial_table_array, in number of
  58.  *                                    struct acpi_table_desc structures
  59.  *
  60.  * RETURN:      Status
  61.  *
  62.  * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
  63.  *              acpi_initialize_tables.
  64.  *
  65.  ******************************************************************************/
  66. acpi_status acpi_allocate_root_table(u32 initial_table_count)
  67. {
  68.  
  69.         acpi_gbl_root_table_list.max_table_count = initial_table_count;
  70.         acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
  71.  
  72.         return (acpi_tb_resize_root_table_list());
  73. }
  74.  
  75. /*******************************************************************************
  76.  *
  77.  * FUNCTION:    acpi_initialize_tables
  78.  *
  79.  * PARAMETERS:  initial_table_array - Pointer to an array of pre-allocated
  80.  *                                    struct acpi_table_desc structures. If NULL, the
  81.  *                                    array is dynamically allocated.
  82.  *              initial_table_count - Size of initial_table_array, in number of
  83.  *                                    struct acpi_table_desc structures
  84.  *              allow_resize        - Flag to tell Table Manager if resize of
  85.  *                                    pre-allocated array is allowed. Ignored
  86.  *                                    if initial_table_array is NULL.
  87.  *
  88.  * RETURN:      Status
  89.  *
  90.  * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
  91.  *
  92.  * NOTE:        Allows static allocation of the initial table array in order
  93.  *              to avoid the use of dynamic memory in confined environments
  94.  *              such as the kernel boot sequence where it may not be available.
  95.  *
  96.  *              If the host OS memory managers are initialized, use NULL for
  97.  *              initial_table_array, and the table will be dynamically allocated.
  98.  *
  99.  ******************************************************************************/
  100.  
  101. acpi_status __init
  102. acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
  103.                        u32 initial_table_count, u8 allow_resize)
  104. {
  105.         acpi_physical_address rsdp_address;
  106.         acpi_status status;
  107.  
  108.         ACPI_FUNCTION_TRACE(acpi_initialize_tables);
  109.  
  110.         /*
  111.          * Setup the Root Table Array and allocate the table array
  112.          * if requested
  113.          */
  114.         if (!initial_table_array) {
  115.                 status = acpi_allocate_root_table(initial_table_count);
  116.                 if (ACPI_FAILURE(status)) {
  117.                         return_ACPI_STATUS(status);
  118.                 }
  119.         } else {
  120.                 /* Root Table Array has been statically allocated by the host */
  121.  
  122.                 memset(initial_table_array, 0,
  123.                        (acpi_size) initial_table_count *
  124.                        sizeof(struct acpi_table_desc));
  125.  
  126.                 acpi_gbl_root_table_list.tables = initial_table_array;
  127.                 acpi_gbl_root_table_list.max_table_count = initial_table_count;
  128.                 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
  129.                 if (allow_resize) {
  130.                         acpi_gbl_root_table_list.flags |=
  131.                             ACPI_ROOT_ALLOW_RESIZE;
  132.                 }
  133.         }
  134.  
  135.         /* Get the address of the RSDP */
  136.  
  137.         rsdp_address = acpi_os_get_root_pointer();
  138.         if (!rsdp_address) {
  139.                 return_ACPI_STATUS(AE_NOT_FOUND);
  140.         }
  141.  
  142.         /*
  143.          * Get the root table (RSDT or XSDT) and extract all entries to the local
  144.          * Root Table Array. This array contains the information of the RSDT/XSDT
  145.          * in a common, more useable format.
  146.          */
  147.    status = acpi_tb_parse_root_table(rsdp_address);
  148.         return_ACPI_STATUS(status);
  149. }
  150.  
  151. ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
  152.  
  153. /*******************************************************************************
  154.  *
  155.  * FUNCTION:    acpi_reallocate_root_table
  156.  *
  157.  * PARAMETERS:  None
  158.  *
  159.  * RETURN:      Status
  160.  *
  161.  * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
  162.  *              root list from the previously provided scratch area. Should
  163.  *              be called once dynamic memory allocation is available in the
  164.  *              kernel.
  165.  *
  166.  ******************************************************************************/
  167. acpi_status __init acpi_reallocate_root_table(void)
  168. {
  169.         acpi_status status;
  170.  
  171.         ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
  172.  
  173.         /*
  174.          * Only reallocate the root table if the host provided a static buffer
  175.          * for the table array in the call to acpi_initialize_tables.
  176.          */
  177.         if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
  178.                 return_ACPI_STATUS(AE_SUPPORT);
  179.         }
  180.  
  181.         acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
  182.  
  183.         status = acpi_tb_resize_root_table_list();
  184.         return_ACPI_STATUS(status);
  185. }
  186.  
  187. ACPI_EXPORT_SYMBOL_INIT(acpi_reallocate_root_table)
  188.  
  189. /*******************************************************************************
  190.  *
  191.  * FUNCTION:    acpi_get_table_header
  192.  *
  193.  * PARAMETERS:  signature           - ACPI signature of needed table
  194.  *              instance            - Which instance (for SSDTs)
  195.  *              out_table_header    - The pointer to the table header to fill
  196.  *
  197.  * RETURN:      Status and pointer to mapped table header
  198.  *
  199.  * DESCRIPTION: Finds an ACPI table header.
  200.  *
  201.  * NOTE:        Caller is responsible in unmapping the header with
  202.  *              acpi_os_unmap_memory
  203.  *
  204.  ******************************************************************************/
  205. acpi_status
  206. acpi_get_table_header(char *signature,
  207.                       u32 instance, struct acpi_table_header *out_table_header)
  208. {
  209.         u32 i;
  210.         u32 j;
  211.         struct acpi_table_header *header;
  212.  
  213.         /* Parameter validation */
  214.  
  215.         if (!signature || !out_table_header) {
  216.                 return (AE_BAD_PARAMETER);
  217.         }
  218.  
  219.         /* Walk the root table list */
  220.  
  221.         for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
  222.              i++) {
  223.                 if (!ACPI_COMPARE_NAME
  224.                     (&(acpi_gbl_root_table_list.tables[i].signature),
  225.                      signature)) {
  226.                         continue;
  227.                 }
  228.  
  229.                 if (++j < instance) {
  230.                         continue;
  231.                 }
  232.  
  233.                 if (!acpi_gbl_root_table_list.tables[i].pointer) {
  234.                         if ((acpi_gbl_root_table_list.tables[i].flags &
  235.                              ACPI_TABLE_ORIGIN_MASK) ==
  236.                             ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) {
  237.                                 header =
  238.                                     acpi_os_map_memory(acpi_gbl_root_table_list.
  239.                                                        tables[i].address,
  240.                                                        sizeof(struct
  241.                                                               acpi_table_header));
  242.                                 if (!header) {
  243.                                         return (AE_NO_MEMORY);
  244.                                 }
  245.  
  246.                                 memcpy(out_table_header, header,
  247.                                        sizeof(struct acpi_table_header));
  248.                                 acpi_os_unmap_memory(header,
  249.                                                      sizeof(struct
  250.                                                             acpi_table_header));
  251.                         } else {
  252.                                 return (AE_NOT_FOUND);
  253.                         }
  254.                 } else {
  255.                         memcpy(out_table_header,
  256.                                acpi_gbl_root_table_list.tables[i].pointer,
  257.                                sizeof(struct acpi_table_header));
  258.                 }
  259.                 return (AE_OK);
  260.         }
  261.  
  262.         return (AE_NOT_FOUND);
  263. }
  264.  
  265. ACPI_EXPORT_SYMBOL(acpi_get_table_header)
  266.  
  267. /*******************************************************************************
  268.  *
  269.  * FUNCTION:    acpi_get_table_with_size
  270.  *
  271.  * PARAMETERS:  signature           - ACPI signature of needed table
  272.  *              instance            - Which instance (for SSDTs)
  273.  *              out_table           - Where the pointer to the table is returned
  274.  *
  275.  * RETURN:      Status and pointer to the requested table
  276.  *
  277.  * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
  278.  *              RSDT/XSDT.
  279.  *
  280.  ******************************************************************************/
  281. acpi_status
  282. acpi_get_table_with_size(char *signature,
  283.                u32 instance, struct acpi_table_header **out_table,
  284.                acpi_size *tbl_size)
  285. {
  286.         u32 i;
  287.         u32 j;
  288.         acpi_status status;
  289.  
  290.         /* Parameter validation */
  291.  
  292.         if (!signature || !out_table) {
  293.                 return (AE_BAD_PARAMETER);
  294.         }
  295.  
  296.         /* Walk the root table list */
  297.  
  298.         for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
  299.              i++) {
  300.                 if (!ACPI_COMPARE_NAME
  301.                     (&(acpi_gbl_root_table_list.tables[i].signature),
  302.                      signature)) {
  303.                         continue;
  304.                 }
  305.  
  306.                 if (++j < instance) {
  307.                         continue;
  308.                 }
  309.  
  310.                 status =
  311.                     acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]);
  312.                 if (ACPI_SUCCESS(status)) {
  313.                         *out_table = acpi_gbl_root_table_list.tables[i].pointer;
  314.                         *tbl_size = acpi_gbl_root_table_list.tables[i].length;
  315.                 }
  316.  
  317.                 if (!acpi_gbl_permanent_mmap) {
  318.                         acpi_gbl_root_table_list.tables[i].pointer = NULL;
  319.                 }
  320.  
  321.                 return (status);
  322.         }
  323.  
  324.         return (AE_NOT_FOUND);
  325. }
  326.  
  327. ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
  328.  
  329. acpi_status
  330. acpi_get_table(char *signature,
  331.                u32 instance, struct acpi_table_header **out_table)
  332. {
  333.         acpi_size tbl_size;
  334.  
  335.         return acpi_get_table_with_size(signature,
  336.                        instance, out_table, &tbl_size);
  337. }
  338.  
  339. ACPI_EXPORT_SYMBOL(acpi_get_table)
  340.  
  341. /*******************************************************************************
  342.  *
  343.  * FUNCTION:    acpi_get_table_by_index
  344.  *
  345.  * PARAMETERS:  table_index         - Table index
  346.  *              table               - Where the pointer to the table is returned
  347.  *
  348.  * RETURN:      Status and pointer to the requested table
  349.  *
  350.  * DESCRIPTION: Obtain a table by an index into the global table list. Used
  351.  *              internally also.
  352.  *
  353.  ******************************************************************************/
  354. acpi_status
  355. acpi_get_table_by_index(u32 table_index, struct acpi_table_header ** table)
  356. {
  357.         acpi_status status;
  358.  
  359.         ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
  360.  
  361.         /* Parameter validation */
  362.  
  363.         if (!table) {
  364.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  365.         }
  366.  
  367.         (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
  368.  
  369.         /* Validate index */
  370.  
  371.         if (table_index >= acpi_gbl_root_table_list.current_table_count) {
  372.                 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  373.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  374.         }
  375.  
  376.         if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
  377.  
  378.                 /* Table is not mapped, map it */
  379.  
  380.                 status =
  381.                     acpi_tb_validate_table(&acpi_gbl_root_table_list.
  382.                                            tables[table_index]);
  383.                 if (ACPI_FAILURE(status)) {
  384.                         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  385.                         return_ACPI_STATUS(status);
  386.                 }
  387.         }
  388.  
  389.         *table = acpi_gbl_root_table_list.tables[table_index].pointer;
  390.         (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  391.         return_ACPI_STATUS(AE_OK);
  392. }
  393.  
  394. ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
  395.  
  396. /*******************************************************************************
  397.  *
  398.  * FUNCTION:    acpi_install_table_handler
  399.  *
  400.  * PARAMETERS:  handler         - Table event handler
  401.  *              context         - Value passed to the handler on each event
  402.  *
  403.  * RETURN:      Status
  404.  *
  405.  * DESCRIPTION: Install a global table event handler.
  406.  *
  407.  ******************************************************************************/
  408. acpi_status
  409. acpi_install_table_handler(acpi_table_handler handler, void *context)
  410. {
  411.         acpi_status status;
  412.  
  413.         ACPI_FUNCTION_TRACE(acpi_install_table_handler);
  414.  
  415.         if (!handler) {
  416.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  417.         }
  418.  
  419.         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  420.         if (ACPI_FAILURE(status)) {
  421.                 return_ACPI_STATUS(status);
  422.         }
  423.  
  424.         /* Don't allow more than one handler */
  425.  
  426.         if (acpi_gbl_table_handler) {
  427.                 status = AE_ALREADY_EXISTS;
  428.                 goto cleanup;
  429.         }
  430.  
  431.         /* Install the handler */
  432.  
  433.         acpi_gbl_table_handler = handler;
  434.         acpi_gbl_table_handler_context = context;
  435.  
  436. cleanup:
  437.         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  438.         return_ACPI_STATUS(status);
  439. }
  440.  
  441. ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
  442.  
  443. /*******************************************************************************
  444.  *
  445.  * FUNCTION:    acpi_remove_table_handler
  446.  *
  447.  * PARAMETERS:  handler         - Table event handler that was installed
  448.  *                                previously.
  449.  *
  450.  * RETURN:      Status
  451.  *
  452.  * DESCRIPTION: Remove a table event handler
  453.  *
  454.  ******************************************************************************/
  455. acpi_status acpi_remove_table_handler(acpi_table_handler handler)
  456. {
  457.         acpi_status status;
  458.  
  459.         ACPI_FUNCTION_TRACE(acpi_remove_table_handler);
  460.  
  461.         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  462.         if (ACPI_FAILURE(status)) {
  463.                 return_ACPI_STATUS(status);
  464.         }
  465.  
  466.         /* Make sure that the installed handler is the same */
  467.  
  468.         if (!handler || handler != acpi_gbl_table_handler) {
  469.                 status = AE_BAD_PARAMETER;
  470.                 goto cleanup;
  471.         }
  472.  
  473.         /* Remove the handler */
  474.  
  475.         acpi_gbl_table_handler = NULL;
  476.  
  477. cleanup:
  478.         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  479.         return_ACPI_STATUS(status);
  480. }
  481.  
  482. ACPI_EXPORT_SYMBOL(acpi_remove_table_handler)
  483.