Skip to content

Commit e3f0958

Browse files
tests/tcg/arc64: add tests for {push,pop}dl_s
This commit adds several tests for push/pop double long instructions. They come in two varieties: - Standalone tests (check_pushdl.S, check_popdl.S) that verify a couple of corner cases in decoding/translation; - MMU tests (check_mmuv48_07.S) that check whether memory exceptions involving those instructions are generated correctly. All of these tests have been verified with nSIM by uncommenting the final brk instruction. The last test in check_mmuv48_07.S does not pass on QEMU due to misaligned access checks having lower priority than page validity ones, suggesting a fix in the exception handling code. Signed-off-by: Artemiy Volkov <[email protected]>
1 parent 3fa3c2c commit e3f0958

File tree

4 files changed

+684
-0
lines changed

4 files changed

+684
-0
lines changed

tests/tcg/arc64/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ TESTCASES += check_qmach.tst
9494
#TESTCASES += check_swapl.tst
9595
TESTCASES += check_lddl.tst
9696
TESTCASES += check_stdl.tst
97+
TESTCASES += check_popdl.tst
98+
TESTCASES += check_pushdl.tst
9799

98100
all: $(TESTCASES)
99101
OBJECTS = ivt.o

tests/tcg/arc64/check_mmuv48_07.S

Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
; check_mmuv48_07.S
2+
;
3+
; A couple of tests checking EFA values for page fault exceptions triggered
4+
; when executing pushdl/popdl instructions near page boundaries.
5+
; In case of a failure, consult the "fail" label section of the code.
6+
7+
.include "macros.inc"
8+
.include "mmuv48.inc"
9+
10+
;;;;;;;;;;;;;;;;;;;;;;;;;;; Test checking routines ;;;;;;;;;;;;;;;;;;;;;;;;;;
11+
12+
; Test case counter
13+
.data
14+
test_nr:
15+
.word 0x0
16+
17+
; Increment the test counter and set (Z,N,C,V) to (0,0,0,0).
18+
.macro prep_test_case
19+
ld r13, [test_nr]
20+
add_s r13, r13, 1 ; increase test case counter
21+
st r13, [test_nr]
22+
add.f 0, 0, 1 ; (Z, N, C, V) = (0, 0, 0, 0)
23+
.endm
24+
25+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Tables for Tests ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26+
;
27+
; If TxSZ are 16, there is a 4-level page table and the regions are:
28+
;
29+
; (T0SZ, T1SZ) = (16, 16) 4-level page table
30+
; VA: 0x0000_0000_0000_0000 -> RTP0 Top 16 bits 0
31+
; VA: 0x0000_FFFF_FFFF_FFFF -> RTP0 Top 16 bits 0
32+
;
33+
; VA: 0xFFFF_0000_0000_0000 -> RTP1 Top 16 bits 1
34+
; VA: 0xFFFF_FFFF_FFFF_FFFF -> RTP1 Top 16 bits 1
35+
;
36+
; VA: 0x0001_0000_0000_0000 -> EV_IMMUFault Not all top 16 bits 0
37+
; VA: 0xFFFE_0000_0000_0000 -> EV_DMMUFault Not all top 16 bits 1
38+
39+
; RTP0
40+
;
41+
; table1@0x1000_0000 (tarc.ld) table2@0x1000_1000
42+
; ,------------------. ,---------------------------------.
43+
; | [ 0 ] table 2 | | [ 0 ] 1G block 0x0000_0000 AF V |
44+
; | [ 0 ] | | [ 1 ] table 3 |
45+
; | ... xxxxx0 | | [ 2 ] 1G block 0x8000_0000 AF V |
46+
; | [ 0 ] | | ... xxxxxxxxxxxxxxxxxxx0 |
47+
; `------------------' `---------------------------------'
48+
; ,------------------. ,----------------------------------.
49+
; | [ 0 ] table 4 | | [ 0 ] 4KB page 0x2000_0000 AF V |
50+
; | [ 1 ] xxxxx0 | | [ 1 ] 4KB page 0x2000_1000 AF V |
51+
; | [ 2 ] xxxxx0 | | [ 2 ] 4KB page 0x2000_2000 AF V |
52+
; | [ 3 ] xxxxx0 | | [ 3 ] page hole |
53+
; | [ 4 ] xxxxx0 | | [ 4 ] 4KB page 0x2000_4000 AF V |
54+
; | ... xxxxx0 | | ... xxxxxxxxxxxxxxxxxxxx0 |
55+
; | [511] xxxxx0 | | [512] xxxxxxxxxxxxxxxxxxxx0 |
56+
; `------------------' `----------------------------------'
57+
; table3@0x1000_2000 table4@0x1000_3000
58+
;
59+
; Important translations are:
60+
; 0x8000_0000 -> 0xBFFF_FFFF - code
61+
; 0x4000_0000 -> 0x4000_5000 - range of stack pointer
62+
;
63+
64+
.section .data.pagetables
65+
; 0x10000000
66+
pt_l1_base:
67+
.8byte 0x10001000 | kTableValid
68+
.space (0x1000 - 1 * 8)
69+
70+
.align 0x1000
71+
; 0x10001000
72+
pt_l2_base:
73+
.8byte 0x00000000 | kAF | kBlockValid
74+
.8byte 0x10002000 | kTableValid; 0x4000_0000 -> 0x7FFF_FFFC
75+
.8byte 0x80000000 | kAF | kBlockValid
76+
.space (0x1000 - 3 * 8)
77+
78+
.align 0x1000
79+
; 0x10002000
80+
pt_l3_base:
81+
.8byte 0x10003000 | kTableValid; 0x4000_0000 -> 0x4001_0000
82+
.space (0x1000 - 1 * 8)
83+
84+
.align 0x1000
85+
; 0x10003000
86+
pt_l4_base:
87+
.8byte 0x20000000 | kAF | kPageValid
88+
.8byte 0x20001000 | kAF | kPageValid
89+
.8byte 0x20002000 | kAF | kPageValid
90+
.8byte 0 ; empty page for boundary tests (0x4000_3000)
91+
.8byte 0x20004000 | kAF | kPageValid
92+
.space (0x1000 - 5 * 8)
93+
94+
.text
95+
GENERAL_EXCEPTION_HANDLING EV_TLBMissD
96+
GENERAL_EXCEPTION_HANDLING EV_Misaligned
97+
98+
;;;;;;;;;;;;;;;;;;;;;;;;;;;; MMUv48_07 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
99+
100+
; Let the tests begin
101+
start
102+
103+
; set up exception handling
104+
mov r0, 0x80000000
105+
sr r0, [int_vector_base]
106+
107+
; write page table base
108+
mov r0, pt_l1_base
109+
sr r0, [MMU_RTP0]
110+
111+
MMUV48_SET_TSZ_TO_16
112+
113+
; Test 01
114+
; Normal pushdl/popdl execution inside a mapped region
115+
;
116+
prep_test_case
117+
MMUV6_ENABLE
118+
119+
mov sp, 0x400001000
120+
pushdl_s r0
121+
popdl_s r0
122+
xor.f 0, sp, 0x400001000
123+
bne @fail
124+
125+
MMUV6_DISABLE
126+
127+
; Test 02
128+
; popdl at the beginning of empty page
129+
; expected EFA = boundary
130+
set_except_handler @test_02_tlbmissd_handler
131+
132+
prep_test_case
133+
MMUV6_ENABLE
134+
135+
mov sp, 0x40003000
136+
test_02_tlbmissd:
137+
popdl_s r0
138+
b @fail
139+
140+
; Expected results:
141+
test_02_tlbmissd_handler:
142+
movl r8, EV_DMMUFAULT_1 ; ecr
143+
movl r9, @test_02_tlbmissd ; eret
144+
movl r10, 0x40003000 ; efa
145+
movl r11, @test_02_end ; new eret
146+
147+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
148+
149+
test_02_end:
150+
; Fall through
151+
152+
MMUV6_DISABLE
153+
154+
; Test 03
155+
; popdl at 4 bytes before beginning of empty page
156+
; expected EFA = boundary
157+
set_except_handler @test_03_tlbmissd_handler
158+
159+
prep_test_case
160+
MMUV6_ENABLE
161+
162+
mov sp, 0x40002ffc
163+
test_03_tlbmissd:
164+
popdl_s r0
165+
b @fail
166+
167+
; Expected results:
168+
test_03_tlbmissd_handler:
169+
movl r8, EV_DMMUFAULT_1 ; ecr
170+
movl r9, @test_03_tlbmissd ; eret
171+
movl r10, 0x40003000 ; efa
172+
movl r11, @test_03_end ; new eret
173+
174+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
175+
176+
test_03_end:
177+
; Fall through
178+
179+
MMUV6_DISABLE
180+
181+
; Test 04
182+
; popdl at 8 bytes before beginning of empty page
183+
; expected EFA = boundary
184+
set_except_handler @test_04_tlbmissd_handler
185+
186+
prep_test_case
187+
MMUV6_ENABLE
188+
189+
mov sp, 0x40002ff8
190+
test_04_tlbmissd:
191+
popdl_s r0
192+
b @fail
193+
194+
; Expected results:
195+
test_04_tlbmissd_handler:
196+
movl r8, EV_DMMUFAULT_1 ; ecr
197+
movl r9, @test_04_tlbmissd ; eret
198+
movl r10, 0x40003000 ; efa
199+
movl r11, @test_04_end ; new eret
200+
201+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
202+
203+
test_04_end:
204+
; Fall through
205+
206+
MMUV6_DISABLE
207+
208+
; Test 05
209+
; popdl at 12 bytes before beginning of empty page
210+
; expected EFA = boundary
211+
set_except_handler @test_05_tlbmissd_handler
212+
213+
prep_test_case
214+
MMUV6_ENABLE
215+
216+
mov sp, 0x40002ff4
217+
test_05_tlbmissd:
218+
popdl_s r0
219+
b @fail
220+
221+
; Expected results:
222+
test_05_tlbmissd_handler:
223+
movl r8, EV_DMMUFAULT_1 ; ecr
224+
movl r9, @test_05_tlbmissd ; eret
225+
movl r10, 0x40003000 ; efa
226+
movl r11, @test_05_end ; new eret
227+
228+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
229+
230+
test_05_end:
231+
; Fall through
232+
233+
MMUV6_DISABLE
234+
235+
; Test 06
236+
; pushdl 4 bytes after beginning of empty page
237+
; expected EFA = boundary-12
238+
set_except_handler @test_06_tlbmissd_handler
239+
240+
prep_test_case
241+
MMUV6_ENABLE
242+
243+
mov sp, 0x40004004
244+
test_06_tlbmissd:
245+
pushdl_s r0
246+
b @fail
247+
248+
; Expected results:
249+
test_06_tlbmissd_handler:
250+
movl r8, EV_DMMUFAULT_2 ; ecr
251+
movl r9, @test_06_tlbmissd ; eret
252+
movl r10, 0x40003ff4 ; efa
253+
movl r11, @test_06_end ; new eret
254+
255+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
256+
257+
test_06_end:
258+
; Fall through
259+
260+
MMUV6_DISABLE
261+
262+
; Test 07
263+
; pushdl 8 bytes after beginning of empty page
264+
; expected EFA = boundary-8
265+
set_except_handler @test_07_tlbmissd_handler
266+
267+
prep_test_case
268+
MMUV6_ENABLE
269+
270+
mov sp, 0x40004008
271+
test_07_tlbmissd:
272+
pushdl_s r0
273+
b @fail
274+
275+
; Expected results:
276+
test_07_tlbmissd_handler:
277+
movl r8, EV_DMMUFAULT_2 ; ecr
278+
movl r9, @test_07_tlbmissd ; eret
279+
movl r10, 0x40003ff8 ; efa
280+
movl r11, @test_07_end ; new eret
281+
282+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
283+
284+
test_07_end:
285+
; Fall through
286+
287+
MMUV6_DISABLE
288+
289+
; Test 08
290+
; pushdl 12 bytes after beginning of empty page
291+
; expected EFA = boundary-4
292+
set_except_handler @test_08_tlbmissd_handler
293+
294+
prep_test_case
295+
MMUV6_ENABLE
296+
297+
mov sp, 0x4000400c
298+
test_08_tlbmissd:
299+
pushdl_s r0
300+
b @fail
301+
302+
; Expected results:
303+
test_08_tlbmissd_handler:
304+
movl r8, EV_DMMUFAULT_2 ; ecr
305+
movl r9, @test_08_tlbmissd ; eret
306+
movl r10, 0x40003ffc ; efa
307+
movl r11, @test_08_end ; new eret
308+
309+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
310+
311+
test_08_end:
312+
; Fall through
313+
314+
MMUV6_DISABLE
315+
316+
; Test 09
317+
; pushdl 1 byte after beginning of empty page
318+
; MisalignedAccess exception
319+
set_except_handler @test_09_mc_handler
320+
321+
prep_test_case
322+
MMUV6_ENABLE
323+
324+
mov sp, 0x40004001
325+
test_09_mc:
326+
pushdl_s r0
327+
b @fail
328+
329+
; Expected results:
330+
test_09_mc_handler:
331+
movl r8, MISALIGNED_DATA_ACCESS ; ecr
332+
movl r9, @test_09_mc ; eret
333+
movl r10, 0x40003ff1 ; efa
334+
movl r11, @test_09_end ; new eret
335+
336+
BASE_EXCEPTION_CHECK r8, r9, r10, r11
337+
338+
test_09_end:
339+
; Fall through
340+
341+
MMUV6_DISABLE
342+
343+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reporting ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
344+
345+
valhalla:
346+
MMUV6_DISABLE
347+
print "[PASS]"
348+
mov r1, 0xdecaf ; for now: good value in nSIM tracing
349+
b @1f
350+
351+
; If a test fails, it jumps here. Although, for the sake of uniformity,
352+
; the printed output does not say much about which test case failed,
353+
; one can uncomment the print_number line below or set a breakpoint
354+
; here to check the R0 register for the test case number.
355+
fail:
356+
MMUV6_DISABLE
357+
print "[FAIL]"
358+
mov r1, 0xbadcafe ; for now: bad value in nSIM tracing
359+
ld r0, [test_nr]
360+
;print_number r0
361+
1:
362+
;flag 0x1 ; for now: nSIM ends here
363+
;brk
364+
print " MMUv48_07: pushdl/popdl MMU tests\n"
365+
end

0 commit comments

Comments
 (0)