|
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void);
|
|
|
|
|
|
static void acpi_tb_validate_fadt(void);
|
|
|
|
|
|
+static void acpi_tb_setup_fadt_registers(void);
|
|
|
+
|
|
|
/* Table for conversion of FADT to common internal format and FADT validation */
|
|
|
|
|
|
typedef struct acpi_fadt_info {
|
|
@@ -130,7 +132,38 @@ static struct acpi_fadt_info fadt_info_table[] = {
|
|
|
ACPI_FADT_SEPARATE_LENGTH}
|
|
|
};
|
|
|
|
|
|
-#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
|
|
|
+#define ACPI_FADT_INFO_ENTRIES \
|
|
|
+ (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
|
|
|
+
|
|
|
+/* Table used to split Event Blocks into separate status/enable registers */
|
|
|
+
|
|
|
+typedef struct acpi_fadt_pm_info {
|
|
|
+ struct acpi_generic_address *target;
|
|
|
+ u8 source;
|
|
|
+ u8 register_num;
|
|
|
+
|
|
|
+} acpi_fadt_pm_info;
|
|
|
+
|
|
|
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
|
|
|
+ {&acpi_gbl_xpm1a_status,
|
|
|
+ ACPI_FADT_OFFSET(xpm1a_event_block),
|
|
|
+ 0},
|
|
|
+
|
|
|
+ {&acpi_gbl_xpm1a_enable,
|
|
|
+ ACPI_FADT_OFFSET(xpm1a_event_block),
|
|
|
+ 1},
|
|
|
+
|
|
|
+ {&acpi_gbl_xpm1b_status,
|
|
|
+ ACPI_FADT_OFFSET(xpm1b_event_block),
|
|
|
+ 0},
|
|
|
+
|
|
|
+ {&acpi_gbl_xpm1b_enable,
|
|
|
+ ACPI_FADT_OFFSET(xpm1b_event_block),
|
|
|
+ 1}
|
|
|
+};
|
|
|
+
|
|
|
+#define ACPI_FADT_PM_INFO_ENTRIES \
|
|
|
+ (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
|
|
|
|
|
|
/*******************************************************************************
|
|
|
*
|
|
@@ -172,7 +205,6 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
|
|
|
* FUNCTION: acpi_tb_parse_fadt
|
|
|
*
|
|
|
* PARAMETERS: table_index - Index for the FADT
|
|
|
- * Flags - Flags
|
|
|
*
|
|
|
* RETURN: None
|
|
|
*
|
|
@@ -181,7 +213,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
|
|
|
*
|
|
|
******************************************************************************/
|
|
|
|
|
|
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
|
|
|
+void acpi_tb_parse_fadt(u32 table_index)
|
|
|
{
|
|
|
u32 length;
|
|
|
struct acpi_table_header *table;
|
|
@@ -208,7 +240,7 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
|
|
|
*/
|
|
|
(void)acpi_tb_verify_checksum(table, length);
|
|
|
|
|
|
- /* Obtain a local copy of the FADT in common ACPI 2.0+ format */
|
|
|
+ /* Create a local copy of the FADT in common ACPI 2.0+ format */
|
|
|
|
|
|
acpi_tb_create_local_fadt(table, length);
|
|
|
|
|
@@ -219,10 +251,10 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
|
|
|
/* Obtain the DSDT and FACS tables via their addresses within the FADT */
|
|
|
|
|
|
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
|
|
|
- flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
|
|
|
+ ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
|
|
|
|
|
|
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
|
|
|
- flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
|
|
|
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
|
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
@@ -266,11 +298,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
|
|
|
ACPI_MEMCPY(&acpi_gbl_FADT, table,
|
|
|
ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
|
|
|
|
|
|
- /*
|
|
|
- * 1) Convert the local copy of the FADT to the common internal format
|
|
|
- * 2) Validate some of the important values within the FADT
|
|
|
- */
|
|
|
+ /* Convert the local copy of the FADT to the common internal format */
|
|
|
+
|
|
|
acpi_tb_convert_fadt();
|
|
|
+
|
|
|
+ /* Validate FADT values now, before we make any changes */
|
|
|
+
|
|
|
+ acpi_tb_validate_fadt();
|
|
|
+
|
|
|
+ /* Initialize the global ACPI register structures */
|
|
|
+
|
|
|
+ acpi_tb_setup_fadt_registers();
|
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
@@ -282,31 +320,35 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
|
|
|
* RETURN: None
|
|
|
*
|
|
|
* DESCRIPTION: Converts all versions of the FADT to a common internal format.
|
|
|
- * Expand all 32-bit addresses to 64-bit.
|
|
|
+ * Expand 32-bit addresses to 64-bit as necessary.
|
|
|
*
|
|
|
* NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
|
|
|
* and must contain a copy of the actual FADT.
|
|
|
*
|
|
|
- * ACPICA will use the "X" fields of the FADT for all addresses.
|
|
|
+ * Notes on 64-bit register addresses:
|
|
|
+ *
|
|
|
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
|
|
|
+ * fields of the FADT for all ACPI register addresses.
|
|
|
*
|
|
|
- * "X" fields are optional extensions to the original V1.0 fields. Even if
|
|
|
- * they are present in the structure, they can be optionally not used by
|
|
|
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
|
|
|
- * if the corresponding X field is zero.
|
|
|
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
|
|
|
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
|
|
|
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
|
|
|
+ * 32-bit V1.0 fields if the corresponding X field is zero.
|
|
|
*
|
|
|
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
|
|
|
- * "X" fields.
|
|
|
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
|
|
|
+ * corresponding "X" fields in the internal FADT.
|
|
|
*
|
|
|
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
|
|
|
- * expanding the corresponding ACPI 1.0 field.
|
|
|
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
|
|
|
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
|
|
|
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
|
|
|
+ * regardless of whether the host OS is 32-bit or 64-bit.
|
|
|
*
|
|
|
******************************************************************************/
|
|
|
|
|
|
static void acpi_tb_convert_fadt(void)
|
|
|
{
|
|
|
- u8 pm1_register_bit_width;
|
|
|
- u8 pm1_register_byte_width;
|
|
|
- struct acpi_generic_address *target64;
|
|
|
+ struct acpi_generic_address *address64;
|
|
|
+ u32 address32;
|
|
|
u32 i;
|
|
|
|
|
|
/* Update the local FADT table header length */
|
|
@@ -355,140 +397,56 @@ static void acpi_tb_convert_fadt(void)
|
|
|
* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
|
|
|
* generic address structures as necessary. Later code will always use
|
|
|
* the 64-bit address structures.
|
|
|
+ *
|
|
|
+ * March 2009:
|
|
|
+ * We now always use the 32-bit address if it is valid (non-null). This
|
|
|
+ * is not in accordance with the ACPI specification which states that
|
|
|
+ * the 64-bit address supersedes the 32-bit version, but we do this for
|
|
|
+ * compatibility with other ACPI implementations. Most notably, in the
|
|
|
+ * case where both the 32 and 64 versions are non-null, we use the 32-bit
|
|
|
+ * version. This is the only address that is guaranteed to have been
|
|
|
+ * tested by the BIOS manufacturer.
|
|
|
*/
|
|
|
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
|
|
|
- target64 =
|
|
|
- ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
|
|
|
- fadt_info_table[i].address64);
|
|
|
+ address32 = *ACPI_ADD_PTR(u32,
|
|
|
+ &acpi_gbl_FADT,
|
|
|
+ fadt_info_table[i].address32);
|
|
|
|
|
|
- /* Expand only if the 64-bit X target is null */
|
|
|
+ address64 = ACPI_ADD_PTR(struct acpi_generic_address,
|
|
|
+ &acpi_gbl_FADT,
|
|
|
+ fadt_info_table[i].address64);
|
|
|
|
|
|
- if (!target64->address) {
|
|
|
+ /*
|
|
|
+ * If both 32- and 64-bit addresses are valid (non-zero),
|
|
|
+ * they must match.
|
|
|
+ */
|
|
|
+ if (address64->address && address32 &&
|
|
|
+ (address64->address != (u64) address32)) {
|
|
|
+ ACPI_ERROR((AE_INFO,
|
|
|
+ "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
|
|
|
+ fadt_info_table[i].name, address32,
|
|
|
+ ACPI_FORMAT_UINT64(address64->address)));
|
|
|
+ }
|
|
|
|
|
|
- /* The space_id is always I/O for the 32-bit legacy address fields */
|
|
|
+ /* Always use 32-bit address if it is valid (non-null) */
|
|
|
|
|
|
- acpi_tb_init_generic_address(target64,
|
|
|
+ if (address32) {
|
|
|
+ /*
|
|
|
+ * Copy the 32-bit address to the 64-bit GAS structure. The
|
|
|
+ * Space ID is always I/O for 32-bit legacy address fields
|
|
|
+ */
|
|
|
+ acpi_tb_init_generic_address(address64,
|
|
|
ACPI_ADR_SPACE_SYSTEM_IO,
|
|
|
*ACPI_ADD_PTR(u8,
|
|
|
&acpi_gbl_FADT,
|
|
|
fadt_info_table
|
|
|
[i].length),
|
|
|
- (u64) * ACPI_ADD_PTR(u32,
|
|
|
- &acpi_gbl_FADT,
|
|
|
- fadt_info_table
|
|
|
- [i].
|
|
|
- address32));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Validate FADT values now, before we make any changes */
|
|
|
-
|
|
|
- acpi_tb_validate_fadt();
|
|
|
-
|
|
|
- /*
|
|
|
- * Optionally check all register lengths against the default values and
|
|
|
- * update them if they are incorrect.
|
|
|
- */
|
|
|
- if (acpi_gbl_use_default_register_widths) {
|
|
|
- for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
|
|
|
- target64 =
|
|
|
- ACPI_ADD_PTR(struct acpi_generic_address,
|
|
|
- &acpi_gbl_FADT,
|
|
|
- fadt_info_table[i].address64);
|
|
|
-
|
|
|
- /*
|
|
|
- * If a valid register (Address != 0) and the (default_length > 0)
|
|
|
- * (Not a GPE register), then check the width against the default.
|
|
|
- */
|
|
|
- if ((target64->address) &&
|
|
|
- (fadt_info_table[i].default_length > 0) &&
|
|
|
- (fadt_info_table[i].default_length !=
|
|
|
- target64->bit_width)) {
|
|
|
- ACPI_WARNING((AE_INFO,
|
|
|
- "Invalid length for %s: %d, using default %d",
|
|
|
- fadt_info_table[i].name,
|
|
|
- target64->bit_width,
|
|
|
- fadt_info_table[i].
|
|
|
- default_length));
|
|
|
-
|
|
|
- /* Incorrect size, set width to the default */
|
|
|
-
|
|
|
- target64->bit_width =
|
|
|
- fadt_info_table[i].default_length;
|
|
|
- }
|
|
|
+ address32);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * Get the length of the individual PM1 registers (enable and status).
|
|
|
- * Each register is defined to be (event block length / 2).
|
|
|
- */
|
|
|
- pm1_register_bit_width =
|
|
|
- (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
|
|
|
- pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
|
|
|
-
|
|
|
- /*
|
|
|
- * Adjust the lengths of the PM1 Event Blocks so that they can be used to
|
|
|
- * access the PM1 status register(s). Use (width / 2)
|
|
|
- */
|
|
|
- acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
|
|
|
- acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
|
|
|
-
|
|
|
- /*
|
|
|
- * Calculate separate GAS structs for the PM1 Enable registers.
|
|
|
- * These addresses do not appear (directly) in the FADT, so it is
|
|
|
- * useful to calculate them once, here.
|
|
|
- *
|
|
|
- * The PM event blocks are split into two register blocks, first is the
|
|
|
- * PM Status Register block, followed immediately by the PM Enable
|
|
|
- * Register block. Each is of length (xpm1x_event_block.bit_width/2).
|
|
|
- *
|
|
|
- * On various systems the v2 fields (and particularly the bit widths)
|
|
|
- * cannot be relied upon, though. Hence resort to using the v1 length
|
|
|
- * here (and warn about the inconsistency).
|
|
|
- */
|
|
|
- if (acpi_gbl_FADT.xpm1a_event_block.bit_width
|
|
|
- != acpi_gbl_FADT.pm1_event_length * 8)
|
|
|
- printk(KERN_WARNING "FADT: "
|
|
|
- "X_PM1a_EVT_BLK.bit_width (%u) does not match"
|
|
|
- " PM1_EVT_LEN (%u)\n",
|
|
|
- acpi_gbl_FADT.xpm1a_event_block.bit_width,
|
|
|
- acpi_gbl_FADT.pm1_event_length);
|
|
|
-
|
|
|
- /* The PM1A register block is required */
|
|
|
-
|
|
|
- acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
|
|
|
- acpi_gbl_FADT.xpm1a_event_block.space_id,
|
|
|
- pm1_register_byte_width,
|
|
|
- (acpi_gbl_FADT.xpm1a_event_block.address +
|
|
|
- pm1_register_byte_width));
|
|
|
- /* Don't forget to copy space_id of the GAS */
|
|
|
- acpi_gbl_xpm1a_enable.space_id =
|
|
|
- acpi_gbl_FADT.xpm1a_event_block.space_id;
|
|
|
-
|
|
|
- /* The PM1B register block is optional, ignore if not present */
|
|
|
-
|
|
|
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
|
|
|
- if (acpi_gbl_FADT.xpm1b_event_block.bit_width
|
|
|
- != acpi_gbl_FADT.pm1_event_length * 8)
|
|
|
- printk(KERN_WARNING "FADT: "
|
|
|
- "X_PM1b_EVT_BLK.bit_width (%u) does not match"
|
|
|
- " PM1_EVT_LEN (%u)\n",
|
|
|
- acpi_gbl_FADT.xpm1b_event_block.bit_width,
|
|
|
- acpi_gbl_FADT.pm1_event_length);
|
|
|
- acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
|
|
|
- acpi_gbl_FADT.xpm1b_event_block.space_id,
|
|
|
- pm1_register_byte_width,
|
|
|
- (acpi_gbl_FADT.xpm1b_event_block.
|
|
|
- address + pm1_register_byte_width));
|
|
|
- /* Don't forget to copy space_id of the GAS */
|
|
|
- acpi_gbl_xpm1b_enable.space_id =
|
|
|
- acpi_gbl_FADT.xpm1b_event_block.space_id;
|
|
|
-
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
-/******************************************************************************
|
|
|
+/*******************************************************************************
|
|
|
*
|
|
|
* FUNCTION: acpi_tb_validate_fadt
|
|
|
*
|
|
@@ -525,18 +483,22 @@ static void acpi_tb_validate_fadt(void)
|
|
|
(acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
|
|
|
ACPI_WARNING((AE_INFO,
|
|
|
"32/64X FACS address mismatch in FADT - "
|
|
|
- "two FACS tables! %8.8X/%8.8X%8.8X",
|
|
|
+ "%8.8X/%8.8X%8.8X, using 32",
|
|
|
acpi_gbl_FADT.facs,
|
|
|
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
|
|
|
+
|
|
|
+ acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
|
|
|
}
|
|
|
|
|
|
if (acpi_gbl_FADT.dsdt &&
|
|
|
(acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
|
|
|
ACPI_WARNING((AE_INFO,
|
|
|
"32/64X DSDT address mismatch in FADT - "
|
|
|
- "two DSDT tables! %8.8X/%8.8X%8.8X",
|
|
|
+ "%8.8X/%8.8X%8.8X, using 32",
|
|
|
acpi_gbl_FADT.dsdt,
|
|
|
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
|
|
|
+
|
|
|
+ acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
|
|
|
}
|
|
|
|
|
|
/* Examine all of the 64-bit extended address fields (X fields) */
|
|
@@ -561,7 +523,8 @@ static void acpi_tb_validate_fadt(void)
|
|
|
* For each extended field, check for length mismatch between the
|
|
|
* legacy length field and the corresponding 64-bit X length field.
|
|
|
*/
|
|
|
- if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
|
|
|
+ if (address64->address &&
|
|
|
+ (address64->bit_width != ACPI_MUL_8(length))) {
|
|
|
ACPI_WARNING((AE_INFO,
|
|
|
"32/64X length mismatch in %s: %d/%d",
|
|
|
name, ACPI_MUL_8(length),
|
|
@@ -575,7 +538,8 @@ static void acpi_tb_validate_fadt(void)
|
|
|
*/
|
|
|
if (!address64->address || !length) {
|
|
|
ACPI_ERROR((AE_INFO,
|
|
|
- "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
|
|
|
+ "Required field %s has zero address and/or length:"
|
|
|
+ " %8.8X%8.8X/%X",
|
|
|
name,
|
|
|
ACPI_FORMAT_UINT64(address64->
|
|
|
address),
|
|
@@ -584,27 +548,112 @@ static void acpi_tb_validate_fadt(void)
|
|
|
} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
|
|
|
/*
|
|
|
* Field is optional (PM2Control, GPE0, GPE1) AND has its own
|
|
|
- * length field. If present, both the address and length must be valid.
|
|
|
+ * length field. If present, both the address and length must
|
|
|
+ * be valid.
|
|
|
*/
|
|
|
- if ((address64->address && !length)
|
|
|
- || (!address64->address && length)) {
|
|
|
+ if ((address64->address && !length) ||
|
|
|
+ (!address64->address && length)) {
|
|
|
ACPI_WARNING((AE_INFO,
|
|
|
- "Optional field %s has zero address or length: %8.8X%8.8X/%X",
|
|
|
+ "Optional field %s has zero address or length: "
|
|
|
+ "%8.8X%8.8X/%X",
|
|
|
name,
|
|
|
ACPI_FORMAT_UINT64(address64->
|
|
|
address),
|
|
|
length));
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- /* If both 32- and 64-bit addresses are valid (non-zero), they must match */
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_tb_setup_fadt_registers
|
|
|
+ *
|
|
|
+ * PARAMETERS: None, uses acpi_gbl_FADT.
|
|
|
+ *
|
|
|
+ * RETURN: None
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
|
|
|
+ * force FADT register definitions to their default lengths.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
|
|
|
- if (address64->address && *address32 &&
|
|
|
- (address64->address != (u64) * address32)) {
|
|
|
- ACPI_ERROR((AE_INFO,
|
|
|
- "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
|
|
|
- name, *address32,
|
|
|
- ACPI_FORMAT_UINT64(address64->address)));
|
|
|
+static void acpi_tb_setup_fadt_registers(void)
|
|
|
+{
|
|
|
+ struct acpi_generic_address *target64;
|
|
|
+ struct acpi_generic_address *source64;
|
|
|
+ u8 pm1_register_byte_width;
|
|
|
+ u32 i;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Optionally check all register lengths against the default values and
|
|
|
+ * update them if they are incorrect.
|
|
|
+ */
|
|
|
+ if (acpi_gbl_use_default_register_widths) {
|
|
|
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
|
|
|
+ target64 =
|
|
|
+ ACPI_ADD_PTR(struct acpi_generic_address,
|
|
|
+ &acpi_gbl_FADT,
|
|
|
+ fadt_info_table[i].address64);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If a valid register (Address != 0) and the (default_length > 0)
|
|
|
+ * (Not a GPE register), then check the width against the default.
|
|
|
+ */
|
|
|
+ if ((target64->address) &&
|
|
|
+ (fadt_info_table[i].default_length > 0) &&
|
|
|
+ (fadt_info_table[i].default_length !=
|
|
|
+ target64->bit_width)) {
|
|
|
+ ACPI_WARNING((AE_INFO,
|
|
|
+ "Invalid length for %s: %d, using default %d",
|
|
|
+ fadt_info_table[i].name,
|
|
|
+ target64->bit_width,
|
|
|
+ fadt_info_table[i].
|
|
|
+ default_length));
|
|
|
+
|
|
|
+ /* Incorrect size, set width to the default */
|
|
|
+
|
|
|
+ target64->bit_width =
|
|
|
+ fadt_info_table[i].default_length;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Get the length of the individual PM1 registers (enable and status).
|
|
|
+ * Each register is defined to be (event block length / 2). Extra divide
|
|
|
+ * by 8 converts bits to bytes.
|
|
|
+ */
|
|
|
+ pm1_register_byte_width = (u8)
|
|
|
+ ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
|
|
|
+ * registers. These addresses do not appear (directly) in the FADT, so it
|
|
|
+ * is useful to pre-calculate them from the PM1 Event Block definitions.
|
|
|
+ *
|
|
|
+ * The PM event blocks are split into two register blocks, first is the
|
|
|
+ * PM Status Register block, followed immediately by the PM Enable
|
|
|
+ * Register block. Each is of length (pm1_event_length/2)
|
|
|
+ *
|
|
|
+ * Note: The PM1A event block is required by the ACPI specification.
|
|
|
+ * However, the PM1B event block is optional and is rarely, if ever,
|
|
|
+ * used.
|
|
|
+ */
|
|
|
+
|
|
|
+ for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
|
|
|
+ source64 =
|
|
|
+ ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
|
|
|
+ fadt_pm_info_table[i].source);
|
|
|
+
|
|
|
+ if (source64->address) {
|
|
|
+ acpi_tb_init_generic_address(fadt_pm_info_table[i].
|
|
|
+ target, source64->space_id,
|
|
|
+ pm1_register_byte_width,
|
|
|
+ source64->address +
|
|
|
+ (fadt_pm_info_table[i].
|
|
|
+ register_num *
|
|
|
+ pm1_register_byte_width));
|
|
|
}
|
|
|
}
|
|
|
}
|