// 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);
