blob: e750875ea43b00b3517b5222537acfa533c4e06e [file] [log] [blame]
Alexander Gendin038cb022023-10-09 01:24:36 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Tests for mbr command
4 *
5 * Copyright 2023 Matrox Video
6 * Written by Alex Gendin <agendin@matrox.com>
7 */
8
9#include <dm.h>
10#include <console.h>
11#include <dm/test.h>
12#include <mapmem.h>
13#include <part.h>
14#include <asm/global_data.h>
15#include <dm/device-internal.h>
16#include <dm/lists.h>
17#include <test/suites.h>
18#include <test/ut.h>
19
20DECLARE_GLOBAL_DATA_PTR;
21/*
22 * Requirements for running test manually:
23 * mmc6.img - File size needs to be at least 12 MiB
24 *
25 * Command to create mmc6.img:
26 * $ dd if=/dev/zero of=mmc6.img bs=12M count=1
27 *
28 * To run this test manually, place mmc6.img into the same directory as u-boot,
29 * then run:
30 * $ ./u-boot -Tc 'ut mbr'
31 *
32 * To run this test as part of U-Boot test:
33 * $ ./test/py/test.py --bd sandbox --build -k ut_dm -v
34 * Note: mmc6.img will be created by the test suit.
35 */
36
37static char * mbr_parts_header = "setenv mbr_parts '";
38static char * mbr_parts_p1 = "uuid_disk=0x12345678;name=p1,start=8M,bootable,size=1M,id=0x0e";
39static char * mbr_parts_p2 = ";name=p2,size=1M,id=0x0e";
40static char * mbr_parts_p3 = ";name=p3,size=1M,id=0x0e";
41static char * mbr_parts_p4 = ";name=p4,size=1M,id=0x0e";
42static char * mbr_parts_p5 = ";name=[ext],size=2M,id=0x05;name=p5,size=1M,id=0x0e";
43static char * mbr_parts_tail = "'";
44
45/*
46 * One MBR partition
47000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
48000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 00 |...%$..@........|
49000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
50000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
51000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
52*/
Simon Glass40d2a6e2024-09-01 16:26:21 -060053static unsigned int mbr_cmp_start = 0x1b8;
Alexander Gendin038cb022023-10-09 01:24:36 +000054static unsigned mbr_cmp_size = 0x48;
55static unsigned char mbr_parts_ref_p1[] = {
56 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
570x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
61};
62
63/*
64 * Two MBR partitions
65000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
66000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
67000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 00 |%..F...H........|
68000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
69000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
70*/
71static unsigned char mbr_parts_ref_p2[] = {
72 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
730x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
740x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
77};
78
79/*
80 * Three MBR partitions
81000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
82000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
83000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
84000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 00 |...f%..P........|
85000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
86*/
87static unsigned char mbr_parts_ref_p3[] = {
88 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
890x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
900x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46,
910x06, 0x01, 0x0e, 0x66, 0x25, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
93};
94
95/*
96 * Four MBR partitions
97000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
98000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
99000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
100000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
101000001f0 26 01 0e 87 06 01 00 58 00 00 00 08 00 00 55 aa |&......X......U.|
102*/
103static unsigned char mbr_parts_ref_p4[] = {
104 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
1050x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
1060x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46,
1070x06, 0x01, 0x0e, 0x66, 0x25, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66,
1080x26, 0x01, 0x0e, 0x87, 0x06, 0x01, 0x00, 0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x55, 0xaa
109};
110
111/*
112 * Five MBR partitions
113000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
114000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
115000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
116000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
117000001f0 26 01 05 a7 26 01 00 58 00 00 00 10 00 00 55 aa |&...&..X......U.|
118*/
119static unsigned char mbr_parts_ref_p5[] = {
120 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
1210x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
1220x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46,
1230x06, 0x01, 0x0e, 0x66, 0x25, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66,
1240x26, 0x01, 0x05, 0xa7, 0x26, 0x01, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x55, 0xaa
125};
126static unsigned ebr_cmp_start = 0x1B8;
127static unsigned ebr_cmp_size = 0x48;
128/*
129 * EBR
13000b001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 |................|
13100b001c0 07 01 0e a7 26 01 00 08 00 00 00 08 00 00 00 00 |....&...........|
13200b001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
13300b001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
13400b001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
135*/
136static unsigned char ebr_parts_ref_p5[] = {
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87,
1380x07, 0x01, 0x0e, 0xa7, 0x26, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
1390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
142};
143
144/* Fill write buffers with pseudo-random data */
145static void init_write_buffers(char *mbr_wb, size_t mbr_wb_size,
146 char *ebr_wb, size_t ebr_wb_size, unsigned seed)
147{
148 while (mbr_wb_size--) {
149 *mbr_wb++ = seed;
150 seed *= 43;
151 seed += 17 + mbr_wb_size/4;
152 }
153 while (ebr_wb_size--) {
154 *ebr_wb++ = seed;
155 seed *= 43;
156 seed += 17 + ebr_wb_size/4;
157 }
158}
159
160/* Build string with MBR partition(s) layout */
161static unsigned build_mbr_parts(char *buf, size_t buf_size, unsigned num_parts)
162{
163 size_t bytes_remaining, cur_str_size;
164 char * cur_buf;
165
166 if (!num_parts || num_parts > 5 || !buf)
167 return 1;
168
169 cur_buf = buf;
170 *cur_buf = '\0';
171 bytes_remaining = buf_size;
172
173 cur_str_size = sizeof(mbr_parts_header);
174 if (cur_str_size + 1 > bytes_remaining)
175 return 1;
176 strcat(cur_buf, mbr_parts_header);
177 bytes_remaining -= cur_str_size;
178
179 if (num_parts >= 1) {
180 cur_str_size = sizeof(mbr_parts_p1);
181 if (cur_str_size + 1 > bytes_remaining)
182 return 1;
183 strcat(cur_buf, mbr_parts_p1);
184 bytes_remaining -= cur_str_size;
185
186 if (num_parts >= 2) {
187 cur_str_size = sizeof(mbr_parts_p2);
188 if (cur_str_size + 1 > bytes_remaining)
189 return 1;
190 strcat(cur_buf, mbr_parts_p2);
191 bytes_remaining -= cur_str_size;
192
193 if (num_parts >= 3) {
194 cur_str_size = sizeof(mbr_parts_p3);
195 if (cur_str_size + 1 > bytes_remaining)
196 return 1;
197 strcat(cur_buf, mbr_parts_p3);
198 bytes_remaining -= cur_str_size;
199
200 if (num_parts == 4) {
201 cur_str_size = sizeof(mbr_parts_p4);
202 if (cur_str_size + 1 > bytes_remaining)
203 return 1;
204 strcat(cur_buf, mbr_parts_p4);
205 bytes_remaining -= cur_str_size;
206
207 }
Alexander Gendin207fc532023-11-08 03:05:19 +0000208 else if (num_parts == 5) {
209 cur_str_size = sizeof(mbr_parts_p5);
210 if (cur_str_size + 1 > bytes_remaining)
211 return 1;
212 strcat(cur_buf, mbr_parts_p5);
213 bytes_remaining -= cur_str_size;
Alexander Gendin038cb022023-10-09 01:24:36 +0000214
Alexander Gendin207fc532023-11-08 03:05:19 +0000215 }
Alexander Gendin038cb022023-10-09 01:24:36 +0000216 }
217 }
218 }
219
220 cur_str_size = sizeof(mbr_parts_tail);
221 if (cur_str_size + 1 > bytes_remaining)
222 return 1;
223 strcat(cur_buf, mbr_parts_tail);
224
225 return 0;
226}
227
228static int mbr_test_run(struct unit_test_state *uts)
229{
230 struct blk_desc *mmc_dev_desc;
231 unsigned char mbr_wbuf[512], ebr_wbuf[512], rbuf[512];
232 char mbr_parts_buf[256];
233 ulong mbr_wa, ebr_wa, ra, ebr_blk, mbr_parts_max;
234 struct udevice *dev;
235 ofnode root, node;
236
237 /* Enable the mmc6 node for this test */
238 root = oftree_root(oftree_default());
239 node = ofnode_find_subnode(root, "mmc6");
240 ut_assert(ofnode_valid(node));
241 ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false));
242
Alexander Gendin2036ad12024-02-03 02:56:19 +0000243 /*
244 * 1 byte for null character
245 * 2 reserved bytes
246 */
247 mbr_parts_max = 1 + 2 +
Alexander Gendin038cb022023-10-09 01:24:36 +0000248 strlen(mbr_parts_header) +
249 strlen(mbr_parts_p1) +
250 strlen(mbr_parts_p2) +
251 strlen(mbr_parts_p3) +
252 max(strlen(mbr_parts_p4), strlen(mbr_parts_p5)) +
253 strlen(mbr_parts_tail);
254 ut_assertf(sizeof(mbr_parts_buf) >= mbr_parts_max, "Buffer avail: %ld; buffer req: %ld\n",
255 sizeof(mbr_parts_buf), mbr_parts_max);
256
257 mbr_wa = map_to_sysmem(mbr_wbuf);
258 ebr_wa = map_to_sysmem(ebr_wbuf);
259 ra = map_to_sysmem(rbuf);
Simon Glass40d2a6e2024-09-01 16:26:21 -0600260 ebr_blk = (ulong)0xb00000 / 0x200;
Alexander Gendin038cb022023-10-09 01:24:36 +0000261
262 /* Make sure mmc6 exists */
263 ut_asserteq(6, blk_get_device_by_str("mmc", "6", &mmc_dev_desc));
Alexander Gendin038cb022023-10-09 01:24:36 +0000264 ut_assertok(run_commandf("mmc dev 6"));
265 ut_assert_nextline("switch to partitions #0, OK");
266 ut_assert_nextline("mmc6 is current device");
Simon Glassc579bd42024-08-22 07:58:03 -0600267 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000268
269 /* Make sure mmc6 is 12+ MiB in size */
Simon Glass345567c2024-09-01 16:26:22 -0600270 ut_assertok(run_commandf("mmc read %lx %lx 1", ra,
Simon Glass40d2a6e2024-09-01 16:26:21 -0600271 (ulong)0xbffe00 / 0x200));
Alexander Gendin038cb022023-10-09 01:24:36 +0000272
273 /* Test one MBR partition */
274 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
275 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 1));
Simon Glass345567c2024-09-01 16:26:22 -0600276 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Alexander Gendin038cb022023-10-09 01:24:36 +0000277 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600278 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000279 ut_assertok(memcmp(mbr_wbuf, rbuf, 512));
Simon Glass345567c2024-09-01 16:26:22 -0600280 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000281 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600282 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000283 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Alexander Gendin038cb022023-10-09 01:24:36 +0000284 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
285 ut_assertok(run_commandf("mbr write mmc 6"));
Simon Glass56228252024-08-22 07:57:58 -0600286 ut_assert_nextlinen("MMC read: dev # 6");
Alexander Gendin038cb022023-10-09 01:24:36 +0000287 ut_assert_nextline("MBR: write success!");
288 ut_assertok(run_commandf("mbr verify mmc 6"));
289 ut_assert_nextline("MBR: verify success!");
290 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600291 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000292 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Simon Glassc579bd42024-08-22 07:58:03 -0600293 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000294 /*
295 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
296 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 00 |...%$..@........|
297 000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
298 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
299 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
300 */
301 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600302 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000303 for (unsigned i = 0; i < mbr_cmp_size; i++) {
304 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p1[i],
Simon Glass345567c2024-09-01 16:26:22 -0600305 "1P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000306 mbr_cmp_start + i, mbr_parts_ref_p1[i], rbuf[mbr_cmp_start + i]);
307 }
308
309 /* Test two MBR partitions */
310 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
311 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 2));
Simon Glass345567c2024-09-01 16:26:22 -0600312 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Alexander Gendin038cb022023-10-09 01:24:36 +0000313 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600314 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000315 ut_assertok(memcmp(mbr_wbuf, rbuf, 512));
Simon Glass345567c2024-09-01 16:26:22 -0600316 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000317 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600318 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000319 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Alexander Gendin038cb022023-10-09 01:24:36 +0000320 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
321 ut_assertok(run_commandf("mbr write mmc 6"));
322 ut_assert_nextline("MBR: write success!");
323 ut_assertok(run_commandf("mbr verify mmc 6"));
324 ut_assert_nextline("MBR: verify success!");
325 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600326 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000327 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Simon Glassc579bd42024-08-22 07:58:03 -0600328 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000329 /*
330 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
331 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
332 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 00 |%..F...H........|
333 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
334 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
335 */
336 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600337 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000338 for (unsigned i = 0; i < mbr_cmp_size; i++) {
339 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p2[i],
Simon Glass345567c2024-09-01 16:26:22 -0600340 "2P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000341 mbr_cmp_start + i, mbr_parts_ref_p2[i], rbuf[mbr_cmp_start + i]);
342 }
343
344 /* Test three MBR partitions */
345 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
346 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 3));
Simon Glass345567c2024-09-01 16:26:22 -0600347 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Alexander Gendin038cb022023-10-09 01:24:36 +0000348 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600349 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000350 ut_assertok(memcmp(mbr_wbuf, rbuf, 512));
Simon Glass345567c2024-09-01 16:26:22 -0600351 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000352 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600353 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000354 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Alexander Gendin038cb022023-10-09 01:24:36 +0000355 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
356 ut_assertok(run_commandf("mbr write mmc 6"));
357 ut_assert_nextline("MBR: write success!");
358 ut_assertok(run_commandf("mbr verify mmc 6"));
359 ut_assert_nextline("MBR: verify success!");
360 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600361 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000362 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Simon Glassc579bd42024-08-22 07:58:03 -0600363 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000364 /*
365 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
366 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
367 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
368 000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 00 |...f%..P........|
369 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
370 */
371 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600372 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000373 for (unsigned i = 0; i < mbr_cmp_size; i++) {
374 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p3[i],
Simon Glass345567c2024-09-01 16:26:22 -0600375 "3P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000376 mbr_cmp_start + i, mbr_parts_ref_p3[i], rbuf[mbr_cmp_start + i]);
377 }
378
379 /* Test four MBR partitions */
380 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
381 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 4));
Simon Glass345567c2024-09-01 16:26:22 -0600382 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Alexander Gendin038cb022023-10-09 01:24:36 +0000383 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600384 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000385 ut_assertok(memcmp(mbr_wbuf, rbuf, 512));
Simon Glass345567c2024-09-01 16:26:22 -0600386 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000387 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600388 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000389 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Alexander Gendin038cb022023-10-09 01:24:36 +0000390 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
391 ut_assertok(run_commandf("mbr write mmc 6"));
392 ut_assert_nextline("MBR: write success!");
393 ut_assertok(run_commandf("mbr verify mmc 6"));
394 ut_assert_nextline("MBR: verify success!");
395 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600396 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000397 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Simon Glassc579bd42024-08-22 07:58:03 -0600398 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000399 /*
400 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
401 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
402 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
403 000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
404 000001f0 26 01 0e 87 06 01 00 58 00 00 00 08 00 00 55 aa |&......X......U.|
405 */
406 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600407 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000408 for (unsigned i = 0; i < mbr_cmp_size; i++) {
409 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p4[i],
Simon Glass345567c2024-09-01 16:26:22 -0600410 "4P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000411 mbr_cmp_start + i, mbr_parts_ref_p4[i], rbuf[mbr_cmp_start + i]);
412 }
413
414 /* Test five MBR partitions */
415 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
416 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 5));
Simon Glass345567c2024-09-01 16:26:22 -0600417 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Alexander Gendin038cb022023-10-09 01:24:36 +0000418 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600419 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000420 ut_assertok(memcmp(mbr_wbuf, rbuf, 512));
Simon Glass345567c2024-09-01 16:26:22 -0600421 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000422 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600423 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000424 ut_assertok(memcmp(ebr_wbuf, rbuf, 512));
Alexander Gendin038cb022023-10-09 01:24:36 +0000425 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
426 ut_assertf(0 == run_commandf("mbr write mmc 6"), "Invalid partitions string: %s\n", mbr_parts_buf);
427 ut_assert_nextline("MBR: write success!");
428 ut_assertok(run_commandf("mbr verify mmc 6"));
429 ut_assert_nextline("MBR: verify success!");
Simon Glassc579bd42024-08-22 07:58:03 -0600430 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000431 /*
432 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
433 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
434 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
435 000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
436 000001f0 26 01 05 a7 26 01 00 58 00 00 00 10 00 00 55 aa |&...&..X......U.|
437 */
438 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600439 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000440 for (unsigned i = 0; i < mbr_cmp_size; i++) {
441 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p5[i],
Simon Glass345567c2024-09-01 16:26:22 -0600442 "5P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000443 mbr_cmp_start + i, mbr_parts_ref_p5[i], rbuf[mbr_cmp_start + i]);
444 }
445 /*
446 00b001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 |................|
447 00b001c0 07 01 0e a7 26 01 00 08 00 00 00 08 00 00 00 00 |....&...........|
448 00b001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
449 00b001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
450 00b001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
451 */
452 memset(rbuf, 0, sizeof(rbuf));
Simon Glass345567c2024-09-01 16:26:22 -0600453 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000454 for (unsigned i = 0; i < ebr_cmp_size; i++) {
455 ut_assertf(rbuf[ebr_cmp_start + i] == ebr_parts_ref_p5[i],
Simon Glass345567c2024-09-01 16:26:22 -0600456 "5P EBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000457 ebr_cmp_start + i, ebr_parts_ref_p5[i], rbuf[ebr_cmp_start + i]);
458 }
Simon Glass2a1f1692024-09-01 16:26:31 -0600459 unmap_sysmem(mbr_wbuf);
460 unmap_sysmem(ebr_wbuf);
461 unmap_sysmem(rbuf);
Alexander Gendin038cb022023-10-09 01:24:36 +0000462
463 return 0;
464}
465
466/* Declare mbr test */
Simon Glass11fcfa32024-08-22 07:57:50 -0600467UNIT_TEST(mbr_test_run, UTF_CONSOLE, mbr_test);
Alexander Gendin038cb022023-10-09 01:24:36 +0000468
469int do_ut_mbr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
470{
471 struct unit_test *tests = UNIT_TEST_SUITE_START(mbr_test);
472 const int n_ents = UNIT_TEST_SUITE_COUNT(mbr_test);
473
474 return cmd_ut_category("mbr", "mbr_test_", tests, n_ents, argc, argv);
475}
476
477static int dm_test_cmd_mbr(struct unit_test_state *uts)
478{
479 return mbr_test_run(uts);
480}
Simon Glass11fcfa32024-08-22 07:57:50 -0600481DM_TEST(dm_test_cmd_mbr, UTF_SCAN_FDT | UTF_CONSOLE);