acpi.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Tests for ACPI table generation
  4. *
  5. * Copyright 2019 Google LLC
  6. * Written by Simon Glass <sjg@chromium.org>
  7. */
  8. #include <common.h>
  9. #include <console.h>
  10. #include <dm.h>
  11. #include <malloc.h>
  12. #include <mapmem.h>
  13. #include <tables_csum.h>
  14. #include <version_string.h>
  15. #include <acpi/acpigen.h>
  16. #include <acpi/acpi_device.h>
  17. #include <acpi/acpi_table.h>
  18. #include <asm/global_data.h>
  19. #include <dm/acpi.h>
  20. #include <dm/test.h>
  21. #include <test/ut.h>
  22. #include "acpi.h"
  23. #define BUF_SIZE 4096
  24. #define OEM_REVISION ((((version_num / 1000) % 10) << 28) | \
  25. (((version_num / 100) % 10) << 24) | \
  26. (((version_num / 10) % 10) << 20) | \
  27. ((version_num % 10) << 16) | \
  28. (((version_num_patch / 10) % 10) << 12) | \
  29. ((version_num_patch % 10) << 8) | \
  30. 0x01)
  31. /**
  32. * struct testacpi_plat - Platform data for the test ACPI device
  33. *
  34. * @no_name: true to emit an empty ACPI name from testacpi_get_name()
  35. * @return_error: true to return an error instead of a name
  36. */
  37. struct testacpi_plat {
  38. bool return_error;
  39. bool no_name;
  40. };
  41. /**
  42. * setup_ctx_and_base_tables() - Set up context along with RSDP, RSDT and XSDT
  43. *
  44. * Set up the context with the given start position. Some basic tables are
  45. * always needed, so set them up as well.
  46. *
  47. * @ctx: Context to set up
  48. */
  49. static int setup_ctx_and_base_tables(struct unit_test_state *uts,
  50. struct acpi_ctx *ctx, ulong start)
  51. {
  52. struct acpi_writer *entry = ACPI_WRITER_GET(0base);
  53. acpi_setup_ctx(ctx, start);
  54. ctx->tab_start = ctx->current;
  55. ut_assertok(acpi_write_one(ctx, entry));
  56. return 0;
  57. }
  58. static int testacpi_write_tables(const struct udevice *dev,
  59. struct acpi_ctx *ctx)
  60. {
  61. struct acpi_dmar *dmar;
  62. int ret;
  63. dmar = (struct acpi_dmar *)ctx->current;
  64. acpi_create_dmar(dmar, DMAR_INTR_REMAP);
  65. ctx->current += sizeof(struct acpi_dmar);
  66. ret = acpi_add_table(ctx, dmar);
  67. if (ret)
  68. return log_msg_ret("add", ret);
  69. return 0;
  70. }
  71. static int testacpi_get_name(const struct udevice *dev, char *out_name)
  72. {
  73. struct testacpi_plat *plat = dev_get_plat(dev);
  74. if (plat->return_error)
  75. return -EINVAL;
  76. if (plat->no_name) {
  77. *out_name = '\0';
  78. return 0;
  79. }
  80. if (device_get_uclass_id(dev->parent) == UCLASS_TEST_ACPI)
  81. return acpi_copy_name(out_name, ACPI_TEST_CHILD_NAME);
  82. else
  83. return acpi_copy_name(out_name, ACPI_TEST_DEV_NAME);
  84. }
  85. static int testacpi_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
  86. {
  87. const char *data;
  88. data = dev_read_string(dev, "acpi-ssdt-test-data");
  89. if (data) {
  90. while (*data)
  91. acpigen_emit_byte(ctx, *data++);
  92. }
  93. return 0;
  94. }
  95. static int testacpi_inject_dsdt(const struct udevice *dev, struct acpi_ctx *ctx)
  96. {
  97. const char *data;
  98. data = dev_read_string(dev, "acpi-dsdt-test-data");
  99. if (data) {
  100. while (*data)
  101. acpigen_emit_byte(ctx, *data++);
  102. }
  103. return 0;
  104. }
  105. struct acpi_ops testacpi_ops = {
  106. .get_name = testacpi_get_name,
  107. .write_tables = testacpi_write_tables,
  108. .fill_ssdt = testacpi_fill_ssdt,
  109. .inject_dsdt = testacpi_inject_dsdt,
  110. };
  111. static const struct udevice_id testacpi_ids[] = {
  112. { .compatible = "denx,u-boot-acpi-test" },
  113. { }
  114. };
  115. U_BOOT_DRIVER(testacpi_drv) = {
  116. .name = "testacpi_drv",
  117. .of_match = testacpi_ids,
  118. .id = UCLASS_TEST_ACPI,
  119. .bind = dm_scan_fdt_dev,
  120. .plat_auto = sizeof(struct testacpi_plat),
  121. ACPI_OPS_PTR(&testacpi_ops)
  122. };
  123. UCLASS_DRIVER(testacpi) = {
  124. .name = "testacpi",
  125. .id = UCLASS_TEST_ACPI,
  126. };
  127. /* Test ACPI get_name() */
  128. static int dm_test_acpi_get_name(struct unit_test_state *uts)
  129. {
  130. char name[ACPI_NAME_MAX];
  131. struct udevice *dev, *dev2, *i2c, *spi, *timer, *sound;
  132. struct udevice *pci, *root;
  133. /* Test getting the name from the driver */
  134. ut_assertok(uclass_first_device_err(UCLASS_TEST_ACPI, &dev));
  135. ut_assertok(acpi_get_name(dev, name));
  136. ut_asserteq_str(ACPI_TEST_DEV_NAME, name);
  137. /* Test getting the name from the device tree */
  138. ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
  139. &dev2));
  140. ut_assertok(acpi_get_name(dev2, name));
  141. ut_asserteq_str("GHIJ", name);
  142. /* Test getting the name from acpi_device_get_name() */
  143. ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
  144. ut_assertok(acpi_get_name(i2c, name));
  145. ut_asserteq_str("I2C0", name);
  146. ut_assertok(uclass_first_device_err(UCLASS_SPI, &spi));
  147. ut_assertok(acpi_get_name(spi, name));
  148. ut_asserteq_str("SPI0", name);
  149. /* ACPI doesn't know about the timer */
  150. ut_assertok(uclass_first_device_err(UCLASS_TIMER, &timer));
  151. ut_asserteq(-ENOENT, acpi_get_name(timer, name));
  152. /* May as well test the rest of the cases */
  153. ut_assertok(uclass_first_device_err(UCLASS_SOUND, &sound));
  154. ut_assertok(acpi_get_name(sound, name));
  155. ut_asserteq_str("HDAS", name);
  156. ut_assertok(uclass_first_device_err(UCLASS_PCI, &pci));
  157. ut_assertok(acpi_get_name(pci, name));
  158. ut_asserteq_str("PCI0", name);
  159. ut_assertok(uclass_first_device_err(UCLASS_ROOT, &root));
  160. ut_assertok(acpi_get_name(root, name));
  161. ut_asserteq_str("\\_SB", name);
  162. /* Note that we don't have tests for acpi_name_from_id() */
  163. return 0;
  164. }
  165. DM_TEST(dm_test_acpi_get_name, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  166. /* Test acpi_get_table_revision() */
  167. static int dm_test_acpi_get_table_revision(struct unit_test_state *uts)
  168. {
  169. ut_asserteq(1, acpi_get_table_revision(ACPITAB_MCFG));
  170. ut_asserteq(2, acpi_get_table_revision(ACPITAB_RSDP));
  171. ut_asserteq(4, acpi_get_table_revision(ACPITAB_TPM2));
  172. ut_asserteq(-EINVAL, acpi_get_table_revision(ACPITAB_COUNT));
  173. return 0;
  174. }
  175. DM_TEST(dm_test_acpi_get_table_revision,
  176. UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  177. /* Test acpi_create_dmar() */
  178. static int dm_test_acpi_create_dmar(struct unit_test_state *uts)
  179. {
  180. struct acpi_dmar dmar;
  181. struct udevice *cpu;
  182. ut_assertok(uclass_first_device_err(UCLASS_CPU, &cpu));
  183. ut_assertnonnull(cpu);
  184. ut_assertok(acpi_create_dmar(&dmar, DMAR_INTR_REMAP));
  185. ut_asserteq(DMAR_INTR_REMAP, dmar.flags);
  186. ut_asserteq(32 - 1, dmar.host_address_width);
  187. return 0;
  188. }
  189. DM_TEST(dm_test_acpi_create_dmar, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  190. /* Test acpi_fill_header() */
  191. static int dm_test_acpi_fill_header(struct unit_test_state *uts)
  192. {
  193. struct acpi_table_header hdr;
  194. /* Make sure these 5 fields are not changed */
  195. hdr.length = 0x11;
  196. hdr.revision = 0x22;
  197. hdr.checksum = 0x33;
  198. hdr.aslc_revision = 0x44;
  199. acpi_fill_header(&hdr, "ABCD");
  200. ut_asserteq_mem("ABCD", hdr.signature, sizeof(hdr.signature));
  201. ut_asserteq(0x11, hdr.length);
  202. ut_asserteq(0x22, hdr.revision);
  203. ut_asserteq(0x33, hdr.checksum);
  204. ut_asserteq_mem(OEM_ID, hdr.oem_id, sizeof(hdr.oem_id));
  205. ut_asserteq_mem(OEM_TABLE_ID, hdr.oem_table_id,
  206. sizeof(hdr.oem_table_id));
  207. ut_asserteq(OEM_REVISION, hdr.oem_revision);
  208. ut_asserteq_mem(ASLC_ID, hdr.aslc_id, sizeof(hdr.aslc_id));
  209. ut_asserteq(0x44, hdr.aslc_revision);
  210. return 0;
  211. }
  212. DM_TEST(dm_test_acpi_fill_header, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  213. /* Test ACPI write_tables() */
  214. static int dm_test_acpi_write_tables(struct unit_test_state *uts)
  215. {
  216. struct acpi_dmar *dmar;
  217. struct acpi_ctx ctx;
  218. ulong addr;
  219. void *buf;
  220. int i;
  221. buf = malloc(BUF_SIZE);
  222. ut_assertnonnull(buf);
  223. addr = map_to_sysmem(buf);
  224. ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
  225. dmar = ctx.current;
  226. ut_assertok(acpi_write_dev_tables(&ctx));
  227. /*
  228. * We should have three dmar tables, one for each
  229. * "denx,u-boot-acpi-test" device
  230. */
  231. ut_asserteq_ptr(dmar + 3, ctx.current);
  232. ut_asserteq(DMAR_INTR_REMAP, dmar->flags);
  233. ut_asserteq(32 - 1, dmar->host_address_width);
  234. ut_asserteq(DMAR_INTR_REMAP, dmar[1].flags);
  235. ut_asserteq(32 - 1, dmar[1].host_address_width);
  236. ut_asserteq(DMAR_INTR_REMAP, dmar[2].flags);
  237. ut_asserteq(32 - 1, dmar[2].host_address_width);
  238. /* Check that the pointers were added correctly */
  239. for (i = 0; i < 3; i++) {
  240. ut_asserteq(map_to_sysmem(dmar + i), ctx.rsdt->entry[i]);
  241. ut_asserteq(map_to_sysmem(dmar + i), ctx.xsdt->entry[i]);
  242. }
  243. ut_asserteq(0, ctx.rsdt->entry[3]);
  244. ut_asserteq(0, ctx.xsdt->entry[3]);
  245. return 0;
  246. }
  247. DM_TEST(dm_test_acpi_write_tables, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  248. /* Test basic ACPI functions */
  249. static int dm_test_acpi_basic(struct unit_test_state *uts)
  250. {
  251. struct acpi_ctx ctx;
  252. /* Check align works */
  253. ctx.current = (void *)5;
  254. acpi_align(&ctx);
  255. ut_asserteq_ptr((void *)16, ctx.current);
  256. /* Check that align does nothing if already aligned */
  257. acpi_align(&ctx);
  258. ut_asserteq_ptr((void *)16, ctx.current);
  259. acpi_align64(&ctx);
  260. ut_asserteq_ptr((void *)64, ctx.current);
  261. acpi_align64(&ctx);
  262. ut_asserteq_ptr((void *)64, ctx.current);
  263. /* Check incrementing */
  264. acpi_inc(&ctx, 3);
  265. ut_asserteq_ptr((void *)67, ctx.current);
  266. acpi_inc_align(&ctx, 3);
  267. ut_asserteq_ptr((void *)80, ctx.current);
  268. return 0;
  269. }
  270. DM_TEST(dm_test_acpi_basic, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  271. /* Test setup_ctx_and_base_tables */
  272. static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts)
  273. {
  274. struct acpi_rsdp *rsdp;
  275. struct acpi_rsdt *rsdt;
  276. struct acpi_xsdt *xsdt;
  277. struct acpi_ctx ctx;
  278. void *buf, *end;
  279. ulong addr;
  280. /*
  281. * Use an unaligned address deliberately, by allocating an aligned
  282. * address and then adding 4 to it
  283. */
  284. buf = memalign(64, BUF_SIZE);
  285. ut_assertnonnull(buf);
  286. addr = map_to_sysmem(buf);
  287. ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr + 4));
  288. ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd_acpi_start());
  289. rsdp = buf + 16;
  290. ut_asserteq_ptr(rsdp, ctx.rsdp);
  291. ut_asserteq_mem(RSDP_SIG, rsdp->signature, sizeof(rsdp->signature));
  292. ut_asserteq(sizeof(*rsdp), rsdp->length);
  293. ut_assertok(table_compute_checksum(rsdp, 20));
  294. ut_assertok(table_compute_checksum(rsdp, sizeof(*rsdp)));
  295. rsdt = PTR_ALIGN((void *)rsdp + sizeof(*rsdp), 16);
  296. ut_asserteq_ptr(rsdt, ctx.rsdt);
  297. ut_asserteq_mem("RSDT", rsdt->header.signature, ACPI_NAME_LEN);
  298. ut_asserteq(sizeof(*rsdt), rsdt->header.length);
  299. ut_assertok(table_compute_checksum(rsdt, sizeof(*rsdt)));
  300. xsdt = PTR_ALIGN((void *)rsdt + sizeof(*rsdt), 16);
  301. ut_asserteq_ptr(xsdt, ctx.xsdt);
  302. ut_asserteq_mem("XSDT", xsdt->header.signature, ACPI_NAME_LEN);
  303. ut_asserteq(sizeof(*xsdt), xsdt->header.length);
  304. ut_assertok(table_compute_checksum(xsdt, sizeof(*xsdt)));
  305. end = PTR_ALIGN((void *)xsdt + sizeof(*xsdt), 64);
  306. ut_asserteq_ptr(end, ctx.current);
  307. ut_asserteq(map_to_sysmem(rsdt), rsdp->rsdt_address);
  308. ut_asserteq(map_to_sysmem(xsdt), rsdp->xsdt_address);
  309. return 0;
  310. }
  311. DM_TEST(dm_test_setup_ctx_and_base_tables,
  312. UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  313. /* Test 'acpi list' command */
  314. static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
  315. {
  316. struct acpi_ctx ctx;
  317. ulong addr;
  318. void *buf;
  319. buf = memalign(16, BUF_SIZE);
  320. ut_assertnonnull(buf);
  321. addr = map_to_sysmem(buf);
  322. ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
  323. ut_assertok(acpi_write_dev_tables(&ctx));
  324. console_record_reset();
  325. run_command("acpi list", 0);
  326. ut_assert_nextline("Name Base Size Detail");
  327. ut_assert_nextline("---- -------- ----- ------");
  328. ut_assert_nextline("RSDP %08lx %5zx v02 U-BOOT", addr,
  329. sizeof(struct acpi_rsdp));
  330. addr = ALIGN(addr + sizeof(struct acpi_rsdp), 16);
  331. ut_assert_nextline("RSDT %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0",
  332. addr, sizeof(struct acpi_table_header) +
  333. 3 * sizeof(u32), OEM_REVISION);
  334. addr = ALIGN(addr + sizeof(struct acpi_rsdt), 16);
  335. ut_assert_nextline("XSDT %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0",
  336. addr, sizeof(struct acpi_table_header) +
  337. 3 * sizeof(u64), OEM_REVISION);
  338. addr = ALIGN(addr + sizeof(struct acpi_xsdt), 64);
  339. ut_assert_nextline("DMAR %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0",
  340. addr, sizeof(struct acpi_dmar), OEM_REVISION);
  341. addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
  342. ut_assert_nextline("DMAR %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0",
  343. addr, sizeof(struct acpi_dmar), OEM_REVISION);
  344. addr = ALIGN(addr + sizeof(struct acpi_dmar), 16);
  345. ut_assert_nextline("DMAR %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0",
  346. addr, sizeof(struct acpi_dmar), OEM_REVISION);
  347. ut_assert_console_end();
  348. return 0;
  349. }
  350. DM_TEST(dm_test_acpi_cmd_list, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  351. /* Test 'acpi dump' command */
  352. static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
  353. {
  354. struct acpi_ctx ctx;
  355. ulong addr;
  356. void *buf;
  357. buf = memalign(16, BUF_SIZE);
  358. ut_assertnonnull(buf);
  359. addr = map_to_sysmem(buf);
  360. ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
  361. ut_assertok(acpi_write_dev_tables(&ctx));
  362. /* First search for a non-existent table */
  363. console_record_reset();
  364. run_command("acpi dump rdst", 0);
  365. ut_assert_nextline("Table 'RDST' not found");
  366. ut_assert_console_end();
  367. /* Now a real table */
  368. console_record_reset();
  369. run_command("acpi dump dmar", 0);
  370. addr = ALIGN(map_to_sysmem(ctx.xsdt) + sizeof(struct acpi_xsdt), 64);
  371. ut_assert_nextline("DMAR @ %08lx", addr);
  372. ut_assert_nextlines_are_dump(0x30);
  373. ut_assert_console_end();
  374. return 0;
  375. }
  376. DM_TEST(dm_test_acpi_cmd_dump, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  377. /* Test acpi_device_path() */
  378. static int dm_test_acpi_device_path(struct unit_test_state *uts)
  379. {
  380. struct testacpi_plat *plat;
  381. char buf[ACPI_PATH_MAX];
  382. struct udevice *dev, *child;
  383. ut_assertok(uclass_first_device_err(UCLASS_TEST_ACPI, &dev));
  384. ut_assertok(acpi_device_path(dev, buf, sizeof(buf)));
  385. ut_asserteq_str("\\_SB." ACPI_TEST_DEV_NAME, buf);
  386. /* Test running out of space */
  387. buf[5] = '\0';
  388. ut_asserteq(-ENOSPC, acpi_device_path(dev, buf, 5));
  389. ut_asserteq('\0', buf[5]);
  390. /* Test a three-component name */
  391. ut_assertok(device_first_child_err(dev, &child));
  392. ut_assertok(acpi_device_path(child, buf, sizeof(buf)));
  393. ut_asserteq_str("\\_SB." ACPI_TEST_DEV_NAME "." ACPI_TEST_CHILD_NAME,
  394. buf);
  395. /* Test handling of a device which doesn't produce a name */
  396. plat = dev_get_plat(dev);
  397. plat->no_name = true;
  398. ut_assertok(acpi_device_path(child, buf, sizeof(buf)));
  399. ut_asserteq_str("\\_SB." ACPI_TEST_CHILD_NAME, buf);
  400. /* Test handling of a device which returns an error */
  401. plat = dev_get_plat(dev);
  402. plat->return_error = true;
  403. ut_asserteq(-EINVAL, acpi_device_path(child, buf, sizeof(buf)));
  404. return 0;
  405. }
  406. DM_TEST(dm_test_acpi_device_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  407. /* Test acpi_device_status() */
  408. static int dm_test_acpi_device_status(struct unit_test_state *uts)
  409. {
  410. struct udevice *dev;
  411. ut_assertok(uclass_first_device_err(UCLASS_TEST_ACPI, &dev));
  412. ut_asserteq(ACPI_DSTATUS_ALL_ON, acpi_device_status(dev));
  413. return 0;
  414. }
  415. DM_TEST(dm_test_acpi_device_status, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  416. /* Test acpi_fill_ssdt() */
  417. static int dm_test_acpi_fill_ssdt(struct unit_test_state *uts)
  418. {
  419. struct acpi_ctx ctx;
  420. u8 *buf;
  421. buf = malloc(BUF_SIZE);
  422. ut_assertnonnull(buf);
  423. acpi_reset_items();
  424. ctx.current = buf;
  425. buf[4] = 'z'; /* sentinel */
  426. ut_assertok(acpi_fill_ssdt(&ctx));
  427. /*
  428. * These values come from acpi-test2's acpi-ssdt-test-data property.
  429. * This device comes first because of u-boot,acpi-ssdt-order
  430. */
  431. ut_asserteq('c', buf[0]);
  432. ut_asserteq('d', buf[1]);
  433. /* These values come from acpi-test's acpi-ssdt-test-data property */
  434. ut_asserteq('a', buf[2]);
  435. ut_asserteq('b', buf[3]);
  436. ut_asserteq('z', buf[4]);
  437. return 0;
  438. }
  439. DM_TEST(dm_test_acpi_fill_ssdt, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  440. /* Test acpi_inject_dsdt() */
  441. static int dm_test_acpi_inject_dsdt(struct unit_test_state *uts)
  442. {
  443. struct acpi_ctx ctx;
  444. u8 *buf;
  445. buf = malloc(BUF_SIZE);
  446. ut_assertnonnull(buf);
  447. acpi_reset_items();
  448. ctx.current = buf;
  449. buf[4] = 'z'; /* sentinel */
  450. ut_assertok(acpi_inject_dsdt(&ctx));
  451. /*
  452. * These values come from acpi-test's acpi-dsdt-test-data property.
  453. * There is no u-boot,acpi-dsdt-order so device-tree order is used.
  454. */
  455. ut_asserteq('h', buf[0]);
  456. ut_asserteq('i', buf[1]);
  457. /* These values come from acpi-test's acpi-dsdt-test-data property */
  458. ut_asserteq('j', buf[2]);
  459. ut_asserteq('k', buf[3]);
  460. ut_asserteq('z', buf[4]);
  461. return 0;
  462. }
  463. DM_TEST(dm_test_acpi_inject_dsdt, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  464. /* Test 'acpi items' command */
  465. static int dm_test_acpi_cmd_items(struct unit_test_state *uts)
  466. {
  467. struct acpi_ctx ctx;
  468. ulong addr;
  469. void *buf;
  470. buf = malloc(BUF_SIZE);
  471. ut_assertnonnull(buf);
  472. addr = map_to_sysmem(buf);
  473. acpi_reset_items();
  474. ctx.current = buf;
  475. ut_assertok(acpi_fill_ssdt(&ctx));
  476. console_record_reset();
  477. run_command("acpi items", 0);
  478. ut_assert_nextline("Seq Type Base Size Device/Writer");
  479. ut_assert_nextline("--- ----- -------- ---- -------------");
  480. ut_assert_nextline(" 0 ssdt %8lx 2 acpi-test", addr);
  481. ut_assert_nextline(" 1 ssdt %8lx 2 acpi-test2", addr + 2);
  482. ut_assert_console_end();
  483. acpi_reset_items();
  484. ctx.current = buf;
  485. ut_assertok(acpi_inject_dsdt(&ctx));
  486. console_record_reset();
  487. run_command("acpi items", 0);
  488. ut_assert_nextlinen("Seq");
  489. ut_assert_nextlinen("---");
  490. ut_assert_nextline(" 0 dsdt %8lx 2 acpi-test", addr);
  491. ut_assert_nextline(" 1 dsdt %8lx 2 acpi-test2", addr + 2);
  492. ut_assert_console_end();
  493. console_record_reset();
  494. run_command("acpi items -d", 0);
  495. ut_assert_nextlinen("Seq");
  496. ut_assert_nextlinen("---");
  497. ut_assert_nextline(" 0 dsdt %8lx 2 acpi-test", addr);
  498. ut_assert_nextlines_are_dump(2);
  499. ut_assert_nextline("%s", "");
  500. ut_assert_nextline(" 1 dsdt %8lx 2 acpi-test2", addr + 2);
  501. ut_assert_nextlines_are_dump(2);
  502. ut_assert_nextline("%s", "");
  503. ut_assert_console_end();
  504. return 0;
  505. }
  506. DM_TEST(dm_test_acpi_cmd_items, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  507. /* Test 'acpi set' command */
  508. static int dm_test_acpi_cmd_set(struct unit_test_state *uts)
  509. {
  510. struct acpi_ctx ctx;
  511. ulong addr;
  512. void *buf;
  513. gd_set_acpi_start(0);
  514. console_record_reset();
  515. ut_asserteq(0, gd_acpi_start());
  516. ut_assertok(run_command("acpi set", 0));
  517. ut_assert_nextline("ACPI pointer: 0");
  518. buf = memalign(16, BUF_SIZE);
  519. ut_assertnonnull(buf);
  520. addr = map_to_sysmem(buf);
  521. ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
  522. ut_assertok(acpi_write_dev_tables(&ctx));
  523. ut_assertok(run_command("acpi set", 0));
  524. ut_assert_nextline("ACPI pointer: %lx", addr);
  525. ut_assertok(run_command("acpi set 0", 0));
  526. ut_assert_nextline("Setting ACPI pointer to 0");
  527. ut_asserteq(0, gd_acpi_start());
  528. ut_assertok(run_commandf("acpi set %lx", addr));
  529. ut_assert_nextline("Setting ACPI pointer to %lx", addr);
  530. ut_asserteq(addr, gd_acpi_start());
  531. ut_assert_console_end();
  532. return 0;
  533. }
  534. DM_TEST(dm_test_acpi_cmd_set, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);