aboutsummaryrefslogtreecommitdiff
path: root/sim/testsuite/bfin/cec-multi-pending.S
blob: 63f3780905872ddae580efac070eb21a2050ff8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# Blackfin testcase for multiple pending IVGs vs masked state
# mach: bfin
# sim: --environment operating

#include "test.h"
	.include "testutils.inc"

	# This test keeps P5 as the base of the EVT table

	.macro set_evt lvl:req, sym:req
	loadsym R1, \sym;
	[P5 + 4 * \lvl\()] = R1;
	.endm

	.macro check_cec mmr:req, valid:req
	imm32 P3, \mmr;
	R0 = [P3];
	R1 = ~0x1f;
	R0 = R0 & R1;
	imm32 R1, \valid;
	CC = R1 == R0;
	IF CC JUMP 1f;
	dbg_fail
1:
	.endm

	.macro delay cnt:req
	imm32 P2, \cnt
	LSETUP (1f, 1f) LC1 = P2;
1:	mnop;
	.endm

	start

	# First mark all EVTs as fails (they shouldn't be activated)
	imm32 P5, EVT0;
	P1 = P5;
	loadsym R1, fail_lvl
	imm32 P2, 16
	LSETUP (1f, 1f) LC0 = P2;
1:	[P1++] = R1;

	# Lower ourselves to EVT15
	set_evt 15, evt15;
	R7 = 0 (x);
	BITSET (R7, 15);
	sti R7;
	loadsym R1, wait;
	RETI = R1;
	RAISE 15;
	RTI;

wait:
	jump wait;

evt15:
	# We shouldn't come back here
	set_evt 15, fail_lvl;

	# Activate interrupt nesting early
	[--SP] = RETI;

	# Raise some higher levels, but they should be masked and so
	# they should never be activated ...
	RAISE 6;
	RAISE 5;
	RAISE 9;
	RAISE 12;

	# Only IVG15 should be pending
	check_cec IPEND, (1<<15);

	# But all should be latched
	check_cec ILAT, (1<<5) | (1<<6) | (1<<9) | (1<<12);

	# Delay a little in case a higher level wrongly activates
	delay 30

	# If we're still here, things are still good.  So let's
	# transition up *slightly*, but not to the highest latched.
	set_evt 12, evt12;
	cli R7;
	BITSET (R7, 12);
	sti R7;

	# Let CEC raise us to IVG12
	delay 30
	# CEC should have been faster than this ...
	dbg_fail

evt12:
	# We shouldn't come back here
	set_evt 12, fail_lvl;

	# Raise some higher levels, but they should be masked and so
	# they should never be activated ...
	RAISE 11;

	# Both IVG15 and IVG12 should be pending
	check_cec IPEND, (1<<15) | (1<<12);

	# But all should be latched
	check_cec ILAT, (1<<5) | (1<<6) | (1<<9) | (1<<11);

	# Activate interrupt nesting a little later
	[--SP] = RETI;

	# Still here, so unmask a higher IVG again to move up
	set_evt 9, evt9;
	cli R7;
	BITSET (R7, 9);
	sti R7;
	delay 30

	# CEC should have been faster than this ...
	dbg_fail

evt9:
	# We shouldn't come back here
	set_evt 9, fail_lvl;

	# IVG9 should also be pending now
	check_cec IPEND, (1<<15) | (1<<12) | (1<<9);

	# But all should be latched
	check_cec ILAT, (1<<5) | (1<<6) | (1<<11);

	# Unmask the next level, but IPEND[4] is set, so we should stay here
	set_evt 6, evt6;
	cli R7;
	BITSET (R7, 6);
	sti R7;

	# Delay a little in case a higher level wrongly activates
	delay 30

	# Good, now unmask things globally
	[--SP] = RETI;
	delay 30

	# CEC should have been faster than this ...
	dbg_fail

evt6:
	# We shouldn't come back here
	set_evt 6, fail_lvl;

	# IVG6 should also be pending now
	check_cec IPEND, (1<<15) | (1<<12) | (1<<9) | (1<<6);

	# But all should be latched
	check_cec ILAT, (1<<5) | (1<<11);

	# Activate interrupt nesting a little later
	[--SP] = RETI;

	# Unmask the next level, but do it via IMASK
	set_evt 5, evt5;
	imm32 P2, IMASK;
	R7 = [P2];
	BITSET (R7, 5);
	[P2] = R7;
	delay 30

	# CEC should have been faster than this ...
	dbg_fail

evt5:
	# We shouldn't come back here
	set_evt 5, fail_lvl;

	# IVG5 should also be pending now
	check_cec IPEND, (1<<15) | (1<<12) | (1<<9) | (1<<6) | (1<<5);

	# But all should be latched
	check_cec ILAT, (1<<11);

	# All good!
	dbg_pass;

fail_lvl:
	dbg_fail;