dbtest.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /*******************************************************************************
  3. *
  4. * Module Name: dbtest - Various debug-related tests
  5. *
  6. ******************************************************************************/
  7. #include <acpi/acpi.h>
  8. #include "accommon.h"
  9. #include "acdebug.h"
  10. #include "acnamesp.h"
  11. #include "acpredef.h"
  12. #define _COMPONENT ACPI_CA_DEBUGGER
  13. ACPI_MODULE_NAME("dbtest")
  14. /* Local prototypes */
  15. static void acpi_db_test_all_objects(void);
  16. static acpi_status
  17. acpi_db_test_one_object(acpi_handle obj_handle,
  18. u32 nesting_level, void *context, void **return_value);
  19. static acpi_status
  20. acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
  21. static acpi_status
  22. acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
  23. static acpi_status
  24. acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
  25. static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node);
  26. static acpi_status
  27. acpi_db_read_from_object(struct acpi_namespace_node *node,
  28. acpi_object_type expected_type,
  29. union acpi_object **value);
  30. static acpi_status
  31. acpi_db_write_to_object(struct acpi_namespace_node *node,
  32. union acpi_object *value);
  33. static void acpi_db_evaluate_all_predefined_names(char *count_arg);
  34. static acpi_status
  35. acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
  36. u32 nesting_level,
  37. void *context, void **return_value);
  38. /*
  39. * Test subcommands
  40. */
  41. static struct acpi_db_argument_info acpi_db_test_types[] = {
  42. {"OBJECTS"},
  43. {"PREDEFINED"},
  44. {NULL} /* Must be null terminated */
  45. };
  46. #define CMD_TEST_OBJECTS 0
  47. #define CMD_TEST_PREDEFINED 1
  48. #define BUFFER_FILL_VALUE 0xFF
  49. /*
  50. * Support for the special debugger read/write control methods.
  51. * These methods are installed into the current namespace and are
  52. * used to read and write the various namespace objects. The point
  53. * is to force the AML interpreter do all of the work.
  54. */
  55. #define ACPI_DB_READ_METHOD "\\_T98"
  56. #define ACPI_DB_WRITE_METHOD "\\_T99"
  57. static acpi_handle read_handle = NULL;
  58. static acpi_handle write_handle = NULL;
  59. /* ASL Definitions of the debugger read/write control methods */
  60. #if 0
  61. definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
  62. {
  63. method(_T98, 1, not_serialized) { /* Read */
  64. return (de_ref_of(arg0))
  65. }
  66. }
  67. definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
  68. {
  69. method(_T99, 2, not_serialized) { /* Write */
  70. store(arg1, arg0)
  71. }
  72. }
  73. #endif
  74. static unsigned char read_method_code[] = {
  75. 0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000 "SSDT...." */
  76. 0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008 "..Intel." */
  77. 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010 "DEBUG..." */
  78. 0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018 "....INTL" */
  79. 0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020 "... .._T" */
  80. 0x39, 0x38, 0x01, 0xA4, 0x83, 0x68 /* 00000028 "98...h" */
  81. };
  82. static unsigned char write_method_code[] = {
  83. 0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000 "SSDT...." */
  84. 0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008 "..Intel." */
  85. 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010 "DEBUG..." */
  86. 0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018 "....INTL" */
  87. 0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020 "... .._T" */
  88. 0x39, 0x39, 0x02, 0x70, 0x69, 0x68 /* 00000028 "99.pih" */
  89. };
  90. /*******************************************************************************
  91. *
  92. * FUNCTION: acpi_db_execute_test
  93. *
  94. * PARAMETERS: type_arg - Subcommand
  95. *
  96. * RETURN: None
  97. *
  98. * DESCRIPTION: Execute various debug tests.
  99. *
  100. * Note: Code is prepared for future expansion of the TEST command.
  101. *
  102. ******************************************************************************/
  103. void acpi_db_execute_test(char *type_arg)
  104. {
  105. u32 temp;
  106. acpi_ut_strupr(type_arg);
  107. temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
  108. if (temp == ACPI_TYPE_NOT_FOUND) {
  109. acpi_os_printf("Invalid or unsupported argument\n");
  110. return;
  111. }
  112. switch (temp) {
  113. case CMD_TEST_OBJECTS:
  114. acpi_db_test_all_objects();
  115. break;
  116. case CMD_TEST_PREDEFINED:
  117. acpi_db_evaluate_all_predefined_names(NULL);
  118. break;
  119. default:
  120. break;
  121. }
  122. }
  123. /*******************************************************************************
  124. *
  125. * FUNCTION: acpi_db_test_all_objects
  126. *
  127. * PARAMETERS: None
  128. *
  129. * RETURN: None
  130. *
  131. * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
  132. * namespace by reading/writing/comparing all data objects such
  133. * as integers, strings, buffers, fields, buffer fields, etc.
  134. *
  135. ******************************************************************************/
  136. static void acpi_db_test_all_objects(void)
  137. {
  138. acpi_status status;
  139. /* Install the debugger read-object control method if necessary */
  140. if (!read_handle) {
  141. status = acpi_install_method(read_method_code);
  142. if (ACPI_FAILURE(status)) {
  143. acpi_os_printf
  144. ("%s, Could not install debugger read method\n",
  145. acpi_format_exception(status));
  146. return;
  147. }
  148. status =
  149. acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
  150. if (ACPI_FAILURE(status)) {
  151. acpi_os_printf
  152. ("Could not obtain handle for debug method %s\n",
  153. ACPI_DB_READ_METHOD);
  154. return;
  155. }
  156. }
  157. /* Install the debugger write-object control method if necessary */
  158. if (!write_handle) {
  159. status = acpi_install_method(write_method_code);
  160. if (ACPI_FAILURE(status)) {
  161. acpi_os_printf
  162. ("%s, Could not install debugger write method\n",
  163. acpi_format_exception(status));
  164. return;
  165. }
  166. status =
  167. acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
  168. if (ACPI_FAILURE(status)) {
  169. acpi_os_printf
  170. ("Could not obtain handle for debug method %s\n",
  171. ACPI_DB_WRITE_METHOD);
  172. return;
  173. }
  174. }
  175. /* Walk the entire namespace, testing each supported named data object */
  176. (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  177. ACPI_UINT32_MAX, acpi_db_test_one_object,
  178. NULL, NULL, NULL);
  179. }
  180. /*******************************************************************************
  181. *
  182. * FUNCTION: acpi_db_test_one_object
  183. *
  184. * PARAMETERS: acpi_walk_callback
  185. *
  186. * RETURN: Status
  187. *
  188. * DESCRIPTION: Test one namespace object. Supported types are Integer,
  189. * String, Buffer, buffer_field, and field_unit. All other object
  190. * types are simply ignored.
  191. *
  192. * Note: Support for Packages is not implemented.
  193. *
  194. ******************************************************************************/
  195. static acpi_status
  196. acpi_db_test_one_object(acpi_handle obj_handle,
  197. u32 nesting_level, void *context, void **return_value)
  198. {
  199. struct acpi_namespace_node *node;
  200. union acpi_operand_object *obj_desc;
  201. union acpi_operand_object *region_obj;
  202. acpi_object_type local_type;
  203. u32 bit_length = 0;
  204. u32 byte_length = 0;
  205. acpi_status status = AE_OK;
  206. node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
  207. obj_desc = node->object;
  208. /*
  209. * For the supported types, get the actual bit length or
  210. * byte length. Map the type to one of Integer/String/Buffer.
  211. */
  212. switch (node->type) {
  213. case ACPI_TYPE_INTEGER:
  214. /* Integer width is either 32 or 64 */
  215. local_type = ACPI_TYPE_INTEGER;
  216. bit_length = acpi_gbl_integer_bit_width;
  217. break;
  218. case ACPI_TYPE_STRING:
  219. local_type = ACPI_TYPE_STRING;
  220. byte_length = obj_desc->string.length;
  221. break;
  222. case ACPI_TYPE_BUFFER:
  223. local_type = ACPI_TYPE_BUFFER;
  224. byte_length = obj_desc->buffer.length;
  225. bit_length = byte_length * 8;
  226. break;
  227. case ACPI_TYPE_PACKAGE:
  228. local_type = ACPI_TYPE_PACKAGE;
  229. break;
  230. case ACPI_TYPE_FIELD_UNIT:
  231. case ACPI_TYPE_BUFFER_FIELD:
  232. case ACPI_TYPE_LOCAL_REGION_FIELD:
  233. case ACPI_TYPE_LOCAL_INDEX_FIELD:
  234. case ACPI_TYPE_LOCAL_BANK_FIELD:
  235. local_type = ACPI_TYPE_INTEGER;
  236. if (obj_desc) {
  237. /*
  238. * Returned object will be a Buffer if the field length
  239. * is larger than the size of an Integer (32 or 64 bits
  240. * depending on the DSDT version).
  241. */
  242. bit_length = obj_desc->common_field.bit_length;
  243. byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
  244. if (bit_length > acpi_gbl_integer_bit_width) {
  245. local_type = ACPI_TYPE_BUFFER;
  246. }
  247. }
  248. break;
  249. default:
  250. /* Ignore all other types */
  251. return (AE_OK);
  252. }
  253. /* Emit the common prefix: Type:Name */
  254. acpi_os_printf("%14s: %4.4s",
  255. acpi_ut_get_type_name(node->type), node->name.ascii);
  256. if (!obj_desc) {
  257. acpi_os_printf(" Ignoring, no attached object\n");
  258. return (AE_OK);
  259. }
  260. /*
  261. * Check for unsupported region types. Note: acpi_exec simulates
  262. * access to system_memory, system_IO, PCI_Config, and EC.
  263. */
  264. switch (node->type) {
  265. case ACPI_TYPE_LOCAL_REGION_FIELD:
  266. region_obj = obj_desc->field.region_obj;
  267. switch (region_obj->region.space_id) {
  268. case ACPI_ADR_SPACE_SYSTEM_MEMORY:
  269. case ACPI_ADR_SPACE_SYSTEM_IO:
  270. case ACPI_ADR_SPACE_PCI_CONFIG:
  271. break;
  272. default:
  273. acpi_os_printf
  274. (" %s space is not supported in this command [%4.4s]\n",
  275. acpi_ut_get_region_name(region_obj->region.
  276. space_id),
  277. region_obj->region.node->name.ascii);
  278. return (AE_OK);
  279. }
  280. break;
  281. default:
  282. break;
  283. }
  284. /* At this point, we have resolved the object to one of the major types */
  285. switch (local_type) {
  286. case ACPI_TYPE_INTEGER:
  287. status = acpi_db_test_integer_type(node, bit_length);
  288. break;
  289. case ACPI_TYPE_STRING:
  290. status = acpi_db_test_string_type(node, byte_length);
  291. break;
  292. case ACPI_TYPE_BUFFER:
  293. status = acpi_db_test_buffer_type(node, bit_length);
  294. break;
  295. case ACPI_TYPE_PACKAGE:
  296. status = acpi_db_test_package_type(node);
  297. break;
  298. default:
  299. acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
  300. local_type);
  301. break;
  302. }
  303. /* Exit on error, but don't abort the namespace walk */
  304. if (ACPI_FAILURE(status)) {
  305. status = AE_OK;
  306. goto exit;
  307. }
  308. switch (node->type) {
  309. case ACPI_TYPE_LOCAL_REGION_FIELD:
  310. region_obj = obj_desc->field.region_obj;
  311. acpi_os_printf(" (%s)",
  312. acpi_ut_get_region_name(region_obj->region.
  313. space_id));
  314. break;
  315. default:
  316. break;
  317. }
  318. exit:
  319. acpi_os_printf("\n");
  320. return (status);
  321. }
  322. /*******************************************************************************
  323. *
  324. * FUNCTION: acpi_db_test_integer_type
  325. *
  326. * PARAMETERS: node - Parent NS node for the object
  327. * bit_length - Actual length of the object. Used for
  328. * support of arbitrary length field_unit
  329. * and buffer_field objects.
  330. *
  331. * RETURN: Status
  332. *
  333. * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
  334. * write/read/compare of an arbitrary new value, then performs
  335. * a write/read/compare of the original value.
  336. *
  337. ******************************************************************************/
  338. static acpi_status
  339. acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
  340. {
  341. union acpi_object *temp1 = NULL;
  342. union acpi_object *temp2 = NULL;
  343. union acpi_object *temp3 = NULL;
  344. union acpi_object write_value;
  345. u64 value_to_write;
  346. acpi_status status;
  347. if (bit_length > 64) {
  348. acpi_os_printf(" Invalid length for an Integer: %u",
  349. bit_length);
  350. return (AE_OK);
  351. }
  352. /* Read the original value */
  353. status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
  354. if (ACPI_FAILURE(status)) {
  355. return (status);
  356. }
  357. acpi_os_printf(" (%4.4X/%3.3X) %8.8X%8.8X",
  358. bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
  359. ACPI_FORMAT_UINT64(temp1->integer.value));
  360. value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
  361. if (temp1->integer.value == value_to_write) {
  362. value_to_write = 0;
  363. }
  364. /* Write a new value */
  365. write_value.type = ACPI_TYPE_INTEGER;
  366. write_value.integer.value = value_to_write;
  367. status = acpi_db_write_to_object(node, &write_value);
  368. if (ACPI_FAILURE(status)) {
  369. goto exit;
  370. }
  371. /* Ensure that we can read back the new value */
  372. status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
  373. if (ACPI_FAILURE(status)) {
  374. goto exit;
  375. }
  376. if (temp2->integer.value != value_to_write) {
  377. acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
  378. ACPI_FORMAT_UINT64(temp2->integer.value),
  379. ACPI_FORMAT_UINT64(value_to_write));
  380. }
  381. /* Write back the original value */
  382. write_value.integer.value = temp1->integer.value;
  383. status = acpi_db_write_to_object(node, &write_value);
  384. if (ACPI_FAILURE(status)) {
  385. goto exit;
  386. }
  387. /* Ensure that we can read back the original value */
  388. status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
  389. if (ACPI_FAILURE(status)) {
  390. goto exit;
  391. }
  392. if (temp3->integer.value != temp1->integer.value) {
  393. acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
  394. ACPI_FORMAT_UINT64(temp3->integer.value),
  395. ACPI_FORMAT_UINT64(temp1->integer.value));
  396. }
  397. exit:
  398. if (temp1) {
  399. acpi_os_free(temp1);
  400. }
  401. if (temp2) {
  402. acpi_os_free(temp2);
  403. }
  404. if (temp3) {
  405. acpi_os_free(temp3);
  406. }
  407. return (AE_OK);
  408. }
  409. /*******************************************************************************
  410. *
  411. * FUNCTION: acpi_db_test_buffer_type
  412. *
  413. * PARAMETERS: node - Parent NS node for the object
  414. * bit_length - Actual length of the object.
  415. *
  416. * RETURN: Status
  417. *
  418. * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
  419. * write/read/compare of an arbitrary new value, then performs
  420. * a write/read/compare of the original value.
  421. *
  422. ******************************************************************************/
  423. static acpi_status
  424. acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
  425. {
  426. union acpi_object *temp1 = NULL;
  427. union acpi_object *temp2 = NULL;
  428. union acpi_object *temp3 = NULL;
  429. u8 *buffer;
  430. union acpi_object write_value;
  431. acpi_status status;
  432. u32 byte_length;
  433. u32 i;
  434. u8 extra_bits;
  435. byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
  436. if (byte_length == 0) {
  437. acpi_os_printf(" Ignoring zero length buffer");
  438. return (AE_OK);
  439. }
  440. /* Allocate a local buffer */
  441. buffer = ACPI_ALLOCATE_ZEROED(byte_length);
  442. if (!buffer) {
  443. return (AE_NO_MEMORY);
  444. }
  445. /* Read the original value */
  446. status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
  447. if (ACPI_FAILURE(status)) {
  448. goto exit;
  449. }
  450. /* Emit a few bytes of the buffer */
  451. acpi_os_printf(" (%4.4X/%3.3X)", bit_length, temp1->buffer.length);
  452. for (i = 0; ((i < 4) && (i < byte_length)); i++) {
  453. acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
  454. }
  455. acpi_os_printf("... ");
  456. /*
  457. * Write a new value.
  458. *
  459. * Handle possible extra bits at the end of the buffer. Can
  460. * happen for field_units larger than an integer, but the bit
  461. * count is not an integral number of bytes. Zero out the
  462. * unused bits.
  463. */
  464. memset(buffer, BUFFER_FILL_VALUE, byte_length);
  465. extra_bits = bit_length % 8;
  466. if (extra_bits) {
  467. buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
  468. }
  469. write_value.type = ACPI_TYPE_BUFFER;
  470. write_value.buffer.length = byte_length;
  471. write_value.buffer.pointer = buffer;
  472. status = acpi_db_write_to_object(node, &write_value);
  473. if (ACPI_FAILURE(status)) {
  474. goto exit;
  475. }
  476. /* Ensure that we can read back the new value */
  477. status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
  478. if (ACPI_FAILURE(status)) {
  479. goto exit;
  480. }
  481. if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
  482. acpi_os_printf(" MISMATCH 2: New buffer value");
  483. }
  484. /* Write back the original value */
  485. write_value.buffer.length = byte_length;
  486. write_value.buffer.pointer = temp1->buffer.pointer;
  487. status = acpi_db_write_to_object(node, &write_value);
  488. if (ACPI_FAILURE(status)) {
  489. goto exit;
  490. }
  491. /* Ensure that we can read back the original value */
  492. status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
  493. if (ACPI_FAILURE(status)) {
  494. goto exit;
  495. }
  496. if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
  497. acpi_os_printf(" MISMATCH 3: While restoring original buffer");
  498. }
  499. exit:
  500. ACPI_FREE(buffer);
  501. if (temp1) {
  502. acpi_os_free(temp1);
  503. }
  504. if (temp2) {
  505. acpi_os_free(temp2);
  506. }
  507. if (temp3) {
  508. acpi_os_free(temp3);
  509. }
  510. return (status);
  511. }
  512. /*******************************************************************************
  513. *
  514. * FUNCTION: acpi_db_test_string_type
  515. *
  516. * PARAMETERS: node - Parent NS node for the object
  517. * byte_length - Actual length of the object.
  518. *
  519. * RETURN: Status
  520. *
  521. * DESCRIPTION: Test read/write for an String-valued object. Performs a
  522. * write/read/compare of an arbitrary new value, then performs
  523. * a write/read/compare of the original value.
  524. *
  525. ******************************************************************************/
  526. static acpi_status
  527. acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
  528. {
  529. union acpi_object *temp1 = NULL;
  530. union acpi_object *temp2 = NULL;
  531. union acpi_object *temp3 = NULL;
  532. char *value_to_write = "Test String from AML Debugger";
  533. union acpi_object write_value;
  534. acpi_status status;
  535. /* Read the original value */
  536. status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
  537. if (ACPI_FAILURE(status)) {
  538. return (status);
  539. }
  540. acpi_os_printf(" (%4.4X/%3.3X) \"%s\"", (temp1->string.length * 8),
  541. temp1->string.length, temp1->string.pointer);
  542. /* Write a new value */
  543. write_value.type = ACPI_TYPE_STRING;
  544. write_value.string.length = strlen(value_to_write);
  545. write_value.string.pointer = value_to_write;
  546. status = acpi_db_write_to_object(node, &write_value);
  547. if (ACPI_FAILURE(status)) {
  548. goto exit;
  549. }
  550. /* Ensure that we can read back the new value */
  551. status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
  552. if (ACPI_FAILURE(status)) {
  553. goto exit;
  554. }
  555. if (strcmp(temp2->string.pointer, value_to_write)) {
  556. acpi_os_printf(" MISMATCH 2: %s, expecting %s",
  557. temp2->string.pointer, value_to_write);
  558. }
  559. /* Write back the original value */
  560. write_value.string.length = strlen(temp1->string.pointer);
  561. write_value.string.pointer = temp1->string.pointer;
  562. status = acpi_db_write_to_object(node, &write_value);
  563. if (ACPI_FAILURE(status)) {
  564. goto exit;
  565. }
  566. /* Ensure that we can read back the original value */
  567. status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
  568. if (ACPI_FAILURE(status)) {
  569. goto exit;
  570. }
  571. if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
  572. acpi_os_printf(" MISMATCH 3: %s, expecting %s",
  573. temp3->string.pointer, temp1->string.pointer);
  574. }
  575. exit:
  576. if (temp1) {
  577. acpi_os_free(temp1);
  578. }
  579. if (temp2) {
  580. acpi_os_free(temp2);
  581. }
  582. if (temp3) {
  583. acpi_os_free(temp3);
  584. }
  585. return (status);
  586. }
  587. /*******************************************************************************
  588. *
  589. * FUNCTION: acpi_db_test_package_type
  590. *
  591. * PARAMETERS: node - Parent NS node for the object
  592. *
  593. * RETURN: Status
  594. *
  595. * DESCRIPTION: Test read for a Package object.
  596. *
  597. ******************************************************************************/
  598. static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node)
  599. {
  600. union acpi_object *temp1 = NULL;
  601. acpi_status status;
  602. /* Read the original value */
  603. status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1);
  604. if (ACPI_FAILURE(status)) {
  605. return (status);
  606. }
  607. acpi_os_printf(" %8.8X Elements", temp1->package.count);
  608. acpi_os_free(temp1);
  609. return (status);
  610. }
  611. /*******************************************************************************
  612. *
  613. * FUNCTION: acpi_db_read_from_object
  614. *
  615. * PARAMETERS: node - Parent NS node for the object
  616. * expected_type - Object type expected from the read
  617. * value - Where the value read is returned
  618. *
  619. * RETURN: Status
  620. *
  621. * DESCRIPTION: Performs a read from the specified object by invoking the
  622. * special debugger control method that reads the object. Thus,
  623. * the AML interpreter is doing all of the work, increasing the
  624. * validity of the test.
  625. *
  626. ******************************************************************************/
  627. static acpi_status
  628. acpi_db_read_from_object(struct acpi_namespace_node *node,
  629. acpi_object_type expected_type,
  630. union acpi_object **value)
  631. {
  632. union acpi_object *ret_value;
  633. struct acpi_object_list param_objects;
  634. union acpi_object params[2];
  635. struct acpi_buffer return_obj;
  636. acpi_status status;
  637. params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
  638. params[0].reference.actual_type = node->type;
  639. params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
  640. param_objects.count = 1;
  641. param_objects.pointer = params;
  642. return_obj.length = ACPI_ALLOCATE_BUFFER;
  643. acpi_gbl_method_executing = TRUE;
  644. status = acpi_evaluate_object(read_handle, NULL,
  645. &param_objects, &return_obj);
  646. acpi_gbl_method_executing = FALSE;
  647. if (ACPI_FAILURE(status)) {
  648. acpi_os_printf("Could not read from object, %s",
  649. acpi_format_exception(status));
  650. return (status);
  651. }
  652. ret_value = (union acpi_object *)return_obj.pointer;
  653. switch (ret_value->type) {
  654. case ACPI_TYPE_INTEGER:
  655. case ACPI_TYPE_BUFFER:
  656. case ACPI_TYPE_STRING:
  657. case ACPI_TYPE_PACKAGE:
  658. /*
  659. * Did we receive the type we wanted? Most important for the
  660. * Integer/Buffer case (when a field is larger than an Integer,
  661. * it should return a Buffer).
  662. */
  663. if (ret_value->type != expected_type) {
  664. acpi_os_printf
  665. (" Type mismatch: Expected %s, Received %s",
  666. acpi_ut_get_type_name(expected_type),
  667. acpi_ut_get_type_name(ret_value->type));
  668. acpi_os_free(return_obj.pointer);
  669. return (AE_TYPE);
  670. }
  671. *value = ret_value;
  672. break;
  673. default:
  674. acpi_os_printf(" Unsupported return object type, %s",
  675. acpi_ut_get_type_name(ret_value->type));
  676. acpi_os_free(return_obj.pointer);
  677. return (AE_TYPE);
  678. }
  679. return (status);
  680. }
  681. /*******************************************************************************
  682. *
  683. * FUNCTION: acpi_db_write_to_object
  684. *
  685. * PARAMETERS: node - Parent NS node for the object
  686. * value - Value to be written
  687. *
  688. * RETURN: Status
  689. *
  690. * DESCRIPTION: Performs a write to the specified object by invoking the
  691. * special debugger control method that writes the object. Thus,
  692. * the AML interpreter is doing all of the work, increasing the
  693. * validity of the test.
  694. *
  695. ******************************************************************************/
  696. static acpi_status
  697. acpi_db_write_to_object(struct acpi_namespace_node *node,
  698. union acpi_object *value)
  699. {
  700. struct acpi_object_list param_objects;
  701. union acpi_object params[2];
  702. acpi_status status;
  703. params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
  704. params[0].reference.actual_type = node->type;
  705. params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
  706. /* Copy the incoming user parameter */
  707. memcpy(&params[1], value, sizeof(union acpi_object));
  708. param_objects.count = 2;
  709. param_objects.pointer = params;
  710. acpi_gbl_method_executing = TRUE;
  711. status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
  712. acpi_gbl_method_executing = FALSE;
  713. if (ACPI_FAILURE(status)) {
  714. acpi_os_printf("Could not write to object, %s",
  715. acpi_format_exception(status));
  716. }
  717. return (status);
  718. }
  719. /*******************************************************************************
  720. *
  721. * FUNCTION: acpi_db_evaluate_all_predefined_names
  722. *
  723. * PARAMETERS: count_arg - Max number of methods to execute
  724. *
  725. * RETURN: None
  726. *
  727. * DESCRIPTION: Namespace batch execution. Execute predefined names in the
  728. * namespace, up to the max count, if specified.
  729. *
  730. ******************************************************************************/
  731. static void acpi_db_evaluate_all_predefined_names(char *count_arg)
  732. {
  733. struct acpi_db_execute_walk info;
  734. info.count = 0;
  735. info.max_count = ACPI_UINT32_MAX;
  736. if (count_arg) {
  737. info.max_count = strtoul(count_arg, NULL, 0);
  738. }
  739. /* Search all nodes in namespace */
  740. (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  741. ACPI_UINT32_MAX,
  742. acpi_db_evaluate_one_predefined_name, NULL,
  743. (void *)&info, NULL);
  744. acpi_os_printf("Evaluated %u predefined names in the namespace\n",
  745. info.count);
  746. }
  747. /*******************************************************************************
  748. *
  749. * FUNCTION: acpi_db_evaluate_one_predefined_name
  750. *
  751. * PARAMETERS: Callback from walk_namespace
  752. *
  753. * RETURN: Status
  754. *
  755. * DESCRIPTION: Batch execution module. Currently only executes predefined
  756. * ACPI names.
  757. *
  758. ******************************************************************************/
  759. static acpi_status
  760. acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
  761. u32 nesting_level,
  762. void *context, void **return_value)
  763. {
  764. struct acpi_namespace_node *node =
  765. (struct acpi_namespace_node *)obj_handle;
  766. struct acpi_db_execute_walk *info =
  767. (struct acpi_db_execute_walk *)context;
  768. char *pathname;
  769. const union acpi_predefined_info *predefined;
  770. struct acpi_device_info *obj_info;
  771. struct acpi_object_list param_objects;
  772. union acpi_object params[ACPI_METHOD_NUM_ARGS];
  773. union acpi_object *this_param;
  774. struct acpi_buffer return_obj;
  775. acpi_status status;
  776. u16 arg_type_list;
  777. u8 arg_count;
  778. u8 arg_type;
  779. u32 i;
  780. /* The name must be a predefined ACPI name */
  781. predefined = acpi_ut_match_predefined_method(node->name.ascii);
  782. if (!predefined) {
  783. return (AE_OK);
  784. }
  785. if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
  786. return (AE_OK);
  787. }
  788. pathname = acpi_ns_get_normalized_pathname(node, TRUE);
  789. if (!pathname) {
  790. return (AE_OK);
  791. }
  792. /* Get the object info for number of method parameters */
  793. status = acpi_get_object_info(obj_handle, &obj_info);
  794. if (ACPI_FAILURE(status)) {
  795. ACPI_FREE(pathname);
  796. return (status);
  797. }
  798. param_objects.count = 0;
  799. param_objects.pointer = NULL;
  800. if (obj_info->type == ACPI_TYPE_METHOD) {
  801. /* Setup default parameters (with proper types) */
  802. arg_type_list = predefined->info.argument_list;
  803. arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
  804. /*
  805. * Setup the ACPI-required number of arguments, regardless of what
  806. * the actual method defines. If there is a difference, then the
  807. * method is wrong and a warning will be issued during execution.
  808. */
  809. this_param = params;
  810. for (i = 0; i < arg_count; i++) {
  811. arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
  812. this_param->type = arg_type;
  813. switch (arg_type) {
  814. case ACPI_TYPE_INTEGER:
  815. this_param->integer.value = 1;
  816. break;
  817. case ACPI_TYPE_STRING:
  818. this_param->string.pointer =
  819. "This is the default argument string";
  820. this_param->string.length =
  821. strlen(this_param->string.pointer);
  822. break;
  823. case ACPI_TYPE_BUFFER:
  824. this_param->buffer.pointer = (u8 *)params; /* just a garbage buffer */
  825. this_param->buffer.length = 48;
  826. break;
  827. case ACPI_TYPE_PACKAGE:
  828. this_param->package.elements = NULL;
  829. this_param->package.count = 0;
  830. break;
  831. default:
  832. acpi_os_printf
  833. ("%s: Unsupported argument type: %u\n",
  834. pathname, arg_type);
  835. break;
  836. }
  837. this_param++;
  838. }
  839. param_objects.count = arg_count;
  840. param_objects.pointer = params;
  841. }
  842. ACPI_FREE(obj_info);
  843. return_obj.pointer = NULL;
  844. return_obj.length = ACPI_ALLOCATE_BUFFER;
  845. /* Do the actual method execution */
  846. acpi_gbl_method_executing = TRUE;
  847. status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
  848. acpi_os_printf("%-32s returned %s\n",
  849. pathname, acpi_format_exception(status));
  850. acpi_gbl_method_executing = FALSE;
  851. ACPI_FREE(pathname);
  852. /* Ignore status from method execution */
  853. status = AE_OK;
  854. /* Update count, check if we have executed enough methods */
  855. info->count++;
  856. if (info->count >= info->max_count) {
  857. status = AE_CTRL_TERMINATE;
  858. }
  859. return (status);
  860. }