diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index da9db799d387..832d4eb12098 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -10,6 +10,6 @@ target_sources(app PRIVATE ) zephyr_library_include_directories(app PUBLIC - ${sof_module}/src/arch/xtensa/include - ${sof_module}/src/include + ${CMAKE_CURRENT_SOURCE_DIR}/../src/arch/xtensa/include + ${CMAKE_CURRENT_SOURCE_DIR}/../src/include ) diff --git a/app/boards/qemu_xtensa_dc233c.conf b/app/boards/qemu_xtensa_dc233c.conf new file mode 100644 index 000000000000..043644bfc52b --- /dev/null +++ b/app/boards/qemu_xtensa_dc233c.conf @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: BSD-3-Clause +CONFIG_IPC_MAJOR_4=y +CONFIG_ZTEST=y +CONFIG_MM_DRV=y +CONFIG_ZEPHYR_NATIVE_DRIVERS=y diff --git a/app/boards/qemu_xtensa_dc233c_mmu.conf b/app/boards/qemu_xtensa_dc233c_mmu.conf new file mode 100644 index 000000000000..477fe82fb664 --- /dev/null +++ b/app/boards/qemu_xtensa_dc233c_mmu.conf @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: BSD-3-Clause +CONFIG_IPC_MAJOR_4=y +CONFIG_USERSPACE=y +CONFIG_ZTEST=y +CONFIG_TEST_USERSPACE=y +CONFIG_MM_DRV=y +CONFIG_ZEPHYR_NATIVE_DRIVERS=y +CONFIG_SOF_USERSPACE_LL=y +CONFIG_SOF_BOOT_TEST_STANDALONE=y diff --git a/app/prj.conf b/app/prj.conf index 260488e7852b..75e07dfde05c 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -50,3 +50,4 @@ CONFIG_SCHED_CPU_MASK=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=15000 CONFIG_DAI=y CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_SPIN_VALIDATE=n diff --git a/app/src/main.c b/app/src/main.c index 30f755f6a9c6..8fb7251d88ad 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -5,10 +5,16 @@ */ #include - +#include #include LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG); +/* define qemu boot tests if any qemu target is defined, add targets to end */ +#if defined(CONFIG_BOARD_QEMU_XTENSA_DC233C) ||\ + defined(CONFIG_BOARD_QEMU_XTENSA_DC233C_MMU) +#define QEMU_BOOT_TESTS +#endif + /** * Should be included from sof/schedule/task.h * but triggers include chain issue @@ -54,6 +60,9 @@ static int sof_app_main(void) void test_main(void) { sof_app_main(); +#if CONFIG_SOF_BOOT_TEST && defined(QEMU_BOOT_TESTS) + sof_run_boot_tests(); +#endif } #else int main(void) diff --git a/scripts/set_xtensa_params.sh b/scripts/set_xtensa_params.sh index 4bdaf93c809d..a3932818edc1 100644 --- a/scripts/set_xtensa_params.sh +++ b/scripts/set_xtensa_params.sh @@ -150,6 +150,12 @@ case "$platform" in HOST="xtensa-mt8365-elf" TOOLCHAIN_VER="RG-2018.9-linux" ;; + qemu_xtensa | qemu_xtensa_mmu) + PLATFORM="$1" + XTENSA_CORE="" + HOST="xtensa-zephyr-elf" + TOOLCHAIN_VER="" + ;; *) >&2 printf 'Unknown xtensa platform=%s\n' "$platform" return 1 @@ -166,6 +172,8 @@ esac # For Zephyr unit tests case "$platform" in + qemu_xtensa | qemu_xtensa_mmu) + ZEPHYR_TOOLCHAIN_VARIANT='zephyr';; imx8*|mtl|lnl) ZEPHYR_TOOLCHAIN_VARIANT='xt-clang';; *) # The previous, main case/esac already caught invalid input. diff --git a/scripts/xtensa-build-zephyr.py b/scripts/xtensa-build-zephyr.py index 7610f81c1b81..b6a2b8e91a90 100755 --- a/scripts/xtensa-build-zephyr.py +++ b/scripts/xtensa-build-zephyr.py @@ -227,6 +227,14 @@ class PlatformConfig: "imx", "imx95_evk/mimx9596/m7/ddr", "", "", "", "" ), + "qemu_xtensa" : PlatformConfig( + "zephyr", "qemu_xtensa/dc233c", + "", "", "zephyr" + ), + "qemu_xtensa_mmu" : PlatformConfig( + "zephyr", "qemu_xtensa/dc233c/mmu", + "", "", "zephyr" + ), } platform_configs = platform_configs_all.copy() @@ -894,6 +902,7 @@ def build_platforms(): platform_build_dir_name = f"build-{platform}" PLAT_CONFIG = platform_dict["PLAT_CONFIG"] + build_cmd = ["west"] build_cmd += ["-v"] * args.verbose if args.menuconfig: @@ -1144,8 +1153,9 @@ def install_platform(platform, sof_output_dir, platf_build_environ, platform_wco install_key_dir = install_key_dir / args.key_type_subdir os.makedirs(install_key_dir, exist_ok=True) - # looses file owner and group - file is commonly accessible - shutil.copy2(abs_build_dir / "zephyr.ri", install_key_dir / output_fwname) + # looses file owner and group - file is commonly accessible, dont install qemu. + if platform not in ("qemu_xtensa", "qemu_xtensa_mmu"): + shutil.copy2(abs_build_dir / "zephyr.ri", install_key_dir / output_fwname) if args.deployable_build and platform_configs[platform].ipc4: # IPC4 deployable builds are using separate directories per platforms @@ -1298,6 +1308,8 @@ def gzip_compress(fname, gzdst=None): RI_INFO_UNSUPPORTED += ['imx8', 'imx8x', 'imx8m', 'imx8ulp', 'imx95'] RI_INFO_UNSUPPORTED += ['rn', 'acp_6_0'] RI_INFO_UNSUPPORTED += ['mt8186', 'mt8188', 'mt8195', 'mt8196', 'mt8365'] +RI_INFO_UNSUPPORTED += ['qemu_xtensa', 'qemu_xtensa_mmu'] + # For temporary workarounds. Unlike _UNSUPPORTED above, the platforms below will print a warning. RI_INFO_FIXME = [ ] diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index f9bf5d52bef3..2e6c786552b8 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -412,6 +412,8 @@ EXPORT_SYMBOL(z_impl_mod_free); #ifdef CONFIG_USERSPACE #include + +#if CONFIG_FAST_GET const void *z_vrfy_mod_fast_get(struct processing_module *mod, const void * const dram_ptr, size_t size) { @@ -424,6 +426,7 @@ const void *z_vrfy_mod_fast_get(struct processing_module *mod, const void * cons return z_impl_mod_fast_get(mod, dram_ptr, size); } #include +#endif void *z_vrfy_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t size, size_t alignment) diff --git a/src/include/ipc4/pipeline.h b/src/include/ipc4/pipeline.h index 198918cf8577..584cc1e7fd1c 100644 --- a/src/include/ipc4/pipeline.h +++ b/src/include/ipc4/pipeline.h @@ -453,4 +453,9 @@ struct ipc4_chain_dma { } extension; } __attribute__((packed, aligned(4))); +struct ipc4_message_request; + +int ipc4_new_pipeline(struct ipc4_message_request *ipc4); +int ipc4_delete_pipeline(struct ipc4_message_request *ipc4); + #endif diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index fc64c904ef80..b55428bf1a9a 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -127,7 +127,7 @@ static inline const struct ipc4_pipeline_set_state_data *ipc4_get_pipeline_data( /* * Global IPC Operations. */ -__cold static int ipc4_new_pipeline(struct ipc4_message_request *ipc4) +__cold int ipc4_new_pipeline(struct ipc4_message_request *ipc4) { struct ipc *ipc = ipc_get(); @@ -136,7 +136,7 @@ __cold static int ipc4_new_pipeline(struct ipc4_message_request *ipc4) return ipc_pipeline_new(ipc, (ipc_pipe_new *)ipc4); } -__cold static int ipc4_delete_pipeline(struct ipc4_message_request *ipc4) +__cold int ipc4_delete_pipeline(struct ipc4_message_request *ipc4) { struct ipc4_pipeline_delete *pipe; struct ipc *ipc = ipc_get(); diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 1d0d7596cf3b..78aee20ee31a 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -25,4 +25,6 @@ elseif(CONFIG_MT8196) add_subdirectory(mt8196) elseif(CONFIG_MT8365) add_subdirectory(mt8365) +elseif(PLATFORM STREQUAL "qemu_xtensa") + add_subdirectory(qemu_xtensa) endif() diff --git a/src/platform/qemu_xtensa/CMakeLists.txt b/src/platform/qemu_xtensa/CMakeLists.txt new file mode 100644 index 000000000000..8688947cf0c6 --- /dev/null +++ b/src/platform/qemu_xtensa/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: BSD-3-Clause + +add_local_sources(sof platform.c) diff --git a/src/platform/qemu_xtensa/include/platform/lib/clk.h b/src/platform/qemu_xtensa/include/platform/lib/clk.h new file mode 100644 index 000000000000..c9f05cdf405b --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/lib/clk.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_LIB_CLK_H__ +#define __PLATFORM_LIB_CLK_H__ + +/* Dummy clk header for qemu_xtensa */ +#define CLK_MAX_CPU_HZ 10000000 +#define CPU_LOWEST_FREQ_IDX 0 + +#endif /* __PLATFORM_LIB_CLK_H__ */ diff --git a/src/platform/qemu_xtensa/include/platform/lib/dai.h b/src/platform/qemu_xtensa/include/platform/lib/dai.h new file mode 100644 index 000000000000..418c383789a8 --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/lib/dai.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_LIB_DAI_H__ +#define __PLATFORM_LIB_DAI_H__ + +/* Dummy dai header for qemu_xtensa */ + +#endif /* __PLATFORM_LIB_DAI_H__ */ diff --git a/src/platform/qemu_xtensa/include/platform/lib/dma.h b/src/platform/qemu_xtensa/include/platform/lib/dma.h new file mode 100644 index 000000000000..4c4068b99392 --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/lib/dma.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_LIB_DMA_H__ +#define __PLATFORM_LIB_DMA_H__ + +/* Dummy dma header for qemu_xtensa */ +struct dma; + +struct sof_dma { + const struct device *z_dev; +}; + +#endif /* __PLATFORM_LIB_DMA_H__ */ diff --git a/src/platform/qemu_xtensa/include/platform/lib/mailbox.h b/src/platform/qemu_xtensa/include/platform/lib/mailbox.h new file mode 100644 index 000000000000..47c97744fe6d --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/lib/mailbox.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_LIB_MAILBOX_H__ +#define __PLATFORM_LIB_MAILBOX_H__ + +/* Dummy mailbox header for qemu_xtensa */ +#define MAILBOX_HOSTBOX_BASE 0x10000000 +#define MAILBOX_HOSTBOX_SIZE 0x1000 +#define MAILBOX_DSPBOX_BASE 0x10005000 +#define MAILBOX_DSPBOX_SIZE 0x1000 +#define MAILBOX_STREAM_BASE 0x10001000 +#define MAILBOX_STREAM_SIZE 0x1000 +#define MAILBOX_TRACE_BASE 0x10002000 +#define MAILBOX_TRACE_SIZE 0x1000 +#define MAILBOX_EXCEPTION_BASE 0x10003000 +#define MAILBOX_EXCEPTION_SIZE 0x1000 +#define MAILBOX_DEBUG_BASE 0x10004000 +#define MAILBOX_DEBUG_SIZE 0x1000 +#define MAILBOX_SW_REG_BASE 0x10005000 +#define MAILBOX_SW_REG_SIZE 0x1000 + +#include +#include + +static inline void mailbox_sw_regs_write(size_t offset, const void *src, size_t bytes) {} +static inline void mailbox_sw_reg_write(size_t offset, uint32_t val) {} +static inline void mailbox_sw_reg_write64(size_t offset, uint64_t val) {} +static inline uint32_t mailbox_sw_reg_read(size_t offset) { return 0; } +static inline uint64_t mailbox_sw_reg_read64(size_t offset) { return 0; } + +#endif /* __PLATFORM_LIB_MAILBOX_H__ */ diff --git a/src/platform/qemu_xtensa/include/platform/lib/memory.h b/src/platform/qemu_xtensa/include/platform/lib/memory.h new file mode 100644 index 000000000000..d0843904f563 --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/lib/memory.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_LIB_MEMORY_H__ +#define __PLATFORM_LIB_MEMORY_H__ + +/* Dummy memory header for qemu_xtensa */ + +static inline void *platform_shared_get(void *ptr, int bytes) +{ + return ptr; +} + +#define PLATFORM_DCACHE_ALIGN sizeof(void *) +#define HOST_PAGE_SIZE 4096 +#define SHARED_DATA + +#endif /* __PLATFORM_LIB_MEMORY_H__ */ diff --git a/src/platform/qemu_xtensa/include/platform/platform.h b/src/platform/qemu_xtensa/include/platform/platform.h new file mode 100644 index 000000000000..5f89152251b4 --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/platform.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_PLATFORM_H__ +#define __PLATFORM_PLATFORM_H__ + +/* Dummy platform header for qemu_xtensa */ +#define PLATFORM_CORE_COUNT 1 +#define PLATFORM_MAX_CHANNELS 8 +#define PLATFORM_MAX_STREAMS 8 + +#define HW_CFG_VERSION 0x010000 +#define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE + +struct ipc_msg; +static inline void ipc_platform_send_msg_direct(const struct ipc_msg *msg) {} + +#endif /* __PLATFORM_PLATFORM_H__ */ diff --git a/src/platform/qemu_xtensa/include/platform/trace/trace.h b/src/platform/qemu_xtensa/include/platform/trace/trace.h new file mode 100644 index 000000000000..65499099cd52 --- /dev/null +++ b/src/platform/qemu_xtensa/include/platform/trace/trace.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2026 Intel Corporation. + */ + +#ifndef __PLATFORM_TRACE_TRACE_H__ +#define __PLATFORM_TRACE_TRACE_H__ + +/* Dummy trace header for qemu_xtensa */ +#define PLATFORM_TRACE_DICT_FRONT 0 + +#endif /* __PLATFORM_TRACE_TRACE_H__ */ diff --git a/src/platform/qemu_xtensa/platform.c b/src/platform/qemu_xtensa/platform.c new file mode 100644 index 000000000000..2930f133635d --- /dev/null +++ b/src/platform/qemu_xtensa/platform.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2026 Intel Corporation. +// +#include +#include +#include +#include + +void ipc_platform_complete_cmd(struct ipc *ipc) +{ +} + +int platform_boot_complete(uint32_t boot_message) +{ + return 0; +} + +int platform_init(struct sof *sof) +{ + ipc_init(sof); + return 0; +} + +int platform_ipc_init(struct ipc *ipc) +{ + return 0; +} + +int ipc_platform_send_msg(const struct ipc_msg *msg) +{ + return 0; +} diff --git a/src/schedule/zephyr_ll_user.c b/src/schedule/zephyr_ll_user.c index aa33807b4aa3..bf768599d3c5 100644 --- a/src/schedule/zephyr_ll_user.c +++ b/src/schedule/zephyr_ll_user.c @@ -42,8 +42,11 @@ static struct k_heap *zephyr_ll_heap_init(void) k_panic(); } + uintptr_t cached_ptr = (uintptr_t)sys_cache_cached_ptr_get(heap->heap.init_mem); + uintptr_t uncached_ptr = (uintptr_t)sys_cache_uncached_ptr_get(heap->heap.init_mem); + /* Create memory partition for sch_data array */ - mem_partition.start = (uintptr_t)sys_cache_cached_ptr_get(heap->heap.init_mem); + mem_partition.start = cached_ptr; mem_partition.size = heap->heap.init_bytes; mem_partition.attr = K_MEM_PARTITION_P_RW_U_RW | XTENSA_MMU_CACHED_WB; @@ -53,13 +56,15 @@ static struct k_heap *zephyr_ll_heap_init(void) if (ret) k_panic(); - mem_partition.start = (uintptr_t)sys_cache_uncached_ptr_get(heap->heap.init_mem); - mem_partition.attr = K_MEM_PARTITION_P_RW_U_RW; - ret = k_mem_domain_add_partition(&ll_mem_resources.mem_domain, &mem_partition); - tr_dbg(&ll_tr, "init ll heap %p, size %u (uncached), ret %d", - (void *)mem_partition.start, heap->heap.init_bytes, ret); - if (ret) - k_panic(); + if (cached_ptr != uncached_ptr) { + mem_partition.start = uncached_ptr; + mem_partition.attr = K_MEM_PARTITION_P_RW_U_RW; + ret = k_mem_domain_add_partition(&ll_mem_resources.mem_domain, &mem_partition); + tr_dbg(&ll_tr, "init ll heap %p, size %u (uncached), ret %d", + (void *)mem_partition.start, heap->heap.init_bytes, ret); + if (ret) + k_panic(); + } return heap; } diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 61ed49a3d15f..bb25230f89be 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -184,6 +184,8 @@ set_property(TARGET modules_sof PROPERTY CXX_STANDARD 17) zephyr_include_directories(include) zephyr_include_directories(${ZEPHYR_BASE}/kernel/include) zephyr_include_directories(${ZEPHYR_BASE}/arch/${ARCH}/include) +zephyr_include_directories(${SOF_SRC_PATH}/include/sof/audio/module_adapter/iadk/) +zephyr_include_directories(${SOF_SRC_PATH}/include/sof/audio/module_adapter/library/) # SOC level sources # Files that are commented may not be needed. @@ -485,6 +487,11 @@ zephyr_library_sources_ifdef(CONFIG_ZEPHYR_POSIX ${SOF_PLATFORM_PATH}/posix/fuzz.c ) +if (CONFIG_BOARD_QEMU_XTENSA) + set(PLATFORM "qemu_xtensa") + zephyr_library_sources(${SOF_PLATFORM_PATH}/qemu_xtensa/platform.c) +endif() + if(NOT DEFINED PLATFORM) message(FATAL_ERROR "PLATFORM is not defined, check your Kconfiguration?") endif() diff --git a/zephyr/test/CMakeLists.txt b/zephyr/test/CMakeLists.txt index c5b66c83bbaa..4d47a3701a0d 100644 --- a/zephyr/test/CMakeLists.txt +++ b/zephyr/test/CMakeLists.txt @@ -22,4 +22,5 @@ endif() if(CONFIG_SOF_BOOT_TEST_STANDALONE AND CONFIG_SOF_USERSPACE_LL) zephyr_library_sources(userspace/test_ll_task.c) + zephyr_library_sources(userspace/test_ipc4_pipeline.c) endif() diff --git a/zephyr/test/userspace/README.md b/zephyr/test/userspace/README.md index f6d0cc1a8dc3..6c14300ee333 100644 --- a/zephyr/test/userspace/README.md +++ b/zephyr/test/userspace/README.md @@ -32,6 +32,14 @@ Running test: sudo ./cavstool.py sof-ptl.ri - Test results printed to cavstool.py +Running test on QEMU (dc233c MMU): +- Tests can also be built and run locally using Zephyr's QEMU simulator. +- First, build the test application using `xtensa-build-zephyr.py`: + ./scripts/xtensa-build-zephyr.py qemu_xtensa_mmu --cmake-args=-DCONFIG_SOF_BOOT_TEST_STANDALONE=y \ + --cmake-args=-DCONFIG_SOF_USERSPACE_INTERFACE_DMA=y --cmake-args=-DCONFIG_SOF_USERSPACE_LL=y +- Once built, run the test in QEMU: + west build -d build-qemu_xtensa_mmu -t run + References to related assets in Zephyr codebase: - cavstool.py - zephyr/soc/intel/intel_adsp/tools/cavstool.py diff --git a/zephyr/test/userspace/test_ipc4_pipeline.c b/zephyr/test/userspace/test_ipc4_pipeline.c new file mode 100644 index 000000000000..b530b2fd766f --- /dev/null +++ b/zephyr/test/userspace/test_ipc4_pipeline.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright(c) 2026 Intel Corporation. + */ + +/* + * Test case for creation and destruction of IPC4 pipelines. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(sof_boot_test, LOG_LEVEL_DBG); + +ZTEST(userspace_ipc4_pipeline, test_pipeline_create_destroy_helpers) +{ + struct ipc *ipc = ipc_get(); + struct ipc4_pipeline_create msg = { 0 }; + struct ipc_comp_dev *ipc_pipe; + int ret; + + LOG_INF("Starting IPC4 pipeline test (helpers)"); + + /* 1. Setup msg */ + msg.primary.r.instance_id = 1; + msg.primary.r.ppl_priority = SOF_IPC4_PIPELINE_PRIORITY_0; + msg.primary.r.ppl_mem_size = 1; + msg.primary.r.type = SOF_IPC4_GLB_CREATE_PIPELINE; + msg.extension.r.core_id = 0; + + /* 2. Create pipeline */ + ret = ipc_pipeline_new(ipc, (ipc_pipe_new *)&msg); + zassert_equal(ret, 0, "ipc_pipeline_new failed with %d", ret); + + /* 3. Validate pipeline exists */ + ipc_pipe = ipc_get_pipeline_by_id(ipc, 1); + zassert_not_null(ipc_pipe, "pipeline 1 not found after creation"); + + /* 4. Destroy pipeline */ + ret = ipc_pipeline_free(ipc, 1); + zassert_equal(ret, 0, "ipc_pipeline_free failed with %d", ret); + + /* 5. Validate pipeline is destroyed */ + ipc_pipe = ipc_get_pipeline_by_id(ipc, 1); + zassert_is_null(ipc_pipe, "pipeline 1 still exists after destruction"); + + LOG_INF("IPC4 pipeline test (helpers) complete"); +} + +ZTEST(userspace_ipc4_pipeline, test_pipeline_create_destroy_handlers) +{ + struct ipc *ipc = ipc_get(); + struct ipc4_pipeline_create create_msg = { 0 }; + struct ipc4_message_request req = { 0 }; + struct ipc_comp_dev *ipc_pipe; + int ret; + + LOG_INF("Starting IPC4 pipeline test (handlers)"); + + /* 1. Setup create message */ + create_msg.primary.r.instance_id = 2; + create_msg.primary.r.ppl_priority = SOF_IPC4_PIPELINE_PRIORITY_0; + create_msg.primary.r.ppl_mem_size = 1; + create_msg.primary.r.type = SOF_IPC4_GLB_CREATE_PIPELINE; + create_msg.extension.r.core_id = 0; + + /* Pack the create message into a generic request */ + req.primary.dat = create_msg.primary.dat; + req.extension.dat = create_msg.extension.dat; + + /* 2. Create pipeline using handler */ + ret = ipc4_new_pipeline(&req); + zassert_equal(ret, 0, "ipc4_new_pipeline failed with %d", ret); + + /* 3. Validate pipeline exists */ + ipc_pipe = ipc_get_pipeline_by_id(ipc, 2); + zassert_not_null(ipc_pipe, "pipeline 2 not found after creation"); + + /* 4. Setup delete message */ + struct ipc4_pipeline_delete delete_msg = { 0 }; + + delete_msg.primary.r.instance_id = 2; + delete_msg.primary.r.type = SOF_IPC4_GLB_DELETE_PIPELINE; + + /* Pack the delete message into a generic request */ + req.primary.dat = delete_msg.primary.dat; + req.extension.dat = delete_msg.extension.dat; + + /* Destroy pipeline using handler */ + ret = ipc4_delete_pipeline(&req); + zassert_equal(ret, 0, "ipc4_delete_pipeline failed with %d", ret); + + /* 5. Validate pipeline is destroyed */ + ipc_pipe = ipc_get_pipeline_by_id(ipc, 2); + zassert_is_null(ipc_pipe, "pipeline 2 still exists after destruction"); + + LOG_INF("IPC4 pipeline test (handlers) complete"); +} + +static void *ipc4_pipeline_setup(void) +{ + struct sof *sof = sof_get(); + + /* SOF_BOOT_TEST_STANDALONE skips IPC init. We must allocate it manually for testing. */ + if (!sof->ipc) { + sof->ipc = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*sof->ipc)); + sof->ipc->comp_data = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, + SOF_IPC_MSG_MAX_SIZE); + k_spinlock_init(&sof->ipc->lock); + list_init(&sof->ipc->msg_list); + list_init(&sof->ipc->comp_list); + } + + return NULL; +} + +ZTEST_SUITE(userspace_ipc4_pipeline, NULL, ipc4_pipeline_setup, NULL, NULL, NULL); + + diff --git a/zephyr/test/userspace/test_ll_task.c b/zephyr/test/userspace/test_ll_task.c index ec4439cfea6c..4dbcfa91df1e 100644 --- a/zephyr/test/userspace/test_ll_task.c +++ b/zephyr/test/userspace/test_ll_task.c @@ -58,9 +58,6 @@ static void ll_task_test(void) task = zephyr_ll_task_alloc(); zassert_not_null(task, "task allocation failed"); - /* allow user space to report status via 'test_runs' */ - k_mem_domain_add_partition(zephyr_ll_mem_domain(), &userspace_ll_part); - /* work in progress, see pipeline-schedule.c */ ret = schedule_task_init_ll(task, SOF_UUID(test_task_uuid), SOF_SCHEDULE_LL_TIMER, priority, task_callback, @@ -91,19 +88,13 @@ static void ll_task_test(void) ZTEST(userspace_ll, ll_task_test) { +#ifndef CONFIG_QEMU_TARGET ll_task_test(); +#else + ztest_test_skip(); +#endif } ZTEST_SUITE(userspace_ll, NULL, NULL, NULL, NULL, NULL); -/** - * SOF main has booted up and IPC handling is stopped. - * Run test suites with ztest_run_all. - */ -static int run_tests(void) -{ - ztest_run_test_suite(userspace_ll, false, 1, 1, NULL); - return 0; -} -SYS_INIT(run_tests, APPLICATION, 99); diff --git a/zephyr/test/userspace/test_mailbox.c b/zephyr/test/userspace/test_mailbox.c index 766dababb553..adce22f66d7e 100644 --- a/zephyr/test/userspace/test_mailbox.c +++ b/zephyr/test/userspace/test_mailbox.c @@ -79,6 +79,7 @@ static void mailbox_test(void) ZTEST(userspace_mailbox, mailbox_test) { +#ifndef CONFIG_QEMU_TARGET /* first test from kernel */ mailbox_write_to_pipeline_regs(); @@ -86,18 +87,11 @@ ZTEST(userspace_mailbox, mailbox_test) mailbox_test(); ztest_test_pass(); +#else + ztest_test_skip(); +#endif } ZTEST_SUITE(userspace_mailbox, NULL, NULL, NULL, NULL, NULL); -/** - * SOF main has booted up and IPC handling is stopped. - * Run test suites with ztest_run_all. - */ -static int run_tests(void) -{ - ztest_run_test_suite(userspace_mailbox, false, 1, 1, NULL); - return 0; -} -SYS_INIT(run_tests, APPLICATION, 99);