1# Blackfin testcase for returning to the right place while bouncing between
2# multiple CEC levels (like in a Linux system call)
3# mach: bfin
4# sim: --environment operating
5
6#include "test.h"
7	.include "testutils.inc"
8
9	# This test keeps P5 as the base of the EVT table
10
11	.macro set_evt lvl:req, sym:req
12	loadsym R1, \sym;
13	[P5 + 4 * \lvl\()] = R1;
14	.endm
15
16	start
17
18	# First mark all EVTs as fails (they shouldn't be activated)
19	imm32 P5, EVT0;
20	P1 = P5;
21	loadsym R1, fail_lvl
22	imm32 P2, 16
23	LSETUP (1f, 1f) LC0 = P2;
241:	[P1++] = R1;
25
26	# The OS exception handler
27	set_evt 3, _evx;
28	# The OS system call handler
29	set_evt 15, _evt15;
30
31	# Lower ourselves to userspace
32	loadsym R1, _user;
33	loadsym R2, _next_user;
34	RETI = R1;
35	R7 = -1;
36	sti R7;
37	RTI;
38
39_user:
40	EXCPT 0;
41_next_user:
42	dbg_pass
43
44_evx:
45	# RETX should be pointing to the right place
46	R1 = RETX;
47	CC = R1 == R2;
48	IF !CC JUMP fail_lvl;
49
50	# Lower ourselves to the system call handler
51	RAISE 15;
52	RTX;
53
54_evt15:
55	# RETI should be pointing to the right place
56	R1 = RETI;
57	CC = R1 == R2;
58	IF !CC JUMP fail_lvl;
59
60	# Return to userspace now
61	RTI;
62
63fail_lvl:
64	dbg_fail
65