blob: 7581e62df3bb1b5d34cd5ad0073398b040a8983f [file] [log] [blame]
Tobias Waldekranz5a420052023-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
Tobias Waldekranz5a420052023-02-16 16:33:53 +01007#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);