|
@@ -759,7 +759,7 @@ static acpi_status osl_list_bios_tables(void)
|
|
|
|
|
|
/* Skip NULL entries in RSDT/XSDT */
|
|
/* Skip NULL entries in RSDT/XSDT */
|
|
|
|
|
|
- if (!table_address) {
|
|
|
|
|
|
+ if (table_address == 0) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -808,7 +808,8 @@ osl_get_bios_table(char *signature,
|
|
u8 number_of_tables;
|
|
u8 number_of_tables;
|
|
u8 item_size;
|
|
u8 item_size;
|
|
u32 current_instance = 0;
|
|
u32 current_instance = 0;
|
|
- acpi_physical_address table_address = 0;
|
|
|
|
|
|
+ acpi_physical_address table_address;
|
|
|
|
+ acpi_physical_address first_table_address = 0;
|
|
u32 table_length = 0;
|
|
u32 table_length = 0;
|
|
acpi_status status = AE_OK;
|
|
acpi_status status = AE_OK;
|
|
u32 i;
|
|
u32 i;
|
|
@@ -820,9 +821,10 @@ osl_get_bios_table(char *signature,
|
|
ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) ||
|
|
ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) ||
|
|
ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) ||
|
|
ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) ||
|
|
ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
|
|
ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
|
|
- if (instance > 0) {
|
|
|
|
- return (AE_LIMIT);
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+find_next_instance:
|
|
|
|
+
|
|
|
|
+ table_address = 0;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Get the appropriate address, either 32-bit or 64-bit. Be very
|
|
* Get the appropriate address, either 32-bit or 64-bit. Be very
|
|
@@ -830,41 +832,66 @@ osl_get_bios_table(char *signature,
|
|
* Note: The 64-bit addresses have priority.
|
|
* Note: The 64-bit addresses have priority.
|
|
*/
|
|
*/
|
|
if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) {
|
|
if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) {
|
|
- if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) &&
|
|
|
|
- gbl_fadt->Xdsdt) {
|
|
|
|
- table_address =
|
|
|
|
- (acpi_physical_address)gbl_fadt->Xdsdt;
|
|
|
|
- } else
|
|
|
|
- if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT)
|
|
|
|
- && gbl_fadt->dsdt) {
|
|
|
|
- table_address =
|
|
|
|
- (acpi_physical_address)gbl_fadt->dsdt;
|
|
|
|
|
|
+ if (current_instance < 2) {
|
|
|
|
+ if ((gbl_fadt->header.length >=
|
|
|
|
+ MIN_FADT_FOR_XDSDT) && gbl_fadt->Xdsdt
|
|
|
|
+ && current_instance == 0) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_fadt->
|
|
|
|
+ Xdsdt;
|
|
|
|
+ } else
|
|
|
|
+ if ((gbl_fadt->header.length >=
|
|
|
|
+ MIN_FADT_FOR_DSDT)
|
|
|
|
+ && gbl_fadt->dsdt !=
|
|
|
|
+ first_table_address) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_fadt->
|
|
|
|
+ dsdt;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
|
|
} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) {
|
|
- if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) &&
|
|
|
|
- gbl_fadt->Xfacs) {
|
|
|
|
- table_address =
|
|
|
|
- (acpi_physical_address)gbl_fadt->Xfacs;
|
|
|
|
- } else
|
|
|
|
- if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS)
|
|
|
|
- && gbl_fadt->facs) {
|
|
|
|
- table_address =
|
|
|
|
- (acpi_physical_address)gbl_fadt->facs;
|
|
|
|
|
|
+ if (current_instance < 2) {
|
|
|
|
+ if ((gbl_fadt->header.length >=
|
|
|
|
+ MIN_FADT_FOR_XFACS) && gbl_fadt->Xfacs
|
|
|
|
+ && current_instance == 0) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_fadt->
|
|
|
|
+ Xfacs;
|
|
|
|
+ } else
|
|
|
|
+ if ((gbl_fadt->header.length >=
|
|
|
|
+ MIN_FADT_FOR_FACS)
|
|
|
|
+ && gbl_fadt->facs !=
|
|
|
|
+ first_table_address) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_fadt->
|
|
|
|
+ facs;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) {
|
|
} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) {
|
|
if (!gbl_revision) {
|
|
if (!gbl_revision) {
|
|
return (AE_BAD_SIGNATURE);
|
|
return (AE_BAD_SIGNATURE);
|
|
}
|
|
}
|
|
- table_address =
|
|
|
|
- (acpi_physical_address)gbl_rsdp.
|
|
|
|
- xsdt_physical_address;
|
|
|
|
|
|
+ if (current_instance == 0) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_rsdp.
|
|
|
|
+ xsdt_physical_address;
|
|
|
|
+ }
|
|
} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) {
|
|
} else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) {
|
|
- table_address =
|
|
|
|
- (acpi_physical_address)gbl_rsdp.
|
|
|
|
- rsdt_physical_address;
|
|
|
|
|
|
+ if (current_instance == 0) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_rsdp.
|
|
|
|
+ rsdt_physical_address;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
- table_address = (acpi_physical_address)gbl_rsdp_address;
|
|
|
|
- signature = ACPI_SIG_RSDP;
|
|
|
|
|
|
+ if (current_instance == 0) {
|
|
|
|
+ table_address =
|
|
|
|
+ (acpi_physical_address)gbl_rsdp_address;
|
|
|
|
+ signature = ACPI_SIG_RSDP;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (table_address == 0) {
|
|
|
|
+ goto exit_find_table;
|
|
}
|
|
}
|
|
|
|
|
|
/* Now we can get the requested special table */
|
|
/* Now we can get the requested special table */
|
|
@@ -875,6 +902,18 @@ osl_get_bios_table(char *signature,
|
|
}
|
|
}
|
|
|
|
|
|
table_length = ap_get_table_length(mapped_table);
|
|
table_length = ap_get_table_length(mapped_table);
|
|
|
|
+ if (first_table_address == 0) {
|
|
|
|
+ first_table_address = table_address;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Match table instance */
|
|
|
|
+
|
|
|
|
+ if (current_instance != instance) {
|
|
|
|
+ osl_unmap_table(mapped_table);
|
|
|
|
+ mapped_table = NULL;
|
|
|
|
+ current_instance++;
|
|
|
|
+ goto find_next_instance;
|
|
|
|
+ }
|
|
} else { /* Case for a normal ACPI table */
|
|
} else { /* Case for a normal ACPI table */
|
|
|
|
|
|
if (osl_can_use_xsdt()) {
|
|
if (osl_can_use_xsdt()) {
|
|
@@ -913,7 +952,7 @@ osl_get_bios_table(char *signature,
|
|
|
|
|
|
/* Skip NULL entries in RSDT/XSDT */
|
|
/* Skip NULL entries in RSDT/XSDT */
|
|
|
|
|
|
- if (!table_address) {
|
|
|
|
|
|
+ if (table_address == 0) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -946,6 +985,8 @@ osl_get_bios_table(char *signature,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+exit_find_table:
|
|
|
|
+
|
|
if (!mapped_table) {
|
|
if (!mapped_table) {
|
|
return (AE_LIMIT);
|
|
return (AE_LIMIT);
|
|
}
|
|
}
|