/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <kernel.h>
#include <kernel_structs.h>
#include <app_memory/app_memdomain.h>
#include <sys/libc-hooks.h>
#include <sys/util.h>

#define NUM_THREADS	3
#define STACK_SIZE	(512 + CONFIG_TEST_EXTRA_STACKSIZE)

#define STATIC_DATA8	0x7FU
#define STATIC_DATA32	0xABCDEF00U
#define STATIC_DATA64	0x1122334455667788UL

#define PREFIX_8	0x30U
#define PREFIX_32	0x44668800U
#define PREFIX_64	0xFFEEDDCC00000000UL

#ifdef CONFIG_USERSPACE
K_APPMEM_PARTITION_DEFINE(part_common);
struct k_mem_domain dom_common;
#endif /* CONFIG_USERSPACE */

enum test_result {
	TEST_OK,

	/* When thread_data* != STATIC_DATA at thread entry */
	ERR_BAD_STATIC_DATA,

	/* When thread_bss* != 0 at thread entry */
	ERR_BSS_NOT_ZERO,

	/* If data/bss is changed by other threads */
	ERR_DATA_CHANGED_BY_OTHERS,
	ERR_BSS_CHANGED_BY_OTHERS,

	TEST_NOT_STARTED,
};

static K_THREAD_STACK_ARRAY_DEFINE(tls_stack, NUM_THREADS, STACK_SIZE);

static struct k_thread tls_thread[NUM_THREADS];

K_APP_BMEM(part_common) static k_tid_t tls_tid[NUM_THREADS];
K_APP_BMEM(part_common) static enum test_result tls_result[NUM_THREADS];

/* Thread data with initialized values */
static uint8_t  __thread thread_data8  = STATIC_DATA8;
static uint32_t __thread thread_data32 = STATIC_DATA32;
static uint64_t __thread thread_data64 = STATIC_DATA64;

/* Zeroed thread data */
static uint8_t  __thread thread_bss8;
static uint32_t __thread thread_bss32;
static uint64_t __thread thread_bss64;

static void tls_thread_entry(void *p1, void *p2, void *p3)
{
	uint32_t idx;

	idx = (uint32_t)POINTER_TO_UINT(p1);

	/* Check if TLS area in stack is initialized correctly */
	if (thread_data8 != STATIC_DATA8) {
		tls_result[idx] = ERR_BAD_STATIC_DATA;
		goto out;
	}

	if (thread_data32 != STATIC_DATA32) {
		tls_result[idx] = ERR_BAD_STATIC_DATA;
		goto out;
	}

	if (thread_data64 != STATIC_DATA64) {
		tls_result[idx] = ERR_BAD_STATIC_DATA;
		goto out;
	}

	if (thread_bss8 != 0) {
		tls_result[idx] = ERR_BSS_NOT_ZERO;
		goto out;
	}

	if (thread_bss32 != 0) {
		tls_result[idx] = ERR_BSS_NOT_ZERO;
		goto out;
	}

	if (thread_bss64 != 0) {
		tls_result[idx] = ERR_BSS_NOT_ZERO;
		goto out;
	}

	/* Set thread data and see if they remain unchanged */
	thread_data8 = STATIC_DATA8 + idx;
	thread_bss8 = PREFIX_8 + idx;

	thread_data32 = STATIC_DATA32 + idx;
	thread_bss32 = PREFIX_32 + idx;

	thread_data64 = STATIC_DATA64 + idx;
	thread_bss64 = PREFIX_64 + idx;

	/* Let other threads run */
	k_sleep(K_MSEC(100));

	if (thread_data8 != (STATIC_DATA8 + idx)) {
		tls_result[idx] = ERR_DATA_CHANGED_BY_OTHERS;
		goto out;
	}

	if (thread_data32 != (STATIC_DATA32 + idx)) {
		tls_result[idx] = ERR_DATA_CHANGED_BY_OTHERS;
		goto out;
	}

	if (thread_data64 != (STATIC_DATA64 + idx)) {
		tls_result[idx] = ERR_DATA_CHANGED_BY_OTHERS;
		goto out;
	}

	if (thread_bss8 != (PREFIX_8 + idx)) {
		tls_result[idx] = ERR_BSS_CHANGED_BY_OTHERS;
		goto out;
	}

	if (thread_bss32 != (PREFIX_32 + idx)) {
		tls_result[idx] = ERR_BSS_CHANGED_BY_OTHERS;
		goto out;
	}

	if (thread_bss64 != (PREFIX_64 + idx)) {
		tls_result[idx] = ERR_BSS_CHANGED_BY_OTHERS;
		goto out;
	}

	/* Values are all expected. Test passed */
	tls_result[idx] = TEST_OK;

out:
	return;
}

static void start_tls_test(uint32_t thread_options)
{
	unsigned int i;
	bool passed;

	/* Create threads */
	for (i = 0; i < NUM_THREADS; i++) {
		tls_result[i] = TEST_NOT_STARTED;
		tls_tid[i] = k_thread_create(&tls_thread[i], tls_stack[i],
					     STACK_SIZE, tls_thread_entry,
					     UINT_TO_POINTER(i), NULL, NULL,
					     0, thread_options, K_NO_WAIT);
	}

	/* Wait for all threads to run */
	k_sleep(K_MSEC(500));

	/* Stop all threads */
	for (i = 0; i < NUM_THREADS; i++) {
		k_thread_abort(tls_tid[i]);
		k_thread_join(&tls_thread[i], K_FOREVER);
	}

	/* Check test results */
	passed = true;
	for (i = 0; i < NUM_THREADS; i++) {
		TC_PRINT("thread %d: result %d (expecting %d)\n",
			 i, tls_result[i], TEST_OK);
		if (tls_result[i] != TEST_OK) {
			passed = false;
		}
	}

	zassert_true(passed, "Test failed");
}

#ifdef CONFIG_USERSPACE
void test_tls(void)
{
	ztest_test_skip();
}
void test_tls_userspace(void)
{
	/* TLS test in supervisor mode */
	start_tls_test(K_USER | K_INHERIT_PERMS);
}
#else
void test_tls(void)
{
	/* TLS test in supervisor mode */
	start_tls_test(0);
}

void test_tls_userspace(void)
{
	ztest_test_skip();
}
#endif

void test_main(void)
{
#ifdef CONFIG_USERSPACE
	unsigned int i;

	struct k_mem_partition *parts[] = {
		&part_common,
#if Z_LIBC_PARTITION_EXISTS
		&z_libc_partition,
#endif
		&ztest_mem_partition,
	};

	parts[0] = &part_common;
	k_mem_domain_init(&dom_common, ARRAY_SIZE(parts), parts);
	k_mem_domain_add_thread(&dom_common, k_current_get());

	for (i = 0; i < NUM_THREADS; i++) {
		k_thread_access_grant(k_current_get(),
				      &tls_thread[i], &tls_stack[i]);
	}
#endif /* CONFIG_USERSPACE */

	ztest_test_suite(thread_tls,
			 ztest_unit_test(test_tls),
			 ztest_user_unit_test(test_tls_userspace));
	ztest_run_test_suite(thread_tls);

}
