cmd_ut_optee.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
  4. */
  5. #include <common.h>
  6. #include <command.h>
  7. #include <errno.h>
  8. #include <fdt_support.h>
  9. #include <log.h>
  10. #include <malloc.h>
  11. #include <tee/optee.h>
  12. #include <linux/sizes.h>
  13. #include <test/ut.h>
  14. #include <test/optee.h>
  15. #include <test/suites.h>
  16. /* 4k ought to be enough for anybody */
  17. #define FDT_COPY_SIZE (4 * SZ_1K)
  18. extern u32 __dtb_test_optee_base_begin;
  19. extern u32 __dtb_test_optee_optee_begin;
  20. extern u32 __dtb_test_optee_no_optee_begin;
  21. static void *fdt;
  22. static bool expect_success;
  23. static int optee_fdt_firmware(struct unit_test_state *uts)
  24. {
  25. const void *prop;
  26. int offs, len;
  27. offs = fdt_path_offset(fdt, "/firmware/optee");
  28. ut_assert(expect_success ? offs >= 0 : offs < 0);
  29. /* only continue if we have an optee node */
  30. if (offs < 0)
  31. return CMD_RET_SUCCESS;
  32. prop = fdt_getprop(fdt, offs, "compatible", &len);
  33. ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
  34. prop = fdt_getprop(fdt, offs, "method", &len);
  35. ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
  36. return CMD_RET_SUCCESS;
  37. }
  38. OPTEE_TEST(optee_fdt_firmware, 0);
  39. static int optee_fdt_protected_memory(struct unit_test_state *uts)
  40. {
  41. int offs, subnode;
  42. bool found;
  43. offs = fdt_path_offset(fdt, "/firmware/optee");
  44. ut_assert(expect_success ? offs >= 0 : offs < 0);
  45. /* only continue if we have an optee node */
  46. if (offs < 0)
  47. return CMD_RET_SUCCESS;
  48. /* optee inserts its memory regions as reserved-memory nodes */
  49. offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
  50. ut_assert(offs >= 0);
  51. subnode = fdt_first_subnode(fdt, offs);
  52. ut_assert(subnode);
  53. found = 0;
  54. while (subnode >= 0) {
  55. const char *name = fdt_get_name(fdt, subnode, NULL);
  56. struct fdt_resource res;
  57. ut_assert(name);
  58. /* only handle optee reservations */
  59. if (strncmp(name, "optee", 5))
  60. continue;
  61. found = true;
  62. /* check if this subnode has a reg property */
  63. ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
  64. subnode = fdt_next_subnode(fdt, subnode);
  65. }
  66. ut_assert(found);
  67. return CMD_RET_SUCCESS;
  68. }
  69. OPTEE_TEST(optee_fdt_protected_memory, 0);
  70. int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
  71. {
  72. struct unit_test *tests = ll_entry_start(struct unit_test,
  73. optee_test);
  74. const int n_ents = ll_entry_count(struct unit_test, optee_test);
  75. struct unit_test_state *uts;
  76. void *fdt_optee = &__dtb_test_optee_optee_begin;
  77. void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
  78. void *fdt_base = &__dtb_test_optee_base_begin;
  79. int ret = -ENOMEM;
  80. uts = calloc(1, sizeof(*uts));
  81. if (!uts)
  82. return -ENOMEM;
  83. ut_assertok(fdt_check_header(fdt_base));
  84. ut_assertok(fdt_check_header(fdt_optee));
  85. ut_assertok(fdt_check_header(fdt_no_optee));
  86. fdt = malloc(FDT_COPY_SIZE);
  87. if (!fdt)
  88. return ret;
  89. /*
  90. * Resize the FDT to 4k so that we have room to operate on
  91. *
  92. * (and relocate it since the memory might be mapped
  93. * read-only)
  94. */
  95. ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
  96. /*
  97. * (1) Try to copy optee nodes from empty dt.
  98. * This should still run successfully.
  99. */
  100. ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
  101. expect_success = false;
  102. ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
  103. /* (2) Try to copy optee nodes from prefilled dt */
  104. ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
  105. expect_success = true;
  106. ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
  107. /* (3) Try to copy OP-TEE nodes into a already filled DT */
  108. ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
  109. ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
  110. expect_success = true;
  111. ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
  112. free(fdt);
  113. return ret;
  114. }