tbxface.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: tbxface - ACPI table-oriented external interfaces
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #define EXPORT_ACPI_INTERFACES
  10. #include <acpi/acpi.h>
  11. #include "accommon.h"
  12. #include "actables.h"
  13. #define _COMPONENT ACPI_TABLES
  14. ACPI_MODULE_NAME("tbxface")
  15. /*******************************************************************************
  16. *
  17. * FUNCTION: acpi_allocate_root_table
  18. *
  19. * PARAMETERS: initial_table_count - Size of initial_table_array, in number of
  20. * struct acpi_table_desc structures
  21. *
  22. * RETURN: Status
  23. *
  24. * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
  25. * acpi_initialize_tables.
  26. *
  27. ******************************************************************************/
  28. acpi_status acpi_allocate_root_table(u32 initial_table_count)
  29. {
  30. acpi_gbl_root_table_list.max_table_count = initial_table_count;
  31. acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
  32. return (acpi_tb_resize_root_table_list());
  33. }
  34. /*******************************************************************************
  35. *
  36. * FUNCTION: acpi_initialize_tables
  37. *
  38. * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated
  39. * struct acpi_table_desc structures. If NULL, the
  40. * array is dynamically allocated.
  41. * initial_table_count - Size of initial_table_array, in number of
  42. * struct acpi_table_desc structures
  43. * allow_resize - Flag to tell Table Manager if resize of
  44. * pre-allocated array is allowed. Ignored
  45. * if initial_table_array is NULL.
  46. *
  47. * RETURN: Status
  48. *
  49. * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
  50. *
  51. * NOTE: Allows static allocation of the initial table array in order
  52. * to avoid the use of dynamic memory in confined environments
  53. * such as the kernel boot sequence where it may not be available.
  54. *
  55. * If the host OS memory managers are initialized, use NULL for
  56. * initial_table_array, and the table will be dynamically allocated.
  57. *
  58. ******************************************************************************/
  59. acpi_status ACPI_INIT_FUNCTION
  60. acpi_initialize_tables(struct acpi_table_desc *initial_table_array,
  61. u32 initial_table_count, u8 allow_resize)
  62. {
  63. acpi_physical_address rsdp_address;
  64. acpi_status status;
  65. ACPI_FUNCTION_TRACE(acpi_initialize_tables);
  66. /*
  67. * Setup the Root Table Array and allocate the table array
  68. * if requested
  69. */
  70. if (!initial_table_array) {
  71. status = acpi_allocate_root_table(initial_table_count);
  72. if (ACPI_FAILURE(status)) {
  73. return_ACPI_STATUS(status);
  74. }
  75. } else {
  76. /* Root Table Array has been statically allocated by the host */
  77. memset(initial_table_array, 0,
  78. (acpi_size)initial_table_count *
  79. sizeof(struct acpi_table_desc));
  80. acpi_gbl_root_table_list.tables = initial_table_array;
  81. acpi_gbl_root_table_list.max_table_count = initial_table_count;
  82. acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
  83. if (allow_resize) {
  84. acpi_gbl_root_table_list.flags |=
  85. ACPI_ROOT_ALLOW_RESIZE;
  86. }
  87. }
  88. /* Get the address of the RSDP */
  89. rsdp_address = acpi_os_get_root_pointer();
  90. if (!rsdp_address) {
  91. return_ACPI_STATUS(AE_NOT_FOUND);
  92. }
  93. /*
  94. * Get the root table (RSDT or XSDT) and extract all entries to the local
  95. * Root Table Array. This array contains the information of the RSDT/XSDT
  96. * in a common, more usable format.
  97. */
  98. status = acpi_tb_parse_root_table(rsdp_address);
  99. return_ACPI_STATUS(status);
  100. }
  101. ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
  102. /*******************************************************************************
  103. *
  104. * FUNCTION: acpi_reallocate_root_table
  105. *
  106. * PARAMETERS: None
  107. *
  108. * RETURN: Status
  109. *
  110. * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
  111. * root list from the previously provided scratch area. Should
  112. * be called once dynamic memory allocation is available in the
  113. * kernel.
  114. *
  115. ******************************************************************************/
  116. acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
  117. {
  118. acpi_status status;
  119. struct acpi_table_desc *table_desc;
  120. u32 i, j;
  121. ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
  122. /*
  123. * If there are tables unverified, it is required to reallocate the
  124. * root table list to clean up invalid table entries. Otherwise only
  125. * reallocate the root table list if the host provided a static buffer
  126. * for the table array in the call to acpi_initialize_tables().
  127. */
  128. if ((acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) &&
  129. acpi_gbl_enable_table_validation) {
  130. return_ACPI_STATUS(AE_SUPPORT);
  131. }
  132. (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
  133. /*
  134. * Ensure OS early boot logic, which is required by some hosts. If the
  135. * table state is reported to be wrong, developers should fix the
  136. * issue by invoking acpi_put_table() for the reported table during the
  137. * early stage.
  138. */
  139. for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
  140. table_desc = &acpi_gbl_root_table_list.tables[i];
  141. if (table_desc->pointer) {
  142. ACPI_ERROR((AE_INFO,
  143. "Table [%4.4s] is not invalidated during early boot stage",
  144. table_desc->signature.ascii));
  145. }
  146. }
  147. if (!acpi_gbl_enable_table_validation) {
  148. /*
  149. * Now it's safe to do full table validation. We can do deferred
  150. * table initialization here once the flag is set.
  151. */
  152. acpi_gbl_enable_table_validation = TRUE;
  153. for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
  154. ++i) {
  155. table_desc = &acpi_gbl_root_table_list.tables[i];
  156. if (!(table_desc->flags & ACPI_TABLE_IS_VERIFIED)) {
  157. status =
  158. acpi_tb_verify_temp_table(table_desc, NULL,
  159. &j);
  160. if (ACPI_FAILURE(status)) {
  161. acpi_tb_uninstall_table(table_desc);
  162. }
  163. }
  164. }
  165. }
  166. acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
  167. status = acpi_tb_resize_root_table_list();
  168. acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
  169. (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  170. return_ACPI_STATUS(status);
  171. }
  172. ACPI_EXPORT_SYMBOL_INIT(acpi_reallocate_root_table)
  173. /*******************************************************************************
  174. *
  175. * FUNCTION: acpi_get_table_header
  176. *
  177. * PARAMETERS: signature - ACPI signature of needed table
  178. * instance - Which instance (for SSDTs)
  179. * out_table_header - The pointer to the where the table header
  180. * is returned
  181. *
  182. * RETURN: Status and a copy of the table header
  183. *
  184. * DESCRIPTION: Finds and returns an ACPI table header. Caller provides the
  185. * memory where a copy of the header is to be returned
  186. * (fixed length).
  187. *
  188. ******************************************************************************/
  189. acpi_status
  190. acpi_get_table_header(char *signature,
  191. u32 instance, struct acpi_table_header *out_table_header)
  192. {
  193. u32 i;
  194. u32 j;
  195. struct acpi_table_header *header;
  196. /* Parameter validation */
  197. if (!signature || !out_table_header) {
  198. return (AE_BAD_PARAMETER);
  199. }
  200. /* Walk the root table list */
  201. for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
  202. i++) {
  203. if (!ACPI_COMPARE_NAMESEG
  204. (&(acpi_gbl_root_table_list.tables[i].signature),
  205. signature)) {
  206. continue;
  207. }
  208. if (++j < instance) {
  209. continue;
  210. }
  211. if (!acpi_gbl_root_table_list.tables[i].pointer) {
  212. if ((acpi_gbl_root_table_list.tables[i].flags &
  213. ACPI_TABLE_ORIGIN_MASK) ==
  214. ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) {
  215. header =
  216. acpi_os_map_memory(acpi_gbl_root_table_list.
  217. tables[i].address,
  218. sizeof(struct
  219. acpi_table_header));
  220. if (!header) {
  221. return (AE_NO_MEMORY);
  222. }
  223. memcpy(out_table_header, header,
  224. sizeof(struct acpi_table_header));
  225. acpi_os_unmap_memory(header,
  226. sizeof(struct
  227. acpi_table_header));
  228. } else {
  229. return (AE_NOT_FOUND);
  230. }
  231. } else {
  232. memcpy(out_table_header,
  233. acpi_gbl_root_table_list.tables[i].pointer,
  234. sizeof(struct acpi_table_header));
  235. }
  236. return (AE_OK);
  237. }
  238. return (AE_NOT_FOUND);
  239. }
  240. ACPI_EXPORT_SYMBOL(acpi_get_table_header)
  241. /*******************************************************************************
  242. *
  243. * FUNCTION: acpi_get_table
  244. *
  245. * PARAMETERS: signature - ACPI signature of needed table
  246. * instance - Which instance (for SSDTs)
  247. * out_table - Where the pointer to the table is returned
  248. *
  249. * RETURN: Status and pointer to the requested table
  250. *
  251. * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
  252. * RSDT/XSDT.
  253. * Note that an early stage acpi_get_table() call must be paired
  254. * with an early stage acpi_put_table() call. otherwise the table
  255. * pointer mapped by the early stage mapping implementation may be
  256. * erroneously unmapped by the late stage unmapping implementation
  257. * in an acpi_put_table() invoked during the late stage.
  258. *
  259. ******************************************************************************/
  260. acpi_status
  261. acpi_get_table(char *signature,
  262. u32 instance, struct acpi_table_header ** out_table)
  263. {
  264. u32 i;
  265. u32 j;
  266. acpi_status status = AE_NOT_FOUND;
  267. struct acpi_table_desc *table_desc;
  268. /* Parameter validation */
  269. if (!signature || !out_table) {
  270. return (AE_BAD_PARAMETER);
  271. }
  272. /*
  273. * Note that the following line is required by some OSPMs, they only
  274. * check if the returned table is NULL instead of the returned status
  275. * to determined if this function is succeeded.
  276. */
  277. *out_table = NULL;
  278. (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
  279. /* Walk the root table list */
  280. for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
  281. i++) {
  282. table_desc = &acpi_gbl_root_table_list.tables[i];
  283. if (!ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
  284. continue;
  285. }
  286. if (++j < instance) {
  287. continue;
  288. }
  289. status = acpi_tb_get_table(table_desc, out_table);
  290. break;
  291. }
  292. (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  293. return (status);
  294. }
  295. ACPI_EXPORT_SYMBOL(acpi_get_table)
  296. /*******************************************************************************
  297. *
  298. * FUNCTION: acpi_put_table
  299. *
  300. * PARAMETERS: table - The pointer to the table
  301. *
  302. * RETURN: None
  303. *
  304. * DESCRIPTION: Release a table returned by acpi_get_table() and its clones.
  305. * Note that it is not safe if this function was invoked after an
  306. * uninstallation happened to the original table descriptor.
  307. * Currently there is no OSPMs' requirement to handle such
  308. * situations.
  309. *
  310. ******************************************************************************/
  311. void acpi_put_table(struct acpi_table_header *table)
  312. {
  313. u32 i;
  314. struct acpi_table_desc *table_desc;
  315. ACPI_FUNCTION_TRACE(acpi_put_table);
  316. if (!table) {
  317. return_VOID;
  318. }
  319. (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
  320. /* Walk the root table list */
  321. for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
  322. table_desc = &acpi_gbl_root_table_list.tables[i];
  323. if (table_desc->pointer != table) {
  324. continue;
  325. }
  326. acpi_tb_put_table(table_desc);
  327. break;
  328. }
  329. (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  330. return_VOID;
  331. }
  332. ACPI_EXPORT_SYMBOL(acpi_put_table)
  333. /*******************************************************************************
  334. *
  335. * FUNCTION: acpi_get_table_by_index
  336. *
  337. * PARAMETERS: table_index - Table index
  338. * out_table - Where the pointer to the table is returned
  339. *
  340. * RETURN: Status and pointer to the requested table
  341. *
  342. * DESCRIPTION: Obtain a table by an index into the global table list. Used
  343. * internally also.
  344. *
  345. ******************************************************************************/
  346. acpi_status
  347. acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table)
  348. {
  349. acpi_status status;
  350. ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
  351. /* Parameter validation */
  352. if (!out_table) {
  353. return_ACPI_STATUS(AE_BAD_PARAMETER);
  354. }
  355. /*
  356. * Note that the following line is required by some OSPMs, they only
  357. * check if the returned table is NULL instead of the returned status
  358. * to determined if this function is succeeded.
  359. */
  360. *out_table = NULL;
  361. (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
  362. /* Validate index */
  363. if (table_index >= acpi_gbl_root_table_list.current_table_count) {
  364. status = AE_BAD_PARAMETER;
  365. goto unlock_and_exit;
  366. }
  367. status =
  368. acpi_tb_get_table(&acpi_gbl_root_table_list.tables[table_index],
  369. out_table);
  370. unlock_and_exit:
  371. (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
  372. return_ACPI_STATUS(status);
  373. }
  374. ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
  375. /*******************************************************************************
  376. *
  377. * FUNCTION: acpi_install_table_handler
  378. *
  379. * PARAMETERS: handler - Table event handler
  380. * context - Value passed to the handler on each event
  381. *
  382. * RETURN: Status
  383. *
  384. * DESCRIPTION: Install a global table event handler.
  385. *
  386. ******************************************************************************/
  387. acpi_status
  388. acpi_install_table_handler(acpi_table_handler handler, void *context)
  389. {
  390. acpi_status status;
  391. ACPI_FUNCTION_TRACE(acpi_install_table_handler);
  392. if (!handler) {
  393. return_ACPI_STATUS(AE_BAD_PARAMETER);
  394. }
  395. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  396. if (ACPI_FAILURE(status)) {
  397. return_ACPI_STATUS(status);
  398. }
  399. /* Don't allow more than one handler */
  400. if (acpi_gbl_table_handler) {
  401. status = AE_ALREADY_EXISTS;
  402. goto cleanup;
  403. }
  404. /* Install the handler */
  405. acpi_gbl_table_handler = handler;
  406. acpi_gbl_table_handler_context = context;
  407. cleanup:
  408. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  409. return_ACPI_STATUS(status);
  410. }
  411. ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
  412. /*******************************************************************************
  413. *
  414. * FUNCTION: acpi_remove_table_handler
  415. *
  416. * PARAMETERS: handler - Table event handler that was installed
  417. * previously.
  418. *
  419. * RETURN: Status
  420. *
  421. * DESCRIPTION: Remove a table event handler
  422. *
  423. ******************************************************************************/
  424. acpi_status acpi_remove_table_handler(acpi_table_handler handler)
  425. {
  426. acpi_status status;
  427. ACPI_FUNCTION_TRACE(acpi_remove_table_handler);
  428. status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  429. if (ACPI_FAILURE(status)) {
  430. return_ACPI_STATUS(status);
  431. }
  432. /* Make sure that the installed handler is the same */
  433. if (!handler || handler != acpi_gbl_table_handler) {
  434. status = AE_BAD_PARAMETER;
  435. goto cleanup;
  436. }
  437. /* Remove the handler */
  438. acpi_gbl_table_handler = NULL;
  439. cleanup:
  440. (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  441. return_ACPI_STATUS(status);
  442. }
  443. ACPI_EXPORT_SYMBOL(acpi_remove_table_handler)