blob: b14137e589a214cf95226f969babc2c95c8d2c4a [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>
Simon Glassa8c12522024-09-01 16:26:32 -060017#include <linux/sizes.h>
Alexander Gendin038cb022023-10-09 01:24:36 +000018#include <test/suites.h>
19#include <test/ut.h>
20
21DECLARE_GLOBAL_DATA_PTR;
Simon Glassa8c12522024-09-01 16:26:32 -060022
23#define BLKSZ SZ_512 /* block size */
24
Alexander Gendin038cb022023-10-09 01:24:36 +000025/*
26 * Requirements for running test manually:
27 * mmc6.img - File size needs to be at least 12 MiB
28 *
29 * Command to create mmc6.img:
30 * $ dd if=/dev/zero of=mmc6.img bs=12M count=1
31 *
32 * To run this test manually, place mmc6.img into the same directory as u-boot,
33 * then run:
34 * $ ./u-boot -Tc 'ut mbr'
35 *
36 * To run this test as part of U-Boot test:
37 * $ ./test/py/test.py --bd sandbox --build -k ut_dm -v
38 * Note: mmc6.img will be created by the test suit.
39 */
40
41static char * mbr_parts_header = "setenv mbr_parts '";
42static char * mbr_parts_p1 = "uuid_disk=0x12345678;name=p1,start=8M,bootable,size=1M,id=0x0e";
43static char * mbr_parts_p2 = ";name=p2,size=1M,id=0x0e";
44static char * mbr_parts_p3 = ";name=p3,size=1M,id=0x0e";
45static char * mbr_parts_p4 = ";name=p4,size=1M,id=0x0e";
46static char * mbr_parts_p5 = ";name=[ext],size=2M,id=0x05;name=p5,size=1M,id=0x0e";
47static char * mbr_parts_tail = "'";
48
49/*
50 * One MBR partition
51000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
52000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 00 |...%$..@........|
53000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
54000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
55000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
56*/
Simon Glass40d2a6e2024-09-01 16:26:21 -060057static unsigned int mbr_cmp_start = 0x1b8;
Alexander Gendin038cb022023-10-09 01:24:36 +000058static unsigned mbr_cmp_size = 0x48;
59static unsigned char mbr_parts_ref_p1[] = {
60 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
610x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
65};
66
67/*
68 * Two MBR partitions
69000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
70000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
71000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 00 |%..F...H........|
72000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
73000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
74*/
75static unsigned char mbr_parts_ref_p2[] = {
76 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
770x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
780x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
81};
82
83/*
84 * Three MBR partitions
85000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
86000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
87000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
88000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 00 |...f%..P........|
89000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
90*/
91static unsigned char mbr_parts_ref_p3[] = {
92 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
930x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
940x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46,
950x06, 0x01, 0x0e, 0x66, 0x25, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
97};
98
99/*
100 * Four MBR partitions
101000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
102000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
103000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
104000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
105000001f0 26 01 0e 87 06 01 00 58 00 00 00 08 00 00 55 aa |&......X......U.|
106*/
107static unsigned char mbr_parts_ref_p4[] = {
108 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
1090x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
1100x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46,
1110x06, 0x01, 0x0e, 0x66, 0x25, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66,
1120x26, 0x01, 0x0e, 0x87, 0x06, 0x01, 0x00, 0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x55, 0xaa
113};
114
115/*
116 * Five MBR partitions
117000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
118000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
119000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
120000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
121000001f0 26 01 05 a7 26 01 00 58 00 00 00 10 00 00 55 aa |&...&..X......U.|
122*/
123static unsigned char mbr_parts_ref_p5[] = {
124 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x80, 0x05,
1250x05, 0x01, 0x0e, 0x25, 0x24, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x25,
1260x25, 0x01, 0x0e, 0x46, 0x05, 0x01, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46,
1270x06, 0x01, 0x0e, 0x66, 0x25, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66,
1280x26, 0x01, 0x05, 0xa7, 0x26, 0x01, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x55, 0xaa
129};
130static unsigned ebr_cmp_start = 0x1B8;
131static unsigned ebr_cmp_size = 0x48;
132/*
133 * EBR
13400b001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 |................|
13500b001c0 07 01 0e a7 26 01 00 08 00 00 00 08 00 00 00 00 |....&...........|
13600b001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
13700b001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
13800b001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
139*/
140static unsigned char ebr_parts_ref_p5[] = {
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87,
1420x07, 0x01, 0x0e, 0xa7, 0x26, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
1430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
146};
147
148/* Fill write buffers with pseudo-random data */
149static void init_write_buffers(char *mbr_wb, size_t mbr_wb_size,
150 char *ebr_wb, size_t ebr_wb_size, unsigned seed)
151{
152 while (mbr_wb_size--) {
153 *mbr_wb++ = seed;
154 seed *= 43;
155 seed += 17 + mbr_wb_size/4;
156 }
157 while (ebr_wb_size--) {
158 *ebr_wb++ = seed;
159 seed *= 43;
160 seed += 17 + ebr_wb_size/4;
161 }
162}
163
164/* Build string with MBR partition(s) layout */
165static unsigned build_mbr_parts(char *buf, size_t buf_size, unsigned num_parts)
166{
167 size_t bytes_remaining, cur_str_size;
168 char * cur_buf;
169
170 if (!num_parts || num_parts > 5 || !buf)
171 return 1;
172
173 cur_buf = buf;
174 *cur_buf = '\0';
175 bytes_remaining = buf_size;
176
177 cur_str_size = sizeof(mbr_parts_header);
178 if (cur_str_size + 1 > bytes_remaining)
179 return 1;
180 strcat(cur_buf, mbr_parts_header);
181 bytes_remaining -= cur_str_size;
182
183 if (num_parts >= 1) {
184 cur_str_size = sizeof(mbr_parts_p1);
185 if (cur_str_size + 1 > bytes_remaining)
186 return 1;
187 strcat(cur_buf, mbr_parts_p1);
188 bytes_remaining -= cur_str_size;
189
190 if (num_parts >= 2) {
191 cur_str_size = sizeof(mbr_parts_p2);
192 if (cur_str_size + 1 > bytes_remaining)
193 return 1;
194 strcat(cur_buf, mbr_parts_p2);
195 bytes_remaining -= cur_str_size;
196
197 if (num_parts >= 3) {
198 cur_str_size = sizeof(mbr_parts_p3);
199 if (cur_str_size + 1 > bytes_remaining)
200 return 1;
201 strcat(cur_buf, mbr_parts_p3);
202 bytes_remaining -= cur_str_size;
203
204 if (num_parts == 4) {
205 cur_str_size = sizeof(mbr_parts_p4);
206 if (cur_str_size + 1 > bytes_remaining)
207 return 1;
208 strcat(cur_buf, mbr_parts_p4);
209 bytes_remaining -= cur_str_size;
210
211 }
Alexander Gendin207fc532023-11-08 03:05:19 +0000212 else if (num_parts == 5) {
213 cur_str_size = sizeof(mbr_parts_p5);
214 if (cur_str_size + 1 > bytes_remaining)
215 return 1;
216 strcat(cur_buf, mbr_parts_p5);
217 bytes_remaining -= cur_str_size;
Alexander Gendin038cb022023-10-09 01:24:36 +0000218
Alexander Gendin207fc532023-11-08 03:05:19 +0000219 }
Alexander Gendin038cb022023-10-09 01:24:36 +0000220 }
221 }
222 }
223
224 cur_str_size = sizeof(mbr_parts_tail);
225 if (cur_str_size + 1 > bytes_remaining)
226 return 1;
227 strcat(cur_buf, mbr_parts_tail);
228
229 return 0;
230}
231
232static int mbr_test_run(struct unit_test_state *uts)
233{
234 struct blk_desc *mmc_dev_desc;
Simon Glass2ca519b2024-09-01 16:26:33 -0600235 unsigned char *mbr_wbuf, *ebr_wbuf, *rbuf;
Alexander Gendin038cb022023-10-09 01:24:36 +0000236 char mbr_parts_buf[256];
Simon Glass2ca519b2024-09-01 16:26:33 -0600237 ulong addr = 0x1000; /* start address for buffers */
238 ulong mbr_wa = addr, ebr_wa = addr + BLKSZ, ra = addr + BLKSZ * 2;
239 ulong ebr_blk, mbr_parts_max;
Alexander Gendin038cb022023-10-09 01:24:36 +0000240 struct udevice *dev;
241 ofnode root, node;
242
243 /* Enable the mmc6 node for this test */
244 root = oftree_root(oftree_default());
245 node = ofnode_find_subnode(root, "mmc6");
246 ut_assert(ofnode_valid(node));
247 ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false));
248
Alexander Gendin2036ad12024-02-03 02:56:19 +0000249 /*
250 * 1 byte for null character
251 * 2 reserved bytes
252 */
253 mbr_parts_max = 1 + 2 +
Alexander Gendin038cb022023-10-09 01:24:36 +0000254 strlen(mbr_parts_header) +
255 strlen(mbr_parts_p1) +
256 strlen(mbr_parts_p2) +
257 strlen(mbr_parts_p3) +
258 max(strlen(mbr_parts_p4), strlen(mbr_parts_p5)) +
259 strlen(mbr_parts_tail);
260 ut_assertf(sizeof(mbr_parts_buf) >= mbr_parts_max, "Buffer avail: %ld; buffer req: %ld\n",
261 sizeof(mbr_parts_buf), mbr_parts_max);
262
Simon Glass2ca519b2024-09-01 16:26:33 -0600263 mbr_wbuf = map_sysmem(mbr_wa, BLKSZ);
264 ebr_wbuf = map_sysmem(ebr_wa, BLKSZ);
265 rbuf = map_sysmem(ra, BLKSZ);
Simon Glassa8c12522024-09-01 16:26:32 -0600266 ebr_blk = (ulong)0xb00000 / BLKSZ;
Alexander Gendin038cb022023-10-09 01:24:36 +0000267
268 /* Make sure mmc6 exists */
269 ut_asserteq(6, blk_get_device_by_str("mmc", "6", &mmc_dev_desc));
Alexander Gendin038cb022023-10-09 01:24:36 +0000270 ut_assertok(run_commandf("mmc dev 6"));
271 ut_assert_nextline("switch to partitions #0, OK");
272 ut_assert_nextline("mmc6 is current device");
Simon Glassc579bd42024-08-22 07:58:03 -0600273 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000274
275 /* Make sure mmc6 is 12+ MiB in size */
Simon Glass345567c2024-09-01 16:26:22 -0600276 ut_assertok(run_commandf("mmc read %lx %lx 1", ra,
Simon Glassa8c12522024-09-01 16:26:32 -0600277 (ulong)0xbffe00 / BLKSZ));
Alexander Gendin038cb022023-10-09 01:24:36 +0000278
279 /* Test one MBR partition */
280 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
281 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 1));
Simon Glass345567c2024-09-01 16:26:22 -0600282 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Simon Glass2ca519b2024-09-01 16:26:33 -0600283 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600284 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Simon Glassa8c12522024-09-01 16:26:32 -0600285 ut_assertok(memcmp(mbr_wbuf, rbuf, BLKSZ));
Simon Glass345567c2024-09-01 16:26:22 -0600286 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Simon Glass2ca519b2024-09-01 16:26:33 -0600287 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600288 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600289 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Alexander Gendin038cb022023-10-09 01:24:36 +0000290 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
291 ut_assertok(run_commandf("mbr write mmc 6"));
Simon Glass56228252024-08-22 07:57:58 -0600292 ut_assert_nextlinen("MMC read: dev # 6");
Alexander Gendin038cb022023-10-09 01:24:36 +0000293 ut_assert_nextline("MBR: write success!");
294 ut_assertok(run_commandf("mbr verify mmc 6"));
295 ut_assert_nextline("MBR: verify success!");
Simon Glass2ca519b2024-09-01 16:26:33 -0600296 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600297 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600298 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Simon Glassc579bd42024-08-22 07:58:03 -0600299 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000300 /*
301 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
302 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 00 |...%$..@........|
303 000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
304 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
305 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
306 */
Simon Glass2ca519b2024-09-01 16:26:33 -0600307 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600308 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000309 for (unsigned i = 0; i < mbr_cmp_size; i++) {
310 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p1[i],
Simon Glass345567c2024-09-01 16:26:22 -0600311 "1P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000312 mbr_cmp_start + i, mbr_parts_ref_p1[i], rbuf[mbr_cmp_start + i]);
313 }
314
315 /* Test two MBR partitions */
316 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
317 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 2));
Simon Glass345567c2024-09-01 16:26:22 -0600318 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Simon Glass2ca519b2024-09-01 16:26:33 -0600319 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600320 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Simon Glassa8c12522024-09-01 16:26:32 -0600321 ut_assertok(memcmp(mbr_wbuf, rbuf, BLKSZ));
Simon Glass345567c2024-09-01 16:26:22 -0600322 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Simon Glass2ca519b2024-09-01 16:26:33 -0600323 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600324 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600325 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Alexander Gendin038cb022023-10-09 01:24:36 +0000326 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
327 ut_assertok(run_commandf("mbr write mmc 6"));
328 ut_assert_nextline("MBR: write success!");
329 ut_assertok(run_commandf("mbr verify mmc 6"));
330 ut_assert_nextline("MBR: verify success!");
Simon Glass2ca519b2024-09-01 16:26:33 -0600331 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600332 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600333 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Simon Glassc579bd42024-08-22 07:58:03 -0600334 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000335 /*
336 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
337 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
338 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 00 |%..F...H........|
339 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
340 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
341 */
Simon Glass2ca519b2024-09-01 16:26:33 -0600342 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600343 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000344 for (unsigned i = 0; i < mbr_cmp_size; i++) {
345 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p2[i],
Simon Glass345567c2024-09-01 16:26:22 -0600346 "2P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000347 mbr_cmp_start + i, mbr_parts_ref_p2[i], rbuf[mbr_cmp_start + i]);
348 }
349
350 /* Test three MBR partitions */
351 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
352 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 3));
Simon Glass345567c2024-09-01 16:26:22 -0600353 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Simon Glass2ca519b2024-09-01 16:26:33 -0600354 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600355 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Simon Glassa8c12522024-09-01 16:26:32 -0600356 ut_assertok(memcmp(mbr_wbuf, rbuf, BLKSZ));
Simon Glass345567c2024-09-01 16:26:22 -0600357 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Simon Glass2ca519b2024-09-01 16:26:33 -0600358 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600359 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600360 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Alexander Gendin038cb022023-10-09 01:24:36 +0000361 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
362 ut_assertok(run_commandf("mbr write mmc 6"));
363 ut_assert_nextline("MBR: write success!");
364 ut_assertok(run_commandf("mbr verify mmc 6"));
365 ut_assert_nextline("MBR: verify success!");
Simon Glass2ca519b2024-09-01 16:26:33 -0600366 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600367 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600368 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Simon Glassc579bd42024-08-22 07:58:03 -0600369 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000370 /*
371 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
372 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
373 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
374 000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 00 |...f%..P........|
375 000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
376 */
Simon Glass2ca519b2024-09-01 16:26:33 -0600377 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600378 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000379 for (unsigned i = 0; i < mbr_cmp_size; i++) {
380 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p3[i],
Simon Glass345567c2024-09-01 16:26:22 -0600381 "3P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000382 mbr_cmp_start + i, mbr_parts_ref_p3[i], rbuf[mbr_cmp_start + i]);
383 }
384
385 /* Test four MBR partitions */
386 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
387 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 4));
Simon Glass345567c2024-09-01 16:26:22 -0600388 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Simon Glass2ca519b2024-09-01 16:26:33 -0600389 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600390 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Simon Glassa8c12522024-09-01 16:26:32 -0600391 ut_assertok(memcmp(mbr_wbuf, rbuf, BLKSZ));
Simon Glass345567c2024-09-01 16:26:22 -0600392 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Simon Glass2ca519b2024-09-01 16:26:33 -0600393 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600394 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600395 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Alexander Gendin038cb022023-10-09 01:24:36 +0000396 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
397 ut_assertok(run_commandf("mbr write mmc 6"));
398 ut_assert_nextline("MBR: write success!");
399 ut_assertok(run_commandf("mbr verify mmc 6"));
400 ut_assert_nextline("MBR: verify success!");
Simon Glass2ca519b2024-09-01 16:26:33 -0600401 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600402 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600403 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Simon Glassc579bd42024-08-22 07:58:03 -0600404 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000405 /*
406 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
407 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
408 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
409 000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
410 000001f0 26 01 0e 87 06 01 00 58 00 00 00 08 00 00 55 aa |&......X......U.|
411 */
Simon Glass2ca519b2024-09-01 16:26:33 -0600412 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600413 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000414 for (unsigned i = 0; i < mbr_cmp_size; i++) {
415 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p4[i],
Simon Glass345567c2024-09-01 16:26:22 -0600416 "4P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000417 mbr_cmp_start + i, mbr_parts_ref_p4[i], rbuf[mbr_cmp_start + i]);
418 }
419
420 /* Test five MBR partitions */
421 init_write_buffers(mbr_wbuf, sizeof(mbr_wbuf), ebr_wbuf, sizeof(ebr_wbuf), __LINE__);
422 ut_assertok(build_mbr_parts(mbr_parts_buf, sizeof(mbr_parts_buf), 5));
Simon Glass345567c2024-09-01 16:26:22 -0600423 ut_assertok(run_commandf("write mmc 6:0 %lx 0 1", mbr_wa));
Simon Glass2ca519b2024-09-01 16:26:33 -0600424 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600425 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Simon Glassa8c12522024-09-01 16:26:32 -0600426 ut_assertok(memcmp(mbr_wbuf, rbuf, BLKSZ));
Simon Glass345567c2024-09-01 16:26:22 -0600427 ut_assertok(run_commandf("write mmc 6:0 %lx %lx 1", ebr_wa, ebr_blk));
Simon Glass2ca519b2024-09-01 16:26:33 -0600428 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600429 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Simon Glassa8c12522024-09-01 16:26:32 -0600430 ut_assertok(memcmp(ebr_wbuf, rbuf, BLKSZ));
Alexander Gendin038cb022023-10-09 01:24:36 +0000431 ut_assertf(0 == run_commandf(mbr_parts_buf), "Invalid partitions string: %s\n", mbr_parts_buf);
432 ut_assertf(0 == run_commandf("mbr write mmc 6"), "Invalid partitions string: %s\n", mbr_parts_buf);
433 ut_assert_nextline("MBR: write success!");
434 ut_assertok(run_commandf("mbr verify mmc 6"));
435 ut_assert_nextline("MBR: verify success!");
Simon Glassc579bd42024-08-22 07:58:03 -0600436 ut_assert_console_end();
Alexander Gendin038cb022023-10-09 01:24:36 +0000437 /*
438 000001b0 00 00 00 00 00 00 00 00 78 56 34 12 00 00 80 05 |........xV4.....|
439 000001c0 05 01 0e 25 24 01 00 40 00 00 00 08 00 00 00 25 |...%$..@.......%|
440 000001d0 25 01 0e 46 05 01 00 48 00 00 00 08 00 00 00 46 |%..F...H.......F|
441 000001e0 06 01 0e 66 25 01 00 50 00 00 00 08 00 00 00 66 |...f%..P.......f|
442 000001f0 26 01 05 a7 26 01 00 58 00 00 00 10 00 00 55 aa |&...&..X......U.|
443 */
Simon Glass2ca519b2024-09-01 16:26:33 -0600444 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600445 ut_assertok(run_commandf("read mmc 6:0 %lx 0 1", ra));
Alexander Gendin038cb022023-10-09 01:24:36 +0000446 for (unsigned i = 0; i < mbr_cmp_size; i++) {
447 ut_assertf(rbuf[mbr_cmp_start + i] == mbr_parts_ref_p5[i],
Simon Glass345567c2024-09-01 16:26:22 -0600448 "5P MBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000449 mbr_cmp_start + i, mbr_parts_ref_p5[i], rbuf[mbr_cmp_start + i]);
450 }
451 /*
452 00b001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 |................|
453 00b001c0 07 01 0e a7 26 01 00 08 00 00 00 08 00 00 00 00 |....&...........|
454 00b001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
455 00b001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
456 00b001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
457 */
Simon Glass2ca519b2024-09-01 16:26:33 -0600458 memset(rbuf, '\0', BLKSZ);
Simon Glass345567c2024-09-01 16:26:22 -0600459 ut_assertok(run_commandf("read mmc 6:0 %lx %lx 1", ra, ebr_blk));
Alexander Gendin038cb022023-10-09 01:24:36 +0000460 for (unsigned i = 0; i < ebr_cmp_size; i++) {
461 ut_assertf(rbuf[ebr_cmp_start + i] == ebr_parts_ref_p5[i],
Simon Glass345567c2024-09-01 16:26:22 -0600462 "5P EBR+0x%04X: expected %#02X, actual: %#02X\n",
Alexander Gendin038cb022023-10-09 01:24:36 +0000463 ebr_cmp_start + i, ebr_parts_ref_p5[i], rbuf[ebr_cmp_start + i]);
464 }
Simon Glass2a1f1692024-09-01 16:26:31 -0600465 unmap_sysmem(mbr_wbuf);
466 unmap_sysmem(ebr_wbuf);
467 unmap_sysmem(rbuf);
Alexander Gendin038cb022023-10-09 01:24:36 +0000468
469 return 0;
470}
471
472/* Declare mbr test */
Simon Glass11fcfa32024-08-22 07:57:50 -0600473UNIT_TEST(mbr_test_run, UTF_CONSOLE, mbr_test);
Alexander Gendin038cb022023-10-09 01:24:36 +0000474
475int do_ut_mbr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
476{
477 struct unit_test *tests = UNIT_TEST_SUITE_START(mbr_test);
478 const int n_ents = UNIT_TEST_SUITE_COUNT(mbr_test);
479
480 return cmd_ut_category("mbr", "mbr_test_", tests, n_ents, argc, argv);
481}