test: boards/intel_adsp: Add test of adsp_mem API
Add a simple board-specific test of the memory mapping driver. Signed-off-by: Andy Ross <andrew.j.ross@intel.com> Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
206241acd6
commit
96b4a86a51
8
tests/boards/intel_adsp/mm/CMakeLists.txt
Normal file
8
tests/boards/intel_adsp/mm/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(adsp_mem)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
3
tests/boards/intel_adsp/mm/prj.conf
Normal file
3
tests/boards/intel_adsp/mm/prj.conf
Normal file
|
@ -0,0 +1,3 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_MM_DRV=y
|
||||
CONFIG_MM_DRV_INTEL_ADSP_TLB=y
|
291
tests/boards/intel_adsp/mm/src/main.c
Normal file
291
tests/boards/intel_adsp/mm/src/main.c
Normal file
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <ztest.h>
|
||||
#include <zephyr.h>
|
||||
|
||||
#include <toolchain.h>
|
||||
#include <sys/printk.h>
|
||||
#include <sys/util.h>
|
||||
|
||||
#include <drivers/mm/system_mm.h>
|
||||
|
||||
#include <soc.h>
|
||||
#include <cavs-mem.h>
|
||||
|
||||
#define N_PAGES 3
|
||||
#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
|
||||
|
||||
struct pagemem {
|
||||
uint32_t mem[1024];
|
||||
};
|
||||
|
||||
/*
|
||||
* Test 3 pages at a time, but another set of 3 pages
|
||||
* is needed for remapping test.
|
||||
*/
|
||||
uint8_t __aligned(PAGE_SZ) buf[2 * N_PAGES * PAGE_SZ];
|
||||
|
||||
void test_adsp_mem_map_region(void)
|
||||
{
|
||||
int ret;
|
||||
uintptr_t pa[N_PAGES];
|
||||
struct pagemem *page_buf = (void *)buf;
|
||||
|
||||
/* Find a virtual address beyond physical memory */
|
||||
void *va = (void *)ROUND_UP(L2_SRAM_BASE + L2_SRAM_SIZE, PAGE_SZ);
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
/* First N_PAGES pages of page_buf */
|
||||
pa[i] = POINTER_TO_UINT(&page_buf[i]);
|
||||
}
|
||||
|
||||
/* Map our physical pages to the new location */
|
||||
ret = sys_mm_drv_map_region(va, pa[0], N_PAGES * PAGE_SZ, 0U);
|
||||
|
||||
zassert_true(ret == 0, "sys_mm_drv_map_region() failed (%d)", ret);
|
||||
|
||||
/* Mark the new pages */
|
||||
struct pagemem *vps = va;
|
||||
const uint32_t markers[] = { 0x11111111, 0x22222222, 0x33333333 };
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
vps[i].mem[0] = markers[i];
|
||||
|
||||
/*
|
||||
* Make sure it is written back to the mapped
|
||||
* physical memory.
|
||||
*/
|
||||
z_xtensa_cache_flush(&vps[i].mem[0], PAGE_SZ);
|
||||
|
||||
/*
|
||||
* pa[i] is a cached address which means that the cached
|
||||
* version still has the old value before the assignment
|
||||
* above. So we need to invalidate the cache to reload
|
||||
* the new value.
|
||||
*/
|
||||
z_xtensa_cache_inv(UINT_TO_POINTER(pa[i]), PAGE_SZ);
|
||||
}
|
||||
|
||||
/* Verify the originals reflect the change */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps[i].mem[0], *(uint32_t *)pa[i],
|
||||
"mapping and original don't match (0x%x != 0x%x)",
|
||||
vps[i].mem[0], *(uint32_t *)pa[i]);
|
||||
}
|
||||
|
||||
/* Remap to another region (this will unmap the first virtual pages) */
|
||||
struct pagemem *vps2 = &vps[N_PAGES];
|
||||
|
||||
/*
|
||||
* Need to unmap vps2 as sys_mm_drv_remap_region() checks
|
||||
* if the new virtual memory region is all unmapped.
|
||||
*/
|
||||
ret = sys_mm_drv_unmap_region(vps2, N_PAGES * PAGE_SZ);
|
||||
zassert_true(ret == 0, "sys_mm_drv_unmap_region() failed (%d)", ret);
|
||||
|
||||
ret = sys_mm_drv_remap_region(vps, N_PAGES * PAGE_SZ, vps2);
|
||||
zassert_true(ret == 0, "sys_mm_drv_remap_region() failed (%d)", ret);
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps2[i].mem[0], *(uint32_t *)pa[i],
|
||||
"remapping and original don't match");
|
||||
}
|
||||
|
||||
/* Now copy the remapped pages to a third virtual region */
|
||||
struct pagemem *vps3 = &vps2[N_PAGES];
|
||||
uintptr_t new_pages[N_PAGES];
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
/* N_PAGES after the first N_PAGES pages of page_buf */
|
||||
new_pages[i] = POINTER_TO_UINT(&page_buf[i + N_PAGES]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to unmap vps3 as sys_mm_drv_remap_region() checks
|
||||
* if the new virtual memory region is all unmapped.
|
||||
*/
|
||||
ret = sys_mm_drv_unmap_region(vps3, N_PAGES * PAGE_SZ);
|
||||
zassert_true(ret == 0, "sys_mm_drv_unmap_region() failed (%d)", ret);
|
||||
|
||||
ret = sys_mm_drv_move_region(vps2, N_PAGES * PAGE_SZ,
|
||||
vps3, new_pages[0]);
|
||||
zassert_true(ret == 0, "sys_mm_drv_move_region() failed (%d)", ret);
|
||||
|
||||
/* Make sure they match the originals */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps3[i].mem[0], *(uint32_t *)pa[i],
|
||||
"page copy failed to match data (0x%x != 0x%x)",
|
||||
vps3[i].mem[0], *(uint32_t *)pa[i]);
|
||||
}
|
||||
|
||||
/* Modify the copy and make sure the originals are unmodified */
|
||||
const int poison = 0x5a5a5a5a;
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
vps3[i].mem[0] = poison;
|
||||
|
||||
/*
|
||||
* Make sure it is written back to the mapped
|
||||
* physical memory.
|
||||
*/
|
||||
z_xtensa_cache_flush(&vps3[i].mem[0], PAGE_SZ);
|
||||
|
||||
zassert_equal(*(int *)pa[i], markers[i],
|
||||
"page copy modified original");
|
||||
}
|
||||
|
||||
/* Unmap */
|
||||
ret = sys_mm_drv_unmap_region(vps2, N_PAGES * PAGE_SZ);
|
||||
zassert_true(ret == 0, "sys_mm_drv_unmap_region() failed (%d)", ret);
|
||||
|
||||
/* Verify the copied region was not unmapped */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps3[i].mem[0], poison,
|
||||
"copied page data changed after unmap");
|
||||
}
|
||||
|
||||
/* Verify the originals are still unmodified */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(*(int *)pa[i], markers[i],
|
||||
"original page data changed after unmap");
|
||||
}
|
||||
}
|
||||
|
||||
void test_adsp_mem_map_array(void)
|
||||
{
|
||||
int ret;
|
||||
uintptr_t pa[N_PAGES];
|
||||
struct pagemem *page_buf = (void *)buf;
|
||||
|
||||
/* Find a virtual address beyond physical memory */
|
||||
void *va = (void *)ROUND_UP(L2_SRAM_BASE + L2_SRAM_SIZE, PAGE_SZ);
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
/* Uses pages #0, #2, #4 */
|
||||
pa[i] = POINTER_TO_UINT(&page_buf[i * 2]);
|
||||
}
|
||||
|
||||
/* Map our physical pages to the new location */
|
||||
ret = sys_mm_drv_map_array(va, pa, N_PAGES, 0U);
|
||||
|
||||
zassert_true(ret == 0, "sys_mm_drv_map_array() failed (%d)", ret);
|
||||
|
||||
/* Mark the new pages */
|
||||
struct pagemem *vps = va;
|
||||
const uint32_t markers[] = { 0x11111111, 0x22222222, 0x33333333 };
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
vps[i].mem[0] = markers[i];
|
||||
|
||||
/*
|
||||
* Make sure it is written back to the mapped
|
||||
* physical memory.
|
||||
*/
|
||||
z_xtensa_cache_flush(&vps[i].mem[0], PAGE_SZ);
|
||||
|
||||
/*
|
||||
* pa[i] is a cached address which means that the cached
|
||||
* version still has the old value before the assignment
|
||||
* above. So we need to invalidate the cache to reload
|
||||
* the new value.
|
||||
*/
|
||||
z_xtensa_cache_inv(UINT_TO_POINTER(pa[i]), PAGE_SZ);
|
||||
}
|
||||
|
||||
/* Verify the originals reflect the change */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps[i].mem[0], *(uint32_t *)pa[i],
|
||||
"mapping and original don't match (0x%x != 0x%x)",
|
||||
vps[i].mem[0], *(uint32_t *)pa[i]);
|
||||
}
|
||||
|
||||
/* Remap to another region (this will unmap the first virtual pages) */
|
||||
struct pagemem *vps2 = &vps[N_PAGES];
|
||||
|
||||
/*
|
||||
* Need to unmap vps2 as sys_mm_drv_remap_region() checks
|
||||
* if the new virtual memory region is all unmapped.
|
||||
*/
|
||||
ret = sys_mm_drv_unmap_region(vps2, N_PAGES * PAGE_SZ);
|
||||
zassert_true(ret == 0, "sys_mm_drv_unmap_region() failed (%d)", ret);
|
||||
|
||||
ret = sys_mm_drv_remap_region(vps, N_PAGES * PAGE_SZ, vps2);
|
||||
zassert_true(ret == 0, "sys_mm_drv_remap_region() failed (%d)", ret);
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps2[i].mem[0], *(uint32_t *)pa[i],
|
||||
"remapping and original don't match");
|
||||
}
|
||||
|
||||
/* Now copy the remapped pages to a third virtual region */
|
||||
struct pagemem *vps3 = &vps2[N_PAGES];
|
||||
uintptr_t new_pages[N_PAGES];
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
/* Uses pages #1, #3, #5 */
|
||||
new_pages[i] = POINTER_TO_UINT(&page_buf[i * 2 + 1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to unmap vps3 as sys_mm_drv_remap_region() checks
|
||||
* if the new virtual memory region is all unmapped.
|
||||
*/
|
||||
ret = sys_mm_drv_unmap_region(vps3, N_PAGES * PAGE_SZ);
|
||||
zassert_true(ret == 0, "sys_mm_drv_unmap_region() failed (%d)", ret);
|
||||
|
||||
ret = sys_mm_drv_move_array(vps2, N_PAGES * PAGE_SZ,
|
||||
vps3, new_pages, N_PAGES);
|
||||
zassert_true(ret == 0, "sys_mm_drv_move_array() failed (%d)", ret);
|
||||
|
||||
/* Make sure they match the originals */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps3[i].mem[0], *(uint32_t *)pa[i],
|
||||
"page copy failed to match data (0x%x != 0x%x)",
|
||||
vps3[i].mem[0], *(uint32_t *)pa[i]);
|
||||
}
|
||||
|
||||
/* Modify the copy and make sure the originals are unmodified */
|
||||
const int poison = 0x5a5a5a5a;
|
||||
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
vps3[i].mem[0] = poison;
|
||||
|
||||
/*
|
||||
* Make sure it is written back to the mapped
|
||||
* physical memory.
|
||||
*/
|
||||
z_xtensa_cache_flush(&vps3[i].mem[0], PAGE_SZ);
|
||||
|
||||
zassert_equal(*(int *)pa[i], markers[i],
|
||||
"page copy modified original");
|
||||
}
|
||||
|
||||
/* Unmap */
|
||||
ret = sys_mm_drv_unmap_region(vps2, N_PAGES * PAGE_SZ);
|
||||
zassert_true(ret == 0, "sys_mm_drv_unmap_region() failed (%d)", ret);
|
||||
|
||||
/* Verify the copied region was not unmapped */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(vps3[i].mem[0], poison,
|
||||
"copied page data changed after unmap");
|
||||
}
|
||||
|
||||
/* Verify the originals are still unmodified */
|
||||
for (int i = 0; i < N_PAGES; i++) {
|
||||
zassert_equal(*(int *)pa[i], markers[i],
|
||||
"original page data changed after unmap");
|
||||
}
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(adsp_mem,
|
||||
ztest_unit_test(test_adsp_mem_map_region),
|
||||
ztest_unit_test(test_adsp_mem_map_array));
|
||||
|
||||
ztest_run_test_suite(adsp_mem);
|
||||
}
|
5
tests/boards/intel_adsp/mm/testcase.yaml
Normal file
5
tests/boards/intel_adsp/mm/testcase.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
common:
|
||||
tags: boards
|
||||
tests:
|
||||
boards.intel_adsp.mm:
|
||||
platform_allow: intel_adsp_cavs25
|
Loading…
Reference in a new issue