^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: tbutils - ACPI Table utilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "actables.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define _COMPONENT ACPI_TABLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACPI_MODULE_NAME("tbutils")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static acpi_physical_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #if (!ACPI_REDUCED_HARDWARE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * FUNCTION: acpi_tb_initialize_facs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * for accessing the Global Lock and Firmware Waking Vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) acpi_status acpi_tb_initialize_facs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct acpi_table_facs *facs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* If Hardware Reduced flag is set, there is no FACS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (acpi_gbl_reduced_hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) acpi_gbl_FACS = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) } else if (acpi_gbl_FADT.Xfacs &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) (!acpi_gbl_FADT.facs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) || !acpi_gbl_use32_bit_facs_addresses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) (void)acpi_get_table_by_index(acpi_gbl_xfacs_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ACPI_CAST_INDIRECT_PTR(struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) acpi_table_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) &facs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) acpi_gbl_FACS = facs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) } else if (acpi_gbl_FADT.facs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) (void)acpi_get_table_by_index(acpi_gbl_facs_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ACPI_CAST_INDIRECT_PTR(struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) acpi_table_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) &facs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) acpi_gbl_FACS = facs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* If there is no FACS, just continue. There was already an error msg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #endif /* !ACPI_REDUCED_HARDWARE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * FUNCTION: acpi_tb_check_dsdt_header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * if the DSDT has been replaced from outside the OS and/or if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * the DSDT header has been corrupted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void acpi_tb_check_dsdt_header(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Compare original length and checksum to current values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ACPI_BIOS_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) "The DSDT has been corrupted or replaced - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) "old, new headers below"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) acpi_tb_print_table_header(0, acpi_gbl_DSDT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) "Please send DMI info to linux-acpi@vger.kernel.org\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) "If system does not work as expected, please boot with acpi=copy_dsdt"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Disable further error messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) acpi_gbl_original_dsdt_header.checksum =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) acpi_gbl_DSDT->checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * FUNCTION: acpi_tb_copy_dsdt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * PARAMETERS: table_index - Index of installed table to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * RETURN: The copied DSDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Some very bad BIOSs are known to either corrupt the DSDT or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * install a new, bad DSDT. This copy works around the problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct acpi_table_header *new_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct acpi_table_desc *table_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) table_desc = &acpi_gbl_root_table_list.tables[table_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) new_table = ACPI_ALLOCATE(table_desc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!new_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) table_desc->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) memcpy(new_table, table_desc->pointer, table_desc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) acpi_tb_uninstall_table(table_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) tables[acpi_gbl_dsdt_index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ACPI_PTR_TO_PHYSADDR(new_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) new_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ACPI_INFO(("Forced DSDT copy: length 0x%05X copied locally, original unmapped", new_table->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return (new_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * FUNCTION: acpi_tb_get_root_table_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * table_entry_size - sizeof 32 or 64 (RSDT or XSDT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * RETURN: Physical address extracted from the root table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * both 32-bit and 64-bit platforms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * 64-bit platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static acpi_physical_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u64 address64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (table_entry_size == ACPI_RSDT_ENTRY_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * 32-bit platform, RSDT: Return 32-bit table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ((acpi_physical_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (*ACPI_CAST_PTR(u32, table_entry)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * return 64-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ACPI_MOVE_64_TO_64(&address64, table_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #if ACPI_MACHINE_WIDTH == 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (address64 > ACPI_UINT32_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Will truncate 64-bit address to 32 bits, issue warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ACPI_BIOS_WARNING((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) " truncating",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ACPI_FORMAT_UINT64(address64)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return ((acpi_physical_address)(address64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * FUNCTION: acpi_tb_parse_root_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * PARAMETERS: rsdp_address - Pointer to the RSDP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * DESCRIPTION: This function is called to parse the Root System Description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Table (RSDT or XSDT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * be mapped and cannot be copied because it contains the actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * memory location of the ACPI Global Lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) acpi_status ACPI_INIT_FUNCTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct acpi_table_rsdp *rsdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) u32 table_entry_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 table_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct acpi_table_header *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) acpi_physical_address address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u8 *table_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u32 table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ACPI_FUNCTION_TRACE(tb_parse_root_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Map the entire RSDP and extract the address of the RSDT or XSDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!rsdp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) acpi_tb_print_table_header(rsdp_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ACPI_CAST_PTR(struct acpi_table_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) rsdp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Use XSDT if present and not overridden. Otherwise, use RSDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if ((rsdp->revision > 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rsdp->xsdt_physical_address && !acpi_gbl_do_not_use_xsdt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * RSDP contains an XSDT (64-bit physical addresses). We must use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * the XSDT if the revision is > 1 and the XSDT pointer is present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * as per the ACPI specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) address = (acpi_physical_address)rsdp->xsdt_physical_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) table_entry_size = ACPI_XSDT_ENTRY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Root table is an RSDT (32-bit physical addresses) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) address = (acpi_physical_address)rsdp->rsdt_physical_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) table_entry_size = ACPI_RSDT_ENTRY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * It is not possible to map more than one entry in some environments,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * so unmap the RSDP here before mapping other tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Map the RSDT/XSDT table header to get the full table length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) acpi_tb_print_table_header(address, table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Validate length of the table, and map entire table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Minimum length table must contain at least one entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) length = table->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (length < (sizeof(struct acpi_table_header) + table_entry_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ACPI_BIOS_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) "Invalid table length 0x%X in RSDT/XSDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) table = acpi_os_map_memory(address, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (!table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Validate the root table checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) status = acpi_tb_verify_checksum(table, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) acpi_os_unmap_memory(table, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Get the number of entries and pointer to first entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) table_entry_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) table_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Initialize the root table array from the RSDT/XSDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (i = 0; i < table_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) acpi_tb_get_root_table_entry(table_entry, table_entry_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* Skip NULL entries in RSDT/XSDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) goto next_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) status = acpi_tb_install_standard_table(address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) FALSE, TRUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) &table_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ACPI_SUCCESS(status) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) tables[table_index].signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ACPI_SIG_FADT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) acpi_gbl_fadt_index = table_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) acpi_tb_parse_fadt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) next_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) table_entry += table_entry_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) acpi_os_unmap_memory(table, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * FUNCTION: acpi_tb_get_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * PARAMETERS: table_desc - Table descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * out_table - Where the pointer to the table is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * RETURN: Status and pointer to the requested table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * DESCRIPTION: Increase a reference to a table descriptor and return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * validated table pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * If the table descriptor is an entry of the root table list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * this API must be invoked with ACPI_MTX_TABLES acquired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) acpi_tb_get_table(struct acpi_table_desc *table_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct acpi_table_header **out_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ACPI_FUNCTION_TRACE(acpi_tb_get_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (table_desc->validation_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Table need to be "VALIDATED" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) status = acpi_tb_validate_table(table_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) table_desc->validation_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * Detect validation_count overflows to ensure that the warning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * message will only be printed once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ACPI_WARNING((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) "Table %p, Validation count overflows\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) table_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *out_table = table_desc->pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * FUNCTION: acpi_tb_put_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * PARAMETERS: table_desc - Table descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * DESCRIPTION: Decrease a reference to a table descriptor and release the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * validated table pointer if no references.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * If the table descriptor is an entry of the root table list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * this API must be invoked with ACPI_MTX_TABLES acquired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) void acpi_tb_put_table(struct acpi_table_desc *table_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ACPI_FUNCTION_TRACE(acpi_tb_put_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) table_desc->validation_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * Detect validation_count underflows to ensure that the warning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * message will only be printed once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ACPI_WARNING((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) "Table %p, Validation count underflows\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) table_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return_VOID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (table_desc->validation_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* Table need to be "INVALIDATED" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) acpi_tb_invalidate_table(table_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return_VOID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }