diff options
Diffstat (limited to 'drivers/acpi/tables/tbfadt.c')
-rw-r--r-- | drivers/acpi/tables/tbfadt.c | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 8816bab0fe0e..31a4a00d2fd3 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -52,6 +52,10 @@ static void inline | |||
52 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 52 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
53 | u8 bit_width, u64 address); | 53 | u8 bit_width, u64 address); |
54 | 54 | ||
55 | static void acpi_tb_convert_fadt(void); | ||
56 | |||
57 | static void acpi_tb_validate_fadt(void); | ||
58 | |||
55 | /* Table for conversion of FADT to common internal format and FADT validation */ | 59 | /* Table for conversion of FADT to common internal format and FADT validation */ |
56 | 60 | ||
57 | typedef struct acpi_fadt_info { | 61 | typedef struct acpi_fadt_info { |
@@ -178,13 +182,47 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) | |||
178 | */ | 182 | */ |
179 | (void)acpi_tb_verify_checksum(table, length); | 183 | (void)acpi_tb_verify_checksum(table, length); |
180 | 184 | ||
185 | /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ | ||
186 | |||
187 | acpi_tb_create_local_fadt(table, length); | ||
188 | |||
189 | /* All done with the real FADT, unmap it */ | ||
190 | |||
191 | acpi_os_unmap_memory(table, length); | ||
192 | |||
193 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | ||
194 | |||
195 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | ||
196 | flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | ||
197 | |||
198 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, | ||
199 | flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); | ||
200 | } | ||
201 | |||
202 | /******************************************************************************* | ||
203 | * | ||
204 | * FUNCTION: acpi_tb_create_local_fadt | ||
205 | * | ||
206 | * PARAMETERS: Table - Pointer to BIOS FADT | ||
207 | * Length - Length of the table | ||
208 | * | ||
209 | * RETURN: None | ||
210 | * | ||
211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. | ||
212 | * Performs validation on some important FADT fields. | ||
213 | * | ||
214 | ******************************************************************************/ | ||
215 | |||
216 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | ||
217 | { | ||
218 | |||
181 | /* | 219 | /* |
182 | * If the FADT is larger than what we know about, we have a problem. | 220 | * Check if the FADT is larger than what we know about (ACPI 2.0 version). |
183 | * Truncate the table, but make some noise. | 221 | * Truncate the table, but make some noise. |
184 | */ | 222 | */ |
185 | if (length > sizeof(struct acpi_table_fadt)) { | 223 | if (length > sizeof(struct acpi_table_fadt)) { |
186 | ACPI_WARNING((AE_INFO, | 224 | ACPI_WARNING((AE_INFO, |
187 | "FADT (revision %u) is too large, truncating length 0x%X to 0x%X", | 225 | "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%X", |
188 | table->revision, length, | 226 | table->revision, length, |
189 | sizeof(struct acpi_table_fadt))); | 227 | sizeof(struct acpi_table_fadt))); |
190 | } | 228 | } |
@@ -192,27 +230,16 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) | |||
192 | /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ | 230 | /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ |
193 | 231 | ||
194 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); | 232 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); |
233 | |||
195 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | 234 | ACPI_MEMCPY(&acpi_gbl_FADT, table, |
196 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); | 235 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); |
197 | 236 | ||
198 | /* All done with the real FADT, unmap it */ | ||
199 | |||
200 | acpi_os_unmap_memory(table, length); | ||
201 | |||
202 | /* | 237 | /* |
203 | * 1) Convert the local copy of the FADT to the common internal format | 238 | * 1) Convert the local copy of the FADT to the common internal format |
204 | * 2) Validate some of the important values within the FADT | 239 | * 2) Validate some of the important values within the FADT |
205 | */ | 240 | */ |
206 | acpi_tb_convert_fadt(); | 241 | acpi_tb_convert_fadt(); |
207 | acpi_tb_validate_fadt(&acpi_gbl_FADT); | 242 | acpi_tb_validate_fadt(); |
208 | |||
209 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | ||
210 | |||
211 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | ||
212 | flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | ||
213 | |||
214 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, | ||
215 | flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); | ||
216 | } | 243 | } |
217 | 244 | ||
218 | /******************************************************************************* | 245 | /******************************************************************************* |
@@ -244,7 +271,7 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) | |||
244 | * | 271 | * |
245 | ******************************************************************************/ | 272 | ******************************************************************************/ |
246 | 273 | ||
247 | void acpi_tb_convert_fadt(void) | 274 | static void acpi_tb_convert_fadt(void) |
248 | { | 275 | { |
249 | u8 pm1_register_length; | 276 | u8 pm1_register_length; |
250 | struct acpi_generic_address *target; | 277 | struct acpi_generic_address *target; |
@@ -337,7 +364,7 @@ void acpi_tb_convert_fadt(void) | |||
337 | * | 364 | * |
338 | ******************************************************************************/ | 365 | ******************************************************************************/ |
339 | 366 | ||
340 | void acpi_tb_validate_fadt(struct acpi_table_fadt *table) | 367 | static void acpi_tb_validate_fadt(void) |
341 | { | 368 | { |
342 | u32 *address32; | 369 | u32 *address32; |
343 | struct acpi_generic_address *address64; | 370 | struct acpi_generic_address *address64; |
@@ -351,10 +378,14 @@ void acpi_tb_validate_fadt(struct acpi_table_fadt *table) | |||
351 | /* Generate pointers to the 32-bit and 64-bit addresses and get the length */ | 378 | /* Generate pointers to the 32-bit and 64-bit addresses and get the length */ |
352 | 379 | ||
353 | address64 = | 380 | address64 = |
354 | ACPI_ADD_PTR(struct acpi_generic_address, table, | 381 | ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, |
355 | fadt_info_table[i].target); | 382 | fadt_info_table[i].target); |
356 | address32 = ACPI_ADD_PTR(u32, table, fadt_info_table[i].source); | 383 | address32 = |
357 | length = *ACPI_ADD_PTR(u8, table, fadt_info_table[i].length); | 384 | ACPI_ADD_PTR(u32, &acpi_gbl_FADT, |
385 | fadt_info_table[i].source); | ||
386 | length = | ||
387 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, | ||
388 | fadt_info_table[i].length); | ||
358 | 389 | ||
359 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { | 390 | if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) { |
360 | /* | 391 | /* |