Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / diag / assembly / arch / prm / interrupt / interrupt_dmu_cntrl_stall.s
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: interrupt_dmu_cntrl_stall.s
5* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
6* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
7*
8* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9*
10* This program is free software; you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation; version 2 of the License.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License
20* along with this program; if not, write to the Free Software
21* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22*
23* For the avoidance of doubt, and except that if any non-GPL license
24* choice is available it will apply instead, Sun elects to use only
25* the General Public License version 2 (GPLv2) at this time for any
26* software where a choice of GPL license versions is made
27* available with the language indicating that GPLv2 or any later version
28* may be used, or where a choice of which version of the GPL is applied is
29* otherwise unspecified.
30*
31* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
32* CA 95054 USA or visit www.sun.com if you need additional information or
33* have any questions.
34*
35*
36* ========== Copyright Header End ============================================
37*/
38#define HBOOT_HV_ONLY
39#define ENABLE_PCIE_LINK_TRAINING
40
41#define ENABLE_INTR0x60 1
42
43#define INTR0x60_EVENT_QUEUE_BASE event_queue_base
44#define INTR0x60_MSI_START_ADDRESS 0x0
45
46#define INTR0x60_MONDO_IV 7
47
48#define INTR0x60_MSI_0_NUM 100
49#define INTR0x60_MSI_0_EQN 16
50#define INTR0x60_MONDO_40_V 1
51#define INTR0x60_MONDO_40_MODE 1
52#define INTR0x60_MONDO_40_THREAD 0
53#define INTR0x60_MONDO_40_CNTRL 0
54
55#define INTR0x60_MSI_1_NUM 101
56#define INTR0x60_MSI_1_EQN 17
57#define INTR0x60_MONDO_41_V 1
58#define INTR0x60_MONDO_41_MODE 1
59#define INTR0x60_MONDO_41_THREAD 0
60#define INTR0x60_MONDO_41_CNTRL 0
61
62#define INTR0x60_MSI_2_NUM 102
63#define INTR0x60_MSI_2_EQN 18
64#define INTR0x60_MONDO_42_V 1
65#define INTR0x60_MONDO_42_MODE 1
66#define INTR0x60_MONDO_42_THREAD 1
67#define INTR0x60_MONDO_42_CNTRL 1
68
69#define INTR0x60_MSI_3_NUM 103
70#define INTR0x60_MSI_3_EQN 19
71#define INTR0x60_MONDO_43_V 1
72#define INTR0x60_MONDO_43_MODE 1
73#define INTR0x60_MONDO_43_THREAD 2
74#define INTR0x60_MONDO_43_CNTRL 2
75
76#define INTR0x60_MSI_4_NUM 104
77#define INTR0x60_MSI_4_EQN 20
78#define INTR0x60_MONDO_44_V 1
79#define INTR0x60_MONDO_44_MODE 1
80#define INTR0x60_MONDO_44_THREAD 3
81#define INTR0x60_MONDO_44_CNTRL 3
82
83/* Kick off the other MSIs and then stall */
84#define INTR0x60_MSI_0_EXTRA_HANDLER_WHILE_BUSY \
85 call t0_mondo40_handler; \
861: nop
87
88/* Calculate the address for this INO (%g3) in mondo_seen.
89 * Has interrupt to this INO already occured?
90 * Record the interrupt as done. */
91#define INTR0x60_MSI_EXTRA_HANDLER \
92 setx mondo_seen, %g7, %g4; \
93 add %g3, %g4, %g4; \
94 ldub [%g4], %g5; \
95 brz %g5, 1f; \
96 set 1, %g6; \
97 EXIT_BAD; \
981: stub %g6, [%g4]
99
100
101#include "interrupt0x60_defines.h"
102
103#define SYNC_THREADS 1
104
105#include "hboot.s"
106
107#include "interrupt0x60_handler.s"
108
109/************************************************************************
110 Test case code start
111 ************************************************************************/
112SECTION .MAIN
113.text
114.global main
115
116main:
117 rdpr %pstate, %g7
118 or %g7, 0x2, %g7 ! Set interrupt enable
119 wrpr %g7, %pstate
120
121 setx iteration_counter, %o1, %o0
122
123 ta T_RD_THID ! %o1 = thread ID
124 brnz %o1, t1_to_t3_main ! branch if not thread 0
125 nop
126
127
128!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
129!
130! Thread 0 Start Here
131!
132!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
133
134t0_main:
135 setx mondo_seen+40, %l7, %i7
136 mov 4, %i6 ! Set the number of iterations
137
138t0_clear_mondo_seen:
139 stb %i6, [%o0] ! iteration counter
140 stb %g0, [%i7] ! Mondo 40
141 stb %g0, [%i7+1] ! Mondo 41
142 stb %g0, [%i7+2] ! Mondo 42
143 stb %g0, [%i7+3] ! Mondo 43
144 stb %g0, [%i7+4] ! Mondo 44
145
146 /* Kick off first interrupt, trap handler kicks off rest */
147t0_kick_msi_0:
148 ! user event to generate MSI msg.
149 nop ! $EV trig_pc_d(1, @VA(.MAIN.t0_kick_msi_0)) -> EnablePCIeIgCmd ("MSI32", eval(INTR0x60_MSI_0_NUM, 16), 0, 4, 1, *, 1 )
150
151 /* Wait for interrupt to occur. */
152t0_intr_wait:
153#ifdef DTM_ENABLED
154 setx 0x400, %l1, %l2 ! DTM timeout count
155#else
156 setx 0x100, %l1, %l2 ! timeout count
157#endif
158
159t0_intr_wait_loop_top:
160 ldub [%i7], %l0
161 cmp %l0, 1
162 be t0_saw_mondo
163 dec %l2
164 brnz %l2, t0_intr_wait_loop_top
165 nop
166t0_timeout:
167 ! $EV trig_pc_d(1, @VA(.MAIN.t0_timeout)) -> printf("ERROR: T0 timeout waiting for mondo 40",*,1)
168 ba local_test_failed
169 nop
170
171t0_saw_mondo:
172 ldub [%i7+2], %l0 ! Check for mondo 42
173 cmp %l0, 1
174 bne t0_missed_mondo_42
175 ldub [%i7+3], %l0 ! Check for mondo 43
176 cmp %l0, 1
177 bne t0_missed_mondo_43
178 ldub [%i7+4], %l0 ! Check for mondo 44
179 cmp %l0, 1
180 bne t0_missed_mondo_44
181
182 mov 100, %l2
183t0_wait_for_mondo_41:
184 brz %l2, t0_missed_mondo_41
185 dec %l2
186 ldub [%i7+1], %l0 ! Check for mondo 41
187 cmp %l0, 1
188 bne t0_wait_for_mondo_41
189 nop
190
191t0_iteration_passed:
192 dec %i6
193 brz %i6, t0_done
194
195t0_setup_next_iteration:
196 /* Rotate controllers and run it again */
197 best_set_reg(mpeval(PCI_E_INT_MAP_ADDR+PCI_E_INT_MAP_STEP*(40-20)),
198 %l1, %l2)
199 mov 5, %l7 /* Number of mondos that need fixing */
200 mov 0xf, %l6
201 sllx %l6, PCI_E_INT_MAP_INT_CNTRL_NUM_SHIFT, %l6
202t0_setup_next_iteration_top:
203 ldx [%l2], %l3
204 and %l3, %l6, %l4 /* Isolate the controller value */
205 sllx %l4, 1, %l4 /* Generate new controller value */
206 andcc %l4, %l6, %g0 /* Check for 0000 value */
207 bne %xcc, 1f
208 andn %l3, %l6, %l3 /* Clear previous controller value */
209 srlx %l4, 4, %l4 /* Correct for 0000 value */
2101: or %l4, %l3, %l3 /* Merge new value with old CSR value */
211 stx %l3, [%l2]
212
213 dec %l7
214 brnz %l7, t0_setup_next_iteration_top
215 add %l2, PCI_E_INT_MAP_STEP, %l2
216
217 ba t0_clear_mondo_seen
218 nop
219
220 !Done
221t0_done:
222 stx %g0, [%o0] ! Signal other threads that we are done
223 ba test_passed
224 nop
225
226.global t0_mondo40_handler
227t0_mondo40_handler: /* This is called from the trap handler */
228 ! $EV trig_pc_d(1, @VA(.MAIN.t0_mondo40_handler)) -> EnablePCIeIgCmd ("MSI32", eval(INTR0x60_MSI_1_NUM, 16), 0, 4, 1, *, 1 )
229 nop
230t0_mondo40_handler_kick_msi_2:
231 ! $EV trig_pc_d(1, @VA(.MAIN.t0_mondo40_handler_kick_msi_2)) -> EnablePCIeIgCmd ("MSI32", eval(INTR0x60_MSI_2_NUM, 16), 0, 4, 1, *, 1 )
232 nop
233t0_mondo40_handler_kick_msi_3:
234 ! $EV trig_pc_d(1, @VA(.MAIN.t0_mondo40_handler_kick_msi_3)) -> EnablePCIeIgCmd ("MSI32", eval(INTR0x60_MSI_3_NUM, 16), 0, 4, 1, *, 1 )
235 nop
236t0_mondo40_handler_kick_msi_4:
237 ! $EV trig_pc_d(1, @VA(.MAIN.t0_mondo40_handler_kick_msi_4)) -> EnablePCIeIgCmd ("MSI32", eval(INTR0x60_MSI_4_NUM, 16), 0, 4, 1, *, 1 )
238
239/* Wait for the new interrupts to arrive and be processed by other threads */
240#ifdef DTM_ENABLED
241 mov 800, %g7 ! Set the maximum time to wait, DTM
242#else
243 mov 200, %g7 ! Set the maximum time to wait
244#endif
245t0_mondo40_handler_loop_top:
246 brz %g7, t0_mondo40_handler_loop_timeout
247 dec %g7
248 setx mondo_seen+42, %g5, %g6
249 ldub [%g6], %g5
250 brz %g5, t0_mondo40_handler_loop_top
251 ldub [%g6+1], %g5
252 brz %g5, t0_mondo40_handler_loop_top
253 ldub [%g6+2], %g5
254 brz %g5, t0_mondo40_handler_loop_top
255 nop
256/* If we fall to here, all 3 other interrupts have been processed */
257t0_mondo40_handler_retl:
258 retl
259 nop
260
261t0_mondo40_handler_loop_timeout:
262 ! $EV trig_pc_d(1, @VA(.MAIN.t0_mondo40_handler_loop_timeout)) -> printf("ERROR: T0 timeout waiting for mondos 42 thru 44 to be processed",*,1)
263 ba local_test_failed
264 nop
265
266t0_missed_mondo_41:
267 ! $EV trig_pc_d(1, @VA(.MAIN.t0_missed_mondo_41)) -> printf("ERROR: T0 missed mondo 41",*,1)
268 ba local_test_failed
269 nop
270
271t0_missed_mondo_42:
272 ! $EV trig_pc_d(1, @VA(.MAIN.t0_missed_mondo_42)) -> printf("ERROR: T0 missed mondo 42",*,1)
273 ba local_test_failed
274 nop
275
276t0_missed_mondo_43:
277 ! $EV trig_pc_d(1, @VA(.MAIN.t0_missed_mondo_43)) -> printf("ERROR: T0 missed mondo 43",*,1)
278 ba local_test_failed
279 nop
280
281t0_missed_mondo_44:
282 ! $EV trig_pc_d(1, @VA(.MAIN.t0_missed_mondo_44)) -> printf("ERROR: T0 missed mondo 44",*,1)
283 ba local_test_failed
284 nop
285
286!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
287!
288! All Threads Except 0 Start Here
289!
290!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
291
292
293t1_to_t3_main:
294 setx mondo_seen+41, %l7, %i7
295 add %i7, %o1, %i7 ! add thread number to get mondo number
296
297 /* Wait for interrupt to occur. */
298t1_t3_intr_wait:
299#ifdef DTM_ENABLED
300 setx 0x400, %l1, %l2 ! DTM timeout count
301#else
302 setx 0x100, %l1, %l2 ! timeout count
303#endif
304
305t1_t3_intr_wait_loop_top:
306 ldub [%i7], %l0
307 cmp %l0, 1
308 be t1_t3_saw_mondo
309 dec %l2
310 brnz %l2, t1_t3_intr_wait_loop_top
311 nop
312
313t1_t3_timeout:
314 ! $EV trig_pc_d(1, @VA(.MAIN.t1_t3_timeout)) -> printf("ERROR: T1-T3 timeout waiting for mondo",*,1)
315 ba local_test_failed
316 nop
317
318t1_t3_saw_mondo:
319 /* Check if thread 0 has cleared the iteration count */
320 ldub [%o0], %o2
321 brz %o2, t1_t3_done
322 /* If thread 0 has cleared the "mondo seen" flag,
323 * loop again for next controller settings */
324 ldub [%i7], %l0
325 brz %l0, t1_t3_intr_wait
326 nop
327 /* Otherwise, keep looping */
328 ba t1_t3_saw_mondo
329 nop
330
331 !Done
332t1_t3_done:
333 ba test_passed
334 nop
335
336
337test_passed:
338 EXIT_GOOD
339
340local_test_failed:
341 EXIT_BAD
342
343
344
345
346/************************************************************************
347 Test case data start
348************************************************************************/
349
350.align 1024
351.data
352user_data_start:
353iteration_counter: .byte 4 ! Number of controller configs left to do
354
355.global mondo_seen
356mondo_seen: ! One byte per mondo
357 .skip 60, 0 ! Start with virtual mondo 0 for easy math
358
359.align eval(512*1024)
360.global event_queue_base
361event_queue_base:
362 .skip 1024
363user_data_end:
364.end
365
366/************************************************************************/