Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / diag / assembly / arch / prm / interrupt / interrupt_pci_multiple_INTX.s
CommitLineData
86530b38
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: interrupt_pci_multiple_INTX.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
40#ifdef FC_NO_PEU_VERA
41#include "dmaept_defines.h"
42#else /* FC_NO_PEU_VERA */
43#define ENABLE_PCIE_LINK_TRAINING
44#endif /* FC_NO_PEU_VERA */
45
46#define ENABLE_INTR0x60 1
47
48#define INTR0x60_MONDO_IV 63
49
50#define INTR0x60_MONDO_20_V 1
51#define INTR0x60_MONDO_20_THREAD 0
52#define INTR0x60_MONDO_20_CNTRL 0
53
54#define INTR0x60_MONDO_21_V 1
55#define INTR0x60_MONDO_21_MODE 1
56#define INTR0x60_MONDO_21_THREAD 2
57#define INTR0x60_MONDO_21_CNTRL 1
58
59#define INTR0x60_MONDO_22_V 1
60#define INTR0x60_MONDO_22_MODE 1
61#define INTR0x60_MONDO_22_THREAD 4
62#define INTR0x60_MONDO_22_CNTRL 2
63
64#define INTR0x60_MONDO_23_V 1
65#define INTR0x60_MONDO_23_THREAD 6
66#define INTR0x60_MONDO_23_CNTRL 3
67
68
69#ifdef PORTABLE_CORE
70#define MASK_THREAD_ID and %g1, 0x7, %g1;
71#else
72#define MASK_THREAD_ID /*nothing*/
73#endif /* PORTABLE_CORE */
74#define INTR0x60_INTA_EXTRA_HANDLER \
75 MASK_THREAD_ID \
76 setx intr_count, %g4, %g3; \
77 add %g3, %g1, %g3; \
78 ldub [%g3], %g4; \
79 inc %g4; \
80 stb %g4, [%g3]
81#define INTR0x60_INTB_EXTRA_HANDLER INTR0x60_INTA_EXTRA_HANDLER
82#define INTR0x60_INTC_EXTRA_HANDLER INTR0x60_INTA_EXTRA_HANDLER
83#define INTR0x60_INTD_EXTRA_HANDLER INTR0x60_INTA_EXTRA_HANDLER
84
85#include "interrupt0x60_defines.h"
86
87
88#include "hboot.s"
89#include "peu_defines.h"
90#include "ncu_defines.h"
91#include "cmp_macros.h"
92
93#include "interrupt0x60_handler.s"
94
95
96/************************************************************************
97 Test case code start
98 ************************************************************************/
99SECTION .MAIN
100.text
101.global main
102
103main:
104 ta T_CHANGE_HPRIV
105 nop
106
107 ldxa [%g0] ASI_INTR_ID, %g1 ! Get the thread number
108 MASK_THREAD_ID
109 brnz %g1, main_target
110 nop
111
112
113/**************************************************************/
114/* We are the "source" thread that sends interrupts */
115main_source:
116 /* Set up the MONDO DATA registers to non-zero values so that
117 * we wiggle the data path */
118 best_set_reg(0xAAAAAAAAAAAAAAAA, %l7, %l0)
119 best_set_reg(PCI_E_INT_MONDO_DATA_0_ADDR, %l7, %l2)
120init_mondo_data_0:
121 stx %l0, [%l2]
122 xnor %l0, %g0, %l1
123 best_set_reg(PCI_E_INT_MONDO_DATA_1_ADDR, %l7, %l2)
124init_mondo_data_1:
125 stx %l0, [%l2]
126
127 /* Kick off the interrupts */
128
129send_inta_intr:
130#ifdef FC_NO_PEU_VERA
131 ! Setup ASI - little-endian access to PCI space
132 wr %g0, ASI_NL, %asi
133
134 ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since
135 ! BAR is set that way. Physical addresses generated via TSB
136 ! have this offset so mimic that when accessing directly, as here.
137 best_set_reg(mpeval(N2_PCIE_BASE_ADDR
138 + MEM64_OFFSET_BASE_REG_DATA
139 + PCIE_MEM64_OFFSET
140 + PART_0_BASE
141 + (INTR0x60_MONDO_20_DMAEPT_ENGINE << 8)),
142 %l7, %l2)
143 mov %g0, %i1 /* Address 0 for now */
144 ! Store upper half of address
145 srlx %i1, 32, %l0
146 !setx 0xfffc0000, %l1, %l0 ! Always bypass for now.
147 stwa %l0, [%l2+DMAEPT_DATA_ADDR_UPPER] %asi
148
149 ! Store lower half of address
150 stwa %i1, [%l2+DMAEPT_DATA_ADDR_LOWER] %asi
151
152 ! Store pattern value
153 mov %g0, %i2 /* Pattern 0 */
154 stwa %i2, [%l2+DMAEPT_PATTERN] %asi
155
156 ! Interrupt type
157 best_set_reg(DMAEPT_ENDING_INTERRUPT_INTA, %l7, %l5)
158 stwa %l5, [%l2+DMAEPT_ENDING_INTERRUPT] %asi
159
160 ! Packet size
161 mov 4, %i4 /* Max of 4 DW */
162 stwa %i4, [%l2+DMAEPT_MAX_PYLD] %asi
163
164 ! Tag for MR operations, use engine ID
165 mov INTR0x60_MONDO_20_DMAEPT_ENGINE, %i0
166 stwa %i0, [%l2+DMAEPT_TAG] %asi
167
168 ! Fire the DMA
169 best_set_reg(DMAEPT_OPERATION_MW, %l7, %i1) /* 0-byte write */
170 stwa %i1, [%l2+DMAEPT_OPERATION] %asi
171
172#else /* FC_NO_PEU_VERA */
173 ! user event to generate ASSERT_INTA msg.
174 nop ! $EV trig_pc_d(1, @VA(.MAIN.send_inta_intr)) -> EnablePCIeIgCmd ("INTA", 0, 0, "ASSERT", 64'd1, *, 1 )
175 nop
176 nop
177 nop
178 nop
179#endif /* FC_NO_PEU_VERA */
180
181send_intd_intr:
182#ifdef FC_NO_PEU_VERA
183 ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since
184 ! BAR is set that way. Physical addresses generated via TSB
185 ! have this offset so mimic that when accessing directly, as here.
186 best_set_reg(mpeval(N2_PCIE_BASE_ADDR
187 + MEM64_OFFSET_BASE_REG_DATA
188 + PCIE_MEM64_OFFSET
189 + PART_0_BASE
190 + (INTR0x60_MONDO_23_DMAEPT_ENGINE << 8)),
191 %l7, %l2)
192 mov %g0, %i1 /* Address 0 for now */
193 ! Store upper half of address
194 srlx %i1, 32, %l0
195 !setx 0xfffc0000, %l1, %l0 ! Always bypass for now.
196 stwa %l0, [%l2+DMAEPT_DATA_ADDR_UPPER] %asi
197
198 ! Store lower half of address
199 stwa %i1, [%l2+DMAEPT_DATA_ADDR_LOWER] %asi
200
201 ! Store pattern value
202 mov %g0, %i2 /* Pattern 0 */
203 stwa %i2, [%l2+DMAEPT_PATTERN] %asi
204
205 ! Interrupt type
206 best_set_reg(DMAEPT_ENDING_INTERRUPT_INTD, %l7, %l5)
207 stwa %l5, [%l2+DMAEPT_ENDING_INTERRUPT] %asi
208
209 ! Packet size
210 mov 4, %i4 /* Max of 4 DW */
211 stwa %i4, [%l2+DMAEPT_MAX_PYLD] %asi
212
213 ! Tag for MR operations, use engine ID
214 mov INTR0x60_MONDO_20_DMAEPT_ENGINE, %i0
215 stwa %i0, [%l2+DMAEPT_TAG] %asi
216
217 ! Fire the DMA
218 best_set_reg(DMAEPT_OPERATION_MW, %l7, %i1) /* 0-byte write */
219 stwa %i1, [%l2+DMAEPT_OPERATION] %asi
220
221#else /* FC_NO_PEU_VERA */
222 ! user event to generate ASSERT_INTD msg.
223 nop ! $EV trig_pc_d(1, @VA(.MAIN.send_intd_intr)) -> EnablePCIeIgCmd ("INTD", 0, 0, "ASSERT", 64'd1, *, 1 )
224 nop
225 nop
226 nop
227 nop
228#endif /* FC_NO_PEU_VERA */
229
230send_intb_intr:
231#ifdef FC_NO_PEU_VERA
232 ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since
233 ! BAR is set that way. Physical addresses generated via TSB
234 ! have this offset so mimic that when accessing directly, as here.
235 best_set_reg(mpeval(N2_PCIE_BASE_ADDR
236 + MEM64_OFFSET_BASE_REG_DATA
237 + PCIE_MEM64_OFFSET
238 + PART_0_BASE
239 + (INTR0x60_MONDO_21_DMAEPT_ENGINE << 8)),
240 %l7, %l2)
241 mov %g0, %i1 /* Address 0 for now */
242 ! Store upper half of address
243 srlx %i1, 32, %l0
244 !setx 0xfffc0000, %l1, %l0 ! Always bypass for now.
245 stwa %l0, [%l2+DMAEPT_DATA_ADDR_UPPER] %asi
246
247 ! Store lower half of address
248 stwa %i1, [%l2+DMAEPT_DATA_ADDR_LOWER] %asi
249
250 ! Store pattern value
251 mov %g0, %i2 /* Pattern 0 */
252 stwa %i2, [%l2+DMAEPT_PATTERN] %asi
253
254 ! Interrupt type
255 best_set_reg(DMAEPT_ENDING_INTERRUPT_INTB, %l7, %l5)
256 stwa %l5, [%l2+DMAEPT_ENDING_INTERRUPT] %asi
257
258 ! Packet size
259 mov 4, %i4 /* Max of 4 DW */
260 stwa %i4, [%l2+DMAEPT_MAX_PYLD] %asi
261
262 ! Tag for MR operations, use engine ID
263 mov INTR0x60_MONDO_20_DMAEPT_ENGINE, %i0
264 stwa %i0, [%l2+DMAEPT_TAG] %asi
265
266 ! Fire the DMA
267 best_set_reg(DMAEPT_OPERATION_MW, %l7, %i1) /* 0-byte write */
268 stwa %i1, [%l2+DMAEPT_OPERATION] %asi
269
270#else /* FC_NO_PEU_VERA */
271 ! user event to generate ASSERT_INTB msg.
272 nop ! $EV trig_pc_d(1, @VA(.MAIN.send_intb_intr)) -> EnablePCIeIgCmd ("INTB", 0, 0, "ASSERT", 64'd1, *, 1 )
273 nop
274 nop
275 nop
276 nop
277#endif /* FC_NO_PEU_VERA */
278
279send_intc_intr:
280#ifdef FC_NO_PEU_VERA
281 ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since
282 ! BAR is set that way. Physical addresses generated via TSB
283 ! have this offset so mimic that when accessing directly, as here.
284 best_set_reg(mpeval(N2_PCIE_BASE_ADDR
285 + MEM64_OFFSET_BASE_REG_DATA
286 + PCIE_MEM64_OFFSET
287 + PART_0_BASE
288 + (INTR0x60_MONDO_22_DMAEPT_ENGINE << 8)),
289 %l7, %l2)
290 mov %g0, %i1 /* Address 0 for now */
291 ! Store upper half of address
292 srlx %i1, 32, %l0
293 !setx 0xfffc0000, %l1, %l0 ! Always bypass for now.
294 stwa %l0, [%l2+DMAEPT_DATA_ADDR_UPPER] %asi
295
296 ! Store lower half of address
297 stwa %i1, [%l2+DMAEPT_DATA_ADDR_LOWER] %asi
298
299 ! Store pattern value
300 mov %g0, %i2 /* Pattern 0 */
301 stwa %i2, [%l2+DMAEPT_PATTERN] %asi
302
303 ! Interrupt typefff
304 best_set_reg(DMAEPT_ENDING_INTERRUPT_INTC, %l7, %l5)
305 stwa %l5, [%l2+DMAEPT_ENDING_INTERRUPT] %asi
306
307 ! Packet size
308 mov 4, %i4 /* Max of 4 DW */
309 stwa %i4, [%l2+DMAEPT_MAX_PYLD] %asi
310
311 ! Tag for MR operations, use engine ID
312 mov INTR0x60_MONDO_20_DMAEPT_ENGINE, %i0
313 stwa %i0, [%l2+DMAEPT_TAG] %asi
314
315 ! Fire the DMA
316 best_set_reg(DMAEPT_OPERATION_MW, %l7, %i1) /* 0-byte write */
317 stwa %i1, [%l2+DMAEPT_OPERATION] %asi
318
319#else /* FC_NO_PEU_VERA */
320 ! user event to generate ASSERT_INTC msg.
321 nop ! $EV trig_pc_d(1, @VA(.MAIN.send_intc_intr)) -> EnablePCIeIgCmd ("INTC", 0, 0, "ASSERT", 64'd1, *, 1 )
322 nop
323 nop
324 nop
325 nop
326#endif /* FC_NO_PEU_VERA */
327
328 /* We are all done sending interrupts, to go to good trap */
329/* EXIT_GOOD */
330
331/**************************************************************/
332/* Code for target threads */
333main_target:
334intr_wait_2:
335 setx intr_expect, %l1, %g4
336 add %g4, %g1, %g4 ! address of expected interrupt count for this thread
337 ldub [%g4], %g4
338
339 setx intr_count, %l1, %g3
340 add %g3, %g1, %g3 ! address of interrupt count for this thread
341
342#ifdef DTM_ENABLED
343 best_set_reg(0x1600, %l1, %g2) ! DTM timeout count
344#else
345 best_set_reg(0x200, %l1, %g2) ! timeout count
346#endif
347
348intr_wait_loop_top_2:
349 ldub [%g3], %g5
350 cmp %g5, %g4
351 be thread_passed
352 dec %g2
353
354 cmp %g2, 0
355 bne intr_wait_loop_top_2
356 nop
357
358intr_timeout:
359 !$EV trig_pc_d(1, @VA(.MAIN.intr_timeout)) -> printf("ERROR: Timeout waiting for interrupt",*,1)
360 EXIT_BAD
361
362thread_passed:
363 EXIT_GOOD
364
365local_test_failed:
366 EXIT_BAD
367
368
369
370/************************************************************************
371 Test case data start
372************************************************************************/
373
374.align 1024
375.data
376user_data_start:
377intr_expect:
378 .byte 0x1 ! expected interrupt count for thread 0
379 .byte 0x0 ! expected interrupt count for thread 1
380 .byte 0x1 ! expected interrupt count for thread 2
381 .byte 0x0 ! expected interrupt count for thread 3
382 .byte 0x1 ! expected interrupt count for thread 4
383 .byte 0x0 ! expected interrupt count for thread 5
384 .byte 0x1 ! expected interrupt count for thread 6
385 .byte 0x0 ! expected interrupt count for thread 7
386user_data_end:
387
388
389SECTION .HTRAPS
390.data
391.global intr_count
392intr_count:
393 .byte 0x0 ! interrupt count for thread 0
394 .byte 0x0 ! interrupt count for thread 1
395 .byte 0x0 ! interrupt count for thread 2
396 .byte 0x0 ! interrupt count for thread 3
397 .byte 0x0 ! interrupt count for thread 4
398 .byte 0x0 ! interrupt count for thread 5
399 .byte 0x0 ! interrupt count for thread 6
400 .byte 0x0 ! interrupt count for thread 7
401
402.end
403
404/************************************************************************/