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