Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / diag / assembly / arch / prm / interrupt / interrupt_pci_INTx_all_threads.s
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: interrupt_pci_INTx_all_threads.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 MAIN_PAGE_HV_ALSO
39#define ENABLE_PCIE_LINK_TRAINING
40
41#define H_HT0_Interrupt_0x60
42#define My_HT0_Interrupt_0x60 \
43 call my_trap_code; \
44 nop; \
45 retry; \
46 nop;
47
48#include "hboot.s"
49#include "peu_defines.h"
50#include "ncu_defines.h"
51#include "cmp_macros.h"
52
53
54/************************************************************************
55 Test case code start
56 ************************************************************************/
57.text
58.global main
59
60main:
61 ta T_CHANGE_HPRIV
62 nop
63
64 ! Initialize the global registers.
65 mov %g0, %g1
66 mov %g0, %g2
67 mov %g0, %g3
68 mov %g0, %g4
69 mov %g0, %g5
70 mov %g0, %g6
71 mov %g0, %g7
72
73 ta T_RD_THID
74 mov %o1, %g6 ! %o1, %g6 = thread ID
75 set 8, %l7
76 umul %g6, %l7, %l7
77 setx user_data_start, %g1, %g3
78 add %l7, %g3, %g7 ! %g7 = pointer to thread's data area
79
80 cmp %g6, 0x0
81 be main_t0 ! branch if tread 0
82 nop
83 ba main_t1_to_t63 ! branch if not thread 0
84 nop
85
86
87!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
88!
89! Thread 0 Start Here
90!
91!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
92
93main_t0:
94 stx %g0, [%g7] ! Clear this thread's interrupt count
95 membar #Sync
96
97/* Initialize the NCU for the interrupt. */
98
99 ! Disable interrupts
100
101no_intr:
102 rdpr %pstate, %g7
103 xor %g7, 0x2, %g7 ! Reset interrupt enable
104 wrpr %g7, %pstate
105
106 ! Initially set all the Interrupt Management Registers
107 ! Not used in this diag, so set vector number to 0, thread to 0.
108ncu_init:
109 setx INT_MAN, %g1, %g2 ! %g2 = INT_MAN reg. addr.
110 setx INT_MAN_COUNT, %g1, %g4 ! %g4 = INT_MAN reg. count value
111
112ncu_init_loop_top:
113 stx %g0, [%g2]
114 add %g2, INT_MAN_STEP, %g2
115 cmp %g4, 1
116 bne ncu_init_loop_top
117 add %g4, -1, %g4
118
119 ! Initialize Mondo Interrupt Vector Register
120 ! VECTOR = 63
121
122ncu_mondo_int_vec:
123 set 63, %g1
124 setx MONDO_INT_VEC, %g2, %g3
125 stx %g1, [%g3]
126
127 ! Clear Mondo Interrupt Busy registers.
128
129ncu_mondo_int_busy:
130 setx MONDO_INT_BUSY, %g1, %g2
131 setx MONDO_INT_BUSY_STEP, %g1, %g3
132 setx MONDO_INT_BUSY_COUNT, %g1, %g4
133
134ncu_mondo_int_busy_loop_top:
135 stx %g0, [%g2]
136 add %g2, %g3, %g2
137 cmp %g4, 1
138 bne ncu_mondo_int_busy_loop_top
139 dec %g4
140
141 ! Initialize for INTA interrupt in DMU/PEU
142 ! First clear INTA in case one pending.
143
144peu_inta_clear:
145 setx PCI_E_INT_A_CLEAR_ADDR, %g1, %g2
146 set 1, %g3
147 stx %g3, [%g2]
148
149 ! Also clear in Interrupt Clear reg.
150
151peu_intr_clear:
152 setx PCI_E_INT_CLEAR_ADDR, %g1, %g2
153 stx %g0, [%g2]
154
155 ! Now enable INTA in DMU/PEU and set destination thread
156
157peu_inta_enable:
158 setx PCI_E_INT_MAP_ADDR, %g1, %g7
159 setx 0x80000040, %g1, %g6 ! valid = 1, thread id = 0
160#ifdef PORTABLE_CORE
161 ldxa [%g0]ASI_INTR_ID, %o2 ! get full thread ID
162 and %o2, 0x38, %o3 ! get thread 0 of this core
163 sllx %o3, 25, %o3
164 or %g6, %o3, %g6
165#endif
166 stx %g6, [%g7] ! interrupt controller = 1
167
168 ! Enable interrupts
169
170yes_intr:
171 rdpr %pstate, %g7
172 or %g7, 0x2, %g7 ! Set interrupt enable
173 wrpr %g7, %pstate
174
175
176 /* Sync up all the treads. */
177
178#ifndef PORTABLE_CORE
179sync_t0:
180 SYNC_THREAD_MAIN( local_test_failed, %g1, %g2, %g3 )
181#else
182 cmp_sync_threads
183#endif
184
185
186 ! Kick off first interrupt, trap handler kicks off rest
187
188first_inta_intr:
189 ! user event to generate ASSERT_INTA msg.
190 nop ! $EV trig_pc_d(1, @VA(.MAIN.first_inta_intr)) -> EnablePCIeIgCmd ("INTA", 0, 0, "ASSERT", 64'd1, *, * )
191
192 /* Wait for interrupt to occur. */
193
194intr_wait:
195#ifdef DTM_ENABLED
196 setx 0x2000, %g1, %g2 ! DTM timeout count
197#else
198 setx 0x800, %g1, %g2 ! timeout count
199#endif
200 ta T_RD_THID ! %o1 = thread id
201 set 8, %g7
202 umul %o1, %g7, %g7
203 setx user_data_start, %g1, %g3
204 add %g7, %g3, %g7 ! %g7 = pointer to thread's data area
205
206intr_wait_loop_top:
207 ldx [%g7], %g5
208 cmp %g5, 1
209 be t0_new_intr
210 dec %g2
211
212 cmp %g2, 0
213 bne intr_wait_loop_top
214 nop
215 ba local_test_failed
216 nop
217
218 ! Kick off next INTA interrupt
219
220t0_new_intr:
221 ! user event for ASSERT_INTA msg.
222 nop ! $EV trig_pc_d(1, @VA(.MAIN.t0_new_intr)) -> EnablePCIeIgCmd ("INTA", 0, 0, "ASSERT", 64'd1, *, * )
223
224 ba test_passed
225 nop
226
227
228
229
230!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
231!
232! All Threads Except 0 Start Here
233!
234!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
235
236
237main_t1_to_t63:
238 stx %g0, [%g7] ! Clear this thread's interrupt count
239 membar #Sync
240
241#ifndef PORTABLE_CORE
242 SYNC_THREAD_OTHER( %g6,%g1,%g2 )
243#else
244 cmp_sync_threads
245#endif
246
247 /* Wait for interrupt to occur. */
248
249t1_t63_intr_wait:
250#ifdef DTM_ENABLED
251 setx 0x10000, %g1, %g2 ! DTM timeout count
252#else
253 setx 0x4000, %g1, %g2 ! timeout count
254#endif
255 ta T_RD_THID ! %o1 = thread id
256 set 8, %g7
257 umul %o1, %g7, %g7
258 setx user_data_start, %g1, %g3
259 add %g7, %g3, %g7 ! %g7 = pointer to thread's data area
260
261t1_t63_intr_wait_loop_top:
262 ldx [%g7], %g5
263 cmp %g5, 1
264 be t1_t63_last
265 dec %g2
266
267 cmp %g2, 0
268 bne t1_t63_intr_wait_loop_top
269 nop
270 ba local_test_failed
271 nop
272
273 ! Kick off next INTA interrupt, if not in last thread
274
275t1_t63_last:
276 ta T_RD_THID
277#ifndef PORTABLE_CORE
278 cmp %o1, 63
279#else
280 ldxa [%g0]ASI_INTR_ID, %o2 ! get full thread ID
281 and %o2, 0x7, %o3
282 cmp %o3, 7
283#endif
284 be test_passed
285 nop
286
287t1_t63_new_intr:
288 ! user event for ASSERT_INTA msg.
289 nop ! $EV trig_pc_d(1, @VA(.MAIN.t1_t63_new_intr)) -> EnablePCIeIgCmd ("INTA", 0, 0, "ASSERT", 64'd1, *, * )
290
291 ba test_passed
292 nop
293
294
295test_passed:
296 EXIT_GOOD
297
298local_test_failed:
299 EXIT_BAD
300
301
302/**********************************************************************
303 Interrupt trap handler.
304**********************************************************************/
305
306.global my_trap_code
307
308my_trap_code:
309
310 ! Get the thread id.
311 ta T_RD_THID ! %o1 = thread id
312 ldxa [%g0]ASI_INTR_ID, %o2 ! get full thread ID
313 set 8, %l7
314 umul %o1, %l7, %l7
315 setx user_data_start, %l1, %l3
316 add %l7, %l3, %l7 ! %l7 = pointer to thread's data area
317
318 ! Has interrupt to this thread already occured?
319
320trap_mult_intr:
321 ldx [%l7], %l1
322 cmp %l1, 0
323 bne local_test_failed
324 nop
325
326 ! Record interrupt occured for this thread.
327
328trap_intr_flag:
329 set 1, %l1
330 stx %l1, [%l7]
331
332 ! Check Mondo Interrupt Busy reg. for this thread
333
334trap_mondo_busy:
335 setx MONDO_INT_BUSY, %l1, %l2
336 setx MONDO_INT_BUSY_STEP, %l1, %l3
337 mulx %l3, %o2, %l3
338 add %l3, %l2, %l2
339 ldx [%l2], %l4
340 and %l4, 0x40, %l5 ! Is busy bit set?
341 cmp %l5, 0
342 be local_test_failed
343 nop
344
345 ! Check Mondo Interrupt Alias Busy reg.
346
347trap_mondo_abusy:
348 setx MONDO_INT_ABUSY, %l1, %l2
349 ldx [%l2], %l3
350 cmp %l3, %l4 ! ABUSY = BUSY ?
351 bne local_test_failed
352 nop
353
354 ! Check Mondo Interrupt Data 0/1 against Mondo Interrupt Alias Data 0/1
355
356trap_mondo_data0:
357 setx MONDO_INT_DATA0, %l1, %l2
358 setx MONDO_INT_DATA0_STEP, %l1, %l3
359 mulx %l3, %o2, %l3
360 add %l3, %l2, %l2
361 ldx [%l2], %l0 ! %l0 = mondo_int_busy0
362
363trap_mondo_adata0:
364 setx MONDO_INT_ADATA0, %l1, %l4 ! %l5 = mondo_int_abusy0
365 ldx [%l4], %l5
366 cmp %l5, %l0
367 bne local_test_failed
368 nop
369
370trap_mondo_data1:
371 setx MONDO_INT_DATA1, %l1, %l2
372 setx MONDO_INT_DATA1_STEP, %l1, %l3
373 mulx %l3, %o2, %l3
374 add %l3, %l2, %l2
375 ldx [%l2], %l0 ! %l0 = mondo_int_busy1
376
377trap_mondo_adata1:
378 setx MONDO_INT_ADATA1, %l1, %l4 ! %l5 = mondo_int_abusy1
379 ldx [%l4], %l5
380 cmp %l5, %l0
381 bne local_test_failed
382 nop
383
384 ! Check INTA status in DMU/PEU
385
386 ! Interrupt Clear reg.
387
388trap_peu_intr_clear:
389 setx PCI_E_INT_CLEAR_ADDR, %l1, %l2
390 ldx [%l2], %l0
391 cmp %l0, 3 ! Should be in pending state
392 bne local_test_failed
393 nop
394
395trap_peu_inta_status:
396 setx PCI_E_INTX_STATUS_ADDR, %l1, %l2
397 ldx [%l2], %l0
398 cmp %l0, 8 ! INTA should be only one active
399 bne local_test_failed
400 nop
401
402trap_peu_inta_clear:
403 setx PCI_E_INT_A_CLEAR_ADDR, %l1, %l2
404 ldx [%l2], %l0
405 cmp %l0, 1 ! INTA should be active
406 bne local_test_failed
407 nop
408
409 ! Clear the INTA interrupt in the DMU/PEU
410
411trap_inta_clear:
412 ! user event for INTA deassert msg.
413 nop ! $EV trig_pc_d(1, @VA(.MAIN.trap_inta_clear)) -> EnablePCIeIgCmd ("INTA", 0, 0, "DEASSERT", 64'd1, *, * )
414
415 ! Check the INTA status in INTA Clear reg.
416
417#ifdef DTM_ENABLED
418 setx 0x400, %l0, %l1 ! DTM Timeout count
419#else
420 setx 0x100, %l0, %l1 ! Timeout count
421#endif
422 setx PCI_E_INT_A_CLEAR_ADDR, %l0, %l2
423
424trap_inta_clear_loop_top:
425 ldx [%l2], %l0
426 cmp %l0, 0 ! Waiting for idle state
427 be trap_inta_clear_done
428 nop
429 cmp %l1, 1
430 be local_test_failed ! Timeout check
431 dec %l1
432 ba trap_inta_clear_loop_top
433 nop
434
435 ! Check other DMU/PEU INTA registers
436
437trap_inta_clear_done:
438 setx PCI_E_INTX_STATUS_ADDR, %l1, %l2
439 ldx [%l2], %l0
440 cmp %l0, 0 ! All should be inactive
441 bne local_test_failed
442 nop
443
444 ! Interrupt Clear reg.
445
446trap_intr_clear:
447 setx PCI_E_INT_CLEAR_ADDR, %g1, %g2
448 stx %g0, [%g2]
449
450 ! Clear the mondo interrupt in the NCU
451
452trap_mondo_intr_clear:
453 setx MONDO_INT_ABUSY, %l0, %l1
454 stx %g0, [%l1]
455 membar #Sync
456
457 ldx [%l1], %l2
458 and %l2, 0x40, %l2
459 cmp %l2, 0 ! Busy should be cleared
460 bne local_test_failed
461 nop
462
463 ! Clear the interrupt in the core
464
465trap_asi_intr_r_clear:
466 ldxa [%g0]ASI_SWVR_INTR_R, %l5
467 cmp %l5, 63 ! check for correct vector number
468 bne local_test_failed
469 nop
470
471 ! Increment the thread to send next interrupt to.
472
473trap_inc_thread:
474 setx PCI_E_INT_MAP_ADDR, %l0, %l7
475 setx 0x2000000, %l0, %l5
476 ldx [%l7], %l6
477 addx %l6, %l5, %l6
478 stx %l6, [%l7]
479 membar #Sync
480
481 ! Done.
482
483trap_done:
484 jmpl %o7+0x8, %g0
485 nop
486
487
488
489/************************************************************************
490 Test case data start
491************************************************************************/
492
493.align 1024
494.data
495user_data_start:
496 .word 0xffffffff
497 .word 0xffffffff
498 .word 0xffffffff
499 .word 0xffffffff
500user_data_end:
501.end
502
503/************************************************************************/