From 5854670b9862624bf082766f202aebaecac497d3 Mon Sep 17 00:00:00 2001 From: Siyuan Cheng Date: Mon, 17 Oct 2022 16:08:29 +0800 Subject: [PATCH] DSP: add dsp unit test add dsp context switch test add complex multiplication test for ARC processor Signed-off-by: Siyuan Cheng --- arch/arc/core/dsp/swap_dsp_macros.h | 8 +- boards/arc/nsim/nsim_em11d.yaml | 1 + tests/arch/arc/arc_dsp_sharing/CMakeLists.txt | 18 ++ tests/arch/arc/arc_dsp_sharing/README.txt | 43 ++++ tests/arch/arc/arc_dsp_sharing/prj.conf | 6 + .../arc/arc_dsp_sharing/src/calculation_arc.c | 152 ++++++++++++ .../arc/arc_dsp_sharing/src/dsp_context.h | 50 ++++ .../arc/arc_dsp_sharing/src/dsp_regs_arc.h | 81 ++++++ .../arch/arc/arc_dsp_sharing/src/load_store.c | 230 ++++++++++++++++++ tests/arch/arc/arc_dsp_sharing/src/main.c | 31 +++ .../arc/arc_dsp_sharing/src/test_common.h | 17 ++ tests/arch/arc/arc_dsp_sharing/testcase.yaml | 8 + 12 files changed, 641 insertions(+), 4 deletions(-) create mode 100644 tests/arch/arc/arc_dsp_sharing/CMakeLists.txt create mode 100644 tests/arch/arc/arc_dsp_sharing/README.txt create mode 100644 tests/arch/arc/arc_dsp_sharing/prj.conf create mode 100644 tests/arch/arc/arc_dsp_sharing/src/calculation_arc.c create mode 100644 tests/arch/arc/arc_dsp_sharing/src/dsp_context.h create mode 100644 tests/arch/arc/arc_dsp_sharing/src/dsp_regs_arc.h create mode 100644 tests/arch/arc/arc_dsp_sharing/src/load_store.c create mode 100644 tests/arch/arc/arc_dsp_sharing/src/main.c create mode 100644 tests/arch/arc/arc_dsp_sharing/src/test_common.h create mode 100644 tests/arch/arc/arc_dsp_sharing/testcase.yaml diff --git a/arch/arc/core/dsp/swap_dsp_macros.h b/arch/arc/core/dsp/swap_dsp_macros.h index 1047fb43a4..5353eefd5e 100644 --- a/arch/arc/core/dsp/swap_dsp_macros.h +++ b/arch/arc/core/dsp/swap_dsp_macros.h @@ -125,11 +125,11 @@ dsp_skip_save : lr r13, [_ARC_V2_AGU_MOD20] st r13, [sp, ___callee_saved_stack_t_agu_mod20_OFFSET] lr r13, [_ARC_V2_AGU_MOD21] - st r13, [sp, ___callee_saved_stack_t_agu_mod21_OFFSET] + _st32_huge_offset r13, sp, ___callee_saved_stack_t_agu_mod21_OFFSET, r1 lr r13, [_ARC_V2_AGU_MOD22] - st r13, [sp, ___callee_saved_stack_t_agu_mod22_OFFSET] + _st32_huge_offset r13, sp, ___callee_saved_stack_t_agu_mod22_OFFSET, r1 lr r13, [_ARC_V2_AGU_MOD23] - st r13, [sp, ___callee_saved_stack_t_agu_mod23_OFFSET] + _st32_huge_offset r13, sp, ___callee_saved_stack_t_agu_mod23_OFFSET, r1 #endif #endif agu_skip_save : @@ -254,7 +254,7 @@ dsp_skip_load : sr r13, [_ARC_V2_AGU_MOD21] ld r13, [sp, ___callee_saved_stack_t_agu_mod22_OFFSET] sr r13, [_ARC_V2_AGU_MOD22] - st r13, [sp, ___callee_saved_stack_t_agu_mod23_OFFSET] + ld r13, [sp, ___callee_saved_stack_t_agu_mod23_OFFSET] sr r13, [_ARC_V2_AGU_MOD23] #endif #endif diff --git a/boards/arc/nsim/nsim_em11d.yaml b/boards/arc/nsim/nsim_em11d.yaml index 8cfe9ccc49..0c9b25466c 100644 --- a/boards/arc/nsim/nsim_em11d.yaml +++ b/boards/arc/nsim/nsim_em11d.yaml @@ -4,6 +4,7 @@ type: sim simulation: nsim arch: arc toolchain: + - zephyr - arcmwdt testing: ignore_tags: diff --git a/tests/arch/arc/arc_dsp_sharing/CMakeLists.txt b/tests/arch/arc/arc_dsp_sharing/CMakeLists.txt new file mode 100644 index 0000000000..a5bdb82420 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (c) 2022 Synopsys +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(dsp_sharing) + +target_sources(app PRIVATE + src/main.c + src/load_store.c + ) + +if(COMPILER STREQUAL arcmwdt) +zephyr_include_directories(${ARCMWDT_TOOLCHAIN_PATH}/MetaWare/arc/lib/src/fx/include/) +target_sources(app PRIVATE src/calculation_arc.c) +get_property(Z_ARC_DSP_OPTIONS GLOBAL PROPERTY z_arc_dsp_options) +target_compile_options(app PRIVATE ${Z_ARC_DSP_OPTIONS}) +endif() diff --git a/tests/arch/arc/arc_dsp_sharing/README.txt b/tests/arch/arc/arc_dsp_sharing/README.txt new file mode 100644 index 0000000000..69a69d9256 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/README.txt @@ -0,0 +1,43 @@ +Title: Shared DSP Support + +Description: + +This test is only for ARC targets and uses two tasks to: + + 1) Test load and store dsp registers (including arch specific registers) + 2) compute complex vector product and check for any errors + +This tests the ability of tasks to safely share dsp hardware +resources, even when switching occurs preemptively (note that both sets of +tests run concurrently even though they report their progress at different +times). + +The demonstration utilizes semaphores, round robin scheduling, DSP and XY +memory support. + +-------------------------------------------------------------------------------- + +Sample Output: + +Running TESTSUITE dsp_sharing +=================================================================== +START - test_load_store +Load and store OK after 0 (high) + 84 (low) tests +Load and store OK after 100 (high) + 11926 (low) tests +Load and store OK after 200 (high) + 23767 (low) tests +Load and store OK after 300 (high) + 35607 (low) tests +Load and store OK after 400 (high) + 47448 (low) tests +Load and store OK after 500 (high) + 59287 (low) tests + PASS - test_load_store in 10.18 seconds +=================================================================== +START - test_calculation +complex product calculation OK after 50 (high) + 63297 (low) tests (computed -160) +complex product calculation OK after 150 (high) + 188138 (low) tests (computed -160) +complex product calculation OK after 250 (high) + 312972 (low) tests (computed -160) +complex product calculation OK after 350 (high) + 437806 (low) tests (computed -160) +complex product calculation OK after 450 (high) + 562639 (low) tests (computed -160) + PASS - test_calculation in 10.16 seconds +=================================================================== +TESTSUITE dsp_sharing succeeded +=================================================================== +PROJECT EXECUTION SUCCESSFUL diff --git a/tests/arch/arc/arc_dsp_sharing/prj.conf b/tests/arch/arc/arc_dsp_sharing/prj.conf new file mode 100644 index 0000000000..b2d117d0bc --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/prj.conf @@ -0,0 +1,6 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ARC_DSP=y +CONFIG_ARC_DSP_SHARING=y +CONFIG_MAIN_STACK_SIZE=1024 +CONFIG_ARC_DSP_BFLY_SHARING=y diff --git a/tests/arch/arc/arc_dsp_sharing/src/calculation_arc.c b/tests/arch/arc/arc_dsp_sharing/src/calculation_arc.c new file mode 100644 index 0000000000..5803c1c4b9 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/src/calculation_arc.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022 Synopsys + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * @file + * @brief complex number multiplication portion of DSP sharing test + * + * @ingroup kernel_dspsharing_tests + * + * This module is used for the DSP sharing test, and supplements the basic + * load/store test by incorporating two additional threads that utilize the + * DSP unit. + * + * Testing utilizes a pair of tasks that independently compute complex vector + * dot product. The lower priority task is regularly preempted by the higher + * priority task, thereby testing whether DSP context information is properly + * preserved. + * + * A reference value of computed result is computed once at the start of the + * test. All subsequent computations must produce the same value, otherwise + * an error has occurred. + */ + +#include +#include "fxarc.h" +#include "dsp_context.h" +#include "test_common.h" + +/* stored in XY memory, need ARC_AGU_SHARING */ +#define DATA_ATTR __xy __attribute__((section(".Xdata"))) +static DATA_ATTR const cq15_t cq15_a[3] = {{0x20, 10}, {0x10, 20}, {4, 30}}; +static DATA_ATTR const cq15_t cq15_b[3] = {{0x20, 11}, {0x10, 21}, {5, 31}}; + +static volatile short reference_result; + +static volatile unsigned int calc_low_count; +static volatile unsigned int calc_high_count; + +/* Indicates that the load/store test exited */ +static volatile bool test_exited; + +/* Semaphore for signaling end of test */ +static K_SEM_DEFINE(test_exit_sem, 0, 1); + +/** + * @brief Entry point for the low priority compute task + * + * @ingroup kernel_dspsharing_tests + */ +static void calculate_low(void) +{ + volatile short res[2]; + /* Loop until the test finishes, or an error is detected. */ + for (calc_low_count = 0; !test_exited; calc_low_count++) { + + v2accum32_t acc = {0, 0}; + + for (int i = 0; i < 3; i++) { + acc = fx_v2a32_cmac_cq15(acc, cq15_a[i], cq15_b[i]); + } + /* cast reult from v2accum32_ to short type */ + res[0] = fx_q15_cast_asl_rnd_a32(fx_get_v2a32(acc, 0), 15); + res[1] = fx_q15_cast_asl_rnd_a32(fx_get_v2a32(acc, 1), 15); + + if (reference_result == 0) { + reference_result = res[0]; + } else if (reference_result != res[0]) { + printf("Computed result %d, reference result %d\n", + res[0], reference_result); + } + + zassert_equal(reference_result, res[0], "complex product computation error"); + } +} + +/** + * @brief Entry point for the high priority compute task + * + * @ingroup kernel_dspsharing_tests + */ +static void calculate_high(void) +{ + volatile short res[2]; + /* Run the test until the specified maximum test count is reached */ + for (calc_high_count = 0; calc_high_count <= MAX_TESTS; calc_high_count++) { + + v2accum32_t acc = {0, 0}; + + for (int i = 0; i < 3; i++) { + acc = fx_v2a32_cmac_cq15(acc, cq15_a[i], cq15_b[i]); + } + + /* + * Relinquish the processor for the remainder of the current + * system clock tick, so that lower priority threads get a + * chance to run. + * + * This exercises the ability of the kernel to restore the + * DSP state of a low priority thread _and_ the ability of the + * kernel to provide a "clean" DSP state to this thread + * once the sleep ends. + */ + k_sleep(K_MSEC(10)); + + res[0] = fx_q15_cast_asl_rnd_a32(fx_get_v2a32(acc, 0), 15); + res[1] = fx_q15_cast_asl_rnd_a32(fx_get_v2a32(acc, 1), 15); + + if (reference_result == 0) { + reference_result = res[0]; + } else if (reference_result != res[0]) { + printf("Computed result %d, reference result %d\n", + res[0], reference_result); + } + + zassert_equal(reference_result, res[0], "complex product computation error"); + + /* Periodically issue progress report */ + if ((calc_high_count % 100) == 50) { + printf("complex product calculation OK after %u (high) " + "+" + " %u (low) tests (computed %d)\n", + calc_high_count, calc_low_count, res[0]); + } + } + + /* Signal end of test */ + test_exited = true; + k_sem_give(&test_exit_sem); +} + +K_THREAD_DEFINE(cal_low, THREAD_STACK_SIZE, calculate_low, NULL, NULL, NULL, + THREAD_LOW_PRIORITY, THREAD_DSP_FLAGS, K_TICKS_FOREVER); + +K_THREAD_DEFINE(cal_high, THREAD_STACK_SIZE, calculate_high, NULL, NULL, NULL, + THREAD_HIGH_PRIORITY, THREAD_DSP_FLAGS, K_TICKS_FOREVER); + +ZTEST(dsp_sharing, test_calculation) +{ + /* Initialise test states */ + test_exited = false; + k_sem_reset(&test_exit_sem); + + /* Start test threads */ + k_thread_start(cal_low); + k_thread_start(cal_high); + + /* Wait for test threads to exit */ + k_sem_take(&test_exit_sem, K_FOREVER); +} diff --git a/tests/arch/arc/arc_dsp_sharing/src/dsp_context.h b/tests/arch/arc/arc_dsp_sharing/src/dsp_context.h new file mode 100644 index 0000000000..c2a39992cc --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/src/dsp_context.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Synopsys + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief common definitions for the DSP sharing test application + */ + +#ifndef _DSPCONTEXT_H +#define _DSPCONTEXT_H + +struct dsp_volatile_register_set { +#ifdef CONFIG_ARC_DSP_BFLY_SHARING + uintptr_t dsp_bfly0; +#endif +#ifdef CONFIG_ARC_AGU_SHARING + uintptr_t agu_ap0; + uintptr_t agu_os0; +#endif +}; + +struct dsp_non_volatile_register_set { + /* No non-volatile dsp registers */ +}; + +#define SIZEOF_DSP_VOLATILE_REGISTER_SET sizeof(struct dsp_volatile_register_set) +#define SIZEOF_DSP_NON_VOLATILE_REGISTER_SET 0 + +/* the set of ALL dsp registers */ + +struct dsp_register_set { + struct dsp_volatile_register_set dsp_volatile; + struct dsp_non_volatile_register_set dsp_non_volatile; +}; + +#define SIZEOF_DSP_REGISTER_SET \ + (SIZEOF_DSP_VOLATILE_REGISTER_SET + SIZEOF_DSP_NON_VOLATILE_REGISTER_SET) + +/* + * The following constants define the initial byte value used by the background + * task, and the thread when loading up the dsp registers. + */ + +#define MAIN_DSP_REG_CHECK_BYTE ((unsigned char)0xe5) +#define FIBER_DSP_REG_CHECK_BYTE ((unsigned char)0xf9) + +#endif /* _DSPCONTEXT_H */ diff --git a/tests/arch/arc/arc_dsp_sharing/src/dsp_regs_arc.h b/tests/arch/arc/arc_dsp_sharing/src/dsp_regs_arc.h new file mode 100644 index 0000000000..23c3f67001 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/src/dsp_regs_arc.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022, Synopsys. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ARC specific dsp register macros + */ + +#ifndef _DSP_REGS_ARC_H +#define _DSP_REGS_ARC_H + +#include +#include "dsp_context.h" + +/** + * + * @brief Load all dsp registers + * + * This function loads all DSP and AGU registers pointed to by @a regs. + * It is expected that a subsequent call to _store_all_dsp_registers() + * will be issued to dump the dsp registers to memory. + * + * The format/organization of 'struct dsp_register_set'; the generic C test + * code (main.c) merely treat the register set as an array of bytes. + * + * The only requirement is that the arch specific implementations of + * _load_all_dsp_registers() and _store_all_dsp_registers() agree + * on the format. + * + */ +void _load_all_dsp_registers(struct dsp_register_set *regs) +{ + uint32_t *temp = (uint32_t *)regs; + + z_arc_v2_aux_reg_write(_ARC_V2_DSP_BFLY0, *temp++); + z_arc_v2_aux_reg_write(_ARC_V2_AGU_AP0, *temp++); + z_arc_v2_aux_reg_write(_ARC_V2_AGU_OS0, *temp++); +} + +/** + * + * @brief Dump all dsp registers to memory + * + * This function stores all DSP and AGU registers to the memory buffer + * specified by @a regs. It is expected that a previous invocation of + * _load_all_dsp_registers() occurred to load all the dsp + * registers from a memory buffer. + * + */ + +void _store_all_dsp_registers(struct dsp_register_set *regs) +{ + uint32_t *temp = (uint32_t *)regs; + + *temp++ = z_arc_v2_aux_reg_read(_ARC_V2_DSP_BFLY0); + *temp++ = z_arc_v2_aux_reg_read(_ARC_V2_AGU_AP0); + *temp++ = z_arc_v2_aux_reg_read(_ARC_V2_AGU_OS0); +} + +/** + * + * @brief Load then dump all dsp registers to memory + * + * This function loads all DSP and AGU registers from the memory buffer + * specified by @a regs, and then stores them back to that buffer. + * + * This routine is called by a high priority thread prior to calling a primitive + * that pends and triggers a co-operative context switch to a low priority + * thread. + * + */ + +void _load_then_store_all_dsp_registers(struct dsp_register_set *regs) +{ + _load_all_dsp_registers(regs); + _store_all_dsp_registers(regs); +} +#endif /* _DSP_REGS_ARC_H */ diff --git a/tests/arch/arc/arc_dsp_sharing/src/load_store.c b/tests/arch/arc/arc_dsp_sharing/src/load_store.c new file mode 100644 index 0000000000..2eb083a33b --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/src/load_store.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2022, Synopsys. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * @file + * @brief load/store portion of DSP sharing test + * + * @ingroup all_tests + * + * This module implements the load/store portion of the DSP sharing test. This + * version of this test utilizes a pair of tasks. + * + * The load/store test validates the dsp unit context + * save/restore mechanism. This test utilizes a pair of threads of different + * priorities that each use the dsp registers. The context + * switching that occurs exercises the kernel's ability to properly preserve + * the dsp registers. The test also exercises the kernel's ability + * to automatically enable dsp support for a task, if supported. + * + */ + +#include +#include +#include "dsp_regs_arc.h" +#include "dsp_context.h" +#include "test_common.h" + +/* space for dsp register load/store area used by low priority task */ +static struct dsp_register_set dsp_reg_set_load; +static struct dsp_register_set dsp_reg_set_store; + +/* space for dsp register load/store area used by high priority thread */ +static struct dsp_register_set dsp_reg_set; + +static volatile unsigned int load_store_low_count; +static volatile unsigned int load_store_high_count; + +/* Indicates that the load/store test exited */ +static volatile bool test_exited; + +/* Semaphore for signaling end of test */ +static K_SEM_DEFINE(test_exit_sem, 0, 1); + +/** + * @brief Low priority DSP load/store thread + * + * @ingroup kernel_dspsharing_tests + * + * @see k_sched_time_slice_set(), memset(), + * _load_all_dsp_registers(), _store_all_dsp_registers() + */ +static void load_store_low(void) +{ + volatile unsigned int i; + bool error = false; + unsigned char init_byte; + unsigned char *store_ptr = (unsigned char *)&dsp_reg_set_store; + unsigned char *load_ptr = (unsigned char *)&dsp_reg_set_load; + /* + * Initialize dsp load buffer to known values; + * these values must be different than the value used in other threads. + */ + init_byte = MAIN_DSP_REG_CHECK_BYTE; + for (i = 0; i < SIZEOF_DSP_REGISTER_SET; i++) { + load_ptr[i] = init_byte++; + } + + /* Loop until the test finishes, or an error is detected. */ + for (load_store_low_count = 0; !test_exited; load_store_low_count++) { + + /* + * Clear store buffer to erase all traces of any previous + * dsp values that have been saved. + */ + (void)memset(&dsp_reg_set_store, 0, SIZEOF_DSP_REGISTER_SET); + + /* + * Utilize an architecture specific function to load all the + * dsp registers with known values. + */ + _load_all_dsp_registers(&dsp_reg_set_load); + + /* + * Waste some cycles to give the high priority load/store + * thread an opportunity to run when the low priority thread is + * using the dsp registers. + * + * IMPORTANT: This logic requires that sys_clock_tick_get_32() not + * perform any dsp operations! + */ + k_busy_wait(100); + + /* + * Utilize an architecture specific function to dump the + * contents of all dsp registers to memory. + */ + _store_all_dsp_registers(&dsp_reg_set_store); + /* + * Compare each byte of buffer to ensure the expected value is + * present, indicating that the dsp registers weren't + * impacted by the operation of the high priority thread(s). + * + * Display error message and terminate if discrepancies are + * detected. + */ + init_byte = MAIN_DSP_REG_CHECK_BYTE; + + for (i = 0; i < SIZEOF_DSP_REGISTER_SET; i++) { + if (store_ptr[i] != init_byte) { + TC_ERROR("Found 0x%x instead of 0x%x @offset 0x%x\n", + store_ptr[i], init_byte, i); + TC_ERROR("Discrepancy found during iteration %d\n", + load_store_low_count); + error = true; + } + init_byte++; + } + + /* Terminate if a test error has been reported */ + zassert_false(error, NULL); + } +} + +/** + * @brief High priority DSP load/store thread + * + * @ingroup kernel_dspsharing_tests + * + * @see _load_then_store_all_dsp_registers() + */ +static void load_store_high(void) +{ + volatile unsigned int i; + unsigned char init_byte; + unsigned char *reg_set_ptr = (unsigned char *)&dsp_reg_set; + + /* Run the test until the specified maximum test count is reached */ + for (load_store_high_count = 0; + load_store_high_count <= MAX_TESTS; + load_store_high_count++) { + + /* + * Initialize the dsp_reg_set structure by treating it as + * a simple array of bytes (the arrangement and actual number + * of registers is not important for this generic C code). The + * structure is initialized by using the byte value specified + * by the constant FIBER_DSP_REG_CHECK_BYTE, and then + * incrementing the value for each successive location in the + * dsp_reg_set structure. + * + * The initial byte value, and thus the contents of the entire + * dsp_reg_set structure, must be different for each + * thread to effectively test the kernel's ability to + * properly save/restore the dsp-processed values during a + * context switch. + */ + init_byte = FIBER_DSP_REG_CHECK_BYTE; + + for (i = 0; i < SIZEOF_DSP_REGISTER_SET; i++) { + reg_set_ptr[i] = init_byte++; + } + + /* + * Utilize an architecture specific function to load all the + * dsp registers with the contents of the + * dsp_reg_set structure. + * + * The goal of the loading all dsp registers with + * values that differ from the values used in other threads is + * to help determine whether the dsp register + * save/restore mechanism in the kernel's context switcher + * is operating correctly. + * + * When a subsequent k_timer_test() invocation is + * performed, a (cooperative) context switch back to the + * preempted task will occur. This context switch should result + * in restoring the state of the task's dsp + * registers when the task was swapped out due to the + * occurrence of the timer tick. + */ + _load_then_store_all_dsp_registers(&dsp_reg_set); + + /* + * Relinquish the processor for the remainder of the current + * system clock tick, so that lower priority threads get a + * chance to run. + * + * This exercises the ability of the kernel to restore the + * DSP state of a low priority thread _and_ the ability of the + * kernel to provide a "clean" DSP state to this thread + * once the sleep ends. + */ + k_sleep(K_MSEC(1)); + + /* Periodically issue progress report */ + if ((load_store_high_count % 100) == 0) { + PRINT_DATA("Load and store OK after %u (high) " + "+ %u (low) tests\n", + load_store_high_count, + load_store_low_count); + } + } + + /* Signal end of test */ + test_exited = true; + k_sem_give(&test_exit_sem); +} + +K_THREAD_DEFINE(load_low, THREAD_STACK_SIZE, load_store_low, NULL, NULL, NULL, + THREAD_LOW_PRIORITY, THREAD_DSP_FLAGS, K_TICKS_FOREVER); + +K_THREAD_DEFINE(load_high, THREAD_STACK_SIZE, load_store_high, NULL, NULL, NULL, + THREAD_HIGH_PRIORITY, THREAD_DSP_FLAGS, K_TICKS_FOREVER); + +ZTEST(dsp_sharing, test_load_store) +{ + /* Initialise test states */ + test_exited = false; + k_sem_reset(&test_exit_sem); + + /* Start test threads */ + k_thread_start(load_low); + k_thread_start(load_high); + + /* Wait for test threads to exit */ + k_sem_take(&test_exit_sem, K_FOREVER); +} diff --git a/tests/arch/arc/arc_dsp_sharing/src/main.c b/tests/arch/arc/arc_dsp_sharing/src/main.c new file mode 100644 index 0000000000..9367cc5487 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/src/main.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Synopsys + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "test_common.h" + +#ifndef CONFIG_ARC_DSP +#error Rebuild with the ARC_DSP config option enabled +#endif + +#ifndef CONFIG_ARC_DSP_SHARING +#error Rebuild with the ARC_DSP_SHARING config option enabled +#endif + +static void *generic_setup(void) +{ + /* + * Enable round robin scheduling to allow both the low priority complex + * computation and load/store tasks to execute. The high priority complex + * computation and load/store tasks will preempt the low priority tasks + * periodically. + */ + k_sched_time_slice_set(10, THREAD_LOW_PRIORITY); + + return NULL; +} + +ZTEST_SUITE(dsp_sharing, NULL, generic_setup, NULL, NULL, NULL); diff --git a/tests/arch/arc/arc_dsp_sharing/src/test_common.h b/tests/arch/arc/arc_dsp_sharing/src/test_common.h new file mode 100644 index 0000000000..f64c652b59 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/src/test_common.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022 Synopsys + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define MAX_TESTS 500 + +/* + * Test Thread Parameters + */ +#define THREAD_STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) + +#define THREAD_HIGH_PRIORITY 5 +#define THREAD_LOW_PRIORITY 10 + +#define THREAD_DSP_FLAGS (K_ARC_DSP_REGS | K_ARC_AGU_REGS) diff --git a/tests/arch/arc/arc_dsp_sharing/testcase.yaml b/tests/arch/arc/arc_dsp_sharing/testcase.yaml new file mode 100644 index 0000000000..09ac8efa78 --- /dev/null +++ b/tests/arch/arc/arc_dsp_sharing/testcase.yaml @@ -0,0 +1,8 @@ +tests: + dsp_sharing.test_load_store: + filter: CONFIG_ISA_ARCV2 and CONFIG_ARC_HAS_DSP + platform_allow: nsim_em11d + dsp_sharing.test_calculation: + filter: CONFIG_ISA_ARCV2 and CONFIG_ARC_HAS_DSP + toolchain_allow: arcmwdt + platform_allow: nsim_em11d