aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2016-09-07 02:06:54 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-09-09 20:43:02 -0400
commitde56ba95e8d6d760910711744a548b50b3a4262d (patch)
tree2e1e05a6c198aadce4073fd9daa9920337125130
parent955f485dc40cdee265a85ad4af378f2a2cfaf11b (diff)
ACPICA: Interpreter: Fix MLC issues by switching to new term_list grammar for table loading
ACPICA commit 0e24fb67cde08d7df7671d7d7b183490dc79707e The MLC (Module Level Code) is an ACPICA terminology describing the AML code out of any control method, its support is an indication of the interpreter behavior during the table loading. The original implementation of MLC in ACPICA had several issues: 1. Out of any control method, besides of the object creating opcodes, only the code blocks wrapped by "If/Else/While" opcodes were supported. 2. The supported MLC code blocks were executed after loading the table rather than being executed right in place. ============================================================ The demo of this order issue is as follows: Name (OBJ1, 1) If (CND1 == 1) { Name (OBJ2, 2) } Name (OBJ3, 3) The original MLC support created OBJ2 after OBJ3's creation. ============================================================ Other than these limitations, MLC support in ACPICA looks correct. And supporting this should be easy/natural for ACPICA, but enabling of this was blocked by some ACPICA internal and OSPM specific initialization order issues we've fixed recently. The wrong support started from the following false bug fixing commit: Commit: 7f0c826a437157d2b19662977e9cf3b472cf24a6 Subject: ACPICA: Add support for module-level executable AML code Commit: 9a884ab64a4d092b4c3bf24fd9a30f7fbd4591e7 Subject: ACPICA: Add additional module-level code support ... We can confirm Windows interpreter behavior via reverse engineering means. It can be proven that not only If/Else/While wrapped code blocks, all opcodes can be executed at the module level, including operation region accesses. And it can be proven that the MLC should be executed right in place, not in such a deferred way executed after loading the table. And the above facts indeed reflect the spec words around ACPI definition block tables (DSDT/SSDT/...), the entire table and the Scope object is defined by the AML specification in BNF style as: AMLCode := def_block_header term_list def_scope := scope_op pkg_length name_string term_list The bodies of the scope opening terms (AMLCode/Scope) are all term_list, thus the table loading should be no difference than the control method evaluations as the body of the Method is also defined by the AML specification as term_list: def_method := method_op pkg_length name_string method_flags term_list The only difference is: after evaluating control method, created named objects may be freed due to no reference, while named objects created by the table loading should only be freed after unloading the table. So this patch follows the spec and the de-facto standard behavior, enables the new grammar (term_list) for the table loading. By doing so, beyond the fixes to the above issues, we can see additional differences comparing to the old grammar based table loading: 1. Originally, beyond the scope opening terms (AMLCode/Scope), If/Else/While wrapped code blocks under the scope creating terms (Device/power_resource/Processor/thermal_zone) are also supported as deferred MLC, which violates the spec defined grammar where object_list is enforced. With MLC support improved as non-deferred, the interpreter parses such scope creating terms as term_list rather object_list like the scope opening terms. After probing the Windows behavior and proving that it also parses these terms as term_list, we submitted an ECR (Engineering Change Request) to the ASWG (ACPI Specification Working Group) to clarify this. The ECR is titled as "ASL Grammar Clarification for Executable AML Opcodes" and has been accepted by the ASWG. The new grammar will appear in ACPI specification 6.2. 2. Originally, Buffer/Package/operation_region/create_XXXField/bank_field arguments are evaluated in a deferred way after loading the table. With MLC support improved, they are also parsed right in place during the table loading. This is also Windows compliant and the only difference is the removal of the debugging messages implemented before acpi_ds_execute_arguments(), see Link # [1] for the details. A previous commit should have ensured that acpi_check_address_range() won't regress. Note that enabling this feature may cause regressions due to long term Linux ACPI support on top of the wrong grammar. So this patch also prepares a global option to be used to roll back to the old grammar during the period between a regression is reported and the regression is root-cause-fixed. Lv Zheng. Link: https://bugzilla.kernel.org/show_bug.cgi?id=112911 # [1] Link: https://bugzilla.kernel.org/show_bug.cgi?id=117671 # [1] Link: https://bugzilla.kernel.org/show_bug.cgi?id=153541 # [1] Link: https://github.com/acpica/acpica/issues/122 Link: https://bugs.acpica.org/show_bug.cgi?id=963 Link: https://github.com/acpica/acpica/commit/0e24fb67 Reported-and-tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> Reported-by: Ehsan <dashesy@gmail.com> Reported-and-tested-by: Dutch Guy <lucht_piloot@gmx.net> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/acnamesp.h3
-rw-r--r--drivers/acpi/acpica/acparser.h2
-rw-r--r--drivers/acpi/acpica/evrgnini.c3
-rw-r--r--drivers/acpi/acpica/exconfig.c3
-rw-r--r--drivers/acpi/acpica/nsload.c3
-rw-r--r--drivers/acpi/acpica/nsparse.c162
-rw-r--r--drivers/acpi/acpica/psparse.c4
-rw-r--r--drivers/acpi/acpica/psxface.c71
-rw-r--r--drivers/acpi/acpica/tbxfload.c3
-rw-r--r--drivers/acpi/acpica/utxfinit.c3
-rw-r--r--include/acpi/acpixf.h7
11 files changed, 227 insertions, 37 deletions
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index f33a4ba8e0cb..829672a288bd 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -130,6 +130,9 @@ acpi_status
130acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node); 130acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node);
131 131
132acpi_status 132acpi_status
133acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node);
134
135acpi_status
133acpi_ns_one_complete_parse(u32 pass_number, 136acpi_ns_one_complete_parse(u32 pass_number,
134 u32 table_index, 137 u32 table_index,
135 struct acpi_namespace_node *start_node); 138 struct acpi_namespace_node *start_node);
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h
index fc305775c3d7..939d41113970 100644
--- a/drivers/acpi/acpica/acparser.h
+++ b/drivers/acpi/acpica/acparser.h
@@ -78,6 +78,8 @@ extern const u8 acpi_gbl_long_op_index[];
78 */ 78 */
79acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info); 79acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info);
80 80
81acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info);
82
81/* 83/*
82 * psargs - Parse AML opcode arguments 84 * psargs - Parse AML opcode arguments
83 */ 85 */
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index b6ea9c0d0d8c..3843f1fc5dbb 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -553,7 +553,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
553 * 553 *
554 * See acpi_ns_exec_module_code 554 * See acpi_ns_exec_module_code
555 */ 555 */
556 if (obj_desc->method. 556 if (!acpi_gbl_parse_table_as_term_list &&
557 obj_desc->method.
557 info_flags & ACPI_METHOD_MODULE_LEVEL) { 558 info_flags & ACPI_METHOD_MODULE_LEVEL) {
558 handler_obj = 559 handler_obj =
559 obj_desc->method.dispatch.handler; 560 obj_desc->method.dispatch.handler;
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index a1d177d58254..74dd5bac8422 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -118,7 +118,8 @@ acpi_ex_add_table(u32 table_index,
118 /* Execute any module-level code that was found in the table */ 118 /* Execute any module-level code that was found in the table */
119 119
120 acpi_ex_exit_interpreter(); 120 acpi_ex_exit_interpreter();
121 if (acpi_gbl_group_module_level_code) { 121 if (!acpi_gbl_parse_table_as_term_list
122 && acpi_gbl_group_module_level_code) {
122 acpi_ns_exec_module_code_list(); 123 acpi_ns_exec_module_code_list();
123 } 124 }
124 acpi_ex_enter_interpreter(); 125 acpi_ex_enter_interpreter();
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index b5e2b0ada0ab..2daa9a093c56 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -162,7 +162,8 @@ unlock:
162 * other ACPI implementations. Optionally, the execution can be deferred 162 * other ACPI implementations. Optionally, the execution can be deferred
163 * until later, see acpi_initialize_objects. 163 * until later, see acpi_initialize_objects.
164 */ 164 */
165 if (!acpi_gbl_group_module_level_code) { 165 if (!acpi_gbl_parse_table_as_term_list
166 && !acpi_gbl_group_module_level_code) {
166 acpi_ns_exec_module_code_list(); 167 acpi_ns_exec_module_code_list();
167 } 168 }
168 169
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index f631a47724f0..e51012b90118 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -53,6 +53,96 @@ ACPI_MODULE_NAME("nsparse")
53 53
54/******************************************************************************* 54/*******************************************************************************
55 * 55 *
56 * FUNCTION: ns_execute_table
57 *
58 * PARAMETERS: table_desc - An ACPI table descriptor for table to parse
59 * start_node - Where to enter the table into the namespace
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Load ACPI/AML table by executing the entire table as a
64 * term_list.
65 *
66 ******************************************************************************/
67acpi_status
68acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node)
69{
70 acpi_status status;
71 struct acpi_table_header *table;
72 acpi_owner_id owner_id;
73 struct acpi_evaluate_info *info = NULL;
74 u32 aml_length;
75 u8 *aml_start;
76 union acpi_operand_object *method_obj = NULL;
77
78 ACPI_FUNCTION_TRACE(ns_execute_table);
79
80 status = acpi_get_table_by_index(table_index, &table);
81 if (ACPI_FAILURE(status)) {
82 return_ACPI_STATUS(status);
83 }
84
85 /* Table must consist of at least a complete header */
86
87 if (table->length < sizeof(struct acpi_table_header)) {
88 return_ACPI_STATUS(AE_BAD_HEADER);
89 }
90
91 aml_start = (u8 *)table + sizeof(struct acpi_table_header);
92 aml_length = table->length - sizeof(struct acpi_table_header);
93
94 status = acpi_tb_get_owner_id(table_index, &owner_id);
95 if (ACPI_FAILURE(status)) {
96 return_ACPI_STATUS(status);
97 }
98
99 /* Create, initialize, and link a new temporary method object */
100
101 method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
102 if (!method_obj) {
103 return_ACPI_STATUS(AE_NO_MEMORY);
104 }
105
106 /* Allocate the evaluation information block */
107
108 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
109 if (!info) {
110 status = AE_NO_MEMORY;
111 goto cleanup;
112 }
113
114 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
115 "Create table code block: %p\n", method_obj));
116
117 method_obj->method.aml_start = aml_start;
118 method_obj->method.aml_length = aml_length;
119 method_obj->method.owner_id = owner_id;
120 method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
121
122 info->pass_number = ACPI_IMODE_EXECUTE;
123 info->node = start_node;
124 info->obj_desc = method_obj;
125 info->node_flags = info->node->flags;
126 info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
127 if (!info->full_pathname) {
128 status = AE_NO_MEMORY;
129 goto cleanup;
130 }
131
132 status = acpi_ps_execute_table(info);
133
134cleanup:
135 if (info) {
136 ACPI_FREE(info->full_pathname);
137 info->full_pathname = NULL;
138 }
139 ACPI_FREE(info);
140 acpi_ut_remove_reference(method_obj);
141 return_ACPI_STATUS(status);
142}
143
144/*******************************************************************************
145 *
56 * FUNCTION: ns_one_complete_parse 146 * FUNCTION: ns_one_complete_parse
57 * 147 *
58 * PARAMETERS: pass_number - 1 or 2 148 * PARAMETERS: pass_number - 1 or 2
@@ -63,6 +153,7 @@ ACPI_MODULE_NAME("nsparse")
63 * DESCRIPTION: Perform one complete parse of an ACPI/AML table. 153 * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
64 * 154 *
65 ******************************************************************************/ 155 ******************************************************************************/
156
66acpi_status 157acpi_status
67acpi_ns_one_complete_parse(u32 pass_number, 158acpi_ns_one_complete_parse(u32 pass_number,
68 u32 table_index, 159 u32 table_index,
@@ -170,38 +261,47 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
170 261
171 ACPI_FUNCTION_TRACE(ns_parse_table); 262 ACPI_FUNCTION_TRACE(ns_parse_table);
172 263
173 /* 264 if (acpi_gbl_parse_table_as_term_list) {
174 * AML Parse, pass 1 265 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start load pass\n"));
175 *
176 * In this pass, we load most of the namespace. Control methods
177 * are not parsed until later. A parse tree is not created. Instead,
178 * each Parser Op subtree is deleted when it is finished. This saves
179 * a great deal of memory, and allows a small cache of parse objects
180 * to service the entire parse. The second pass of the parse then
181 * performs another complete parse of the AML.
182 */
183 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
184
185 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
186 table_index, start_node);
187 if (ACPI_FAILURE(status)) {
188 return_ACPI_STATUS(status);
189 }
190 266
191 /* 267 status = acpi_ns_execute_table(table_index, start_node);
192 * AML Parse, pass 2 268 if (ACPI_FAILURE(status)) {
193 * 269 return_ACPI_STATUS(status);
194 * In this pass, we resolve forward references and other things 270 }
195 * that could not be completed during the first pass. 271 } else {
196 * Another complete parse of the AML is performed, but the 272 /*
197 * overhead of this is compensated for by the fact that the 273 * AML Parse, pass 1
198 * parse objects are all cached. 274 *
199 */ 275 * In this pass, we load most of the namespace. Control methods
200 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); 276 * are not parsed until later. A parse tree is not created.
201 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, 277 * Instead, each Parser Op subtree is deleted when it is finished.
202 table_index, start_node); 278 * This saves a great deal of memory, and allows a small cache of
203 if (ACPI_FAILURE(status)) { 279 * parse objects to service the entire parse. The second pass of
204 return_ACPI_STATUS(status); 280 * the parse then performs another complete parse of the AML.
281 */
282 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
283
284 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
285 table_index, start_node);
286 if (ACPI_FAILURE(status)) {
287 return_ACPI_STATUS(status);
288 }
289
290 /*
291 * AML Parse, pass 2
292 *
293 * In this pass, we resolve forward references and other things
294 * that could not be completed during the first pass.
295 * Another complete parse of the AML is performed, but the
296 * overhead of this is compensated for by the fact that the
297 * parse objects are all cached.
298 */
299 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
300 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
301 table_index, start_node);
302 if (ACPI_FAILURE(status)) {
303 return_ACPI_STATUS(status);
304 }
205 } 305 }
206 306
207 return_ACPI_STATUS(status); 307 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index 0a23897d8adf..3aa91625fca7 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -571,7 +571,9 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
571 * cleanup to do 571 * cleanup to do
572 */ 572 */
573 if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == 573 if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
574 ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) { 574 ACPI_PARSE_EXECUTE &&
575 !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) ||
576 (ACPI_FAILURE(status))) {
575 acpi_ds_terminate_control_method(walk_state-> 577 acpi_ds_terminate_control_method(walk_state->
576 method_desc, 578 method_desc,
577 walk_state); 579 walk_state);
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c
index cf30cd821f5e..22a52c28c048 100644
--- a/drivers/acpi/acpica/psxface.c
+++ b/drivers/acpi/acpica/psxface.c
@@ -252,6 +252,77 @@ cleanup:
252 252
253/******************************************************************************* 253/*******************************************************************************
254 * 254 *
255 * FUNCTION: acpi_ps_execute_table
256 *
257 * PARAMETERS: info - Method info block, contains:
258 * node - Node to where the is entered into the
259 * namespace
260 * obj_desc - Pseudo method object describing the AML
261 * code of the entire table
262 * pass_number - Parse or execute pass
263 *
264 * RETURN: Status
265 *
266 * DESCRIPTION: Execute a table
267 *
268 ******************************************************************************/
269
270acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info)
271{
272 acpi_status status;
273 union acpi_parse_object *op = NULL;
274 struct acpi_walk_state *walk_state = NULL;
275
276 ACPI_FUNCTION_TRACE(ps_execute_table);
277
278 /* Create and init a Root Node */
279
280 op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
281 if (!op) {
282 status = AE_NO_MEMORY;
283 goto cleanup;
284 }
285
286 /* Create and initialize a new walk state */
287
288 walk_state =
289 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
290 NULL, NULL);
291 if (!walk_state) {
292 status = AE_NO_MEMORY;
293 goto cleanup;
294 }
295
296 status = acpi_ds_init_aml_walk(walk_state, op, info->node,
297 info->obj_desc->method.aml_start,
298 info->obj_desc->method.aml_length, info,
299 info->pass_number);
300 if (ACPI_FAILURE(status)) {
301 goto cleanup;
302 }
303
304 if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
305 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
306 }
307
308 /*
309 * Parse the AML, walk_state will be deleted by parse_aml
310 */
311 status = acpi_ps_parse_aml(walk_state);
312 walk_state = NULL;
313
314cleanup:
315 if (walk_state) {
316 acpi_ds_delete_walk_state(walk_state);
317 }
318 if (op) {
319 acpi_ps_delete_parse_tree(op);
320 }
321 return_ACPI_STATUS(status);
322}
323
324/*******************************************************************************
325 *
255 * FUNCTION: acpi_ps_update_parameter_list 326 * FUNCTION: acpi_ps_update_parameter_list
256 * 327 *
257 * PARAMETERS: info - See struct acpi_evaluate_info 328 * PARAMETERS: info - See struct acpi_evaluate_info
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
index e0cc9199866b..608871212d8c 100644
--- a/drivers/acpi/acpica/tbxfload.c
+++ b/drivers/acpi/acpica/tbxfload.c
@@ -103,7 +103,8 @@ acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void)
103 "While loading namespace from ACPI tables")); 103 "While loading namespace from ACPI tables"));
104 } 104 }
105 105
106 if (!acpi_gbl_group_module_level_code) { 106 if (acpi_gbl_parse_table_as_term_list
107 || !acpi_gbl_group_module_level_code) {
107 /* 108 /*
108 * Initialize the objects that remain uninitialized. This 109 * Initialize the objects that remain uninitialized. This
109 * runs the executable AML that may be part of the 110 * runs the executable AML that may be part of the
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
index d6d946220351..a5ca0f57cd08 100644
--- a/drivers/acpi/acpica/utxfinit.c
+++ b/drivers/acpi/acpica/utxfinit.c
@@ -265,7 +265,8 @@ acpi_status ACPI_INIT_FUNCTION acpi_initialize_objects(u32 flags)
265 * all of the tables have been loaded. It is a legacy option and is 265 * all of the tables have been loaded. It is a legacy option and is
266 * not compatible with other ACPI implementations. See acpi_ns_load_table. 266 * not compatible with other ACPI implementations. See acpi_ns_load_table.
267 */ 267 */
268 if (acpi_gbl_group_module_level_code) { 268 if (!acpi_gbl_parse_table_as_term_list
269 && acpi_gbl_group_module_level_code) {
269 acpi_ns_exec_module_code_list(); 270 acpi_ns_exec_module_code_list();
270 271
271 /* 272 /*
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 8b44717f72f3..cf78ec2b3374 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -195,6 +195,13 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
195ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, TRUE); 195ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, TRUE);
196 196
197/* 197/*
198 * Optionally support module level code by parsing the entire table as
199 * a term_list. Default is FALSE, do not execute entire table until some
200 * lock order issues are fixed.
201 */
202ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, FALSE);
203
204/*
198 * Optionally use 32-bit FADT addresses if and when there is a conflict 205 * Optionally use 32-bit FADT addresses if and when there is a conflict
199 * (address mismatch) between the 32-bit and 64-bit versions of the 206 * (address mismatch) between the 32-bit and 64-bit versions of the
200 * address. Although ACPICA adheres to the ACPI specification which 207 * address. Although ACPICA adheres to the ACPI specification which