aboutsummaryrefslogtreecommitdiff
path: root/test/dm/fwu_mdata.c
blob: 52018f610fe4764f2655f314069578ebd32489b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2022, Linaro Limited
 * Copyright (c) 2022, Heinrich Schuchardt <xypron.glpk@gmx.de>
 */

#include <blk.h>
#include <common.h>
#include <dm.h>
#include <fwu.h>
#include <fwu_mdata.h>
#include <log.h>
#include <malloc.h>
#include <memalign.h>
#include <part.h>

#include <dm/test.h>
#include <test/ut.h>

#include "fwu_mdata_disk_image.h"

/* Block size of compressed disk image */
#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8

static struct udevice *mmc_dev;
static struct blk_desc *dev_desc;

/* One 8 byte block of the compressed disk image */
struct line {
	size_t addr;
	char *line;
};

/* Compressed disk image */
struct compressed_disk_image {
	size_t length;
	struct line lines[];
};

static const struct compressed_disk_image img = FWU_MDATA_DISK_IMG;

/* Decompressed disk image */
static u8 *image;

static int setup_blk_device(struct unit_test_state *uts)
{
	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &mmc_dev));
	ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));

	return 0;
}

static int populate_mmc_disk_image(struct unit_test_state *uts)
{
	u8 *buf;
	size_t i;
	size_t addr;
	size_t len;

	buf = malloc(img.length);
	if (!buf)
		return -ENOMEM;

	memset(buf, 0, img.length);

	for (i = 0; ; i++) {
		if (!img.lines[i].line)
			break;
		addr = img.lines[i].addr;
		len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE;
		if (addr + len > img.length)
			len = img.length - addr;
		memcpy(buf + addr, img.lines[i].line, len);
	}
	image = buf;

	return 0;
}

static int write_mmc_blk_device(struct unit_test_state *uts)
{
	lbaint_t blkcnt;

	blkcnt = BLOCK_CNT(img.length, dev_desc);

	ut_asserteq(blkcnt, blk_dwrite(dev_desc, 0, blkcnt, image));

	return 0;
}

static int dm_test_fwu_mdata_read(struct unit_test_state *uts)
{
	struct udevice *dev;
	struct fwu_mdata mdata = { 0 };

	/*
	 * Trigger lib/fwu_updates/fwu.c fwu_boottime_checks()
	 * to populate g_dev global pointer in that library.
	 */
	event_notify_null(EVT_MAIN_LOOP);

	ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev));
	ut_assertok(setup_blk_device(uts));
	ut_assertok(populate_mmc_disk_image(uts));
	ut_assertok(write_mmc_blk_device(uts));

	ut_assertok(fwu_get_mdata(&mdata));

	ut_asserteq(mdata.version, 0x1);

	return 0;
}
DM_TEST(dm_test_fwu_mdata_read, UT_TESTF_SCAN_FDT);

static int dm_test_fwu_mdata_write(struct unit_test_state *uts)
{
	u32 active_idx;
	struct udevice *dev;
	struct fwu_mdata mdata = { 0 };

	/*
	 * Trigger lib/fwu_updates/fwu.c fwu_boottime_checks()
	 * to populate g_dev global pointer in that library.
	 */
	event_notify_null(EVT_MAIN_LOOP);

	ut_assertok(setup_blk_device(uts));
	ut_assertok(populate_mmc_disk_image(uts));
	ut_assertok(write_mmc_blk_device(uts));

	ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev));

	ut_assertok(fwu_get_mdata(&mdata));

	active_idx = (mdata.active_index + 1) % CONFIG_FWU_NUM_BANKS;
	ut_assertok(fwu_set_active_index(active_idx));

	ut_assertok(fwu_get_mdata(&mdata));
	ut_asserteq(mdata.active_index, active_idx);

	return 0;
}
DM_TEST(dm_test_fwu_mdata_write, UT_TESTF_SCAN_FDT);