void acpi_tb_parse_fadt(u32 table_index) { u32 length; struct acpi_table_header *table; length = acpi_gbl_root_table_list.tables[table_index].length; table = acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index]. address, length); if (!table) { return; } (void)acpi_tb_verify_checksum(table, length); acpi_tb_create_local_fadt(table, length); acpi_os_unmap_memory(table, length); acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); }
void acpi_tb_parse_fadt(u32 table_index) { u32 length; struct acpi_table_header *table; /* * The FADT has multiple versions with different lengths, * and it contains pointers to both the DSDT and FACS tables. * * Get a local copy of the FADT and convert it to a common format * Map entire FADT, assumed to be smaller than one page. */ length = acpi_gbl_root_table_list.tables[table_index].length; table = acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index]. address, length); if (!table) { return; } /* * Validate the FADT checksum before we copy the table. Ignore * checksum error as we want to try to get the DSDT and FACS. */ (void)acpi_tb_verify_checksum(table, length); /* Create a local copy of the FADT in common ACPI 2.0+ format */ acpi_tb_create_local_fadt(table, length); /* All done with the real FADT, unmap it */ acpi_os_unmap_memory(table, length); /* Obtain the DSDT and FACS tables via their addresses within the FADT */ acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); /* If Hardware Reduced flag is set, there is no FACS */ if (!acpi_gbl_reduced_hardware) { acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. Xfacs, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); } }
acpi_status acpi_tb_get_primary_table ( struct acpi_pointer *address, struct acpi_table_desc *table_info) { acpi_status status; struct acpi_table_header header; ACPI_FUNCTION_TRACE ("tb_get_primary_table"); /* Ignore a NULL address in the RSDT */ if (!address->pointer.value) { return_ACPI_STATUS (AE_OK); } /* * Get the header in order to get signature and table size */ status = acpi_tb_get_table_header (address, &header); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Clear the table_info */ ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc)); /* * Check the table signature and make sure it is recognized. * Also checks the header checksum */ table_info->pointer = &header; status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Get the entire table */ status = acpi_tb_get_table_body (address, &header, table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the table */ status = acpi_tb_install_table (table_info); return_ACPI_STATUS (status); }
static acpi_status acpi_tb_get_secondary_table ( struct acpi_pointer *address, acpi_string signature, struct acpi_table_desc *table_info) { acpi_status status; struct acpi_table_header header; ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature); /* Get the header in order to match the signature */ status = acpi_tb_get_table_header (address, &header); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Signature must match request */ if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) { ACPI_REPORT_ERROR (( "Incorrect table signature - wanted [%s] found [%4.4s]\n", signature, header.signature)); return_ACPI_STATUS (AE_BAD_SIGNATURE); } /* * Check the table signature and make sure it is recognized. * Also checks the header checksum */ table_info->pointer = &header; status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Get the entire table */ status = acpi_tb_get_table_body (address, &header, table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the table */ status = acpi_tb_install_table (table_info); return_ACPI_STATUS (status); }
acpi_status acpi_load_table ( acpi_table_header *table_ptr) { acpi_status status; acpi_table_desc table_info; FUNCTION_TRACE ("Acpi_load_table"); if (!table_ptr) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Copy the table to a local buffer */ status = acpi_tb_get_table (0, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the new table into the local data structures */ status = acpi_tb_install_table (NULL, &table_info); if (ACPI_FAILURE (status)) { /* Free table allocated by Acpi_tb_get_table */ acpi_tb_delete_single_table (&table_info); return_ACPI_STATUS (status); } status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); if (ACPI_FAILURE (status)) { /* Uninstall table and free the buffer */ acpi_tb_uninstall_table (table_info.installed_desc); return_ACPI_STATUS (status); } return_ACPI_STATUS (status); }
acpi_status acpi_load_table ( struct acpi_table_header *table_ptr) { acpi_status status; struct acpi_table_desc table_info; struct acpi_pointer address; ACPI_FUNCTION_TRACE ("acpi_load_table"); if (!table_ptr) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Copy the table to a local buffer */ address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; address.pointer.logical = table_ptr; status = acpi_tb_get_table_body (&address, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the new table into the local data structures */ status = acpi_tb_install_table (&table_info); if (ACPI_FAILURE (status)) { /* Free table allocated by acpi_tb_get_table_body */ acpi_tb_delete_single_table (&table_info); return_ACPI_STATUS (status); } /* Convert the table to common format if necessary */ switch (table_info.type) { case ACPI_TABLE_FADT: status = acpi_tb_convert_table_fadt (); break; case ACPI_TABLE_FACS: status = acpi_tb_build_common_facs (&table_info); break; default: /* Load table into namespace if it contains executable AML */ status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); break; } if (ACPI_FAILURE (status)) { /* Uninstall table and free the buffer */ (void) acpi_tb_uninstall_table (table_info.installed_desc); } return_ACPI_STATUS (status); }
static acpi_status acpi_ex_add_table(struct acpi_table_header *table, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle) { acpi_status status; struct acpi_table_desc table_info; union acpi_operand_object *obj_desc; ACPI_FUNCTION_TRACE(ex_add_table); /* Create an object to be the table handle */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE); if (!obj_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Init the table handle */ obj_desc->reference.opcode = AML_LOAD_OP; *ddb_handle = obj_desc; /* Install the new table into the local data structures */ ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); table_info.type = ACPI_TABLE_ID_SSDT; table_info.pointer = table; table_info.length = (acpi_size) table->length; table_info.allocation = ACPI_MEM_ALLOCATED; status = acpi_tb_install_table(&table_info); obj_desc->reference.object = table_info.installed_desc; if (ACPI_FAILURE(status)) { if (status == AE_ALREADY_EXISTS) { /* Table already exists, just return the handle */ return_ACPI_STATUS(AE_OK); } goto cleanup; } /* Add the table to the namespace */ status = acpi_ns_load_table(table_info.installed_desc, parent_node); if (ACPI_FAILURE(status)) { /* Uninstall table on error */ (void)acpi_tb_uninstall_table(table_info.installed_desc); goto cleanup; } return_ACPI_STATUS(AE_OK); cleanup: acpi_ut_remove_reference(obj_desc); *ddb_handle = NULL; return_ACPI_STATUS(status); }