xref: /openbmc/qemu/tests/tcg/xtensa/test_timer.S (revision 2e1cacfb)
1#include "macros.inc"
2
3#define CCOUNT_SHIFT 4
4#define WAIT_LOOPS 20
5#define level1 kernel
6#define INTERRUPT_LEVEL(n) glue3(XCHAL_INT, n, _LEVEL)
7
8.macro      make_ccount_delta target, delta
9    rsr     \delta, ccount
10    rsr     \target, ccount
11    sub     \delta, \target, \delta
12    slli    \delta, \delta, CCOUNT_SHIFT
13    add     \target, \target, \delta
14.endm
15
16test_suite timer
17
18#if XCHAL_HAVE_CCOUNT
19
20test ccount
21    rsr     a3, ccount
22    rsr     a4, ccount
23    assert  ne, a3, a4
24test_end
25
26test ccount_write
27    rsr     a3, ccount
28    rsr     a4, ccount
29    sub     a4, a4, a3
30    movi    a2, 0x12345678
31    wsr     a2, ccount
32    esync
33    rsr     a3, ccount
34    sub     a3, a3, a2
35    slli    a4, a4, 2
36    assert  ltu, a3, a4
37test_end
38
39#if XCHAL_NUM_TIMERS
40
41#if INTERRUPT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
42#define TIMER0_VECTOR kernel
43#else
44#define TIMER0_VECTOR glue(level, INTERRUPT_LEVEL(XCHAL_TIMER0_INTERRUPT))
45#endif
46
47#if XCHAL_NUM_TIMERS > 1
48#if INTERRUPT_LEVEL(XCHAL_TIMER1_INTERRUPT) == 1
49#define TIMER1_VECTOR kernel
50#else
51#define TIMER1_VECTOR glue(level, INTERRUPT_LEVEL(XCHAL_TIMER1_INTERRUPT))
52#endif
53#endif
54
55#if XCHAL_NUM_TIMERS > 2
56#if INTERRUPT_LEVEL(XCHAL_TIMER2_INTERRUPT) == 1
57#define TIMER2_VECTOR kernel
58#else
59#define TIMER2_VECTOR glue(level, INTERRUPT_LEVEL(XCHAL_TIMER2_INTERRUPT))
60#endif
61#endif
62
63test ccount_update_deadline
64    movi    a2, 0
65    wsr     a2, intenable
66    rsr     a2, interrupt
67    wsr     a2, intclear
68    movi    a2, 0
69#if XCHAL_NUM_TIMERS > 1
70    wsr     a2, ccompare1
71#endif
72#if XCHAL_NUM_TIMERS > 2
73    wsr     a2, ccompare2
74#endif
75    movi    a2, 0x12345678
76    wsr     a2, ccompare0
77    rsr     a3, interrupt
78    assert  eqi, a3, 0
79    movi    a2, 0x12345677
80    wsr     a2, ccount
81    esync
82    nop
83    rsr     a2, interrupt
84    movi    a3, 1 << XCHAL_TIMER0_INTERRUPT
85    assert  eq, a2, a3
86test_end
87
88test ccompare
89    movi    a2, 0
90    wsr     a2, intenable
91    rsr     a2, interrupt
92    wsr     a2, intclear
93    movi    a2, 0
94#if XCHAL_NUM_TIMERS > 1
95    wsr     a2, ccompare1
96#endif
97#if XCHAL_NUM_TIMERS > 2
98    wsr     a2, ccompare2
99#endif
100
101    make_ccount_delta a2, a15
102    wsr     a2, ccompare0
1031:
104    rsr     a3, interrupt
105    rsr     a4, ccount
106    rsr     a5, interrupt
107    sub     a4, a4, a2
108    bgez    a4, 2f
109    assert  eqi, a3, 0
110    j       1b
1112:
112    assert  nei, a5, 0
113test_end
114
115test ccompare0_interrupt
116    set_vector TIMER0_VECTOR, 2f
117    movi    a2, 0
118    wsr     a2, intenable
119    rsr     a2, interrupt
120    wsr     a2, intclear
121    movi    a2, 0
122#if XCHAL_NUM_TIMERS > 1
123    wsr     a2, ccompare1
124#endif
125#if XCHAL_NUM_TIMERS > 2
126    wsr     a2, ccompare2
127#endif
128
129    movi    a3, WAIT_LOOPS
130    make_ccount_delta a2, a15
131    wsr     a2, ccompare0
132    rsync
133    rsr     a2, interrupt
134    assert  eqi, a2, 0
135
136    movi    a2, 1 << XCHAL_TIMER0_INTERRUPT
137    wsr     a2, intenable
138    rsil    a2, 0
1391:
140    addi    a3, a3, -1
141    bnez    a3, 1b
142    test_fail
1432:
144#if INTERRUPT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
145    rsr     a2, exccause
146    assert  eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */
147#endif
148test_end
149
150#if XCHAL_NUM_TIMERS > 1
151
152test ccompare1_interrupt
153    set_vector TIMER1_VECTOR, 2f
154    movi    a2, 0
155    wsr     a2, intenable
156    rsr     a2, interrupt
157    wsr     a2, intclear
158    movi    a2, 0
159    wsr     a2, ccompare0
160#if XCHAL_NUM_TIMERS > 2
161    wsr     a2, ccompare2
162#endif
163
164    movi    a3, WAIT_LOOPS
165    make_ccount_delta a2, a15
166    wsr     a2, ccompare1
167    rsync
168    rsr     a2, interrupt
169    assert  eqi, a2, 0
170    movi    a2, 1 << XCHAL_TIMER1_INTERRUPT
171    wsr     a2, intenable
172    rsil    a2, INTERRUPT_LEVEL(XCHAL_TIMER1_INTERRUPT) - 1
1731:
174    addi    a3, a3, -1
175    bnez    a3, 1b
176    test_fail
1772:
178#if INTERRUPT_LEVEL(XCHAL_TIMER1_INTERRUPT) == 1
179    rsr     a2, exccause
180    assert  eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */
181#endif
182test_end
183
184#endif
185#if XCHAL_NUM_TIMERS > 2
186
187test ccompare2_interrupt
188    set_vector TIMER2_VECTOR, 2f
189    movi    a2, 0
190    wsr     a2, intenable
191    rsr     a2, interrupt
192    wsr     a2, intclear
193    movi    a2, 0
194    wsr     a2, ccompare0
195    wsr     a2, ccompare1
196
197    movi    a3, WAIT_LOOPS
198    make_ccount_delta a2, a15
199    wsr     a2, ccompare2
200    rsync
201    rsr     a2, interrupt
202    assert  eqi, a2, 0
203    movi    a2, 1 << XCHAL_TIMER2_INTERRUPT
204    wsr     a2, intenable
205    rsil    a2, INTERRUPT_LEVEL(XCHAL_TIMER2_INTERRUPT) - 1
2061:
207    addi    a3, a3, -1
208    bnez    a3, 1b
209    test_fail
2102:
211#if INTERRUPT_LEVEL(XCHAL_TIMER2_INTERRUPT) == 1
212    rsr     a2, exccause
213    assert  eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */
214#endif
215test_end
216
217#endif
218
219test ccompare_interrupt_masked
220    set_vector TIMER0_VECTOR, 2f
221    movi    a2, 0
222    wsr     a2, intenable
223    rsr     a2, interrupt
224    wsr     a2, intclear
225    movi    a2, 0
226#if XCHAL_NUM_TIMERS > 2
227    wsr     a2, ccompare2
228#endif
229
230    movi    a3, WAIT_LOOPS
231    make_ccount_delta a2, a15
232#if XCHAL_NUM_TIMERS > 1
233    wsr     a2, ccompare1
234#endif
235    add     a2, a2, a15
236    wsr     a2, ccompare0
237    rsync
238    rsr     a2, interrupt
239    assert  eqi, a2, 0
240
241    movi    a2, 1 << XCHAL_TIMER0_INTERRUPT
242    wsr     a2, intenable
243    rsil    a2, 0
2441:
245    addi    a3, a3, -1
246    bnez    a3, 1b
247
248    test_fail
2492:
250#if INTERRUPT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
251    rsr     a2, exccause
252    assert  eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */
253#endif
254test_end
255
256test ccompare_interrupt_masked_waiti
257    set_vector TIMER0_VECTOR, 2f
258    movi    a2, 0
259    wsr     a2, intenable
260    rsr     a2, interrupt
261    wsr     a2, intclear
262    movi    a2, 0
263#if XCHAL_NUM_TIMERS > 2
264    wsr     a2, ccompare2
265#endif
266
267    make_ccount_delta a2, a15
268#if XCHAL_NUM_TIMERS > 1
269    wsr     a2, ccompare1
270#endif
271    add     a2, a2, a15
272    wsr     a2, ccompare0
273    rsync
274    rsr     a2, interrupt
275    assert  eqi, a2, 0
276
277    movi    a2, 1 << XCHAL_TIMER0_INTERRUPT
278    wsr     a2, intenable
279    waiti   0
280    test_fail
2812:
282#if INTERRUPT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
283    rsr     a2, exccause
284    assert  eqi, a2, 4 /* LEVEL1_INTERRUPT_CAUSE */
285#endif
286test_end
287
288#endif
289#endif
290
291test_suite_end
292