xref: /openbmc/linux/drivers/acpi/acpica/tbfind.c (revision 612c2932)
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