mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Set this flag rather than doing things manually in the test. Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			199 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0+
 | 
						|
/*
 | 
						|
 * Copyright (c) 2023 Addiva Elektronik
 | 
						|
 * Author: Tobias Waldekranz <tobias@waldekranz.com>
 | 
						|
 */
 | 
						|
 | 
						|
#include <blk.h>
 | 
						|
#include <blkmap.h>
 | 
						|
#include <dm.h>
 | 
						|
#include <asm/test.h>
 | 
						|
#include <dm/test.h>
 | 
						|
#include <test/test.h>
 | 
						|
#include <test/ut.h>
 | 
						|
 | 
						|
#define BLKSZ 0x200
 | 
						|
 | 
						|
struct mapping {
 | 
						|
	int src;
 | 
						|
	int cnt;
 | 
						|
	int dst;
 | 
						|
};
 | 
						|
 | 
						|
const struct mapping unordered_mapping[] = {
 | 
						|
	{ 0, 1, 3 },
 | 
						|
	{ 1, 3, 0 },
 | 
						|
	{ 4, 2, 6 },
 | 
						|
	{ 6, 2, 4 },
 | 
						|
 | 
						|
	{ 0, 0, 0 }
 | 
						|
};
 | 
						|
 | 
						|
const struct mapping identity_mapping[] = {
 | 
						|
	{ 0, 8, 0 },
 | 
						|
 | 
						|
	{ 0, 0, 0 }
 | 
						|
};
 | 
						|
 | 
						|
static char identity[8 * BLKSZ];
 | 
						|
static char unordered[8 * BLKSZ];
 | 
						|
static char buffer[8 * BLKSZ];
 | 
						|
 | 
						|
