195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: tbfind - find table
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "actables.h"
1395b482a8SLen Brown
1495b482a8SLen Brown #define _COMPONENT ACPI_TABLES
1595b482a8SLen Brown ACPI_MODULE_NAME("tbfind")
1695b482a8SLen Brown
1795b482a8SLen Brown /*******************************************************************************
1895b482a8SLen Brown *
1995b482a8SLen Brown * FUNCTION: acpi_tb_find_table
2095b482a8SLen Brown *
21ba494beeSBob Moore * PARAMETERS: signature - String with ACPI table signature
2295b482a8SLen Brown * oem_id - String with the table OEM ID
2395b482a8SLen Brown * oem_table_id - String with the OEM Table ID
2495b482a8SLen Brown * table_index - Where the table index is returned
2595b482a8SLen Brown *
2695b482a8SLen Brown * RETURN: Status and table index
2795b482a8SLen Brown *
2895b482a8SLen Brown * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
2995b482a8SLen Brown * Signature, OEM ID and OEM Table ID. Returns an index that can
3095b482a8SLen Brown * be used to get the table header or entire table.
3195b482a8SLen Brown *
3295b482a8SLen Brown ******************************************************************************/
3395b482a8SLen Brown acpi_status
acpi_tb_find_table(char * signature,char * oem_id,char * oem_table_id,u32 * table_index)3495b482a8SLen Brown acpi_tb_find_table(char *signature,
3595b482a8SLen Brown char *oem_id, char *oem_table_id, u32 *table_index)
3695b482a8SLen Brown {
37ac0f06ebSLv Zheng acpi_status status = AE_OK;
3895b482a8SLen Brown struct acpi_table_header header;
399f41fd8aSBob Moore u32 i;
4095b482a8SLen Brown
4195b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_find_table);
4295b482a8SLen Brown
439f41fd8aSBob Moore /* Validate the input table signature */
449f41fd8aSBob Moore
456a0df32cSBob Moore if (!acpi_ut_valid_nameseg(signature)) {
469f41fd8aSBob Moore return_ACPI_STATUS(AE_BAD_SIGNATURE);
479f41fd8aSBob Moore }
489f41fd8aSBob Moore
499f41fd8aSBob Moore /* Don't allow the OEM strings to be too long */
509f41fd8aSBob Moore
519f41fd8aSBob Moore if ((strlen(oem_id) > ACPI_OEM_ID_SIZE) ||
529f41fd8aSBob Moore (strlen(oem_table_id) > ACPI_OEM_TABLE_ID_SIZE)) {
539f41fd8aSBob Moore return_ACPI_STATUS(AE_AML_STRING_LIMIT);
549f41fd8aSBob Moore }
559f41fd8aSBob Moore
5695b482a8SLen Brown /* Normalize the input strings */
5795b482a8SLen Brown
584fa4616eSBob Moore memset(&header, 0, sizeof(struct acpi_table_header));
59a3ce7a8eSBob Moore ACPI_COPY_NAMESEG(header.signature, signature);
604fa4616eSBob Moore strncpy(header.oem_id, oem_id, ACPI_OEM_ID_SIZE);
614fa4616eSBob Moore strncpy(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
6295b482a8SLen Brown
6395b482a8SLen Brown /* Search for the table */
6495b482a8SLen Brown
65ac0f06ebSLv Zheng (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
66b9ee2043SBob Moore for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
674fa4616eSBob Moore if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature),
6832786755SBob Moore header.signature, ACPI_NAMESEG_SIZE)) {
6995b482a8SLen Brown
7095b482a8SLen Brown /* Not the requested table */
7195b482a8SLen Brown
7295b482a8SLen Brown continue;
7395b482a8SLen Brown }
7495b482a8SLen Brown
7595b482a8SLen Brown /* Table with matching signature has been found */
7695b482a8SLen Brown
7795b482a8SLen Brown if (!acpi_gbl_root_table_list.tables[i].pointer) {
7895b482a8SLen Brown
7995b482a8SLen Brown /* Table is not currently mapped, map it */
8095b482a8SLen Brown
8195b482a8SLen Brown status =
827f9fc99cSLv Zheng acpi_tb_validate_table(&acpi_gbl_root_table_list.
8395b482a8SLen Brown tables[i]);
8495b482a8SLen Brown if (ACPI_FAILURE(status)) {
85ac0f06ebSLv Zheng goto unlock_and_exit;
8695b482a8SLen Brown }
8795b482a8SLen Brown
8895b482a8SLen Brown if (!acpi_gbl_root_table_list.tables[i].pointer) {
8995b482a8SLen Brown continue;
9095b482a8SLen Brown }
9195b482a8SLen Brown }
9295b482a8SLen Brown
9395b482a8SLen Brown /* Check for table match on all IDs */
9495b482a8SLen Brown
954fa4616eSBob Moore if (!memcmp
9695b482a8SLen Brown (acpi_gbl_root_table_list.tables[i].pointer->signature,
9732786755SBob Moore header.signature, ACPI_NAMESEG_SIZE) && (!oem_id[0]
9895b482a8SLen Brown ||
994fa4616eSBob Moore !memcmp
10095b482a8SLen Brown (acpi_gbl_root_table_list.
10132786755SBob Moore tables[i].
10232786755SBob Moore pointer->oem_id,
10395b482a8SLen Brown header.oem_id,
10495b482a8SLen Brown ACPI_OEM_ID_SIZE))
10595b482a8SLen Brown && (!oem_table_id[0]
1064fa4616eSBob Moore || !memcmp(acpi_gbl_root_table_list.tables[i].pointer->
1074fa4616eSBob Moore oem_table_id, header.oem_table_id,
10895b482a8SLen Brown ACPI_OEM_TABLE_ID_SIZE))) {
10995b482a8SLen Brown *table_index = i;
11095b482a8SLen Brown
11195b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
11295b482a8SLen Brown "Found table [%4.4s]\n",
11395b482a8SLen Brown header.signature));
114ac0f06ebSLv Zheng goto unlock_and_exit;
11595b482a8SLen Brown }
11695b482a8SLen Brown }
117ac0f06ebSLv Zheng status = AE_NOT_FOUND;
11895b482a8SLen Brown
119ac0f06ebSLv Zheng unlock_and_exit:
120ac0f06ebSLv Zheng (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
12186ec64bcSLv Zheng return_ACPI_STATUS(status);
12295b482a8SLen Brown }
123