acpi_status acpi_tb_install_table ( struct acpi_table_desc *table_info) { acpi_status status; ACPI_FUNCTION_TRACE ("tb_install_table"); /* Lock tables while installing */ status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n", table_info->pointer->signature, acpi_format_exception (status))); return_ACPI_STATUS (status); } /* Install the table into the global data structure */ status = acpi_tb_init_table_descriptor (table_info->type, table_info); if (ACPI_FAILURE (status)) { ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n", table_info->pointer->signature, acpi_format_exception (status))); } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", acpi_gbl_table_data[table_info->type].name, table_info->pointer)); (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); return_ACPI_STATUS (status); }
acpi_status acpi_tb_install_table ( acpi_table_header *table_ptr, acpi_table_desc *table_info) { acpi_status status; FUNCTION_TRACE ("Tb_install_table"); /* * Check the table signature and make sure it is recognized * Also checks the header checksum */ status = acpi_tb_recognize_table (table_ptr, table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Lock tables while installing */ acpi_ut_acquire_mutex (ACPI_MTX_TABLES); /* Install the table into the global data structure */ status = acpi_tb_init_table_descriptor (table_info->type, table_info); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer)); acpi_ut_release_mutex (ACPI_MTX_TABLES); return_ACPI_STATUS (status); }
acpi_status acpi_tb_get_table_rsdt ( void) { struct acpi_table_desc table_info; acpi_status status; struct acpi_pointer address; ACPI_FUNCTION_TRACE ("tb_get_table_rsdt"); /* Get the RSDT/XSDT via the RSDP */ acpi_tb_get_rsdt_address (&address); table_info.type = ACPI_TABLE_XSDT; status = acpi_tb_get_table (&address, &table_info); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n", acpi_gbl_RSDP, ACPI_FORMAT_UINT64 (address.pointer.value))); /* Check the RSDT or XSDT signature */ status = acpi_tb_validate_rsdt (table_info.pointer); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Get the number of tables defined in the RSDT or XSDT */ acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer); /* Convert and/or copy to an XSDT structure */ status = acpi_tb_convert_to_xsdt (&table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Save the table pointers and allocation info */ status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } acpi_gbl_XSDT = ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info.pointer); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); return_ACPI_STATUS (status); }
acpi_status acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, acpi_physical_address address, u8 flags) { struct acpi_table_header *table_header; switch (flags & ACPI_TABLE_ORIGIN_MASK) { case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: /* Get the length of the full table from the header */ table_header = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); if (!table_header) { return (AE_NO_MEMORY); } acpi_tb_init_table_descriptor(table_desc, address, flags, table_header); acpi_os_unmap_memory(table_header, sizeof(struct acpi_table_header)); return (AE_OK); case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: table_header = ACPI_CAST_PTR(struct acpi_table_header, ACPI_PHYSADDR_TO_PTR(address)); if (!table_header) { return (AE_NO_MEMORY); } acpi_tb_init_table_descriptor(table_desc, address, flags, table_header); return (AE_OK); default: break; } /* Table is not valid yet */ return (AE_NO_MEMORY); }
/**ltl * 功能: 将ACPI表的描述信息插入到全局列表中 * 参数: * 返回值: * 说明: */ acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) { acpi_status status; ACPI_FUNCTION_TRACE(tb_install_table); /* Lock tables while installing */ /* 1.获取mutex锁 */ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not acquire table mutex")); return_ACPI_STATUS(status); } /* * Ignore a table that is already installed. For example, some BIOS * ASL code will repeatedly attempt to load the same SSDT. */ /* 判定表是否已经在全局列表中 */ status = acpi_tb_is_table_installed(table_info); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } /* Install the table into the global data structure */ /* 将ACPI表的描述信息插入到全局列表中 */ status = acpi_tb_init_table_descriptor(table_info->type, table_info); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not install table [%4.4s]", table_info->pointer->signature)); } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", acpi_gbl_table_data[table_info->type].name, table_info->pointer)); unlock_and_exit: /* 释放mutex锁 */ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_tb_verify_rsdp * * PARAMETERS: Address - RSDP (Pointer to RSDT) * * RETURN: Status * * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) * ******************************************************************************/ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) { struct acpi_table_desc table_info; acpi_status status; struct rsdp_descriptor *rsdp; ACPI_FUNCTION_TRACE(tb_verify_rsdp); switch (address->pointer_type) { case ACPI_LOGICAL_POINTER: rsdp = address->pointer.logical; break; case ACPI_PHYSICAL_POINTER: /* * Obtain access to the RSDP structure */ status = acpi_os_map_memory(address->pointer.physical, sizeof(struct rsdp_descriptor), ACPI_CAST_PTR(void, &rsdp)); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } break; default: return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Verify RSDP signature and checksum */ status = acpi_tb_validate_rsdp(rsdp); if (ACPI_FAILURE(status)) { goto cleanup; } /* RSDP is ok. Init the table info */ table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); table_info.length = sizeof(struct rsdp_descriptor); if (address->pointer_type == ACPI_PHYSICAL_POINTER) { table_info.allocation = ACPI_MEM_MAPPED; } else { table_info.allocation = ACPI_MEM_NOT_ALLOCATED; } /* Save the table pointers and allocation info */ status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); if (ACPI_FAILURE(status)) { goto cleanup; } /* Save the RSDP in a global for easy access */ acpi_gbl_RSDP = ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer); return_ACPI_STATUS(status); /* Error exit */ cleanup: if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor)); } return_ACPI_STATUS(status); }
acpi_status acpi_tb_verify_rsdp ( struct acpi_pointer *address) { struct acpi_table_desc table_info; acpi_status status; struct rsdp_descriptor *rsdp; ACPI_FUNCTION_TRACE ("tb_verify_rsdp"); switch (address->pointer_type) { case ACPI_LOGICAL_POINTER: rsdp = address->pointer.logical; break; case ACPI_PHYSICAL_POINTER: /* * Obtain access to the RSDP structure */ status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor), (void *) &rsdp); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } break; default: return_ACPI_STATUS (AE_BAD_PARAMETER); } /* * The signature and checksum must both be correct */ if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { /* Nope, BAD Signature */ status = AE_BAD_SIGNATURE; goto cleanup; } /* Check the standard checksum */ if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { status = AE_BAD_CHECKSUM; goto cleanup; } /* Check extended checksum if table version >= 2 */ if (rsdp->revision >= 2) { if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) { status = AE_BAD_CHECKSUM; goto cleanup; } } /* The RSDP supplied is OK */ table_info.pointer = ACPI_CAST_PTR (struct acpi_table_header, rsdp); table_info.length = sizeof (struct rsdp_descriptor); table_info.allocation = ACPI_MEM_MAPPED; /* Save the table pointers and allocation info */ status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); if (ACPI_FAILURE (status)) { goto cleanup; } /* Save the RSDP in a global for easy access */ acpi_gbl_RSDP = ACPI_CAST_PTR (struct rsdp_descriptor, table_info.pointer); return_ACPI_STATUS (status); /* Error exit */ cleanup: if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { acpi_os_unmap_memory (rsdp, sizeof (struct rsdp_descriptor)); } return_ACPI_STATUS (status); }