Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: tbfadt   - FADT table utilities
  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("tbfadt")
  50.  
  51. /* Local prototypes */
  52. static void
  53. acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
  54.                              u8 space_id,
  55.                              u8 byte_width,
  56.                              u64 address, char *register_name, u8 flags);
  57.  
  58. static void acpi_tb_convert_fadt(void);
  59.  
  60. static void acpi_tb_setup_fadt_registers(void);
  61.  
  62. static u64
  63. acpi_tb_select_address(char *register_name, u32 address32, u64 address64);
  64.  
  65. /* Table for conversion of FADT to common internal format and FADT validation */
  66.  
  67. typedef struct acpi_fadt_info {
  68.         char *name;
  69.         u16 address64;
  70.         u16 address32;
  71.         u16 length;
  72.         u8 default_length;
  73.         u8 flags;
  74.  
  75. } acpi_fadt_info;
  76.  
  77. #define ACPI_FADT_OPTIONAL          0
  78. #define ACPI_FADT_REQUIRED          1
  79. #define ACPI_FADT_SEPARATE_LENGTH   2
  80. #define ACPI_FADT_GPE_REGISTER      4
  81.  
  82. static struct acpi_fadt_info fadt_info_table[] = {
  83.         {"Pm1aEventBlock",
  84.          ACPI_FADT_OFFSET(xpm1a_event_block),
  85.          ACPI_FADT_OFFSET(pm1a_event_block),
  86.          ACPI_FADT_OFFSET(pm1_event_length),
  87.          ACPI_PM1_REGISTER_WIDTH * 2,   /* Enable + Status register */
  88.          ACPI_FADT_REQUIRED},
  89.  
  90.         {"Pm1bEventBlock",
  91.          ACPI_FADT_OFFSET(xpm1b_event_block),
  92.          ACPI_FADT_OFFSET(pm1b_event_block),
  93.          ACPI_FADT_OFFSET(pm1_event_length),
  94.          ACPI_PM1_REGISTER_WIDTH * 2,   /* Enable + Status register */
  95.          ACPI_FADT_OPTIONAL},
  96.  
  97.         {"Pm1aControlBlock",
  98.          ACPI_FADT_OFFSET(xpm1a_control_block),
  99.          ACPI_FADT_OFFSET(pm1a_control_block),
  100.          ACPI_FADT_OFFSET(pm1_control_length),
  101.          ACPI_PM1_REGISTER_WIDTH,
  102.          ACPI_FADT_REQUIRED},
  103.  
  104.         {"Pm1bControlBlock",
  105.          ACPI_FADT_OFFSET(xpm1b_control_block),
  106.          ACPI_FADT_OFFSET(pm1b_control_block),
  107.          ACPI_FADT_OFFSET(pm1_control_length),
  108.          ACPI_PM1_REGISTER_WIDTH,
  109.          ACPI_FADT_OPTIONAL},
  110.  
  111.         {"Pm2ControlBlock",
  112.          ACPI_FADT_OFFSET(xpm2_control_block),
  113.          ACPI_FADT_OFFSET(pm2_control_block),
  114.          ACPI_FADT_OFFSET(pm2_control_length),
  115.          ACPI_PM2_REGISTER_WIDTH,
  116.          ACPI_FADT_SEPARATE_LENGTH},
  117.  
  118.         {"PmTimerBlock",
  119.          ACPI_FADT_OFFSET(xpm_timer_block),
  120.          ACPI_FADT_OFFSET(pm_timer_block),
  121.          ACPI_FADT_OFFSET(pm_timer_length),
  122.          ACPI_PM_TIMER_WIDTH,
  123.          ACPI_FADT_SEPARATE_LENGTH},    /* ACPI 5.0A: Timer is optional */
  124.  
  125.         {"Gpe0Block",
  126.          ACPI_FADT_OFFSET(xgpe0_block),
  127.          ACPI_FADT_OFFSET(gpe0_block),
  128.          ACPI_FADT_OFFSET(gpe0_block_length),
  129.          0,
  130.          ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER},
  131.  
  132.         {"Gpe1Block",
  133.          ACPI_FADT_OFFSET(xgpe1_block),
  134.          ACPI_FADT_OFFSET(gpe1_block),
  135.          ACPI_FADT_OFFSET(gpe1_block_length),
  136.          0,
  137.          ACPI_FADT_SEPARATE_LENGTH | ACPI_FADT_GPE_REGISTER}
  138. };
  139.  
  140. #define ACPI_FADT_INFO_ENTRIES \
  141.                         (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
  142.  
  143. /* Table used to split Event Blocks into separate status/enable registers */
  144.  
  145. typedef struct acpi_fadt_pm_info {
  146.         struct acpi_generic_address *target;
  147.         u16 source;
  148.         u8 register_num;
  149.  
  150. } acpi_fadt_pm_info;
  151.  
  152. static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
  153.         {&acpi_gbl_xpm1a_status,
  154.          ACPI_FADT_OFFSET(xpm1a_event_block),
  155.          0},
  156.  
  157.         {&acpi_gbl_xpm1a_enable,
  158.          ACPI_FADT_OFFSET(xpm1a_event_block),
  159.          1},
  160.  
  161.         {&acpi_gbl_xpm1b_status,
  162.          ACPI_FADT_OFFSET(xpm1b_event_block),
  163.          0},
  164.  
  165.         {&acpi_gbl_xpm1b_enable,
  166.          ACPI_FADT_OFFSET(xpm1b_event_block),
  167.          1}
  168. };
  169.  
  170. #define ACPI_FADT_PM_INFO_ENTRIES \
  171.                         (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
  172.  
  173. /*******************************************************************************
  174.  *
  175.  * FUNCTION:    acpi_tb_init_generic_address
  176.  *
  177.  * PARAMETERS:  generic_address     - GAS struct to be initialized
  178.  *              space_id            - ACPI Space ID for this register
  179.  *              byte_width          - Width of this register
  180.  *              address             - Address of the register
  181.  *              register_name       - ASCII name of the ACPI register
  182.  *
  183.  * RETURN:      None
  184.  *
  185.  * DESCRIPTION: Initialize a Generic Address Structure (GAS)
  186.  *              See the ACPI specification for a full description and
  187.  *              definition of this structure.
  188.  *
  189.  ******************************************************************************/
  190.  
  191. static void
  192. acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
  193.                              u8 space_id,
  194.                              u8 byte_width,
  195.                              u64 address, char *register_name, u8 flags)
  196. {
  197.         u8 bit_width;
  198.  
  199.         /*
  200.          * Bit width field in the GAS is only one byte long, 255 max.
  201.          * Check for bit_width overflow in GAS.
  202.          */
  203.         bit_width = (u8)(byte_width * 8);
  204.         if (byte_width > 31) {  /* (31*8)=248, (32*8)=256 */
  205.                 /*
  206.                  * No error for GPE blocks, because we do not use the bit_width
  207.                  * for GPEs, the legacy length (byte_width) is used instead to
  208.                  * allow for a large number of GPEs.
  209.                  */
  210.                 if (!(flags & ACPI_FADT_GPE_REGISTER)) {
  211.                         ACPI_ERROR((AE_INFO,
  212.                                     "%s - 32-bit FADT register is too long (%u bytes, %u bits) "
  213.                                     "to convert to GAS struct - 255 bits max, truncating",
  214.                                     register_name, byte_width,
  215.                                     (byte_width * 8)));
  216.                 }
  217.  
  218.                 bit_width = 255;
  219.         }
  220.  
  221.         /*
  222.          * The 64-bit Address field is non-aligned in the byte packed
  223.          * GAS struct.
  224.          */
  225.         ACPI_MOVE_64_TO_64(&generic_address->address, &address);
  226.  
  227.         /* All other fields are byte-wide */
  228.  
  229.         generic_address->space_id = space_id;
  230.         generic_address->bit_width = bit_width;
  231.         generic_address->bit_offset = 0;
  232.         generic_address->access_width = 0;      /* Access width ANY */
  233. }
  234.  
  235. /*******************************************************************************
  236.  *
  237.  * FUNCTION:    acpi_tb_select_address
  238.  *
  239.  * PARAMETERS:  register_name       - ASCII name of the ACPI register
  240.  *              address32           - 32-bit address of the register
  241.  *              address64           - 64-bit address of the register
  242.  *
  243.  * RETURN:      The resolved 64-bit address
  244.  *
  245.  * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
  246.  *              the FADT. Used for the FACS and DSDT addresses.
  247.  *
  248.  * NOTES:
  249.  *
  250.  * Check for FACS and DSDT address mismatches. An address mismatch between
  251.  * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
  252.  * DSDT/X_DSDT) could be a corrupted address field or it might indicate
  253.  * the presence of two FACS or two DSDT tables.
  254.  *
  255.  * November 2013:
  256.  * By default, as per the ACPICA specification, a valid 64-bit address is
  257.  * used regardless of the value of the 32-bit address. However, this
  258.  * behavior can be overridden via the acpi_gbl_use32_bit_fadt_addresses flag.
  259.  *
  260.  ******************************************************************************/
  261.  
  262. static u64
  263. acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
  264. {
  265.  
  266.         if (!address64) {
  267.  
  268.                 /* 64-bit address is zero, use 32-bit address */
  269.  
  270.                 return ((u64)address32);
  271.         }
  272.  
  273.         if (address32 && (address64 != (u64)address32)) {
  274.  
  275.                 /* Address mismatch between 32-bit and 64-bit versions */
  276.  
  277.                 ACPI_BIOS_WARNING((AE_INFO,
  278.                                    "32/64X %s address mismatch in FADT: "
  279.                                    "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
  280.                                    register_name, address32,
  281.                                    ACPI_FORMAT_UINT64(address64),
  282.                                    acpi_gbl_use32_bit_fadt_addresses ? 32 :
  283.                                    64));
  284.  
  285.                 /* 32-bit address override */
  286.  
  287.                 if (acpi_gbl_use32_bit_fadt_addresses) {
  288.                         return ((u64)address32);
  289.                 }
  290.         }
  291.  
  292.         /* Default is to use the 64-bit address */
  293.  
  294.         return (address64);
  295. }
  296.  
  297. /*******************************************************************************
  298.  *
  299.  * FUNCTION:    acpi_tb_parse_fadt
  300.  *
  301.  * PARAMETERS:  None
  302.  *
  303.  * RETURN:      None
  304.  *
  305.  * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
  306.  *              (FADT contains the addresses of the DSDT and FACS)
  307.  *
  308.  ******************************************************************************/
  309.  
  310. void acpi_tb_parse_fadt(void)
  311. {
  312.         u32 length;
  313.         struct acpi_table_header *table;
  314.  
  315.         /*
  316.          * The FADT has multiple versions with different lengths,
  317.          * and it contains pointers to both the DSDT and FACS tables.
  318.          *
  319.          * Get a local copy of the FADT and convert it to a common format
  320.          * Map entire FADT, assumed to be smaller than one page.
  321.          */
  322.         length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
  323.  
  324.         table =
  325.             acpi_os_map_memory(acpi_gbl_root_table_list.
  326.                                tables[acpi_gbl_fadt_index].address, length);
  327.         if (!table) {
  328.                 return;
  329.         }
  330.  
  331.         /*
  332.          * Validate the FADT checksum before we copy the table. Ignore
  333.          * checksum error as we want to try to get the DSDT and FACS.
  334.          */
  335.         (void)acpi_tb_verify_checksum(table, length);
  336.  
  337.         /* Create a local copy of the FADT in common ACPI 2.0+ format */
  338.  
  339.         acpi_tb_create_local_fadt(table, length);
  340.  
  341.         /* All done with the real FADT, unmap it */
  342.  
  343.         acpi_os_unmap_memory(table, length);
  344.  
  345.         /* Obtain the DSDT and FACS tables via their addresses within the FADT */
  346.  
  347.         acpi_tb_install_fixed_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
  348.                                     ACPI_SIG_DSDT, &acpi_gbl_dsdt_index);
  349.  
  350.         /* If Hardware Reduced flag is set, there is no FACS */
  351.  
  352.         if (!acpi_gbl_reduced_hardware) {
  353.                 if (acpi_gbl_FADT.facs) {
  354.                         acpi_tb_install_fixed_table((acpi_physical_address)
  355.                                                     acpi_gbl_FADT.facs,
  356.                                                     ACPI_SIG_FACS,
  357.                                                     &acpi_gbl_facs_index);
  358.                 }
  359.                 if (acpi_gbl_FADT.Xfacs) {
  360.                         acpi_tb_install_fixed_table((acpi_physical_address)
  361.                                                     acpi_gbl_FADT.Xfacs,
  362.                                                     ACPI_SIG_FACS,
  363.                                                     &acpi_gbl_xfacs_index);
  364.                 }
  365.         }
  366. }
  367.  
  368. /*******************************************************************************
  369.  *
  370.  * FUNCTION:    acpi_tb_create_local_fadt
  371.  *
  372.  * PARAMETERS:  table               - Pointer to BIOS FADT
  373.  *              length              - Length of the table
  374.  *
  375.  * RETURN:      None
  376.  *
  377.  * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
  378.  *              Performs validation on some important FADT fields.
  379.  *
  380.  * NOTE:        We create a local copy of the FADT regardless of the version.
  381.  *
  382.  ******************************************************************************/
  383.  
  384. void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
  385. {
  386.         /*
  387.          * Check if the FADT is larger than the largest table that we expect
  388.          * (the ACPI 5.0 version). If so, truncate the table, and issue
  389.          * a warning.
  390.          */
  391.         if (length > sizeof(struct acpi_table_fadt)) {
  392.                 ACPI_BIOS_WARNING((AE_INFO,
  393.                                    "FADT (revision %u) is longer than ACPI 5.0 version, "
  394.                                    "truncating length %u to %u",
  395.                                    table->revision, length,
  396.                                    (u32)sizeof(struct acpi_table_fadt)));
  397.         }
  398.  
  399.         /* Clear the entire local FADT */
  400.  
  401.         memset(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
  402.  
  403.         /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */
  404.  
  405.         memcpy(&acpi_gbl_FADT, table,
  406.                ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
  407.  
  408.         /* Take a copy of the Hardware Reduced flag */
  409.  
  410.         acpi_gbl_reduced_hardware = FALSE;
  411.         if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) {
  412.                 acpi_gbl_reduced_hardware = TRUE;
  413.         }
  414.  
  415.         /* Convert the local copy of the FADT to the common internal format */
  416.  
  417.         acpi_tb_convert_fadt();
  418.  
  419.         /* Initialize the global ACPI register structures */
  420.  
  421.         acpi_tb_setup_fadt_registers();
  422. }
  423.  
  424. /*******************************************************************************
  425.  *
  426.  * FUNCTION:    acpi_tb_convert_fadt
  427.  *
  428.  * PARAMETERS:  none - acpi_gbl_FADT is used.
  429.  *
  430.  * RETURN:      None
  431.  *
  432.  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
  433.  *              Expand 32-bit addresses to 64-bit as necessary. Also validate
  434.  *              important fields within the FADT.
  435.  *
  436.  * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt), and must
  437.  *              contain a copy of the actual BIOS-provided FADT.
  438.  *
  439.  * Notes on 64-bit register addresses:
  440.  *
  441.  * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
  442.  * fields of the FADT for all ACPI register addresses.
  443.  *
  444.  * The 64-bit X fields are optional extensions to the original 32-bit FADT
  445.  * V1.0 fields. Even if they are present in the FADT, they are optional and
  446.  * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
  447.  * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
  448.  * originally zero.
  449.  *
  450.  * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
  451.  * fields are expanded to the corresponding 64-bit X fields in the internal
  452.  * common FADT.
  453.  *
  454.  * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
  455.  * to the corresponding 64-bit X fields, if the 64-bit field is originally
  456.  * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
  457.  * field if the 64-bit field is valid, regardless of whether the host OS is
  458.  * 32-bit or 64-bit.
  459.  *
  460.  * Possible additional checks:
  461.  *  (acpi_gbl_FADT.pm1_event_length >= 4)
  462.  *  (acpi_gbl_FADT.pm1_control_length >= 2)
  463.  *  (acpi_gbl_FADT.pm_timer_length >= 4)
  464.  *  Gpe block lengths must be multiple of 2
  465.  *
  466.  ******************************************************************************/
  467.  
  468. static void acpi_tb_convert_fadt(void)
  469. {
  470.         char *name;
  471.         struct acpi_generic_address *address64;
  472.         u32 address32;
  473.         u8 length;
  474.         u8 flags;
  475.         u32 i;
  476.  
  477.         /*
  478.          * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
  479.          * should be zero are indeed zero. This will workaround BIOSs that
  480.          * inadvertently place values in these fields.
  481.          *
  482.          * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
  483.          * at offset 45, 55, 95, and the word located at offset 109, 110.
  484.          *
  485.          * Note: The FADT revision value is unreliable. Only the length can be
  486.          * trusted.
  487.          */
  488.         if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) {
  489.                 acpi_gbl_FADT.preferred_profile = 0;
  490.                 acpi_gbl_FADT.pstate_control = 0;
  491.                 acpi_gbl_FADT.cst_control = 0;
  492.                 acpi_gbl_FADT.boot_flags = 0;
  493.         }
  494.  
  495.         /*
  496.          * Now we can update the local FADT length to the length of the
  497.          * current FADT version as defined by the ACPI specification.
  498.          * Thus, we will have a common FADT internally.
  499.          */
  500.         acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
  501.  
  502.         /*
  503.          * Expand the 32-bit DSDT addresses to 64-bit as necessary.
  504.          * Later ACPICA code will always use the X 64-bit field.
  505.          */
  506.         acpi_gbl_FADT.Xdsdt = acpi_tb_select_address("DSDT",
  507.                                                      acpi_gbl_FADT.dsdt,
  508.                                                      acpi_gbl_FADT.Xdsdt);
  509.  
  510.         /* If Hardware Reduced flag is set, we are all done */
  511.  
  512.         if (acpi_gbl_reduced_hardware) {
  513.                 return;
  514.         }
  515.  
  516.         /* Examine all of the 64-bit extended address fields (X fields) */
  517.  
  518.         for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
  519.                 /*
  520.                  * Get the 32-bit and 64-bit addresses, as well as the register
  521.                  * length and register name.
  522.                  */
  523.                 address32 = *ACPI_ADD_PTR(u32,
  524.                                           &acpi_gbl_FADT,
  525.                                           fadt_info_table[i].address32);
  526.  
  527.                 address64 = ACPI_ADD_PTR(struct acpi_generic_address,
  528.                                          &acpi_gbl_FADT,
  529.                                          fadt_info_table[i].address64);
  530.  
  531.                 length = *ACPI_ADD_PTR(u8,
  532.                                        &acpi_gbl_FADT,
  533.                                        fadt_info_table[i].length);
  534.  
  535.                 name = fadt_info_table[i].name;
  536.                 flags = fadt_info_table[i].flags;
  537.  
  538.                 /*
  539.                  * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
  540.                  * generic address structures as necessary. Later code will always use
  541.                  * the 64-bit address structures.
  542.                  *
  543.                  * November 2013:
  544.                  * Now always use the 64-bit address if it is valid (non-zero), in
  545.                  * accordance with the ACPI specification which states that a 64-bit
  546.                  * address supersedes the 32-bit version. This behavior can be
  547.                  * overridden by the acpi_gbl_use32_bit_fadt_addresses flag.
  548.                  *
  549.                  * During 64-bit address construction and verification,
  550.                  * these cases are handled:
  551.                  *
  552.                  * Address32 zero, Address64 [don't care]   - Use Address64
  553.                  *
  554.                  * Address32 non-zero, Address64 zero       - Copy/use Address32
  555.                  * Address32 non-zero == Address64 non-zero - Use Address64
  556.                  * Address32 non-zero != Address64 non-zero - Warning, use Address64
  557.                  *
  558.                  * Override: if acpi_gbl_use32_bit_fadt_addresses is TRUE, and:
  559.                  * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
  560.                  *
  561.                  * Note: space_id is always I/O for 32-bit legacy address fields
  562.                  */
  563.                 if (address32) {
  564.                         if (!address64->address) {
  565.  
  566.                                 /* 64-bit address is zero, use 32-bit address */
  567.  
  568.                                 acpi_tb_init_generic_address(address64,
  569.                                                              ACPI_ADR_SPACE_SYSTEM_IO,
  570.                                                              *ACPI_ADD_PTR(u8,
  571.                                                                            &acpi_gbl_FADT,
  572.                                                                            fadt_info_table
  573.                                                                            [i].
  574.                                                                            length),
  575.                                                              (u64)address32,
  576.                                                              name, flags);
  577.                         } else if (address64->address != (u64)address32) {
  578.  
  579.                                 /* Address mismatch */
  580.  
  581.                                 ACPI_BIOS_WARNING((AE_INFO,
  582.                                                    "32/64X address mismatch in FADT/%s: "
  583.                                                    "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
  584.                                                    name, address32,
  585.                                                    ACPI_FORMAT_UINT64
  586.                                                    (address64->address),
  587.                                                    acpi_gbl_use32_bit_fadt_addresses
  588.                                                    ? 32 : 64));
  589.  
  590.                                 if (acpi_gbl_use32_bit_fadt_addresses) {
  591.  
  592.                                         /* 32-bit address override */
  593.  
  594.                                         acpi_tb_init_generic_address(address64,
  595.                                                                      ACPI_ADR_SPACE_SYSTEM_IO,
  596.                                                                      *ACPI_ADD_PTR
  597.                                                                      (u8,
  598.                                                                       &acpi_gbl_FADT,
  599.                                                                       fadt_info_table
  600.                                                                       [i].
  601.                                                                       length),
  602.                                                                      (u64)
  603.                                                                      address32,
  604.                                                                      name,
  605.                                                                      flags);
  606.                                 }
  607.                         }
  608.                 }
  609.  
  610.                 /*
  611.                  * For each extended field, check for length mismatch between the
  612.                  * legacy length field and the corresponding 64-bit X length field.
  613.                  * Note: If the legacy length field is > 0xFF bits, ignore this
  614.                  * check. (GPE registers can be larger than the 64-bit GAS structure
  615.                  * can accomodate, 0xFF bits).
  616.                  */
  617.                 if (address64->address &&
  618.                     (ACPI_MUL_8(length) <= ACPI_UINT8_MAX) &&
  619.                     (address64->bit_width != ACPI_MUL_8(length))) {
  620.                         ACPI_BIOS_WARNING((AE_INFO,
  621.                                            "32/64X length mismatch in FADT/%s: %u/%u",
  622.                                            name, ACPI_MUL_8(length),
  623.                                            address64->bit_width));
  624.                 }
  625.  
  626.                 if (fadt_info_table[i].flags & ACPI_FADT_REQUIRED) {
  627.                         /*
  628.                          * Field is required (Pm1a_event, Pm1a_control).
  629.                          * Both the address and length must be non-zero.
  630.                          */
  631.                         if (!address64->address || !length) {
  632.                                 ACPI_BIOS_ERROR((AE_INFO,
  633.                                                  "Required FADT field %s has zero address and/or length: "
  634.                                                  "0x%8.8X%8.8X/0x%X",
  635.                                                  name,
  636.                                                  ACPI_FORMAT_UINT64(address64->
  637.                                                                     address),
  638.                                                  length));
  639.                         }
  640.                 } else if (fadt_info_table[i].flags & ACPI_FADT_SEPARATE_LENGTH) {
  641.                         /*
  642.                          * Field is optional (Pm2_control, GPE0, GPE1) AND has its own
  643.                          * length field. If present, both the address and length must
  644.                          * be valid.
  645.                          */
  646.                         if ((address64->address && !length) ||
  647.                             (!address64->address && length)) {
  648.                                 ACPI_BIOS_WARNING((AE_INFO,
  649.                                                    "Optional FADT field %s has zero address or length: "
  650.                                                    "0x%8.8X%8.8X/0x%X",
  651.                                                    name,
  652.                                                    ACPI_FORMAT_UINT64
  653.                                                    (address64->address),
  654.                                                    length));
  655.                         }
  656.                 }
  657.         }
  658. }
  659.  
  660. /*******************************************************************************
  661.  *
  662.  * FUNCTION:    acpi_tb_setup_fadt_registers
  663.  *
  664.  * PARAMETERS:  None, uses acpi_gbl_FADT.
  665.  *
  666.  * RETURN:      None
  667.  *
  668.  * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
  669.  *              force FADT register definitions to their default lengths.
  670.  *
  671.  ******************************************************************************/
  672.  
  673. static void acpi_tb_setup_fadt_registers(void)
  674. {
  675.         struct acpi_generic_address *target64;
  676.         struct acpi_generic_address *source64;
  677.         u8 pm1_register_byte_width;
  678.         u32 i;
  679.  
  680.         /*
  681.          * Optionally check all register lengths against the default values and
  682.          * update them if they are incorrect.
  683.          */
  684.         if (acpi_gbl_use_default_register_widths) {
  685.                 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
  686.                         target64 =
  687.                             ACPI_ADD_PTR(struct acpi_generic_address,
  688.                                          &acpi_gbl_FADT,
  689.                                          fadt_info_table[i].address64);
  690.  
  691.                         /*
  692.                          * If a valid register (Address != 0) and the (default_length > 0)
  693.                          * (Not a GPE register), then check the width against the default.
  694.                          */
  695.                         if ((target64->address) &&
  696.                             (fadt_info_table[i].default_length > 0) &&
  697.                             (fadt_info_table[i].default_length !=
  698.                              target64->bit_width)) {
  699.                                 ACPI_BIOS_WARNING((AE_INFO,
  700.                                                    "Invalid length for FADT/%s: %u, using default %u",
  701.                                                    fadt_info_table[i].name,
  702.                                                    target64->bit_width,
  703.                                                    fadt_info_table[i].
  704.                                                    default_length));
  705.  
  706.                                 /* Incorrect size, set width to the default */
  707.  
  708.                                 target64->bit_width =
  709.                                     fadt_info_table[i].default_length;
  710.                         }
  711.                 }
  712.         }
  713.  
  714.         /*
  715.          * Get the length of the individual PM1 registers (enable and status).
  716.          * Each register is defined to be (event block length / 2). Extra divide
  717.          * by 8 converts bits to bytes.
  718.          */
  719.         pm1_register_byte_width = (u8)
  720.             ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
  721.  
  722.         /*
  723.          * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
  724.          * registers. These addresses do not appear (directly) in the FADT, so it
  725.          * is useful to pre-calculate them from the PM1 Event Block definitions.
  726.          *
  727.          * The PM event blocks are split into two register blocks, first is the
  728.          * PM Status Register block, followed immediately by the PM Enable
  729.          * Register block. Each is of length (pm1_event_length/2)
  730.          *
  731.          * Note: The PM1A event block is required by the ACPI specification.
  732.          * However, the PM1B event block is optional and is rarely, if ever,
  733.          * used.
  734.          */
  735.  
  736.         for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
  737.                 source64 =
  738.                     ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
  739.                                  fadt_pm_info_table[i].source);
  740.  
  741.                 if (source64->address) {
  742.                         acpi_tb_init_generic_address(fadt_pm_info_table[i].
  743.                                                      target, source64->space_id,
  744.                                                      pm1_register_byte_width,
  745.                                                      source64->address +
  746.                                                      (fadt_pm_info_table[i].
  747.                                                       register_num *
  748.                                                       pm1_register_byte_width),
  749.                                                      "PmRegisters", 0);
  750.                 }
  751.         }
  752. }
  753.