1 /* Copyright (c) 2022 Intel Corporation
2 * SPDX-License-Identifier: Apache-2.0
3 */
4 #include <zephyr/kernel.h>
5 #include <zephyr/ztest.h>
6 #include <stdlib.h>
7 #include "tests.h"
8
9 intel_adsp_ipc_handler_t ipm_handler;
10
clock_msg(const struct device * dev,void * arg,uint32_t data,uint32_t ext_data)11 static bool clock_msg(const struct device *dev, void *arg,
12 uint32_t data, uint32_t ext_data)
13 {
14 *(uint32_t *)arg = data;
15 return true;
16 }
17
ZTEST(intel_adsp,test_clock_calibrate)18 ZTEST(intel_adsp, test_clock_calibrate)
19 {
20 static volatile uint32_t host_dt;
21 uint32_t cyc0, cyc1, hz, diff;
22
23 /* Prime the host script's timestamp */
24 cyc0 = k_cycle_get_32();
25 intel_adsp_ipc_send_message(INTEL_ADSP_IPC_HOST_DEV, IPCCMD_TIMESTAMP, 0);
26
27 k_msleep(1000);
28 host_dt = 0;
29 intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, clock_msg, (void *)&host_dt);
30
31 /* Now do it again, but with a handler to catch the result */
32 cyc1 = k_cycle_get_32();
33 intel_adsp_ipc_send_message(INTEL_ADSP_IPC_HOST_DEV, IPCCMD_TIMESTAMP, 0);
34 AWAIT(host_dt != 0);
35 intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, NULL, NULL);
36
37 hz = 1000000ULL * (cyc1 - cyc0) / host_dt;
38 printk("CLOCK: %lld Hz\n", (1000000ULL * (cyc1 - cyc0)) / host_dt);
39
40 /* Make sure we're within 1% of spec */
41 diff = abs(hz - CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
42 zassert_true((hz / MIN(1, diff)) > 100, "clock rate wrong");
43 }
44
45 #if XCHAL_HAVE_VECBASE
ZTEST(intel_adsp,test_vecbase_lock)46 ZTEST(intel_adsp, test_vecbase_lock)
47 {
48 uintptr_t vecbase;
49
50 /* Unfortunately there is not symbol to check if the target
51 * supports locking VECBASE. The best we can do is checking if
52 * the first is not set and skip the test.
53 */
54 __asm__ volatile("rsr.vecbase %0" : "=r"(vecbase));
55 if ((vecbase & 0x1) == 0) {
56 ztest_test_skip();
57 }
58
59 /* VECBASE register should have been locked during the cpu
60 * start up. Trying to change its location should fail.
61 */
62 __asm__ volatile("wsr.vecbase %0; rsync" : : "r"(0x0));
63 __asm__ volatile("rsr.vecbase %0" : "=r"(vecbase));
64
65 zassert_not_equal(vecbase, 0x0, "VECBASE was changed");
66 }
67 #endif
68
intel_adsp_setup(void)69 static void *intel_adsp_setup(void)
70 {
71 struct intel_adsp_ipc_data *devdata = INTEL_ADSP_IPC_HOST_DEV->data;
72
73 ipm_handler = devdata->handle_message;
74
75 return NULL;
76 }
77
intel_adsp_teardown(void * data)78 static void intel_adsp_teardown(void *data)
79 {
80 /* Wait a bit so the python script on host is ready to receive
81 * IPC messages. An IPC message could be used instead of a timer,
82 * but expecting IPC to be working on a test suite that is going
83 * to test IPC may not be indicated.
84 */
85 k_msleep(1000);
86 }
87
88 ZTEST_SUITE(intel_adsp, NULL, intel_adsp_setup, NULL, NULL,
89 intel_adsp_teardown);
90
91 ZTEST_SUITE(intel_adsp_boot, NULL, intel_adsp_setup, NULL, NULL, NULL);
92