1 /*
2 * Copyright (c) 2024 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8
9 #include <zephyr/arch/arc/v2/vpx/arc_vpx.h>
10
11 #ifndef CONFIG_ARC_VPX_COOPERATIVE_SHARING
12 #error "Rebuild with the ARC_VPX_COOPERATIVE_SHARING config option enabled"
13 #endif
14
15 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
16
17 static void timer_func(struct k_timer *timer);
18
19 K_THREAD_STACK_DEFINE(payload_stack, STACK_SIZE);
20
21 static K_TIMER_DEFINE(my_timer, timer_func, NULL);
22
23 static struct k_thread payload_thread;
24
25 static volatile int isr_result;
26 static volatile unsigned int isr_vpx_lock_id;
27
28 /**
29 * Obtain the current CPU id.
30 */
current_cpu_id_get(void)31 static int current_cpu_id_get(void)
32 {
33 int key;
34 int id;
35
36 key = arch_irq_lock();
37 id = _current_cpu->id;
38 arch_irq_unlock(key);
39
40 return id;
41 }
42
timer_func(struct k_timer * timer)43 static void timer_func(struct k_timer *timer)
44 {
45 arc_vpx_unlock_force(isr_vpx_lock_id);
46 }
47
arc_vpx_lock_unlock_timed_payload(void * p1,void * p2,void * p3)48 static void arc_vpx_lock_unlock_timed_payload(void *p1, void *p2, void *p3)
49 {
50 int status;
51 unsigned int cpu_id;
52 unsigned int lock_id;
53
54 cpu_id = (unsigned int)(uintptr_t)(p1);
55 ARG_UNUSED(p2);
56 ARG_UNUSED(p3);
57
58 status = arc_vpx_lock(K_NO_WAIT);
59 zassert_equal(0, status, "Expected return value %d, not %d\n", 0, status);
60
61 /*
62 * In 1 second, forcibly release the VPX lock. However, wait up to
63 * 5 seconds before considering this a failure.
64 */
65
66 isr_vpx_lock_id = cpu_id;
67 k_timer_start(&my_timer, K_MSEC(1000), K_FOREVER);
68
69 status = arc_vpx_lock(K_MSEC(5000));
70 zassert_equal(0, status, "Expected return value %d, not %d\n", 0, status);
71
72 arc_vpx_unlock();
73 }
74
ZTEST(vpx_lock,test_arc_vpx_lock_unlock_timed)75 ZTEST(vpx_lock, test_arc_vpx_lock_unlock_timed)
76 {
77 int priority;
78 int cpu_id;
79
80 priority = k_thread_priority_get(k_current_get());
81 cpu_id = current_cpu_id_get();
82
83 k_thread_create(&payload_thread, payload_stack, STACK_SIZE,
84 arc_vpx_lock_unlock_timed_payload,
85 (void *)(uintptr_t)cpu_id, NULL, NULL,
86 priority - 2, 0, K_FOREVER);
87
88 #if defined(CONFIG_SCHED_CPU_MASK) && (CONFIG_MP_MAX_NUM_CPUS > 1)
89 k_thread_cpu_pin(&payload_thread, cpu_id);
90 #endif
91 k_thread_start(&payload_thread);
92
93 k_thread_join(&payload_thread, K_FOREVER);
94 }
95
arc_vpx_lock_unlock_payload(void * p1,void * p2,void * p3)96 static void arc_vpx_lock_unlock_payload(void *p1, void *p2, void *p3)
97 {
98 int status;
99
100 ARG_UNUSED(p1);
101 ARG_UNUSED(p2);
102 ARG_UNUSED(p3);
103
104 /* The VPX lock is available; take it. */
105
106 status = arc_vpx_lock(K_NO_WAIT);
107 zassert_equal(0, status, "Expected return value %d, not %d\n", 0, status);
108
109 /* The VPX lock has already been taken; expect errors */
110
111 status = arc_vpx_lock(K_NO_WAIT);
112 zassert_equal(-EBUSY, status, "Expected return value %d (-EBUSY), not %d\n",
113 -EBUSY, status);
114
115 status = arc_vpx_lock(K_MSEC(10));
116 zassert_equal(-EAGAIN, status, "Expected return value %d (-EAGAIN), not %d\n",
117 -EAGAIN, status);
118
119 /* Verify that unlocking makes it available */
120
121 arc_vpx_unlock();
122
123 status = arc_vpx_lock(K_NO_WAIT);
124 zassert_equal(0, status, "Expected return value %d, not %d\n", 0, status);
125 arc_vpx_unlock();
126 }
127
ZTEST(vpx_lock,test_arc_vpx_lock_unlock)128 ZTEST(vpx_lock, test_arc_vpx_lock_unlock)
129 {
130 int priority;
131 int cpu_id;
132
133 priority = k_thread_priority_get(k_current_get());
134 cpu_id = current_cpu_id_get();
135
136 k_thread_create(&payload_thread, payload_stack, STACK_SIZE,
137 arc_vpx_lock_unlock_payload, NULL, NULL, NULL,
138 priority - 2, 0, K_FOREVER);
139
140 #if defined(CONFIG_SCHED_CPU_MASK) && (CONFIG_MP_MAX_NUM_CPUS > 1)
141 k_thread_cpu_pin(&payload_thread, cpu_id);
142 #endif
143 k_thread_start(&payload_thread);
144
145 k_thread_join(&payload_thread, K_FOREVER);
146 }
147
148 ZTEST_SUITE(vpx_lock, NULL, NULL, NULL, NULL, NULL);
149