135 lines
3.9 KiB
C
135 lines
3.9 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Tests for zip/unzip/gzwrite commands
|
|
*
|
|
* Copyright 2026, Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
*/
|
|
|
|
#include <command.h>
|
|
#include <env.h>
|
|
#include <dm.h>
|
|
#include <dm/lists.h>
|
|
#include <dm/test.h>
|
|
#include <linux/sizes.h>
|
|
#include <mapmem.h>
|
|
#include <part.h>
|
|
#include <test/cmd.h>
|
|
#include <test/test.h>
|
|
#include <test/ut.h>
|
|
#include <u-boot/crc.h>
|
|
|
|
/* sys/random.h is not accessible */
|
|
extern ssize_t getrandom(void *buf, size_t size, unsigned int flags);
|
|
|
|
static const ssize_t sizes[] = { 32, SZ_1K, SZ_4K, SZ_1M, SZ_16M, SZ_1M - 1, SZ_1M + 1, 6758401 };
|
|
|
|
static int do_test_cmd_zip_unzip(struct unit_test_state *uts, ssize_t size,
|
|
const bool gzwrite)
|
|
{
|
|
unsigned long loadaddr = env_get_ulong("loadaddr", 16, 0);
|
|
unsigned long encaddr = loadaddr + size + 0x10000;
|
|
unsigned long decaddr = encaddr + size + 0x10000;
|
|
unsigned char *loadmap = map_sysmem(loadaddr, size);
|
|
unsigned char *decmap = map_sysmem(decaddr, size);
|
|
unsigned char *encmap = map_sysmem(encaddr, size);
|
|
|
|
/*
|
|
* Prepare three buffers, $loadadd, $encaddr, $decaddr, and
|
|
* fill them all with random data. Add slight space between
|
|
* the compressed buffer 'encaddr' and uncompressed buffer
|
|
* 'decaddr', because the compressed data with gzip header
|
|
* might be longer than uncompressed source data 'loadaddr',
|
|
* and if the uncompressed data buffer 'decaddr' followed
|
|
* 'encaddr', the decompression could corrupt end of 'encaddr'
|
|
* buffer.
|
|
*/
|
|
|
|
ut_assert(getrandom(loadmap, size, 0) == size);
|
|
ut_assert(getrandom(decmap, size, 0) == size);
|
|
ut_assert(getrandom(encmap, size, 0) == size);
|
|
|
|
/* Compress data in $loadaddr into $encaddr */
|
|
ut_assertok(run_commandf("zip $loadaddr %zx %zx", size, encaddr));
|
|
console_record_readline(uts->actual_str, sizeof(uts->actual_str));
|
|
ut_assert(strstr(uts->actual_str, "Compressed size: "));
|
|
|
|
if (gzwrite) {
|
|
unsigned int sectsize = DIV_ROUND_UP(size, 512);
|
|
u32 crc = crc32(0, loadmap, size);
|
|
struct blk_desc *mmc_dev_desc;
|
|
|
|
ut_assertok(run_commandf("gzwrite mmc 9 %zx $filesize", encaddr));
|
|
ut_assert_skip_to_line("\t%zu bytes, crc 0x%08x", size, crc);
|
|
|
|
ut_asserteq(9, blk_get_device_by_str("mmc", "9", &mmc_dev_desc));
|
|
ut_assertok(run_commandf("mmc dev 9"));
|
|
ut_assert_nextline("switch to partitions #0, OK");
|
|
ut_assert_nextline("mmc9 is current device");
|
|
|
|
ut_assertok(run_commandf("mmc read %zx 0 %x", decaddr, sectsize));
|
|
ut_assert_nextline("MMC read: dev # 9, block # 0, count %u ... %u blocks read: OK",
|
|
sectsize, sectsize);
|
|
} else {
|
|
/* Decompress data in $encaddr into $decaddr */
|
|
ut_assertok(run_commandf("unzip %zx %zx $filesize", encaddr, decaddr));
|
|
ut_assert_nextline("Uncompressed size: %zu = 0x%zX", size, size);
|
|
}
|
|
|
|
/* Input data and compressed-decompressed data */
|
|
ut_asserteq_mem(loadmap, decmap, size);
|
|
|
|
ut_assert_console_end();
|
|
|
|
unmap_sysmem(loadmap);
|
|
unmap_sysmem(decmap);
|
|
unmap_sysmem(encmap);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int dm_test_cmd_zip_unzip(struct unit_test_state *uts)
|
|
{
|
|
int i, ret;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(sizes); i++) {
|
|
ret = do_test_cmd_zip_unzip(uts, sizes[i], false);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
DM_TEST(dm_test_cmd_zip_unzip, UTF_CONSOLE);
|
|
|
|
static int dm_test_cmd_zip_gzwrite(struct unit_test_state *uts)
|
|
{
|
|
struct udevice *dev;
|
|
ofnode root, node;
|
|
int i, j, ret;
|
|
|
|
/* Enable the mmc9 node for this test */
|
|
root = oftree_root(oftree_default());
|
|
node = ofnode_find_subnode(root, "mmc9");
|
|
ut_assert(ofnode_valid(node));
|
|
ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false));
|
|
|
|
for (i = 0; i < ARRAY_SIZE(sizes); i++) {
|
|
ret = do_test_cmd_zip_unzip(uts, sizes[i], true);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
/* Test various sizes of decompression chunk sizes */
|
|
for (j = 0; j < ARRAY_SIZE(sizes); j++) {
|
|
env_set_ulong("gzwrite_chunk", sizes[j]);
|
|
for (i = 0; i < ARRAY_SIZE(sizes); i++) {
|
|
ret = do_test_cmd_zip_unzip(uts, sizes[i], true);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
DM_TEST(dm_test_cmd_zip_gzwrite, UTF_CONSOLE);
|