Commit ced04366 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPICA: Namespace: Ensure \_SB._INI executed before any _REG

ACPICA commit 8ae25b8d128b6b8509010be321ff6bf2760f3807

There is BIOS code relying on the fact that \_SB._INI should get evaluated
before any other control methods. This may implies a gap in ACPICA/Linux
initialization/enumeration process.

Before revealing Windows true behavior by more validations, this patch only
ensures \_SB._INI evaluated before any _REG control methods. This can help
to make progress to other initialization order fixes. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/8ae25b8dSigned-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 9559130b
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
*/ */
acpi_status acpi_ns_initialize_objects(void); acpi_status acpi_ns_initialize_objects(void);
acpi_status acpi_ns_initialize_devices(void); acpi_status acpi_ns_initialize_devices(u32 flags);
/* /*
* nsload - Namespace loading * nsload - Namespace loading
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "acnamesp.h" #include "acnamesp.h"
#include "acdispat.h" #include "acdispat.h"
#include "acinterp.h" #include "acinterp.h"
#include "acevents.h"
#define _COMPONENT ACPI_NAMESPACE #define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsinit") ACPI_MODULE_NAME("nsinit")
...@@ -133,82 +134,108 @@ acpi_status acpi_ns_initialize_objects(void) ...@@ -133,82 +134,108 @@ acpi_status acpi_ns_initialize_objects(void)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_ns_initialize_devices(void) acpi_status acpi_ns_initialize_devices(u32 flags)
{ {
acpi_status status; acpi_status status;
struct acpi_device_walk_info info; struct acpi_device_walk_info info;
ACPI_FUNCTION_TRACE(ns_initialize_devices); ACPI_FUNCTION_TRACE(ns_initialize_devices);
/* Init counters */ if (!(flags & ACPI_NO_DEVICE_INIT)) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"[Init] Initializing ACPI Devices\n"));
info.device_count = 0; /* Init counters */
info.num_STA = 0;
info.num_INI = 0;
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, info.device_count = 0;
"Initializing Device/Processor/Thermal objects " info.num_STA = 0;
"and executing _INI/_STA methods:\n")); info.num_INI = 0;
/* Tree analysis: find all subtrees that contain _INI methods */ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
"Initializing Device/Processor/Thermal objects "
"and executing _INI/_STA methods:\n"));
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, /* Tree analysis: find all subtrees that contain _INI methods */
ACPI_UINT32_MAX, FALSE,
acpi_ns_find_ini_methods, NULL, &info,
NULL);
if (ACPI_FAILURE(status)) {
goto error_exit;
}
/* Allocate the evaluation information block */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, FALSE,
acpi_ns_find_ini_methods, NULL,
&info, NULL);
if (ACPI_FAILURE(status)) {
goto error_exit;
}
/* Allocate the evaluation information block */
info.evaluate_info = info.evaluate_info =
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
if (!info.evaluate_info) { if (!info.evaluate_info) {
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto error_exit; goto error_exit;
}
/*
* Execute the "global" _INI method that may appear at the root.
* This support is provided for Windows compatibility (Vista+) and
* is not part of the ACPI specification.
*/
info.evaluate_info->prefix_node = acpi_gbl_root_node;
info.evaluate_info->relative_pathname = METHOD_NAME__INI;
info.evaluate_info->parameters = NULL;
info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
status = acpi_ns_evaluate(info.evaluate_info);
if (ACPI_SUCCESS(status)) {
info.num_INI++;
}
} }
/* /*
* Execute the "global" _INI method that may appear at the root. This * Run all _REG methods
* support is provided for Windows compatibility (Vista+) and is not *
* part of the ACPI specification. * Note: Any objects accessed by the _REG methods will be automatically
* initialized, even if they contain executable AML (see the call to
* acpi_ns_initialize_objects below).
*/ */
info.evaluate_info->prefix_node = acpi_gbl_root_node; if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
info.evaluate_info->relative_pathname = METHOD_NAME__INI; ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
info.evaluate_info->parameters = NULL; "[Init] Executing _REG OpRegion methods\n"));
info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
status = acpi_ns_evaluate(info.evaluate_info); status = acpi_ev_initialize_op_regions();
if (ACPI_SUCCESS(status)) { if (ACPI_FAILURE(status)) {
info.num_INI++; goto error_exit;
}
} }
/* Walk namespace to execute all _INIs on present devices */ if (!(flags & ACPI_NO_DEVICE_INIT)) {
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, /* Walk namespace to execute all _INIs on present devices */
ACPI_UINT32_MAX, FALSE,
acpi_ns_init_one_device, NULL, &info,
NULL);
/* status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
* Any _OSI requests should be completed by now. If the BIOS has ACPI_UINT32_MAX, FALSE,
* requested any Windows OSI strings, we will always truncate acpi_ns_init_one_device, NULL,
* I/O addresses to 16 bits -- for Windows compatibility. &info, NULL);
*/
if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) {
acpi_gbl_truncate_io_addresses = TRUE;
}
ACPI_FREE(info.evaluate_info); /*
if (ACPI_FAILURE(status)) { * Any _OSI requests should be completed by now. If the BIOS has
goto error_exit; * requested any Windows OSI strings, we will always truncate
} * I/O addresses to 16 bits -- for Windows compatibility.
*/
if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) {
acpi_gbl_truncate_io_addresses = TRUE;
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ACPI_FREE(info.evaluate_info);
" Executed %u _INI methods requiring %u _STA executions " if (ACPI_FAILURE(status)) {
"(examined %u objects)\n", goto error_exit;
info.num_INI, info.num_STA, info.device_count)); }
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
" Executed %u _INI methods requiring %u _STA executions "
"(examined %u objects)\n",
info.num_INI, info.num_STA,
info.device_count));
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
......
...@@ -301,33 +301,14 @@ acpi_status __init acpi_initialize_objects(u32 flags) ...@@ -301,33 +301,14 @@ acpi_status __init acpi_initialize_objects(u32 flags)
} }
} }
/*
* Run all _REG methods
*
* Note: Any objects accessed by the _REG methods will be automatically
* initialized, even if they contain executable AML (see the call to
* acpi_ns_initialize_objects below).
*/
acpi_gbl_reg_methods_enabled = TRUE; acpi_gbl_reg_methods_enabled = TRUE;
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"[Init] Executing _REG OpRegion methods\n"));
status = acpi_ev_initialize_op_regions();
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
}
/* /*
* Initialize all device objects in the namespace. This runs the device * Initialize all device/region objects in the namespace. This runs
* _STA and _INI methods. * the device _STA and _INI methods and region _REG methods.
*/ */
if (!(flags & ACPI_NO_DEVICE_INIT)) { if (!(flags & (ACPI_NO_DEVICE_INIT | ACPI_NO_ADDRESS_SPACE_INIT))) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, status = acpi_ns_initialize_devices(flags);
"[Init] Initializing ACPI Devices\n"));
status = acpi_ns_initialize_devices();
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment