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