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