dbtest.c 29 KB

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