1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2023 Sean Anderson <seanga2@gmail.com>
4 */
5
6#include <common.h>
7#include <image.h>
8#include <imx_container.h>
9#include <mapmem.h>
10#include <memalign.h>
11#include <rand.h>
12#include <spi_flash.h>
13#include <spl.h>
14#include <test/spl.h>
15#include <test/ut.h>
16#include <u-boot/crc.h>
17
18int board_fit_config_name_match(const char *name)
19{
20	return 0;
21}
22
23struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size)
24{
25	return map_sysmem(0x100000, 0);
26}
27
28/* Try to reuse the load buffer to conserve memory */
29void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len)
30{
31	static void *buf;
32	static size_t size;
33
34	if (size < sectors * bl_len) {
35		free(buf);
36		size = sectors * bl_len;
37		buf = malloc_cache_aligned(size);
38	}
39	return buf;
40}
41
42/* Local flags for spl_image; start from the "top" to avoid conflicts */
43#define SPL_IMX_CONTAINER	0x80000000
44#define SPL_COMP_LZMA		0x40000000
45
46void generate_data(char *data, size_t size, const char *test_name)
47{
48	int i;
49	unsigned int seed = 1;
50
51	while (*test_name) {
52		seed += *test_name++;
53		rand_r(&seed);
54	}
55
56	for (i = 0; i < size; i++)
57		data[i] = (i & 0xf) << 4 | (rand_r(&seed) & 0xf);
58}
59
60static size_t create_legacy(void *dst, struct spl_image_info *spl_image,
61			    size_t *data_offset)
62{
63	struct legacy_img_hdr *hdr = dst;
64	void *data = dst + sizeof(*hdr);
65
66	if (data_offset)
67		*data_offset = data - dst;
68
69	if (!dst)
70		goto out;
71
72	image_set_magic(hdr, IH_MAGIC);
73	image_set_time(hdr, 0);
74	image_set_size(hdr, spl_image->size);
75	image_set_load(hdr, spl_image->load_addr);
76	image_set_ep(hdr, spl_image->entry_point);
77	image_set_dcrc(hdr, crc32(0, data, spl_image->size));
78	image_set_os(hdr, spl_image->os);
79	image_set_arch(hdr, IH_ARCH_DEFAULT);
80	image_set_type(hdr, IH_TYPE_FIRMWARE);
81	image_set_comp(hdr, spl_image->flags & SPL_COMP_LZMA ? IH_COMP_LZMA :
82							       IH_COMP_NONE);
83	image_set_name(hdr, spl_image->name);
84	image_set_hcrc(hdr, crc32(0, (void *)hdr, sizeof(*hdr)));
85
86out:
87	return sizeof(*hdr) + spl_image->size;
88}
89
90static size_t create_imx8(void *dst, struct spl_image_info *spl_image,
91			  size_t *data_offset)
92{
93	struct container_hdr *hdr = dst;
94	struct boot_img_t *img = dst + sizeof(*hdr);
95	size_t length = sizeof(*hdr) + sizeof(*img);
96	/* Align to MMC block size for now */
97	void *data = dst + 512;
98
99	if (data_offset)
100		*data_offset = data - dst;
101
102	if (!dst)
103		goto out;
104
105	hdr->version = CONTAINER_HDR_VERSION;
106	hdr->length_lsb = length & 0xff;
107	hdr->length_msb = length >> 8;
108	hdr->tag = CONTAINER_HDR_TAG;
109	hdr->num_images = 1;
110
111	/* spl_load_imx_container doesn't handle endianness; whoops! */
112	img->offset = data - dst;
113	img->size = spl_image->size;
114	img->dst = spl_image->load_addr;
115	img->entry = spl_image->entry_point;
116
117out:
118	return data - dst + spl_image->size;
119}
120
121#define ADDRESS_CELLS (sizeof(uintptr_t) / sizeof(u32))
122
123static inline int fdt_property_addr(void *fdt, const char *name, uintptr_t val)
124{
125	if (sizeof(uintptr_t) == sizeof(u32))
126		return fdt_property_u32(fdt, name, val);
127	return fdt_property_u64(fdt, name, val);
128}
129
130static size_t start_fit(void *dst, size_t fit_size, size_t data_size,
131			bool external)
132{
133	void *data;
134
135	if (fdt_create(dst, fit_size))
136		return 0;
137	if (fdt_finish_reservemap(dst))
138		return 0;
139	if (fdt_begin_node(dst, ""))
140		return 0;
141	if (fdt_property_u32(dst, FIT_TIMESTAMP_PROP, 0))
142		return 0;
143	if (fdt_property_u32(dst, "#address-cells", ADDRESS_CELLS))
144		return 0;
145	if (fdt_property_string(dst, FIT_DESC_PROP, ""))
146		return 0;
147
148	if (fdt_begin_node(dst, "images"))
149		return 0;
150	if (fdt_begin_node(dst, "u-boot"))
151		return 0;
152
153	if (external) {
154		if (fdt_property_u32(dst, FIT_DATA_OFFSET_PROP, 0))
155			return 0;
156		return fit_size;
157	}
158
159	if (fdt_property_placeholder(dst, FIT_DATA_PROP, data_size, &data))
160		return 0;
161	return data - dst;
162}
163
164static size_t create_fit(void *dst, struct spl_image_info *spl_image,
165			 size_t *data_offset, bool external)
166{
167	size_t prop_size = 596, total_size = prop_size + spl_image->size;
168	size_t off, size;
169
170	if (external) {
171		size = prop_size;
172		off = size;
173	} else {
174		char tmp[256];
175
176		size = total_size;
177		off = start_fit(tmp, sizeof(tmp), 0, false);
178		if (!off)
179			return 0;
180	}
181
182	if (data_offset)
183		*data_offset = off;
184
185	if (!dst)
186		goto out;
187
188	if (start_fit(dst, size, spl_image->size, external) != off)
189		return 0;
190
191	if (fdt_property_string(dst, FIT_DESC_PROP, spl_image->name))
192		return 0;
193	if (fdt_property_string(dst, FIT_TYPE_PROP, "firmware"))
194		return 0;
195	if (fdt_property_string(dst, FIT_COMP_PROP, "none"))
196		return 0;
197	if (fdt_property_u32(dst, FIT_DATA_SIZE_PROP, spl_image->size))
198		return 0;
199	if (fdt_property_string(dst, FIT_OS_PROP,
200				genimg_get_os_short_name(spl_image->os)))
201		return 0;
202	if (fdt_property_string(dst, FIT_ARCH_PROP,
203				genimg_get_arch_short_name(IH_ARCH_DEFAULT)))
204		return 0;
205	if (fdt_property_addr(dst, FIT_ENTRY_PROP, spl_image->entry_point))
206		return 0;
207	if (fdt_property_addr(dst, FIT_LOAD_PROP, spl_image->load_addr))
208		return 0;
209	if (fdt_end_node(dst)) /* u-boot */
210		return 0;
211	if (fdt_end_node(dst)) /* images */
212		return 0;
213
214	if (fdt_begin_node(dst, "configurations"))
215		return 0;
216	if (fdt_property_string(dst, FIT_DEFAULT_PROP, "config-1"))
217		return 0;
218	if (fdt_begin_node(dst, "config-1"))
219		return 0;
220	if (fdt_property_string(dst, FIT_DESC_PROP, spl_image->name))
221		return 0;
222	if (fdt_property_string(dst, FIT_FIRMWARE_PROP, "u-boot"))
223		return 0;
224	if (fdt_end_node(dst)) /* configurations */
225		return 0;
226	if (fdt_end_node(dst)) /* config-1 */
227		return 0;
228
229	if (fdt_end_node(dst)) /* root */
230		return 0;
231	if (fdt_finish(dst))
232		return 0;
233
234	if (external) {
235		if (fdt_totalsize(dst) > size)
236			return 0;
237		fdt_set_totalsize(dst, size);
238	}
239
240out:
241	return total_size;
242}
243
244size_t create_image(void *dst, enum spl_test_image type,
245		    struct spl_image_info *info, size_t *data_offset)
246{
247	bool external = false;
248
249	info->os = IH_OS_U_BOOT;
250	info->load_addr = CONFIG_TEXT_BASE;
251	info->entry_point = CONFIG_TEXT_BASE + 0x100;
252	info->flags = 0;
253
254	switch (type) {
255	case LEGACY_LZMA:
256		info->flags = SPL_COMP_LZMA;
257	case LEGACY:
258		return create_legacy(dst, info, data_offset);
259	case IMX8:
260		info->flags = SPL_IMX_CONTAINER;
261		return create_imx8(dst, info, data_offset);
262	case FIT_EXTERNAL:
263		/*
264		 * spl_fit_append_fdt will clobber external images with U-Boot's
265		 * FDT if the image doesn't have one. Just set the OS to
266		 * something which doesn't take a devicetree.
267		 */
268		if (!IS_ENABLED(CONFIG_LOAD_FIT_FULL))
269			info->os = IH_OS_TEE;
270		external = true;
271	case FIT_INTERNAL:
272		info->flags = SPL_FIT_FOUND;
273		return create_fit(dst, info, data_offset, external);
274	}
275
276	return 0;
277}
278
279int check_image_info(struct unit_test_state *uts, struct spl_image_info *info1,
280		     struct spl_image_info *info2)
281{
282	if (info2->name) {
283		if (info1->flags & SPL_FIT_FOUND)
284			ut_asserteq_str(genimg_get_os_name(info1->os),
285					info2->name);
286		else
287			ut_asserteq_str(info1->name, info2->name);
288	}
289
290	if (info1->flags & SPL_IMX_CONTAINER)
291		ut_asserteq(IH_OS_INVALID, info2->os);
292	else
293		ut_asserteq(info1->os, info2->os);
294
295	ut_asserteq(info1->entry_point, info2->entry_point);
296	if (info1->flags & (SPL_FIT_FOUND | SPL_IMX_CONTAINER) ||
297	    info2->flags & SPL_COPY_PAYLOAD_ONLY) {
298		ut_asserteq(info1->load_addr, info2->load_addr);
299		if (info1->flags & SPL_IMX_CONTAINER)
300			ut_asserteq(0, info2->size);
301		else if (!(info1->flags & SPL_COMP_LZMA))
302			ut_asserteq(info1->size, info2->size);
303	} else {
304		ut_asserteq(info1->load_addr - sizeof(struct legacy_img_hdr),
305			    info2->load_addr);
306		ut_asserteq(info1->size + sizeof(struct legacy_img_hdr),
307			    info2->size);
308	}
309
310	return 0;
311}
312
313static ulong spl_test_read(struct spl_load_info *load, ulong sector,
314			   ulong count, void *buf)
315{
316	memcpy(buf, load->priv + sector, count);
317	return count;
318}
319
320static int spl_test_image(struct unit_test_state *uts, const char *test_name,
321			  enum spl_test_image type)
322{
323	size_t img_size, img_data, data_size = SPL_TEST_DATA_SIZE;
324	struct spl_image_info info_write = {
325		.name = test_name,
326		.size = data_size,
327	}, info_read = { };
328	char *data;
329	void *img;
330
331	img_size = create_image(NULL, type, &info_write, &img_data);
332	ut_assert(img_size);
333	img = calloc(img_size, 1);
334	ut_assertnonnull(img);
335
336	data = img + img_data;
337	generate_data(data, data_size, test_name);
338	ut_asserteq(img_size, create_image(img, type, &info_write, NULL));
339
340	if (type == LEGACY) {
341		ut_assertok(spl_parse_image_header(&info_read, NULL, img));
342		if (check_image_info(uts, &info_write, &info_read))
343			return CMD_RET_FAILURE;
344	} else {
345		struct spl_load_info load;
346
347		spl_set_bl_len(&load, 1);
348		load.priv = img;
349		load.read = spl_test_read;
350		if (type == IMX8)
351			ut_assertok(spl_load_imx_container(&info_read, &load,
352							   0));
353		else if (IS_ENABLED(CONFIG_SPL_FIT_FULL))
354			ut_assertok(spl_parse_image_header(&info_read, NULL,
355							   img));
356		else
357			ut_assertok(spl_load_simple_fit(&info_read, &load, 0,
358							img));
359		if (check_image_info(uts, &info_write, &info_read))
360			return CMD_RET_FAILURE;
361		ut_asserteq_mem(data, phys_to_virt(info_write.load_addr),
362				data_size);
363	}
364
365	free(img);
366	return 0;
367}
368SPL_IMG_TEST(spl_test_image, LEGACY, 0);
369SPL_IMG_TEST(spl_test_image, IMX8, 0);
370SPL_IMG_TEST(spl_test_image, FIT_INTERNAL, 0);
371SPL_IMG_TEST(spl_test_image, FIT_EXTERNAL, 0);
372
373/*
374 * LZMA is too complex to generate on the fly, so let's use some data I put in
375 * the oven^H^H^H^H compressed earlier
376 */
377const char lzma_compressed[] = {
378	0x5d, 0x00, 0x00, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
379	0xff, 0x00, 0x02, 0x05, 0x55, 0x4e, 0x82, 0xbc, 0xc2, 0x42, 0xf6, 0x88,
380	0x6c, 0x99, 0xd6, 0x82, 0x48, 0xa6, 0x06, 0x67, 0xf8, 0x46, 0x7c, 0xe9,
381	0x41, 0x79, 0xfe, 0x90, 0x0b, 0x31, 0x7b, 0x79, 0x91, 0xb8, 0x5f, 0x33,
382	0x11, 0x04, 0xc3, 0x4f, 0xf5, 0x71, 0xd1, 0xfb, 0x94, 0x6b, 0x5f, 0x78,
383	0xe2, 0xfa, 0x6a, 0x21, 0xb6, 0x1d, 0x11, 0x0e, 0x5b, 0x56, 0x6a, 0x5b,
384	0xe9, 0x56, 0x5f, 0x8b, 0x87, 0x61, 0x96, 0x6d, 0xce, 0x66, 0xbb, 0xb6,
385	0xe7, 0x13, 0x5a, 0xd8, 0x84, 0x29, 0x60, 0xa0, 0x80, 0x43, 0xdd, 0x0f,
386	0x4b, 0x85, 0xb0, 0x04, 0x9d, 0x9f, 0x28, 0x97, 0x0a, 0x1e, 0x16, 0xb0,
387	0x45, 0x33, 0x5e, 0x79, 0x4f, 0xaa, 0xee, 0x79, 0x6e, 0xc3, 0x4e, 0x3d,
388	0xe8, 0x67, 0x7c, 0xe0, 0xd0, 0xcc, 0x05, 0x40, 0xae, 0x6b, 0x97, 0x82,
389	0x97, 0x02, 0x01, 0xe2, 0xe3, 0xbc, 0xe4, 0x9b, 0xb3, 0x28, 0xed, 0x5e,
390	0x0d, 0x68, 0x6e, 0xe5, 0x17, 0x0a, 0x86, 0x5a, 0xcd, 0x8d, 0x46, 0x2d,
391	0x06, 0x10, 0xa6, 0x90, 0x44, 0xa1, 0xfc, 0x66, 0x6d, 0x7c, 0x57, 0x57,
392	0x07, 0xbc, 0x95, 0xb2, 0x8d, 0xf0, 0x9f, 0x4d, 0x90, 0x04, 0xaf, 0x0c,
393	0x23, 0x51, 0x1b, 0x34, 0xd5, 0x5c, 0x5d, 0x87, 0x5e, 0x10, 0x2b, 0x71,
394	0xc2, 0xcf, 0xc5, 0x9d, 0x4b, 0x89, 0x01, 0xc4, 0x97, 0xf2, 0xea, 0x83,
395	0x97, 0xfa, 0xe0, 0x51, 0x96, 0x78, 0x4f, 0x44, 0xb8, 0xa8, 0x9d, 0x03,
396	0x1c, 0x6e, 0xb7, 0xc6, 0xd7, 0xc5, 0x3e, 0x32, 0x65, 0xa7, 0x06, 0xab,
397	0x86, 0xfb, 0xd2, 0x9b, 0xd7, 0x86, 0xa8, 0xfe, 0x46, 0x41, 0x2e, 0xc2,
398	0x4e, 0xed, 0xa2, 0x9b, 0x79, 0x36, 0x37, 0x49, 0x90, 0xfc, 0xa6, 0x14,
399	0x93, 0x17, 0x82, 0x62, 0x3f, 0x79, 0x6b, 0x86, 0xc2, 0xeb, 0x82, 0xfe,
400	0x87, 0x49, 0xa5, 0x7e, 0x41, 0xe3, 0x59, 0x60, 0x15, 0x61, 0x4e, 0x3b,
401	0x16, 0xcf, 0xdb, 0x49, 0x2c, 0x84, 0x92, 0x26, 0x40, 0x04, 0x78, 0xd3,
402	0xd6, 0xa6, 0xed, 0x6e, 0x63, 0x49, 0xcb, 0xea, 0xfe, 0x43, 0x85, 0x21,
403	0x1a, 0x28, 0x36, 0x0a, 0x3e, 0x2a, 0xad, 0xba, 0xfc, 0x8a, 0x37, 0x18,
404	0xb4, 0x80, 0xbe, 0x6a, 0x36, 0x14, 0x03, 0xdd, 0xa3, 0x37, 0xbd, 0xc1,
405	0x8a, 0xbb, 0x2d, 0xd4, 0x08, 0xd7, 0x4b, 0xc4, 0xe9, 0xb8, 0xb4, 0x65,
406	0xdd, 0xf6, 0xe8, 0x17, 0x2c, 0x2c, 0x9b, 0x1e, 0x92, 0x0b, 0xcb, 0x22,
407	0x7c, 0x1b, 0x74, 0x8d, 0x65, 0x11, 0x5f, 0xfe, 0xf5, 0x2a, 0xc2, 0xbe,
408	0xea, 0xa2, 0xf1, 0x7b, 0xe8, 0xaf, 0x32, 0x5a, 0x0a, 0x5b, 0xd2, 0x5a,
409	0x11, 0x22, 0x79, 0xfa, 0xae, 0x2d, 0xe8, 0xc6, 0x17, 0xba, 0x17, 0x81,
410	0x6a, 0x63, 0xb5, 0x26, 0xd7, 0x8d, 0xd0, 0x66, 0x0c, 0x4a, 0x0c, 0x22,
411	0x1b, 0x20, 0x9f, 0x3d, 0x0b, 0x1b, 0x59, 0x53, 0x89, 0x9b, 0x5e, 0xbd,
412	0x3d, 0xd1, 0xdd, 0xff, 0xca, 0xb2, 0xb7, 0x12, 0x8d, 0x03, 0xaa, 0xc3,
413	0x1d, 0x56, 0x76, 0x14, 0xf8, 0xee, 0xb3, 0xeb, 0x80, 0x38, 0xc1, 0xc1,
414	0x1a, 0xef, 0x4a, 0xd5, 0x16, 0x1f, 0x5e, 0x21, 0x5d, 0x46, 0x01, 0xb3,
415	0xa4, 0xf7, 0x99, 0x94, 0x05, 0xc6, 0xc8, 0x06, 0xd8, 0x1c, 0xac, 0x47,
416	0x13, 0x54, 0x13, 0x1b, 0x1f, 0xb6, 0x23, 0x9c, 0x73, 0x2b, 0x57, 0x32,
417	0x94, 0x92, 0xf1, 0x71, 0x44, 0x40, 0x02, 0xc3, 0x21, 0x4a, 0x2f, 0x36,
418	0x5e, 0x8a, 0xd0, 0x4b, 0x02, 0xc7, 0x6e, 0xcf, 0xed, 0xa2, 0xdb, 0xce,
419	0x0a, 0x0f, 0x66, 0x4f, 0xb2, 0x3d, 0xb6, 0xcc, 0x75, 0x45, 0x80, 0x0a,
420	0x49, 0x4a, 0xe7, 0xe7, 0x24, 0x62, 0x65, 0xc7, 0x02, 0x22, 0x13, 0xbe,
421	0x6c, 0xa9, 0x9a, 0x8b, 0xa9, 0x1b, 0x2b, 0x3a, 0xde, 0x5e, 0x37, 0xbd,
422	0x7f, 0x85, 0xd1, 0x32, 0x1d, 0xbf, 0x03, 0x8a, 0x3b, 0xe5, 0xb3, 0xfd,
423	0x01, 0xca, 0xde, 0x0d, 0x7a, 0x5b, 0x01, 0x05, 0x1d, 0x3c, 0x23, 0x00,
424	0x60, 0xb7, 0x50, 0xfd, 0x0d, 0xd7, 0x63, 0x92, 0xd6, 0xb0, 0x48, 0x3a,
425	0x2d, 0xa3, 0xf8, 0xf6, 0x44, 0xe1, 0xda, 0x3b, 0xf4, 0x39, 0x47, 0xc4,
426	0x4d, 0x8f, 0x54, 0x78, 0xec, 0x27, 0x7b, 0xc6, 0xe4, 0x81, 0x3a, 0x3f,
427	0xa5, 0x61, 0x9d, 0xcb, 0x71, 0x0b, 0x0d, 0x55, 0xea, 0x5b, 0xeb, 0x58,
428	0xa5, 0x49, 0xb5, 0x44, 0x1b, 0xb0, 0x0d, 0x1f, 0x58, 0xfb, 0x7a, 0xd4,
429	0x09, 0x1e, 0x9a, 0x7e, 0x21, 0xba, 0xb3, 0x36, 0xa6, 0x04, 0x74, 0xe1,
430	0xd0, 0xca, 0x02, 0x11, 0x84, 0x93, 0x8f, 0x86, 0x3d, 0x79, 0xbf, 0xa8,
431	0xec, 0x0a, 0x23, 0x5e, 0xde, 0xc4, 0xc6, 0xda, 0x45, 0xbd, 0x95, 0x74,
432	0x7b, 0xbf, 0xc1, 0x80, 0x48, 0x3f, 0x10, 0xb6, 0xb9, 0x5c, 0x31, 0x52,
433	0x06, 0x5a, 0xac, 0xec, 0x94, 0x21, 0x80, 0x51, 0xba, 0x64, 0xed, 0x9d,
434	0x27, 0x72, 0x8d, 0x17, 0x43, 0x5f, 0xf1, 0x60, 0xfa, 0xb5, 0x65, 0xd4,
435	0xb9, 0xf8, 0xfc, 0x48, 0x7b, 0xe3, 0xfe, 0xae, 0xe4, 0x71, 0x4a, 0x3d,
436	0x8c, 0xf5, 0x72, 0x8b, 0xbf, 0x60, 0xd8, 0x6a, 0x8f, 0x51, 0x82, 0xae,
437	0x98, 0xd0, 0x56, 0xf9, 0xa8, 0x3a, 0xad, 0x86, 0x26, 0xa8, 0x5a, 0xf8,
438	0x63, 0x87, 0x2c, 0x74, 0xbf, 0xf9, 0x7d, 0x00, 0xa0, 0x2f, 0x17, 0x23,
439	0xb7, 0x62, 0x94, 0x19, 0x47, 0x57, 0xf9, 0xa8, 0xe7, 0x4b, 0xe9, 0x2b,
440	0xe8, 0xb4, 0x03, 0xbf, 0x23, 0x75, 0xfe, 0xc3, 0x94, 0xc0, 0xa9, 0x5b,
441	0x07, 0xb5, 0x75, 0x87, 0xcc, 0xa5, 0xb5, 0x9b, 0x35, 0x29, 0xe4, 0xb1,
442	0xaa, 0x04, 0x57, 0xe9, 0xa3, 0xd0, 0xa3, 0xe4, 0x11, 0xe1, 0xaa, 0x3b,
443	0x67, 0x09, 0x60, 0x83, 0x23, 0x72, 0xa6, 0x7b, 0x73, 0x22, 0x5b, 0x4a,
444	0xe0, 0xf0, 0xa3, 0xeb, 0x9c, 0x91, 0xda, 0xba, 0x8b, 0xc1, 0x32, 0xa9,
445	0x24, 0x13, 0x51, 0xe4, 0x67, 0x49, 0x4a, 0xd9, 0x3d, 0xae, 0x80, 0xfd,
446	0x0a, 0x0d, 0x56, 0x98, 0x66, 0xa2, 0x6d, 0x92, 0x54, 0x7f, 0x82, 0xe5,
447	0x17, 0x39, 0xd3, 0xaa, 0xc4, 0x4e, 0x6f, 0xe1, 0x2e, 0xfe, 0x03, 0x44,
448	0x8a, 0xdd, 0xeb, 0xc0, 0x74, 0x79, 0x63, 0x33, 0x2b, 0x4b, 0xb5, 0x62,
449	0xdd, 0x47, 0xba, 0x6e, 0xfc, 0x91, 0x08, 0xa9, 0x17, 0x8c, 0x47, 0x61,
450	0xd9, 0x32, 0xe9, 0xa0, 0xb3, 0xa2, 0x82, 0xc9, 0xa6, 0x32, 0xa1, 0xca,
451	0x7c, 0x41, 0xa6, 0x5a, 0xe2, 0x46, 0xb6, 0x45, 0x53, 0x72, 0x55, 0x9e,
452	0xdf, 0xac, 0x96, 0x68, 0xe5, 0xdc, 0x4e, 0x2d, 0xa8, 0x1e, 0x7a, 0x8e,
453	0xff, 0x54, 0xe4, 0x0a, 0x33, 0x5d, 0x97, 0xdf, 0x4e, 0x36, 0x96, 0xba,
454	0x52, 0xd9, 0xa9, 0xec, 0x52, 0xe5, 0x1d, 0x94, 0xfe, 0x1c, 0x46, 0x54,
455	0xa6, 0x8e, 0x85, 0x47, 0xba, 0xeb, 0x4b, 0x8d, 0x57, 0xe4, 0x34, 0x24,
456	0x9e, 0x80, 0xb5, 0xc9, 0xa9, 0x94, 0x1d, 0xe4, 0x18, 0xb6, 0x07, 0x1e,
457	0xfa, 0xe0, 0x1c, 0x88, 0x06, 0x84, 0xaa, 0xcb, 0x5e, 0xfa, 0x15, 0x5a,
458	0xdd, 0x10, 0x43, 0x81, 0xf2, 0x50, 0x3e, 0x93, 0x26, 0x77, 0x1c, 0x77,
459	0xe9, 0x0c, 0xfc, 0x5f, 0xdd, 0x67, 0x31, 0x02, 0xc6, 0xdd, 0xf4, 0x30,
460	0x76, 0x51, 0xce, 0x56, 0xba, 0x7f, 0x44, 0xbd, 0x42, 0x9f, 0x10, 0x8c,
461	0x56, 0x49, 0x48, 0xa2, 0xcb, 0xc4, 0xdd, 0x29, 0xae, 0xf0, 0x33, 0x35,
462	0x46, 0x69, 0x1d, 0xae, 0xde, 0xde, 0x98, 0x82, 0x79, 0xa6, 0x50, 0x28,
463	0xb3, 0x5f, 0x10, 0x24, 0x63, 0xee, 0x9a, 0x22, 0xbe, 0xf8, 0x3a, 0xf4,
464	0xab, 0x98, 0xfe, 0xdf, 0x30, 0x03, 0xe8, 0x45, 0x8c, 0xf4, 0x85, 0xc6,
465	0x98, 0x7b, 0x35, 0xb8, 0x30, 0x9c, 0x15, 0xa6, 0x45, 0xbd, 0x39, 0x84,
466	0xe7, 0x43, 0x4b, 0x05, 0xa4, 0x8f, 0x52, 0x8e, 0x4a, 0xe4, 0x87, 0xc1,
467	0xdc, 0xdf, 0x25, 0x9c, 0x5c, 0x37, 0xd0, 0x66, 0x12, 0x41, 0x66, 0x8c,
468	0x28, 0xd0, 0x3f, 0x5c, 0x7f, 0x15, 0x9b, 0xcf, 0xa0, 0xae, 0x29, 0x33,
469	0xb0, 0xe4, 0xb7, 0x36, 0x2a, 0x45, 0x83, 0xff, 0x86, 0x75, 0xcf, 0xa7,
470	0x4d, 0x5c, 0xa8, 0xcf, 0x3f, 0xf2, 0xc8, 0xde, 0xdd, 0xad, 0x42, 0x8f,
471	0x0e, 0xd0, 0x11, 0x24, 0x42, 0x86, 0x51, 0x52, 0x76, 0x21, 0x68, 0xf1,
472	0xa7, 0x8f, 0xdb, 0x5b, 0x78, 0xfa, 0x44, 0x5f, 0xee, 0x31, 0xda, 0x62,
473	0x5f, 0xfe, 0x69, 0xae, 0x97, 0xc9, 0xb5, 0x04, 0x76, 0x79, 0x2e, 0xb9,
474	0xd9, 0x1b, 0xdd, 0xb7, 0xc4, 0x12, 0x78, 0xb2, 0x4d, 0xab, 0xd2, 0x29,
475	0x25, 0x8c, 0xd5, 0x52, 0x4a, 0xd7, 0x2e, 0x18, 0x9d, 0xa2, 0xee, 0x7b,
476	0xa5, 0xe5, 0x35, 0x3c, 0xb5, 0x54, 0x1c, 0x7f, 0x87, 0x4b, 0xc0, 0xbb,
477	0x1a, 0x85, 0x19, 0xc0, 0xa9, 0x2b, 0x4d, 0xed, 0x71, 0xc0, 0x15, 0xb3,
478	0x49, 0x2c, 0x46, 0xfc, 0x37, 0x40, 0xc0, 0x60, 0xd0, 0x00, 0x96, 0xfa,
479	0x7f, 0xbb, 0x30, 0x94, 0x6b, 0x81, 0x61, 0xc5, 0x13, 0x93, 0x95, 0xaa,
480	0xf3, 0x8d, 0x1d, 0xac, 0xdb, 0xbd, 0xc3, 0x90, 0xf3, 0xd2, 0x5f, 0x3a,
481	0x08, 0xb1, 0xc9, 0x3a, 0xe8, 0x25, 0x4d, 0x20, 0x2a, 0xe9, 0x4c, 0xaf,
482	0x9b, 0x54, 0x7b, 0xaf, 0x89, 0x44, 0x3a, 0x60, 0x23, 0xd3, 0x02, 0xb1,
483	0xb3, 0x9a, 0x3a, 0xb0, 0xa0, 0xdb, 0x61, 0x0b, 0xac, 0x55, 0xa1, 0x36,
484	0x55, 0x5b, 0xc4, 0xc5, 0xbd, 0x2a, 0x16, 0xe9, 0xe7, 0x86, 0x7f, 0xdb,
485	0xee, 0x90, 0xfa, 0xfd, 0x08, 0x7f, 0x1a, 0x43, 0xe0, 0xb8, 0x21, 0xb3,
486	0xe3, 0xdf, 0x27, 0x56, 0x61, 0xc4, 0xe8, 0xd5, 0x60, 0xe9, 0x6d, 0x49,
487	0xd9, 0xa8, 0xf5, 0xd9, 0xfc, 0x66, 0x82, 0xe9, 0x80, 0x5b, 0x85, 0x16,
488	0x55, 0x2b, 0xef, 0x50, 0x90, 0x6c, 0x5d, 0x81, 0x00, 0x00, 0x88, 0x9b,
489	0xb4, 0x62, 0x49, 0x46, 0x2e, 0x5d, 0x71, 0x95, 0xff, 0x63, 0xfb, 0x93,
490	0x23, 0xf8, 0x9f, 0xa2, 0x55, 0x56, 0xd4, 0xd5, 0xf7, 0xae, 0xaf, 0xd3,
491	0xf6, 0x82, 0xc8, 0xdd, 0x89, 0x0f, 0x7e, 0x89, 0x0d, 0x0d, 0x7f, 0x4f,
492	0x84, 0xa7, 0x16, 0xe8, 0xaf, 0xf2, 0x95, 0xd7, 0xc3, 0x66, 0xd6, 0x85,
493	0x5b, 0xa1, 0xbb, 0xea, 0x31, 0x02, 0xac, 0xa2, 0x7b, 0x50, 0xf4, 0x78,
494	0x29, 0x49, 0x59, 0xf6, 0x41, 0x42, 0x52, 0xa8, 0x19, 0xfb, 0x3d, 0xda,
495	0xa9, 0x8d, 0xac, 0xe1, 0x25, 0xd4, 0x12, 0x1e, 0x2b, 0x48, 0x44, 0xb0,
496	0xf6, 0x29, 0xd0, 0x55, 0x22, 0xb4, 0xe7, 0xbc, 0x22, 0x97, 0x1f, 0xe2,
497	0xe1, 0x73, 0x16, 0x13, 0x7a, 0x00, 0x62, 0x14, 0xcb, 0x25, 0x9b, 0x21,
498	0x98, 0x9d, 0xb8, 0xd8, 0xf4, 0x65, 0xf6, 0x8f, 0x39, 0xe4, 0x76, 0xf7,
499	0x30, 0xaf, 0xbc, 0x3a, 0xfe, 0x0e, 0xf1, 0x81, 0xa7, 0xff, 0x4d, 0xa7,
500	0xff, 0xbf, 0x15, 0x60, 0x0b, 0xcd, 0x69, 0xd5, 0x77, 0xba, 0xcb, 0x7b,
501	0x5a, 0xfb, 0x34, 0xc7, 0x5d, 0x13, 0x33, 0xd7, 0x86, 0x02, 0x43, 0x57,
502	0x52, 0x2c, 0x74, 0x61, 0x21, 0xa3, 0x34, 0xf5, 0x89, 0x51, 0x44, 0x89,
503	0xfc, 0xbb, 0x57, 0x5c, 0x6d, 0xb0, 0x2e, 0x8c, 0xff, 0x73, 0xe5, 0x09,
504	0x13, 0x3b, 0x45, 0x5b, 0x27, 0x88, 0xee, 0x9b, 0xab, 0x57, 0x7c, 0x9b,
505	0xb9, 0x78, 0x73, 0xd2, 0x2d, 0x98, 0x6f, 0xd2, 0x78, 0xb3, 0xeb, 0xaa,
506	0x18, 0x44, 0x87, 0x6d, 0x51, 0x1e, 0x9b, 0x73, 0xaa, 0x91, 0x1a, 0x4f,
507	0x69, 0x78, 0xef, 0x3f, 0xb1, 0x2d, 0x39, 0x3e, 0xda, 0x31, 0xfc, 0x99,
508	0xf6, 0xa2, 0x8c, 0xe5, 0xfd, 0x97, 0x95, 0x77, 0x37, 0xef, 0xf5, 0xd1,
509	0xc8, 0x74, 0x2c, 0x9a, 0x1f, 0x23, 0x8f, 0x72, 0x96, 0x3d, 0xb5, 0xad,
510	0x28, 0xa0, 0x6c, 0x66, 0xe8, 0xee, 0xaa, 0x9d, 0xc2, 0x8a, 0x56, 0x54,
511	0x89, 0x74, 0x56, 0xdc, 0x57, 0x49, 0xc3, 0x8e, 0xb9, 0x3a, 0x91, 0x34,
512	0xc4, 0x5e, 0x0b, 0x13, 0x63, 0x5e, 0xeb, 0xc5, 0xef, 0xc7, 0xe9, 0x7f,
513	0x27, 0xe8, 0xe7, 0xe5, 0x0d, 0x83, 0x95, 0x5f, 0x8a, 0xf2, 0xb2, 0x22,
514	0x03, 0x8d, 0x71, 0x4f, 0x62, 0xb7, 0xf1, 0x87, 0xf5, 0x3f, 0xc4, 0x23,
515	0x21, 0x40, 0x35, 0xcf, 0x79, 0x7a, 0x5b, 0x9d, 0x76, 0xb2, 0xdc, 0x6a,
516	0xb5, 0x1d, 0x8b, 0xb6, 0x9a, 0x19, 0xe4, 0x87, 0xf5, 0xce, 0x38, 0xf3,
517	0x70, 0xbf, 0x9e, 0x86, 0xa6, 0x07, 0x53, 0xdd, 0x5d, 0xc7, 0x72, 0x84,
518	0x47, 0x38, 0xd0, 0xe2, 0xeb, 0x64, 0x4c, 0x3a, 0x1e, 0xf6, 0x56, 0x79,
519	0x75, 0x75, 0x14, 0x5d, 0xe4, 0x1d, 0x9d, 0xbb, 0xe1, 0x35, 0x03, 0x5e,
520	0x4f, 0x8f, 0xea, 0x95, 0xde, 0x19, 0x57, 0x98, 0xe9, 0x2c, 0x42, 0x22,
521	0xcb, 0x0f, 0x15, 0x7a, 0x6b, 0x53, 0xc3, 0xec, 0xdc, 0xa0, 0x66, 0x26,
522	0x91, 0x04, 0x83, 0x75, 0x09, 0x0c, 0x22, 0x05, 0xec, 0x3a, 0x2d, 0x39,
523	0xea, 0x19, 0xf2, 0x1d, 0xdb, 0xba, 0x5c, 0x46, 0x47, 0xd4, 0x94, 0x6d,
524	0x51, 0xdb, 0x68, 0xde, 0x0c, 0xa0, 0x36, 0x8f, 0xbc, 0xfd, 0x9b, 0x8f,
525	0xfe, 0x04, 0x1f, 0xde, 0x1e, 0x77, 0xb5, 0x80, 0xb9, 0x9c, 0x1b, 0x24,
526	0x61, 0xfc, 0x2b, 0xc0, 0x42, 0x2b, 0xc5, 0x90, 0x58, 0xa2, 0xb1, 0x38,
527	0x58, 0xf2, 0x8b, 0x65, 0xbf, 0xe8, 0xe6, 0x79, 0xcf, 0x65, 0x35, 0xa5,
528	0xe1, 0xb7, 0x8b, 0x95, 0x54, 0xd7, 0x1d, 0xf0, 0x91, 0x18, 0xc0, 0x5d,
529	0x2c, 0xb5, 0xca, 0x1a, 0x7f, 0x8d, 0xfb, 0x9e, 0x57, 0x1c, 0x5c, 0xf0,
530	0x94, 0x36, 0x51, 0x95, 0x27, 0x62, 0xca, 0x92, 0x96, 0xe5, 0x00, 0x2e,
531	0xa4, 0x41, 0x97, 0xbf, 0x28, 0x3c, 0x6d, 0xc1, 0xb7, 0xe9, 0x1c, 0x2e,
532	0x3e, 0xe0, 0x5e, 0x89, 0x0c, 0x78, 0x88, 0x80, 0xb8, 0x30, 0xd2, 0x22,
533	0xf9, 0x71, 0xb4, 0xc8, 0xee, 0xe6, 0x80, 0x04, 0x04, 0x9a, 0xfb, 0x0c,
534	0x36, 0xcb, 0xea, 0x66, 0xf9, 0x52, 0x8c, 0x66, 0xbf, 0x4c, 0x0f, 0xf4,
535	0xf8, 0x1e, 0x7e, 0x39, 0x80, 0xe8, 0x82, 0x4b, 0x0e, 0x66, 0x1d, 0x51,
536	0x16, 0xa9, 0x8d, 0xd6, 0xea, 0x33, 0xb0, 0x2c, 0x36, 0x25, 0xf5, 0x01,
537	0x30, 0x7e, 0x03, 0x7f, 0xae, 0x8e, 0xd6, 0x25, 0x62, 0x6d, 0x99, 0x8c,
538	0x1f, 0xc1, 0x22, 0xf0, 0x94, 0x80, 0xbf, 0x82, 0x51, 0xea, 0xc2, 0x5a,
539	0x3c, 0x85, 0x2a, 0x5d, 0xbe, 0xae, 0xe1, 0xe3, 0x07, 0x92, 0xd2, 0x40,
540	0x47, 0xe8, 0x0f, 0x1a, 0xa5, 0x73, 0x64, 0x26, 0xc4, 0xac, 0xca, 0xc2,
541	0x83, 0x5a, 0x56, 0xbc, 0x81, 0x21, 0xcb, 0x72, 0xf3, 0xe7, 0x82, 0x1e,
542	0xc8, 0x54, 0x18, 0x42, 0xfe, 0xd6, 0xfc, 0x96, 0x0e, 0x03, 0x29, 0x98,
543	0x4f, 0xd1, 0xd2, 0x98, 0x7c, 0x9e, 0x4e, 0x1a, 0x0f, 0xd6, 0x4e, 0xa4,
544	0x52, 0x1b, 0xd1, 0xd8, 0x36, 0xf7, 0x47, 0x5f, 0xce, 0xcb, 0x87, 0x36,
545	0xc8, 0x9b, 0x44, 0xc6, 0x7a, 0xf3, 0x45, 0x28, 0xae, 0x96, 0x5a, 0x85,
546	0x62, 0x8b, 0x10, 0xc2, 0x7b, 0x39, 0x51, 0xdf, 0xf4, 0x21, 0xc2, 0x6b,
547	0x6f, 0x93, 0x27, 0xed, 0xf6, 0xea, 0xff, 0x2a, 0x21, 0x70, 0x84, 0x4e,
548	0x21, 0xac, 0xbc, 0x06, 0x41, 0xd3, 0x59, 0xa0, 0xa1, 0x50, 0xa6, 0x87,
549	0xa2, 0x48, 0xad, 0x94, 0x44, 0x8d, 0x2f, 0xa8, 0xc6, 0x10, 0xb5, 0xeb,
550	0x66, 0x82, 0x94, 0x5f, 0xae, 0x6a, 0x56, 0xb4, 0x8d, 0xf4, 0x62, 0x80,
551	0xe4, 0x42, 0xc4, 0xbc, 0xe7, 0xee, 0xa6, 0x96, 0x3b, 0xfd, 0xc0, 0x92,
552	0x7d, 0xcd, 0xe7, 0x0c, 0x99, 0x9a, 0xb6, 0x83, 0xcf, 0x45, 0xe5, 0x74,
553	0xb3, 0xbc, 0xc0, 0x40, 0xad, 0x4d, 0xfc, 0xa7, 0x92, 0x35, 0x13, 0x81,
554	0x5c, 0x9c, 0x21, 0x00, 0xa4, 0x37, 0x07, 0x1d, 0x19, 0xfc, 0x88, 0x4d,
555	0x71, 0x43, 0x7d, 0x94, 0xf7, 0x32, 0xb8, 0x4b, 0x8a, 0x54, 0xd6, 0xe4,
556	0x37, 0x4f, 0x27, 0x1f, 0xfd, 0x45, 0x83, 0xb9, 0x14, 0x5a, 0xf7, 0x36,
557	0xdc, 0x98, 0xad, 0x99, 0xb9, 0x38, 0x69, 0xac, 0x18, 0x7e, 0x47, 0xd0,
558	0x63, 0x27, 0xba, 0xe7, 0xd5, 0x1d, 0x7b, 0x6e, 0xde, 0x28, 0x7b, 0xf1,
559	0x84, 0x4d, 0x2d, 0x7c, 0x16, 0x38, 0x4b, 0x16, 0xa9, 0x10, 0x83, 0xfb,
560	0xe0, 0xe0, 0x6f, 0xdd, 0x03, 0x0a, 0xb8, 0x81, 0xf5, 0x8c, 0x98, 0xc3,
561	0xf4, 0xc8, 0x31, 0x3a, 0xed, 0x14, 0x83, 0x89, 0xc3, 0x0e, 0xf7, 0xba,
562	0x84, 0xb0, 0x49, 0xdf, 0xc6, 0x6b, 0xed, 0xbe, 0xd4, 0xa3, 0x83, 0x3a,
563	0xe6, 0x6d, 0xa3, 0x83, 0x17, 0x43, 0x5e, 0x3a, 0x83, 0xda, 0x81, 0xe3,
564	0x26, 0x95, 0x6b, 0xe5, 0x30, 0x28, 0x6d, 0xec, 0xd7, 0xd7, 0x35, 0xfa,
565	0x1a, 0xad, 0x86, 0x04, 0x05, 0x2c, 0x76, 0x3f, 0xb2, 0x83, 0x92, 0x4e,
566	0xef, 0x05, 0xde, 0x13, 0x26, 0x68, 0x80, 0x57, 0xee, 0x92, 0x80, 0xa3,
567	0x99, 0xb4, 0xac, 0x98, 0x31, 0xd4, 0xf3, 0xe2, 0x60, 0xd9, 0xb9, 0x8d,
568	0x20, 0xf7, 0x97, 0x70, 0x10, 0xd6, 0xba, 0x86, 0xb8, 0x9c, 0xb8, 0xf8,
569	0x49, 0x71, 0x28, 0x9d, 0x05, 0x38, 0x1f, 0x63, 0xba, 0xf7, 0x15, 0x60,
570	0x96, 0x61, 0x84, 0x68, 0xeb, 0x5d, 0x28, 0x51, 0xe3, 0x51, 0xdd, 0x69,
571	0x8a, 0xdd, 0xba, 0xec, 0xbd, 0xd3, 0xa1, 0x42, 0x83, 0x59, 0x77, 0x11,
572	0x12, 0x86, 0x5b, 0x8d, 0x30, 0xcf, 0xdf, 0x6f, 0xea, 0x9d, 0x31, 0xa2,
573	0x65, 0xa5, 0x61, 0xc0, 0xde, 0x52, 0x6c, 0x72, 0x71, 0x0b, 0x4c, 0x7a,
574	0x4c, 0x9f, 0x75, 0x74, 0x38, 0xc8, 0xdd, 0x12, 0xba, 0x21, 0x57, 0x1b,
575	0x45, 0xb3, 0x02, 0x1d, 0x67, 0x22, 0x66, 0x53, 0x18, 0x48, 0xed, 0x60,
576	0x40, 0x55, 0xd1, 0x25, 0x3b, 0xbc, 0x08, 0x7b, 0x19, 0x8a, 0x30, 0x5b,
577	0x02, 0x4f, 0x65, 0x42, 0xff, 0xce, 0x87, 0xe8, 0x97, 0x2b, 0xbb, 0xfe,
578	0x52, 0x52, 0x72, 0xe8, 0xb5, 0x77, 0xb7, 0x8e, 0x94, 0x34, 0xbc, 0x46,
579	0xf1, 0xe1, 0x94, 0x98, 0x19, 0xbe, 0x7c, 0x3f, 0xf6, 0x0e, 0xe4, 0xbb,
580	0x88, 0x32, 0x07, 0x83, 0x64, 0xad, 0xd7, 0xd1, 0xe8, 0x35, 0x8d, 0x5d,
581	0x70, 0x16, 0xc8, 0x11, 0x94, 0x39, 0xc9, 0xac, 0xd6, 0xed, 0x6b, 0xdf,
582	0xc8, 0xf3, 0x1d, 0x5e, 0x37, 0xd8, 0xb5, 0x86, 0x9b, 0xc2, 0xdc, 0x3c,
583	0x5c, 0x04, 0x52, 0x5c, 0x11, 0x88, 0x0a, 0x2b, 0x78, 0x48, 0x9e, 0x5e,
584	0x98, 0x57, 0x5a, 0xd1, 0x77, 0x1c, 0x7d, 0x5f, 0x60, 0xbb, 0x61, 0x7e,
585	0x7e, 0x2a, 0xaf, 0x44, 0x14, 0x88, 0xfc, 0xa5, 0x31, 0xb7, 0xd4, 0x44,
586	0x48, 0xda, 0xb5, 0x71, 0xa8, 0xd8, 0x4f, 0x79, 0xcd, 0xe4, 0xbe, 0xb6,
587	0x1a, 0x61, 0x74, 0x4b, 0xd8, 0xec, 0xd7, 0xbf, 0xad, 0x57, 0x00, 0x42,
588	0x04, 0xe8, 0xb3, 0xec, 0x47, 0x1d, 0x2a, 0x0a, 0xde, 0x7c, 0x6e, 0x5e,
589	0xf8, 0xaa, 0x44, 0x05, 0x10, 0xab, 0xe9, 0x4e, 0xd7, 0x44, 0x0b, 0x97,
590	0x6f, 0x1a, 0xc1, 0x59, 0x2b, 0xe4, 0xe1, 0x8a, 0x13, 0x82, 0x65, 0xd8,
591	0xae, 0x5f, 0x2b, 0xbc, 0xa6, 0x14, 0x39, 0xaf, 0x38, 0x41, 0x26, 0x74,
592	0xdb, 0x55, 0x6b, 0xe2, 0x21, 0x80, 0x5d, 0x20, 0xc3, 0xf5, 0x82, 0xee,
593	0xcc, 0x3c, 0xc9, 0xb4, 0xeb, 0x52, 0xe9, 0x13, 0x8a, 0xea, 0xc6, 0x19,
594	0x70, 0x37, 0x1b, 0xb8, 0x2e, 0x86, 0xa2, 0xe9, 0x9d, 0xb6, 0xd5, 0xd6,
595	0xf3, 0xa8, 0x31, 0xf3, 0x02, 0xaa, 0x10, 0x33, 0x3f, 0xba, 0xf8, 0xf9,
596	0x46, 0x5b, 0xe1, 0xd7, 0x34, 0x9f, 0x94, 0xcb, 0xfb, 0xb1, 0x3d, 0x60,
597	0x77, 0x85, 0x14, 0xd4, 0xcf, 0x55, 0x60, 0x5d, 0x47, 0x6c, 0x07, 0xb4,
598	0xc7, 0x73, 0xbd, 0x49, 0xbd, 0xa5, 0x31, 0xa1, 0xfa, 0x34, 0x3a, 0x8b,
599	0x77, 0x1b, 0xaa, 0xaf, 0xa5, 0x87, 0x12, 0x4e, 0x36, 0x06, 0x14, 0xe7,
600	0xb3, 0xb8, 0x87, 0x6c, 0x4b, 0x50, 0xc9, 0x52, 0x1b, 0x19, 0x48, 0x69,
601	0x5b, 0x7f, 0xd8, 0xc9, 0x14, 0xb8, 0x11, 0xa0, 0x51, 0x09, 0xbd, 0x42,
602	0x5a, 0x50, 0x32, 0x57, 0x69, 0x39, 0x30, 0xdb, 0xbf, 0x8b, 0x93, 0x54,
603	0x43, 0x80, 0x4e, 0xd0, 0xc6, 0xf2, 0x81, 0x15, 0x6d, 0xef, 0x5a, 0xb6,
604	0x4d, 0x70, 0x93, 0x88, 0x8d, 0xce, 0x0d, 0xb8, 0xe9, 0xac, 0xa2, 0xcd,
605	0xc7, 0x18, 0xa5, 0x95, 0xb7, 0xf6, 0x0c, 0x6f, 0xe1, 0x10, 0x7b, 0x22,
606	0xf8, 0x81, 0x18, 0x42, 0x6a, 0x09, 0x75, 0x20, 0xb4, 0x2f, 0x67, 0x7a,
607	0xda, 0x55, 0x28, 0xc3, 0x81, 0xf7, 0xc1, 0xf0, 0xe6, 0x1b, 0x29, 0x9c,
608	0x72, 0x87, 0xe5, 0x4c, 0xa9, 0x5b, 0x5b, 0x62, 0xb5, 0xb7, 0x1e, 0x82,
609	0xc3, 0x7b, 0xaf, 0xe9, 0x6f, 0x37, 0x31, 0x9f, 0x79, 0xe7, 0x4f, 0x06,
610	0x1e, 0xff, 0xff, 0x80, 0x8e, 0x00, 0x00
611};
612
613const size_t lzma_compressed_size = sizeof(lzma_compressed);
614
615int do_spl_test_load(struct unit_test_state *uts, const char *test_name,
616		     enum spl_test_image type, struct spl_image_loader *loader,
617		     int (*write_image)(struct unit_test_state *, void *, size_t))
618{
619	size_t img_size, img_data, plain_size = SPL_TEST_DATA_SIZE;
620	struct spl_image_info info_write = {
621		.name = test_name,
622		.size = type == LEGACY_LZMA ? sizeof(lzma_compressed) :
623					      plain_size,
624	}, info_read = { };
625	struct spl_boot_device bootdev = {
626		.boot_device = loader->boot_device,
627	};
628	char *data, *plain;
629	void *img;
630
631	img_size = create_image(NULL, type, &info_write, &img_data);
632	ut_assert(img_size);
633	img = calloc(img_size, 1);
634	ut_assertnonnull(img);
635
636	data = img + img_data;
637	if (type == LEGACY_LZMA) {
638		plain = malloc(plain_size);
639		ut_assertnonnull(plain);
640		generate_data(plain, plain_size, "lzma");
641		memcpy(data, lzma_compressed, sizeof(lzma_compressed));
642	} else {
643		plain = data;
644		generate_data(plain, plain_size, test_name);
645	}
646	ut_asserteq(img_size, create_image(img, type, &info_write, NULL));
647
648	if (write_image(uts, img, img_size))
649		return CMD_RET_FAILURE;
650
651	ut_assertok(loader->load_image(&info_read, &bootdev));
652	if (check_image_info(uts, &info_write, &info_read))
653		return CMD_RET_FAILURE;
654	if (type == LEGACY_LZMA)
655		ut_asserteq(plain_size, info_read.size);
656	ut_asserteq_mem(plain, phys_to_virt(info_write.load_addr), plain_size);
657
658	if (type == LEGACY_LZMA)
659		free(plain);
660	free(img);
661	return 0;
662}
663