dbcmds.c 32 KB

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