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