📄 tbutils.c
字号:
} /* Map just the table header */ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); if (!table) { return; } /* If a particular signature is expected, signature must match */ if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { ACPI_ERROR((AE_INFO, "Invalid signature 0x%X for ACPI table [%s]", *ACPI_CAST_PTR(u32, table->signature), signature)); goto unmap_and_exit; } /* Initialize the table entry */ acpi_gbl_root_table_list.tables[table_index].address = address; acpi_gbl_root_table_list.tables[table_index].length = table->length; acpi_gbl_root_table_list.tables[table_index].flags = flags; ACPI_MOVE_32_TO_32(& (acpi_gbl_root_table_list.tables[table_index]. signature), table->signature); acpi_tb_print_table_header(address, table); if (table_index == ACPI_TABLE_INDEX_DSDT) { /* Global integer width is based upon revision of the DSDT */ acpi_ut_set_integer_width(table->revision); } unmap_and_exit: acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));}/******************************************************************************* * * FUNCTION: acpi_tb_get_root_table_entry * * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry * table_entry_size - sizeof 32 or 64 (RSDT or XSDT) * * RETURN: Physical address extracted from the root table * * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on * both 32-bit and 64-bit platforms * * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on * 64-bit platforms. * ******************************************************************************/static acpi_physical_addressacpi_tb_get_root_table_entry(u8 * table_entry, acpi_native_uint table_entry_size){ u64 address64; /* * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT */ if (table_entry_size == sizeof(u32)) { /* * 32-bit platform, RSDT: Return 32-bit table entry * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return */ return ((acpi_physical_address) (*ACPI_CAST_PTR(u32, table_entry))); } else { /* * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit */ ACPI_MOVE_64_TO_64(&address64, table_entry);#if ACPI_MACHINE_WIDTH == 32 if (address64 > ACPI_UINT32_MAX) { /* Will truncate 64-bit address to 32 bits, issue warning */ ACPI_WARNING((AE_INFO, "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating", ACPI_FORMAT_UINT64(address64))); }#endif return ((acpi_physical_address) (address64)); }}/******************************************************************************* * * FUNCTION: acpi_tb_parse_root_table * * PARAMETERS: Rsdp - Pointer to the RSDP * Flags - Flags * * RETURN: Status * * DESCRIPTION: This function is called to parse the Root System Description * Table (RSDT or XSDT) * * NOTE: Tables are mapped (not copied) for efficiency. The FACS must * be mapped and cannot be copied because it contains the actual * memory location of the ACPI Global Lock. * ******************************************************************************/acpi_status __initacpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags){ struct acpi_table_rsdp *rsdp; acpi_native_uint table_entry_size; acpi_native_uint i; u32 table_count; struct acpi_table_header *table; acpi_physical_address address; acpi_physical_address uninitialized_var(rsdt_address); u32 length; u8 *table_entry; acpi_status status; ACPI_FUNCTION_TRACE(tb_parse_root_table); /* * Map the entire RSDP and extract the address of the RSDT or XSDT */ rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp)); if (!rsdp) { return_ACPI_STATUS(AE_NO_MEMORY); } acpi_tb_print_table_header(rsdp_address, ACPI_CAST_PTR(struct acpi_table_header, rsdp)); /* Differentiate between RSDT and XSDT root tables */ if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { /* * Root table is an XSDT (64-bit physical addresses). We must use the * XSDT if the revision is > 1 and the XSDT pointer is present, as per * the ACPI specification. */ address = (acpi_physical_address) rsdp->xsdt_physical_address; table_entry_size = sizeof(u64); rsdt_address = (acpi_physical_address) rsdp->rsdt_physical_address; } else { /* Root table is an RSDT (32-bit physical addresses) */ address = (acpi_physical_address) rsdp->rsdt_physical_address; table_entry_size = sizeof(u32); } /* * It is not possible to map more than one entry in some environments, * so unmap the RSDP here before mapping other tables */ acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); if (table_entry_size == sizeof(u64)) { if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) { /* XSDT has NULL entry, RSDT is used */ address = rsdt_address; table_entry_size = sizeof(u32); ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, " "using RSDT")); } } /* Map the RSDT/XSDT table header to get the full table length */ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); if (!table) { return_ACPI_STATUS(AE_NO_MEMORY); } acpi_tb_print_table_header(address, table); /* Get the length of the full table, verify length and map entire table */ length = table->length; acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); if (length < sizeof(struct acpi_table_header)) { ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", length)); return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); } table = acpi_os_map_memory(address, length); if (!table) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Validate the root table checksum */ status = acpi_tb_verify_checksum(table, length); if (ACPI_FAILURE(status)) { acpi_os_unmap_memory(table, length); return_ACPI_STATUS(status); } /* Calculate the number of tables described in the root table */ table_count = (u32) ((table->length - sizeof(struct acpi_table_header)) / table_entry_size); /* * First two entries in the table array are reserved for the DSDT and FACS, * which are not actually present in the RSDT/XSDT - they come from the FADT */ table_entry = ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); acpi_gbl_root_table_list.count = 2; /* * Initialize the root table array from the RSDT/XSDT */ for (i = 0; i < table_count; i++) { if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { /* There is no more room in the root table array, attempt resize */ status = acpi_tb_resize_root_table_list(); if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "Truncating %u table entries!", (unsigned) (acpi_gbl_root_table_list.size - acpi_gbl_root_table_list. count))); break; } } /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. address = acpi_tb_get_root_table_entry(table_entry, table_entry_size); table_entry += table_entry_size; acpi_gbl_root_table_list.count++; } /* * It is not possible to map more than one entry in some environments, * so unmap the root table here before mapping other tables */ acpi_os_unmap_memory(table, length); /* * Complete the initialization of the root table array by examining * the header of each table */ for (i = 2; i < acpi_gbl_root_table_list.count; i++) { acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. address, flags, NULL, i); /* Special case for FADT - get the DSDT and FACS */ if (ACPI_COMPARE_NAME (&acpi_gbl_root_table_list.tables[i].signature, ACPI_SIG_FADT)) { acpi_tb_parse_fadt(i, flags); } } return_ACPI_STATUS(AE_OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -