dbcmds.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /*******************************************************************************
  3. *
  4. * Module Name: dbcmds - Miscellaneous debug commands and output routines
  5. *
  6. ******************************************************************************/
  7. #include <acpi/acpi.h>
  8. #include "accommon.h"
  9. #include "acevents.h"
  10. #include "acdebug.h"
  11. #include "acnamesp.h"
  12. #include "acresrc.h"
  13. #include "actables.h"
  14. #define _COMPONENT ACPI_CA_DEBUGGER
  15. ACPI_MODULE_NAME("dbcmds")
  16. /* Local prototypes */
  17. static void
  18. acpi_dm_compare_aml_resources(u8 *aml1_buffer,
  19. acpi_rsdesc_size aml1_buffer_length,
  20. u8 *aml2_buffer,
  21. acpi_rsdesc_size aml2_buffer_length);
  22. static acpi_status
  23. acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
  24. static acpi_status
  25. acpi_db_resource_callback(struct acpi_resource *resource, void *context);
  26. static acpi_status
  27. acpi_db_device_resources(acpi_handle obj_handle,
  28. u32 nesting_level, void *context, void **return_value);
  29. static void acpi_db_do_one_sleep_state(u8 sleep_state);
  30. static char *acpi_db_trace_method_name = NULL;
  31. /*******************************************************************************
  32. *
  33. * FUNCTION: acpi_db_convert_to_node
  34. *
  35. * PARAMETERS: in_string - String to convert
  36. *
  37. * RETURN: Pointer to a NS node
  38. *
  39. * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
  40. * alphanumeric strings.
  41. *
  42. ******************************************************************************/
  43. struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
  44. {
  45. struct acpi_namespace_node *node;
  46. acpi_size address;
  47. if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
  48. /* Numeric argument, convert */
  49. address = strtoul(in_string, NULL, 16);
  50. node = ACPI_TO_POINTER(address);
  51. if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
  52. acpi_os_printf("Address %p is invalid", node);
  53. return (NULL);
  54. }
  55. /* Make sure pointer is valid NS node */
  56. if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
  57. acpi_os_printf
  58. ("Address %p is not a valid namespace node [%s]\n",
  59. node, acpi_ut_get_descriptor_name(node));
  60. return (NULL);
  61. }
  62. } else {
  63. /*
  64. * Alpha argument: The parameter is a name string that must be
  65. * resolved to a Namespace object.
  66. */
  67. node = acpi_db_local_ns_lookup(in_string);
  68. if (!node) {
  69. acpi_os_printf
  70. ("Could not find [%s] in namespace, defaulting to root node\n",
  71. in_string);
  72. node = acpi_gbl_root_node;
  73. }
  74. }
  75. return (node);
  76. }
  77. /*******************************************************************************
  78. *
  79. * FUNCTION: acpi_db_sleep
  80. *
  81. * PARAMETERS: object_arg - Desired sleep state (0-5). NULL means
  82. * invoke all possible sleep states.
  83. *
  84. * RETURN: Status
  85. *
  86. * DESCRIPTION: Simulate sleep/wake sequences
  87. *
  88. ******************************************************************************/
  89. acpi_status acpi_db_sleep(char *object_arg)
  90. {
  91. u8 sleep_state;
  92. u32 i;
  93. ACPI_FUNCTION_TRACE(acpi_db_sleep);
  94. /* Null input (no arguments) means to invoke all sleep states */
  95. if (!object_arg) {
  96. acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
  97. ACPI_S_STATES_MAX);
  98. for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
  99. acpi_db_do_one_sleep_state((u8)i);
  100. }
  101. return_ACPI_STATUS(AE_OK);
  102. }
  103. /* Convert argument to binary and invoke the sleep state */
  104. sleep_state = (u8)strtoul(object_arg, NULL, 0);
  105. acpi_db_do_one_sleep_state(sleep_state);
  106. return_ACPI_STATUS(AE_OK);
  107. }
  108. /*******************************************************************************
  109. *
  110. * FUNCTION: acpi_db_do_one_sleep_state
  111. *
  112. * PARAMETERS: sleep_state - Desired sleep state (0-5)
  113. *
  114. * RETURN: None
  115. *
  116. * DESCRIPTION: Simulate a sleep/wake sequence
  117. *
  118. ******************************************************************************/
  119. static void acpi_db_do_one_sleep_state(u8 sleep_state)
  120. {
  121. acpi_status status;
  122. u8 sleep_type_a;
  123. u8 sleep_type_b;
  124. /* Validate parameter */
  125. if (sleep_state > ACPI_S_STATES_MAX) {
  126. acpi_os_printf("Sleep state %d out of range (%d max)\n",
  127. sleep_state, ACPI_S_STATES_MAX);
  128. return;
  129. }
  130. acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
  131. sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
  132. /* Get the values for the sleep type registers (for display only) */
  133. status =
  134. acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
  135. if (ACPI_FAILURE(status)) {
  136. acpi_os_printf("Could not evaluate [%s] method, %s\n",
  137. acpi_gbl_sleep_state_names[sleep_state],
  138. acpi_format_exception(status));
  139. return;
  140. }
  141. acpi_os_printf
  142. ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
  143. sleep_state, sleep_type_a, sleep_type_b);
  144. /* Invoke the various sleep/wake interfaces */
  145. acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
  146. sleep_state);
  147. status = acpi_enter_sleep_state_prep(sleep_state);
  148. if (ACPI_FAILURE(status)) {
  149. goto error_exit;
  150. }
  151. acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
  152. status = acpi_enter_sleep_state(sleep_state);
  153. if (ACPI_FAILURE(status)) {
  154. goto error_exit;
  155. }
  156. acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
  157. sleep_state);
  158. status = acpi_leave_sleep_state_prep(sleep_state);
  159. if (ACPI_FAILURE(status)) {
  160. goto error_exit;
  161. }
  162. acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
  163. sleep_state);
  164. status = acpi_leave_sleep_state(sleep_state);
  165. if (ACPI_FAILURE(status)) {
  166. goto error_exit;
  167. }
  168. return;
  169. error_exit:
  170. ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
  171. sleep_state));
  172. }
  173. /*******************************************************************************
  174. *
  175. * FUNCTION: acpi_db_display_locks
  176. *
  177. * PARAMETERS: None
  178. *
  179. * RETURN: None
  180. *
  181. * DESCRIPTION: Display information about internal mutexes.
  182. *
  183. ******************************************************************************/
  184. void acpi_db_display_locks(void)
  185. {
  186. u32 i;
  187. for (i = 0; i < ACPI_MAX_MUTEX; i++) {
  188. acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
  189. acpi_gbl_mutex_info[i].thread_id ==
  190. ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
  191. }
  192. }
  193. /*******************************************************************************
  194. *
  195. * FUNCTION: acpi_db_display_table_info
  196. *
  197. * PARAMETERS: table_arg - Name of table to be displayed
  198. *
  199. * RETURN: None
  200. *
  201. * DESCRIPTION: Display information about loaded tables. Current
  202. * implementation displays all loaded tables.
  203. *
  204. ******************************************************************************/
  205. void acpi_db_display_table_info(char *table_arg)
  206. {
  207. u32 i;
  208. struct acpi_table_desc *table_desc;
  209. acpi_status status;
  210. /* Header */
  211. acpi_os_printf("Idx ID Status Type "
  212. "TableHeader (Sig, Address, Length, Misc)\n");
  213. /* Walk the entire root table list */
  214. for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
  215. table_desc = &acpi_gbl_root_table_list.tables[i];
  216. /* Index and Table ID */
  217. acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
  218. /* Decode the table flags */
  219. if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
  220. acpi_os_printf("NotLoaded ");
  221. } else {
  222. acpi_os_printf(" Loaded ");
  223. }
  224. switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
  225. case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
  226. acpi_os_printf("External/virtual ");
  227. break;
  228. case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
  229. acpi_os_printf("Internal/physical ");
  230. break;
  231. case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
  232. acpi_os_printf("Internal/virtual ");
  233. break;
  234. default:
  235. acpi_os_printf("INVALID TYPE ");
  236. break;
  237. }
  238. /* Make sure that the table is mapped */
  239. status = acpi_tb_validate_table(table_desc);
  240. if (ACPI_FAILURE(status)) {
  241. return;
  242. }
  243. /* Dump the table header */
  244. if (table_desc->pointer) {
  245. acpi_tb_print_table_header(table_desc->address,
  246. table_desc->pointer);
  247. } else {
  248. /* If the pointer is null, the table has been unloaded */
  249. ACPI_INFO(("%4.4s - Table has been unloaded",
  250. table_desc->signature.ascii));
  251. }
  252. }
  253. }
  254. /*******************************************************************************
  255. *
  256. * FUNCTION: acpi_db_unload_acpi_table
  257. *
  258. * PARAMETERS: object_name - Namespace pathname for an object that
  259. * is owned by the table to be unloaded
  260. *
  261. * RETURN: None
  262. *
  263. * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
  264. * by the table.
  265. *
  266. ******************************************************************************/
  267. void acpi_db_unload_acpi_table(char *object_name)
  268. {
  269. struct acpi_namespace_node *node;
  270. acpi_status status;
  271. /* Translate name to an Named object */
  272. node = acpi_db_convert_to_node(object_name);
  273. if (!node) {
  274. return;
  275. }
  276. status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
  277. if (ACPI_SUCCESS(status)) {
  278. acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
  279. object_name, node);
  280. } else {
  281. acpi_os_printf("%s, while unloading parent table of [%s]\n",
  282. acpi_format_exception(status), object_name);
  283. }
  284. }
  285. /*******************************************************************************
  286. *
  287. * FUNCTION: acpi_db_send_notify
  288. *
  289. * PARAMETERS: name - Name of ACPI object where to send notify
  290. * value - Value of the notify to send.
  291. *
  292. * RETURN: None
  293. *
  294. * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
  295. * named object as an ACPI notify.
  296. *
  297. ******************************************************************************/
  298. void acpi_db_send_notify(char *name, u32 value)
  299. {
  300. struct acpi_namespace_node *node;
  301. acpi_status status;
  302. /* Translate name to an Named object */
  303. node = acpi_db_convert_to_node(name);
  304. if (!node) {
  305. return;
  306. }
  307. /* Dispatch the notify if legal */
  308. if (acpi_ev_is_notify_object(node)) {
  309. status = acpi_ev_queue_notify_request(node, value);
  310. if (ACPI_FAILURE(status)) {
  311. acpi_os_printf("Could not queue notify\n");
  312. }
  313. } else {
  314. acpi_os_printf("Named object [%4.4s] Type %s, "
  315. "must be Device/Thermal/Processor type\n",
  316. acpi_ut_get_node_name(node),
  317. acpi_ut_get_type_name(node->type));
  318. }
  319. }
  320. /*******************************************************************************
  321. *
  322. * FUNCTION: acpi_db_display_interfaces
  323. *
  324. * PARAMETERS: action_arg - Null, "install", or "remove"
  325. * interface_name_arg - Name for install/remove options
  326. *
  327. * RETURN: None
  328. *
  329. * DESCRIPTION: Display or modify the global _OSI interface list
  330. *
  331. ******************************************************************************/
  332. void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
  333. {
  334. struct acpi_interface_info *next_interface;
  335. char *sub_string;
  336. acpi_status status;
  337. /* If no arguments, just display current interface list */
  338. if (!action_arg) {
  339. (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
  340. ACPI_WAIT_FOREVER);
  341. next_interface = acpi_gbl_supported_interfaces;
  342. while (next_interface) {
  343. if (!(next_interface->flags & ACPI_OSI_INVALID)) {
  344. acpi_os_printf("%s\n", next_interface->name);
  345. }
  346. next_interface = next_interface->next;
  347. }
  348. acpi_os_release_mutex(acpi_gbl_osi_mutex);
  349. return;
  350. }
  351. /* If action_arg exists, so must interface_name_arg */
  352. if (!interface_name_arg) {
  353. acpi_os_printf("Missing Interface Name argument\n");
  354. return;
  355. }
  356. /* Uppercase the action for match below */
  357. acpi_ut_strupr(action_arg);
  358. /* install - install an interface */
  359. sub_string = strstr("INSTALL", action_arg);
  360. if (sub_string) {
  361. status = acpi_install_interface(interface_name_arg);
  362. if (ACPI_FAILURE(status)) {
  363. acpi_os_printf("%s, while installing \"%s\"\n",
  364. acpi_format_exception(status),
  365. interface_name_arg);
  366. }
  367. return;
  368. }
  369. /* remove - remove an interface */
  370. sub_string = strstr("REMOVE", action_arg);
  371. if (sub_string) {
  372. status = acpi_remove_interface(interface_name_arg);
  373. if (ACPI_FAILURE(status)) {
  374. acpi_os_printf("%s, while removing \"%s\"\n",
  375. acpi_format_exception(status),
  376. interface_name_arg);
  377. }
  378. return;
  379. }
  380. /* Invalid action_arg */
  381. acpi_os_printf("Invalid action argument: %s\n", action_arg);
  382. return;
  383. }
  384. /*******************************************************************************
  385. *
  386. * FUNCTION: acpi_db_display_template
  387. *
  388. * PARAMETERS: buffer_arg - Buffer name or address
  389. *
  390. * RETURN: None
  391. *
  392. * DESCRIPTION: Dump a buffer that contains a resource template
  393. *
  394. ******************************************************************************/
  395. void acpi_db_display_template(char *buffer_arg)
  396. {
  397. struct acpi_namespace_node *node;
  398. acpi_status status;
  399. struct acpi_buffer return_buffer;
  400. /* Translate buffer_arg to an Named object */
  401. node = acpi_db_convert_to_node(buffer_arg);
  402. if (!node || (node == acpi_gbl_root_node)) {
  403. acpi_os_printf("Invalid argument: %s\n", buffer_arg);
  404. return;
  405. }
  406. /* We must have a buffer object */
  407. if (node->type != ACPI_TYPE_BUFFER) {
  408. acpi_os_printf
  409. ("Not a Buffer object, cannot be a template: %s\n",
  410. buffer_arg);
  411. return;
  412. }
  413. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  414. return_buffer.pointer = acpi_gbl_db_buffer;
  415. /* Attempt to convert the raw buffer to a resource list */
  416. status = acpi_rs_create_resource_list(node->object, &return_buffer);
  417. acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
  418. acpi_dbg_level |= ACPI_LV_RESOURCES;
  419. if (ACPI_FAILURE(status)) {
  420. acpi_os_printf
  421. ("Could not convert Buffer to a resource list: %s, %s\n",
  422. buffer_arg, acpi_format_exception(status));
  423. goto dump_buffer;
  424. }
  425. /* Now we can dump the resource list */
  426. acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
  427. return_buffer.pointer));
  428. dump_buffer:
  429. acpi_os_printf("\nRaw data buffer:\n");
  430. acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
  431. node->object->buffer.length,
  432. DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
  433. acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
  434. return;
  435. }
  436. /*******************************************************************************
  437. *
  438. * FUNCTION: acpi_dm_compare_aml_resources
  439. *
  440. * PARAMETERS: aml1_buffer - Contains first resource list
  441. * aml1_buffer_length - Length of first resource list
  442. * aml2_buffer - Contains second resource list
  443. * aml2_buffer_length - Length of second resource list
  444. *
  445. * RETURN: None
  446. *
  447. * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
  448. * order to isolate a miscompare to an individual resource)
  449. *
  450. ******************************************************************************/
  451. static void
  452. acpi_dm_compare_aml_resources(u8 *aml1_buffer,
  453. acpi_rsdesc_size aml1_buffer_length,
  454. u8 *aml2_buffer,
  455. acpi_rsdesc_size aml2_buffer_length)
  456. {
  457. u8 *aml1;
  458. u8 *aml2;
  459. u8 *aml1_end;
  460. u8 *aml2_end;
  461. acpi_rsdesc_size aml1_length;
  462. acpi_rsdesc_size aml2_length;
  463. acpi_rsdesc_size offset = 0;
  464. u8 resource_type;
  465. u32 count = 0;
  466. u32 i;
  467. /* Compare overall buffer sizes (may be different due to size rounding) */
  468. if (aml1_buffer_length != aml2_buffer_length) {
  469. acpi_os_printf("**** Buffer length mismatch in converted "
  470. "AML: Original %X, New %X ****\n",
  471. aml1_buffer_length, aml2_buffer_length);
  472. }
  473. aml1 = aml1_buffer;
  474. aml2 = aml2_buffer;
  475. aml1_end = aml1_buffer + aml1_buffer_length;
  476. aml2_end = aml2_buffer + aml2_buffer_length;
  477. /* Walk the descriptor lists, comparing each descriptor */
  478. while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
  479. /* Get the lengths of each descriptor */
  480. aml1_length = acpi_ut_get_descriptor_length(aml1);
  481. aml2_length = acpi_ut_get_descriptor_length(aml2);
  482. resource_type = acpi_ut_get_resource_type(aml1);
  483. /* Check for descriptor length match */
  484. if (aml1_length != aml2_length) {
  485. acpi_os_printf
  486. ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
  487. "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
  488. resource_type, offset, aml1_length, aml2_length);
  489. }
  490. /* Check for descriptor byte match */
  491. else if (memcmp(aml1, aml2, aml1_length)) {
  492. acpi_os_printf
  493. ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
  494. "Offset %8.8X ****\n", count, resource_type,
  495. offset);
  496. for (i = 0; i < aml1_length; i++) {
  497. if (aml1[i] != aml2[i]) {
  498. acpi_os_printf
  499. ("Mismatch at byte offset %.2X: is %2.2X, "
  500. "should be %2.2X\n", i, aml2[i],
  501. aml1[i]);
  502. }
  503. }
  504. }
  505. /* Exit on end_tag descriptor */
  506. if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
  507. return;
  508. }
  509. /* Point to next descriptor in each buffer */
  510. count++;
  511. offset += aml1_length;
  512. aml1 += aml1_length;
  513. aml2 += aml2_length;
  514. }
  515. }
  516. /*******************************************************************************
  517. *
  518. * FUNCTION: acpi_dm_test_resource_conversion
  519. *
  520. * PARAMETERS: node - Parent device node
  521. * name - resource method name (_CRS)
  522. *
  523. * RETURN: Status
  524. *
  525. * DESCRIPTION: Compare the original AML with a conversion of the AML to
  526. * internal resource list, then back to AML.
  527. *
  528. ******************************************************************************/
  529. static acpi_status
  530. acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
  531. {
  532. acpi_status status;
  533. struct acpi_buffer return_buffer;
  534. struct acpi_buffer resource_buffer;
  535. struct acpi_buffer new_aml;
  536. union acpi_object *original_aml;
  537. acpi_os_printf("Resource Conversion Comparison:\n");
  538. new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
  539. return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
  540. resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
  541. /* Get the original _CRS AML resource template */
  542. status = acpi_evaluate_object(node, name, NULL, &return_buffer);
  543. if (ACPI_FAILURE(status)) {
  544. acpi_os_printf("Could not obtain %s: %s\n",
  545. name, acpi_format_exception(status));
  546. return (status);
  547. }
  548. /* Get the AML resource template, converted to internal resource structs */
  549. status = acpi_get_current_resources(node, &resource_buffer);
  550. if (ACPI_FAILURE(status)) {
  551. acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
  552. acpi_format_exception(status));
  553. goto exit1;
  554. }
  555. /* Convert internal resource list to external AML resource template */
  556. status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
  557. if (ACPI_FAILURE(status)) {
  558. acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
  559. acpi_format_exception(status));
  560. goto exit2;
  561. }
  562. /* Compare original AML to the newly created AML resource list */
  563. original_aml = return_buffer.pointer;
  564. acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
  565. (acpi_rsdesc_size)original_aml->buffer.
  566. length, new_aml.pointer,
  567. (acpi_rsdesc_size)new_aml.length);
  568. /* Cleanup and exit */
  569. ACPI_FREE(new_aml.pointer);
  570. exit2:
  571. ACPI_FREE(resource_buffer.pointer);
  572. exit1:
  573. ACPI_FREE(return_buffer.pointer);
  574. return (status);
  575. }
  576. /*******************************************************************************
  577. *
  578. * FUNCTION: acpi_db_resource_callback
  579. *
  580. * PARAMETERS: acpi_walk_resource_callback
  581. *
  582. * RETURN: Status
  583. *
  584. * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
  585. * acpi_walk_resource_buffer.
  586. *
  587. ******************************************************************************/
  588. static acpi_status
  589. acpi_db_resource_callback(struct acpi_resource *resource, void *context)
  590. {
  591. return (AE_OK);
  592. }
  593. /*******************************************************************************
  594. *
  595. * FUNCTION: acpi_db_device_resources
  596. *
  597. * PARAMETERS: acpi_walk_callback
  598. *
  599. * RETURN: Status
  600. *
  601. * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
  602. *
  603. ******************************************************************************/
  604. static acpi_status
  605. acpi_db_device_resources(acpi_handle obj_handle,
  606. u32 nesting_level, void *context, void **return_value)
  607. {
  608. struct acpi_namespace_node *node;
  609. struct acpi_namespace_node *prt_node = NULL;
  610. struct acpi_namespace_node *crs_node = NULL;
  611. struct acpi_namespace_node *prs_node = NULL;
  612. struct acpi_namespace_node *aei_node = NULL;
  613. char *parent_path;
  614. struct acpi_buffer return_buffer;
  615. acpi_status status;
  616. node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
  617. parent_path = acpi_ns_get_normalized_pathname(node, TRUE);
  618. if (!parent_path) {
  619. return (AE_NO_MEMORY);
  620. }
  621. /* Get handles to the resource methods for this device */
  622. (void)acpi_get_handle(node, METHOD_NAME__PRT,
  623. ACPI_CAST_PTR(acpi_handle, &prt_node));
  624. (void)acpi_get_handle(node, METHOD_NAME__CRS,
  625. ACPI_CAST_PTR(acpi_handle, &crs_node));
  626. (void)acpi_get_handle(node, METHOD_NAME__PRS,
  627. ACPI_CAST_PTR(acpi_handle, &prs_node));
  628. (void)acpi_get_handle(node, METHOD_NAME__AEI,
  629. ACPI_CAST_PTR(acpi_handle, &aei_node));
  630. if (!prt_node && !crs_node && !prs_node && !aei_node) {
  631. goto cleanup; /* Nothing to do */
  632. }
  633. acpi_os_printf("\nDevice: %s\n", parent_path);
  634. /* Prepare for a return object of arbitrary size */
  635. return_buffer.pointer = acpi_gbl_db_buffer;
  636. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  637. /* _PRT */
  638. if (prt_node) {
  639. acpi_os_printf("Evaluating _PRT\n");
  640. status =
  641. acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
  642. if (ACPI_FAILURE(status)) {
  643. acpi_os_printf("Could not evaluate _PRT: %s\n",
  644. acpi_format_exception(status));
  645. goto get_crs;
  646. }
  647. return_buffer.pointer = acpi_gbl_db_buffer;
  648. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  649. status = acpi_get_irq_routing_table(node, &return_buffer);
  650. if (ACPI_FAILURE(status)) {
  651. acpi_os_printf("GetIrqRoutingTable failed: %s\n",
  652. acpi_format_exception(status));
  653. goto get_crs;
  654. }
  655. acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
  656. }
  657. /* _CRS */
  658. get_crs:
  659. if (crs_node) {
  660. acpi_os_printf("Evaluating _CRS\n");
  661. return_buffer.pointer = acpi_gbl_db_buffer;
  662. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  663. status =
  664. acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
  665. if (ACPI_FAILURE(status)) {
  666. acpi_os_printf("Could not evaluate _CRS: %s\n",
  667. acpi_format_exception(status));
  668. goto get_prs;
  669. }
  670. /* This code exercises the acpi_walk_resources interface */
  671. status = acpi_walk_resources(node, METHOD_NAME__CRS,
  672. acpi_db_resource_callback, NULL);
  673. if (ACPI_FAILURE(status)) {
  674. acpi_os_printf("AcpiWalkResources failed: %s\n",
  675. acpi_format_exception(status));
  676. goto get_prs;
  677. }
  678. /* Get the _CRS resource list (test ALLOCATE buffer) */
  679. return_buffer.pointer = NULL;
  680. return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
  681. status = acpi_get_current_resources(node, &return_buffer);
  682. if (ACPI_FAILURE(status)) {
  683. acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
  684. acpi_format_exception(status));
  685. goto get_prs;
  686. }
  687. /* This code exercises the acpi_walk_resource_buffer interface */
  688. status = acpi_walk_resource_buffer(&return_buffer,
  689. acpi_db_resource_callback,
  690. NULL);
  691. if (ACPI_FAILURE(status)) {
  692. acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
  693. acpi_format_exception(status));
  694. goto end_crs;
  695. }
  696. /* Dump the _CRS resource list */
  697. acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
  698. return_buffer.
  699. pointer));
  700. /*
  701. * Perform comparison of original AML to newly created AML. This
  702. * tests both the AML->Resource conversion and the Resource->AML
  703. * conversion.
  704. */
  705. (void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
  706. /* Execute _SRS with the resource list */
  707. acpi_os_printf("Evaluating _SRS\n");
  708. status = acpi_set_current_resources(node, &return_buffer);
  709. if (ACPI_FAILURE(status)) {
  710. acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
  711. acpi_format_exception(status));
  712. goto end_crs;
  713. }
  714. end_crs:
  715. ACPI_FREE(return_buffer.pointer);
  716. }
  717. /* _PRS */
  718. get_prs:
  719. if (prs_node) {
  720. acpi_os_printf("Evaluating _PRS\n");
  721. return_buffer.pointer = acpi_gbl_db_buffer;
  722. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  723. status =
  724. acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
  725. if (ACPI_FAILURE(status)) {
  726. acpi_os_printf("Could not evaluate _PRS: %s\n",
  727. acpi_format_exception(status));
  728. goto get_aei;
  729. }
  730. return_buffer.pointer = acpi_gbl_db_buffer;
  731. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  732. status = acpi_get_possible_resources(node, &return_buffer);
  733. if (ACPI_FAILURE(status)) {
  734. acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
  735. acpi_format_exception(status));
  736. goto get_aei;
  737. }
  738. acpi_rs_dump_resource_list(ACPI_CAST_PTR
  739. (struct acpi_resource,
  740. acpi_gbl_db_buffer));
  741. }
  742. /* _AEI */
  743. get_aei:
  744. if (aei_node) {
  745. acpi_os_printf("Evaluating _AEI\n");
  746. return_buffer.pointer = acpi_gbl_db_buffer;
  747. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  748. status =
  749. acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
  750. if (ACPI_FAILURE(status)) {
  751. acpi_os_printf("Could not evaluate _AEI: %s\n",
  752. acpi_format_exception(status));
  753. goto cleanup;
  754. }
  755. return_buffer.pointer = acpi_gbl_db_buffer;
  756. return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
  757. status = acpi_get_event_resources(node, &return_buffer);
  758. if (ACPI_FAILURE(status)) {
  759. acpi_os_printf("AcpiGetEventResources failed: %s\n",
  760. acpi_format_exception(status));
  761. goto cleanup;
  762. }
  763. acpi_rs_dump_resource_list(ACPI_CAST_PTR
  764. (struct acpi_resource,
  765. acpi_gbl_db_buffer));
  766. }
  767. cleanup:
  768. ACPI_FREE(parent_path);
  769. return (AE_OK);
  770. }
  771. /*******************************************************************************
  772. *
  773. * FUNCTION: acpi_db_display_resources
  774. *
  775. * PARAMETERS: object_arg - String object name or object pointer.
  776. * NULL or "*" means "display resources for
  777. * all devices"
  778. *
  779. * RETURN: None
  780. *
  781. * DESCRIPTION: Display the resource objects associated with a device.
  782. *
  783. ******************************************************************************/
  784. void acpi_db_display_resources(char *object_arg)
  785. {
  786. struct acpi_namespace_node *node;
  787. acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
  788. acpi_dbg_level |= ACPI_LV_RESOURCES;
  789. /* Asterisk means "display resources for all devices" */
  790. if (!object_arg || (!strcmp(object_arg, "*"))) {
  791. (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
  792. ACPI_UINT32_MAX,
  793. acpi_db_device_resources, NULL, NULL,
  794. NULL);
  795. } else {
  796. /* Convert string to object pointer */
  797. node = acpi_db_convert_to_node(object_arg);
  798. if (node) {
  799. if (node->type != ACPI_TYPE_DEVICE) {
  800. acpi_os_printf
  801. ("%4.4s: Name is not a device object (%s)\n",
  802. node->name.ascii,
  803. acpi_ut_get_type_name(node->type));
  804. } else {
  805. (void)acpi_db_device_resources(node, 0, NULL,
  806. NULL);
  807. }
  808. }
  809. }
  810. acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
  811. }
  812. /*******************************************************************************
  813. *
  814. * FUNCTION: acpi_db_generate_ged
  815. *
  816. * PARAMETERS: ged_arg - Raw GED number, ascii string
  817. *
  818. * RETURN: None
  819. *
  820. * DESCRIPTION: Simulate firing of a GED
  821. *
  822. ******************************************************************************/
  823. void acpi_db_generate_interrupt(char *gsiv_arg)
  824. {
  825. u32 gsiv_number;
  826. struct acpi_ged_handler_info *ged_info = acpi_gbl_ged_handler_list;
  827. if (!ged_info) {
  828. acpi_os_printf("No GED handling present\n");
  829. }
  830. gsiv_number = strtoul(gsiv_arg, NULL, 0);
  831. while (ged_info) {
  832. if (ged_info->int_id == gsiv_number) {
  833. struct acpi_object_list arg_list;
  834. union acpi_object arg0;
  835. acpi_handle evt_handle = ged_info->evt_method;
  836. acpi_status status;
  837. acpi_os_printf("Evaluate GED _EVT (GSIV=%d)\n",
  838. gsiv_number);
  839. if (!evt_handle) {
  840. acpi_os_printf("Undefined _EVT method\n");
  841. return;
  842. }
  843. arg0.integer.type = ACPI_TYPE_INTEGER;
  844. arg0.integer.value = gsiv_number;
  845. arg_list.count = 1;
  846. arg_list.pointer = &arg0;
  847. status =
  848. acpi_evaluate_object(evt_handle, NULL, &arg_list,
  849. NULL);
  850. if (ACPI_FAILURE(status)) {
  851. acpi_os_printf("Could not evaluate _EVT\n");
  852. return;
  853. }
  854. }
  855. ged_info = ged_info->next;
  856. }
  857. }
  858. #if (!ACPI_REDUCED_HARDWARE)
  859. /*******************************************************************************
  860. *
  861. * FUNCTION: acpi_db_generate_gpe
  862. *
  863. * PARAMETERS: gpe_arg - Raw GPE number, ascii string
  864. * block_arg - GPE block number, ascii string
  865. * 0 or 1 for FADT GPE blocks
  866. *
  867. * RETURN: None
  868. *
  869. * DESCRIPTION: Simulate firing of a GPE
  870. *
  871. ******************************************************************************/
  872. void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
  873. {
  874. u32 block_number = 0;
  875. u32 gpe_number;
  876. struct acpi_gpe_event_info *gpe_event_info;
  877. gpe_number = strtoul(gpe_arg, NULL, 0);
  878. /*
  879. * If no block arg, or block arg == 0 or 1, use the FADT-defined
  880. * GPE blocks.
  881. */
  882. if (block_arg) {
  883. block_number = strtoul(block_arg, NULL, 0);
  884. if (block_number == 1) {
  885. block_number = 0;
  886. }
  887. }
  888. gpe_event_info =
  889. acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
  890. gpe_number);
  891. if (!gpe_event_info) {
  892. acpi_os_printf("Invalid GPE\n");
  893. return;
  894. }
  895. (void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
  896. }
  897. /*******************************************************************************
  898. *
  899. * FUNCTION: acpi_db_generate_sci
  900. *
  901. * PARAMETERS: None
  902. *
  903. * RETURN: None
  904. *
  905. * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
  906. *
  907. ******************************************************************************/
  908. void acpi_db_generate_sci(void)
  909. {
  910. acpi_ev_sci_dispatch();
  911. }
  912. #endif /* !ACPI_REDUCED_HARDWARE */
  913. /*******************************************************************************
  914. *
  915. * FUNCTION: acpi_db_trace
  916. *
  917. * PARAMETERS: enable_arg - ENABLE/AML to enable tracer
  918. * DISABLE to disable tracer
  919. * method_arg - Method to trace
  920. * once_arg - Whether trace once
  921. *
  922. * RETURN: None
  923. *
  924. * DESCRIPTION: Control method tracing facility
  925. *
  926. ******************************************************************************/
  927. void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
  928. {
  929. u32 debug_level = 0;
  930. u32 debug_layer = 0;
  931. u32 flags = 0;
  932. acpi_ut_strupr(enable_arg);
  933. acpi_ut_strupr(once_arg);
  934. if (method_arg) {
  935. if (acpi_db_trace_method_name) {
  936. ACPI_FREE(acpi_db_trace_method_name);
  937. acpi_db_trace_method_name = NULL;
  938. }
  939. acpi_db_trace_method_name =
  940. ACPI_ALLOCATE(strlen(method_arg) + 1);
  941. if (!acpi_db_trace_method_name) {
  942. acpi_os_printf("Failed to allocate method name (%s)\n",
  943. method_arg);
  944. return;
  945. }
  946. strcpy(acpi_db_trace_method_name, method_arg);
  947. }
  948. if (!strcmp(enable_arg, "ENABLE") ||
  949. !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
  950. if (!strcmp(enable_arg, "ENABLE")) {
  951. /* Inherit current console settings */
  952. debug_level = acpi_gbl_db_console_debug_level;
  953. debug_layer = acpi_dbg_layer;
  954. } else {
  955. /* Restrict console output to trace points only */
  956. debug_level = ACPI_LV_TRACE_POINT;
  957. debug_layer = ACPI_EXECUTER;
  958. }
  959. flags = ACPI_TRACE_ENABLED;
  960. if (!strcmp(enable_arg, "OPCODE")) {
  961. flags |= ACPI_TRACE_OPCODE;
  962. }
  963. if (once_arg && !strcmp(once_arg, "ONCE")) {
  964. flags |= ACPI_TRACE_ONESHOT;
  965. }
  966. }
  967. (void)acpi_debug_trace(acpi_db_trace_method_name,
  968. debug_level, debug_layer, flags);
  969. }