static void mkblob(void *base, const struct mapping *m)
 | 
						|
{
 | 
						|
	int nr;
 | 
						|
 | 
						|
	for (; m->cnt; m++) {
 | 
						|
		for (nr = 0; nr < m->cnt; nr++) {
 | 
						|
			memset(base + (m->dst + nr) * BLKSZ,
 | 
						|
			       m->src + nr, BLKSZ);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static int dm_test_blkmap_read(struct unit_test_state *uts)
 | 
						|
{
 | 
						|
	struct udevice *dev, *blk;
 | 
						|
	const struct mapping *m;
 | 
						|
 | 
						|
	ut_assertok(blkmap_create("rdtest", &dev));
 | 
						|
	ut_assertok(blk_get_from_parent(dev, &blk));
 | 
						|
 | 
						|
	/* Generate an ordered and an unordered pattern in memory */
 | 
						|
	mkblob(unordered, unordered_mapping);
 | 
						|
	mkblob(identity, identity_mapping);
 | 
						|
 | 
						|
	/* Create a blkmap that cancels out the disorder */
 | 
						|
	for (m = unordered_mapping; m->cnt; m++) {
 | 
						|
		ut_assertok(blkmap_map_mem(dev, m->src, m->cnt,
 | 
						|
					   unordered + m->dst * BLKSZ));
 | 
						|
	}
 | 
						|
 | 
						|
	/* Read out the data via the blkmap device to another area,
 | 
						|
	 * and verify that it matches the ordered pattern.
 | 
						|
	 */
 | 
						|
	ut_asserteq(8, blk_read(blk, 0, 8, buffer));
 | 
						|
	ut_assertok(memcmp(buffer, identity, sizeof(buffer)));
 | 
						|
 | 
						|
	ut_assertok(blkmap_destroy(dev));
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
DM_TEST(dm_test_blkmap_read, 0);
 | 
						|
 | 
						|
static int dm_test_blkmap_write(struct unit_test_state *uts)
 | 
						|
{
 | 
						|
	struct udevice *dev, *blk;
 | 
						|
	const struct mapping *m;
 | 
						|
 | 
						|
	ut_assertok(blkmap_create("wrtest", &dev));
 | 
						|
	ut_assertok(blk_get_from_parent(dev, &blk));
 | 
						|
 | 
						|
	/* Generate an ordered and an unordered pattern in memory */
 | 
						|
	mkblob(unordered, unordered_mapping);
 | 
						|
	mkblob(identity, identity_mapping);
 | 
						|
 | 
						|
	/* Create a blkmap that mimics the disorder */
 | 
						|
	for (m = unordered_mapping; m->cnt; m++) {
 | 
						|
		ut_assertok(blkmap_map_mem(dev, m->src, m->cnt,
 | 
						|
					   buffer + m->dst * BLKSZ));
 | 
						|
	}
 | 
						|
 | 
						|
	/* Write the ordered data via the blkmap device to another
 | 
						|
	 * area, and verify that the result matches the unordered
 | 
						|
	 * pattern.
 | 
						|
	 */
 | 
						|
	ut_asserteq(8, blk_write(blk, 0, 8, identity));
 | 
						|
	ut_assertok(memcmp(buffer, unordered, sizeof(buffer)));
 | 
						|
 | 
						|
	ut_assertok(blkmap_destroy(dev));
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
DM_TEST(dm_test_blkmap_write, 0);
 | 
						|
 | 
						|
static int dm_test_blkmap_slicing(struct unit_test_state *uts)
 | 
						|
{
 | 
						|
	struct udevice *dev;
 | 
						|
 | 
						|
	ut_assertok(blkmap_create("slicetest", &dev));
 | 
						|
 | 
						|
	ut_assertok(blkmap_map_mem(dev, 8, 8, NULL));
 | 
						|
 | 
						|
	/* Can't overlap on the low end */
 | 
						|
	ut_asserteq(-EBUSY, blkmap_map_mem(dev,  4, 5, NULL));
 | 
						|
	/* Can't be inside */
 | 
						|
	ut_asserteq(-EBUSY, blkmap_map_mem(dev, 10, 2, NULL));
 | 
						|
	/* Can't overlap on the high end */
 | 
						|
	ut_asserteq(-EBUSY, blkmap_map_mem(dev, 15, 4, NULL));
 | 
						|
 | 
						|
	/* But we should be able to add slices right before and
 | 
						|
	 * after
 | 
						|
	 */
 | 
						|
	ut_assertok(blkmap_map_mem(dev,  4, 4, NULL));
 | 
						|
	ut_assertok(blkmap_map_mem(dev, 16, 4, NULL));
 | 
						|
 | 
						|
	ut_assertok(blkmap_destroy(dev));
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
DM_TEST(dm_test_blkmap_slicing, 0);
 | 
						|
 | 
						|
static int dm_test_blkmap_creation(struct unit_test_state *uts)
 | 
						|
{
 | 
						|
	struct udevice *first, *second;
 | 
						|
 | 
						|
	ut_assertok(blkmap_create("first", &first));
 | 
						|
 | 
						|
	/* Can't have two "first"s */
 | 
						|
	ut_asserteq(-EBUSY, blkmap_create("first", &second));
 | 
						|
 | 
						|
	/* But "second" should be fine */
 | 
						|
	ut_assertok(blkmap_create("second", &second));
 | 
						|
 | 
						|
	/* Once "first" is destroyed, we should be able to create it
 | 
						|
	 * again
 | 
						|
	 */
 | 
						|
	ut_assertok(blkmap_destroy(first));
 | 
						|
	ut_assertok(blkmap_create("first", &first));
 | 
						|
 | 
						|
	ut_assertok(blkmap_destroy(first));
 | 
						|
	ut_assertok(blkmap_destroy(second));
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
DM_TEST(dm_test_blkmap_creation, 0);
 | 
						|
 | 
						|
static int dm_test_cmd_blkmap(struct unit_test_state *uts)
 | 
						|
{
 | 
						|
	ulong loadaddr = env_get_hex("loadaddr", 0);
 | 
						|
	struct udevice *dev;
 | 
						|
 | 
						|
	ut_assertok(run_command("blkmap info", 0));
 | 
						|
	ut_assert_console_end();
 | 
						|
 | 
						|
	ut_assertok(run_command("blkmap create ramdisk", 0));
 | 
						|
	ut_assert_nextline("Created \"ramdisk\"");
 | 
						|
	ut_assert_console_end();
 | 
						|
 | 
						|
	ut_assertnonnull((dev = blkmap_from_label("ramdisk")));
 | 
						|
 | 
						|
	ut_assertok(run_commandf("blkmap map ramdisk 0 800 mem 0x%lx", loadaddr));
 | 
						|
	ut_assert_nextline("Block 0x0+0x800 mapped to 0x%lx", loadaddr);
 | 
						|
	ut_assert_console_end();
 | 
						|
 | 
						|
	ut_assertok(run_command("blkmap info", 0));
 | 
						|
	ut_assert_nextline("Device 0: Vendor: U-Boot Rev: 1.0 Prod: blkmap");
 | 
						|
	ut_assert_nextline("            Type: Hard Disk");
 | 
						|
	ut_assert_nextline("            Capacity: 1.0 MB = 0.0 GB (2048 x 512)");
 | 
						|
	ut_assert_console_end();
 | 
						|
 | 
						|
	ut_assertok(run_command("blkmap get ramdisk dev devnum", 0));
 | 
						|
	ut_asserteq(dev_seq(dev), env_get_hex("devnum", 0xdeadbeef));
 | 
						|
 | 
						|
	ut_assertok(run_command("blkmap destroy ramdisk", 0));
 | 
						|
	ut_assert_nextline("Destroyed \"ramdisk\"");
 | 
						|
	ut_assert_console_end();
 | 
						|
 | 
						|
	ut_assertok(run_command("blkmap info", 0));
 | 
						|
	ut_assert_console_end();
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
DM_TEST(dm_test_cmd_blkmap, UTF_CONSOLE);
 |