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