blkmap.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2023 Addiva Elektronik
  4. * Author: Tobias Waldekranz <tobias@waldekranz.com>
  5. */
  6. #include <common.h>
  7. #include <blk.h>
  8. #include <blkmap.h>
  9. #include <dm.h>
  10. #include <asm/test.h>
  11. #include <dm/test.h>
  12. #include <test/test.h>
  13. #include <test/ut.h>
  14. #define BLKSZ 0x200
  15. struct mapping {
  16. int src;
  17. int cnt;
  18. int dst;
  19. };
  20. const struct mapping unordered_mapping[] = {
  21. { 0, 1, 3 },
  22. { 1, 3, 0 },
  23. { 4, 2, 6 },
  24. { 6, 2, 4 },
  25. { 0, 0, 0 }
  26. };
  27. const struct mapping identity_mapping[] = {
  28. { 0, 8, 0 },
  29. { 0, 0, 0 }
  30. };
  31. static char identity[8 * BLKSZ];
  32. static char unordered[8 * BLKSZ];
  33. static char buffer[8 * BLKSZ];
  34. static void mkblob(void *base, const struct mapping *m)
  35. {
  36. int nr;
  37. for (; m->cnt; m++) {
  38. for (nr = 0; nr < m->cnt; nr++) {
  39. memset(base + (m->dst + nr) * BLKSZ,
  40. m->src + nr, BLKSZ);
  41. }
  42. }
  43. }
  44. static int dm_test_blkmap_read(struct unit_test_state *uts)
  45. {
  46. struct udevice *dev, *blk;
  47. const struct mapping *m;
  48. ut_assertok(blkmap_create("rdtest", &dev));
  49. ut_assertok(blk_get_from_parent(dev, &blk));
  50. /* Generate an ordered and an unordered pattern in memory */
  51. mkblob(unordered, unordered_mapping);
  52. mkblob(identity, identity_mapping);
  53. /* Create a blkmap that cancels out the disorder */
  54. for (m = unordered_mapping; m->cnt; m++) {
  55. ut_assertok(blkmap_map_mem(dev, m->src, m->cnt,
  56. unordered + m->dst * BLKSZ));
  57. }
  58. /* Read out the data via the blkmap device to another area,
  59. * and verify that it matches the ordered pattern.
  60. */
  61. ut_asserteq(8, blk_read(blk, 0, 8, buffer));
  62. ut_assertok(memcmp(buffer, identity, sizeof(buffer)));
  63. ut_assertok(blkmap_destroy(dev));
  64. return 0;
  65. }
  66. DM_TEST(dm_test_blkmap_read, 0);
  67. static int dm_test_blkmap_write(struct unit_test_state *uts)
  68. {
  69. struct udevice *dev, *blk;
  70. const struct mapping *m;
  71. ut_assertok(blkmap_create("wrtest", &dev));
  72. ut_assertok(blk_get_from_parent(dev, &blk));
  73. /* Generate an ordered and an unordered pattern in memory */
  74. mkblob(unordered, unordered_mapping);
  75. mkblob(identity, identity_mapping);
  76. /* Create a blkmap that mimics the disorder */
  77. for (m = unordered_mapping; m->cnt; m++) {
  78. ut_assertok(blkmap_map_mem(dev, m->src, m->cnt,
  79. buffer + m->dst * BLKSZ));
  80. }
  81. /* Write the ordered data via the blkmap device to another
  82. * area, and verify that the result matches the unordered
  83. * pattern.
  84. */
  85. ut_asserteq(8, blk_write(blk, 0, 8, identity));
  86. ut_assertok(memcmp(buffer, unordered, sizeof(buffer)));
  87. ut_assertok(blkmap_destroy(dev));
  88. return 0;
  89. }
  90. DM_TEST(dm_test_blkmap_write, 0);
  91. static int dm_test_blkmap_slicing(struct unit_test_state *uts)
  92. {
  93. struct udevice *dev;
  94. ut_assertok(blkmap_create("slicetest", &dev));
  95. ut_assertok(blkmap_map_mem(dev, 8, 8, NULL));
  96. /* Can't overlap on the low end */
  97. ut_asserteq(-EBUSY, blkmap_map_mem(dev, 4, 5, NULL));
  98. /* Can't be inside */
  99. ut_asserteq(-EBUSY, blkmap_map_mem(dev, 10, 2, NULL));
  100. /* Can't overlap on the high end */
  101. ut_asserteq(-EBUSY, blkmap_map_mem(dev, 15, 4, NULL));
  102. /* But we should be able to add slices right before and
  103. * after
  104. */
  105. ut_assertok(blkmap_map_mem(dev, 4, 4, NULL));
  106. ut_assertok(blkmap_map_mem(dev, 16, 4, NULL));
  107. ut_assertok(blkmap_destroy(dev));
  108. return 0;
  109. }
  110. DM_TEST(dm_test_blkmap_slicing, 0);
  111. static int dm_test_blkmap_creation(struct unit_test_state *uts)
  112. {
  113. struct udevice *first, *second;
  114. ut_assertok(blkmap_create("first", &first));
  115. /* Can't have two "first"s */
  116. ut_asserteq(-EBUSY, blkmap_create("first", &second));
  117. /* But "second" should be fine */
  118. ut_assertok(blkmap_create("second", &second));
  119. /* Once "first" is destroyed, we should be able to create it
  120. * again
  121. */
  122. ut_assertok(blkmap_destroy(first));
  123. ut_assertok(blkmap_create("first", &first));
  124. ut_assertok(blkmap_destroy(first));
  125. ut_assertok(blkmap_destroy(second));
  126. return 0;
  127. }
  128. DM_TEST(dm_test_blkmap_creation, 0);
  129. static int dm_test_cmd_blkmap(struct unit_test_state *uts)
  130. {
  131. ulong loadaddr = env_get_hex("loadaddr", 0);
  132. struct udevice *dev;
  133. console_record_reset();
  134. ut_assertok(run_command("blkmap info", 0));
  135. ut_assert_console_end();
  136. ut_assertok(run_command("blkmap create ramdisk", 0));
  137. ut_assert_nextline("Created \"ramdisk\"");
  138. ut_assert_console_end();
  139. ut_assertnonnull((dev = blkmap_from_label("ramdisk")));
  140. ut_assertok(run_commandf("blkmap map ramdisk 0 800 mem 0x%lx", loadaddr));
  141. ut_assert_nextline("Block 0x0+0x800 mapped to 0x%lx", loadaddr);
  142. ut_assert_console_end();
  143. ut_assertok(run_command("blkmap info", 0));
  144. ut_assert_nextline("Device 0: Vendor: U-Boot Rev: 1.0 Prod: blkmap");
  145. ut_assert_nextline(" Type: Hard Disk");
  146. ut_assert_nextline(" Capacity: 1.0 MB = 0.0 GB (2048 x 512)");
  147. ut_assert_console_end();
  148. ut_assertok(run_command("blkmap get ramdisk dev devnum", 0));
  149. ut_asserteq(dev_seq(dev), env_get_hex("devnum", 0xdeadbeef));
  150. ut_assertok(run_command("blkmap destroy ramdisk", 0));
  151. ut_assert_nextline("Destroyed \"ramdisk\"");
  152. ut_assert_console_end();
  153. ut_assertok(run_command("blkmap info", 0));
  154. ut_assert_console_end();
  155. return 0;
  156. }
  157. DM_TEST(dm_test_cmd_blkmap, 0);