1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2022, Linaro Limited
4 * Copyright (c) 2022, Heinrich Schuchardt <xypron.glpk@gmx.de>
5 */
6
7 #include <blk.h>
8 #include <common.h>
9 #include <dm.h>
10 #include <fwu.h>
11 #include <fwu_mdata.h>
12 #include <log.h>
13 #include <malloc.h>
14 #include <memalign.h>
15 #include <part.h>
16
17 #include <dm/test.h>
18 #include <test/ut.h>
19
20 #include "fwu_mdata_disk_image.h"
21
22 /* Block size of compressed disk image */
23 #define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8
24
25 static struct udevice *mmc_dev;
26 static struct blk_desc *dev_desc;
27
28 /* One 8 byte block of the compressed disk image */
29 struct line {
30 size_t addr;
31 char *line;
32 };
33
34 /* Compressed disk image */
35 struct compressed_disk_image {
36 size_t length;
37 struct line lines[];
38 };
39
40 static const struct compressed_disk_image img = FWU_MDATA_DISK_IMG;
41
42 /* Decompressed disk image */
43 static u8 *image;
44
setup_blk_device(struct unit_test_state * uts)45 static int setup_blk_device(struct unit_test_state *uts)
46 {
47 ut_assertok(uclass_get_device(UCLASS_MMC, 0, &mmc_dev));
48 ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
49
50 return 0;
51 }
52
populate_mmc_disk_image(struct unit_test_state * uts)53 static int populate_mmc_disk_image(struct unit_test_state *uts)
54 {
55 u8 *buf;
56 size_t i;
57 size_t addr;
58 size_t len;
59
60 buf = malloc(img.length);
61 if (!buf)
62 return -ENOMEM;
63
64 memset(buf, 0, img.length);
65
66 for (i = 0; ; i++) {
67 if (!img.lines[i].line)
68 break;
69 addr = img.lines[i].addr;
70 len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
71 if (addr + len > img.length)
72 len = img.length - addr;
73 memcpy(buf + addr, img.lines[i].line, len);
74 }
75 image = buf;
76
77 return 0;
78 }
79
write_mmc_blk_device(struct unit_test_state * uts)80 static int write_mmc_blk_device(struct unit_test_state *uts)
81 {
82 lbaint_t blkcnt;
83
84 blkcnt = BLOCK_CNT(img.length, dev_desc);
85
86 ut_asserteq(blkcnt, blk_dwrite(dev_desc, 0, blkcnt, image));
87
88 return 0;
89 }
90
dm_test_fwu_mdata_read(struct unit_test_state * uts)91 static int dm_test_fwu_mdata_read(struct unit_test_state *uts)
92 {
93 struct udevice *dev;
94 struct fwu_mdata mdata = { 0 };
95
96 ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev));
97 ut_assertok(setup_blk_device(uts));
98 ut_assertok(populate_mmc_disk_image(uts));
99 ut_assertok(write_mmc_blk_device(uts));
100
101 ut_assertok(fwu_get_mdata(dev, &mdata));
102
103 ut_asserteq(mdata.version, 0x1);
104
105 return 0;
106 }
107 DM_TEST(dm_test_fwu_mdata_read, UT_TESTF_SCAN_FDT);
108
dm_test_fwu_mdata_write(struct unit_test_state * uts)109 static int dm_test_fwu_mdata_write(struct unit_test_state *uts)
110 {
111 u32 active_idx;
112 struct udevice *dev;
113 struct fwu_mdata mdata = { 0 };
114
115 ut_assertok(setup_blk_device(uts));
116 ut_assertok(populate_mmc_disk_image(uts));
117 ut_assertok(write_mmc_blk_device(uts));
118
119 ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev));
120
121 ut_assertok(fwu_get_mdata(dev, &mdata));
122
123 active_idx = (mdata.active_index + 1) % CONFIG_FWU_NUM_BANKS;
124 ut_assertok(fwu_set_active_index(active_idx));
125
126 ut_assertok(fwu_get_mdata(dev, &mdata));
127 ut_asserteq(mdata.active_index, active_idx);
128
129 return 0;
130 }
131 DM_TEST(dm_test_fwu_mdata_write, UT_TESTF_SCAN_FDT);
132
dm_test_fwu_mdata_check(struct unit_test_state * uts)133 static int dm_test_fwu_mdata_check(struct unit_test_state *uts)
134 {
135 struct udevice *dev;
136
137 ut_assertok(setup_blk_device(uts));
138 ut_assertok(populate_mmc_disk_image(uts));
139 ut_assertok(write_mmc_blk_device(uts));
140
141 ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev));
142
143 ut_assertok(fwu_check_mdata_validity());
144
145 return 0;
146 }
147 DM_TEST(dm_test_fwu_mdata_check, UT_TESTF_SCAN_FDT);
148