/* SPDX-License-Identifier: GPL-2.0-only */

#include <tests/test.h>
#include <cbmem.h>
#include <commonlib/bsd/cbmem_id.h>
#include <stage_cache.h>

#define CBMEM_SIZE (32 * KiB)

/* CBMEM top pointer used by implementation. */
extern uintptr_t _cbmem_top_ptr;

void cbmem_run_init_hooks(int is_recovery)
{
}

static void *get_cbmem_ptr(void)
{
	void *cbmem_top_ptr = (void *)_cbmem_top_ptr;
	if (cbmem_top_ptr)
		return cbmem_top_ptr - CBMEM_SIZE;
	else
		return NULL;
}

static void clear_cbmem(void)
{
	void *ptr = get_cbmem_ptr();
	if (ptr)
		memset(ptr, 0, CBMEM_SIZE);
}

int setup_test(void **state)
{
	void *cbmem_top_ptr = malloc(CBMEM_SIZE);

	if (!cbmem_top_ptr)
		return -1;

	_cbmem_top_ptr = (uintptr_t)cbmem_top_ptr + CBMEM_SIZE;
	clear_cbmem();
	cbmem_initialize_empty();
	return 0;
}

int teardown_test(void **state)
{
	if (_cbmem_top_ptr && (_cbmem_top_ptr - CBMEM_SIZE))
		free((void *)(_cbmem_top_ptr - CBMEM_SIZE));

	_cbmem_top_ptr = 0;
	return 0;
}

/* This function is used as prog_entry of struct prog to prevent potential calls to unaccessible
   or incorrect addresses. */
void prog_entry_mock(void *arg)
{
}

/* This test checks if stage_cache_add() correctly adds CBMEM_ID_STAGE_x_META
   and CBMEM_ID_STAGEx_CACHE entries to cbmem. stage_cache_add() must create meta
   entry containing load address, entry address and argument for it. It also must
   copy buffer pointer pointed by start pointer of prog struct to cache entry. */
void test_stage_cache_add(void **state)
{
	const int id = 12;
	int arg = 0xC14;
	struct stage_cache *meta = NULL;
	uint8_t *prog_data_buf = NULL;
	const size_t data_sz = 4 * KiB;
	uint8_t *data = malloc(data_sz);
	struct prog prog_data = {0};

	assert_non_null(data);
	memset(data, 0xDB, data_sz);
	prog_data = (struct prog)PROG_INIT(PROG_ROMSTAGE, "test_prog");
	prog_set_area(&prog_data, data, data_sz);
	prog_set_entry(&prog_data, prog_entry_mock, &arg);

	stage_cache_add(id, &prog_data);

	meta = cbmem_find(CBMEM_ID_STAGEx_META + id);
	assert_non_null(meta);
	assert_int_equal(meta->load_addr, (uintptr_t)prog_start(&prog_data));
	assert_int_equal(meta->entry_addr, (uintptr_t)prog_entry(&prog_data));
	assert_int_equal(meta->arg, (uintptr_t)prog_entry_arg(&prog_data));

	prog_data_buf = cbmem_find(CBMEM_ID_STAGEx_CACHE + id);
	assert_non_null(prog_data_buf);
	assert_memory_equal(data, prog_data_buf, data_sz);

	free(data);
}

/* This test checks if stage_cache_add_raw() correctly creates entry with data from
   provided buffer. Data should be accessible using cbmem_find() with
   (CBMEM_ID_STAGEx_RAW + id) parameter. */
void test_stage_cache_add_raw(void **state)
{
	const int id = 55;
	const size_t data_sz = 8 * KiB;
	uint8_t *data = malloc(data_sz);
	uint8_t *data_raw = NULL;

	assert_non_null(data);
	memset(data, 0x91, data_sz);

	stage_cache_add_raw(id, data, data_sz);

	data_raw = cbmem_find(CBMEM_ID_STAGEx_RAW + id);
	assert_non_null(data_raw);
	assert_memory_equal(data_raw, data, data_sz);

	free(data);
}


/* This test checks if stage_cache_get_raw() correctly extracts base and size of previously
   added entry.  */
void test_stage_cache_get_raw(void **state)
{
	const int id = 23;
	const size_t data_sz = 3 * KiB;
	uint8_t *data = malloc(data_sz);
	size_t data_out_sz = 0;
	uint8_t *data_out = NULL;

	assert_non_null(data);
	memset(data, 0x3c, data_sz);
	stage_cache_add_raw(id, data, data_sz);

	stage_cache_get_raw(id, (void **)&data_out, &data_out_sz);

	assert_int_equal(data_sz, data_out_sz);
	assert_memory_equal(data, data_out, data_sz);

	free(data);
}

/* This test checks if stage_cache_load_stage() correctly loads previously added stage data
   and its metadata. */
void test_stage_cache_load_stage(void **state)
{
	int id = 0xCC;
	struct prog prog_out = {0};
	const size_t data_sz = 7 * KiB;
	uint8_t *data = malloc(data_sz);
	uint8_t *data_bak = malloc(data_sz);
	struct prog prog_data = {0};
	int arg = 0x33224455;

	assert_non_null(data);
	assert_non_null(data_bak);
	memset(data, 0x45, data_sz);

	prog_data = (struct prog)PROG_INIT(PROG_RAMSTAGE, "test_prog");
	prog_set_area(&prog_data, data, data_sz);
	prog_set_entry(&prog_data, prog_entry_mock, &arg);
	stage_cache_add(id, &prog_data);

	/* Copy current data to backup buffer and clear current buffer */
	memcpy(data_bak, data, data_sz);
	memset(data, 0, data_sz);

	/* Load stage data. Data should be returned to the same buffer. */
	stage_cache_load_stage(id, &prog_out);

	/* Data should be same as it was before */
	assert_memory_equal(data, data_bak, data_sz);
	assert_int_equal(prog_start(&prog_data), prog_start(&prog_out));
	assert_int_equal(prog_size(&prog_data), prog_size(&prog_out));
	assert_ptr_equal(prog_entry(&prog_data), prog_entry(&prog_out));
	assert_ptr_equal(prog_entry_arg(&prog_data), prog_entry_arg(&prog_out));

	free(data_bak);
	free(data);
}

int main(void)
{
	const struct CMUnitTest tests[] = {
		cmocka_unit_test_setup_teardown(test_stage_cache_add, setup_test,
						teardown_test),
		cmocka_unit_test_setup_teardown(test_stage_cache_add_raw, setup_test,
						teardown_test),
		cmocka_unit_test_setup_teardown(test_stage_cache_get_raw, setup_test,
						teardown_test),
		cmocka_unit_test_setup_teardown(test_stage_cache_load_stage, setup_test,
						teardown_test),
	};

	return cb_run_group_tests(tests, NULL, NULL);
}
