Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: interrupt_pci_spurious_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 | #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 | ||
60 | main: | |
61 | ta T_CHANGE_HPRIV | |
62 | nop | |
63 | ||
64 | stx %g0, [%g7] ! Clear this thread's interrupt count | |
65 | membar #Sync | |
66 | ||
67 | /* Initialize the NCU for the interrupt. */ | |
68 | ||
69 | ! Disable interrupts | |
70 | ||
71 | no_intr: | |
72 | rdpr %pstate, %g7 | |
73 | xor %g7, 0x2, %g7 ! Reset interrupt enable | |
74 | wrpr %g7, %pstate | |
75 | ||
76 | ! Initially set all the Interrupt Management Registers | |
77 | ! Not used in this diag, so set vector number to 1, thread to 0. | |
78 | ncu_init: | |
79 | setx INT_MAN, %g1, %g2 ! %g2 = INT_MAN reg. addr. | |
80 | setx INT_MAN_COUNT, %g1, %g4 ! %g4 = INT_MAN reg. count value | |
81 | set 1, %g1 | |
82 | ||
83 | ncu_init_loop_top: | |
84 | stx %g1, [%g2] | |
85 | add %g2, INT_MAN_STEP, %g2 | |
86 | cmp %g4, 1 | |
87 | bne ncu_init_loop_top | |
88 | add %g4, -1, %g4 | |
89 | ||
90 | ! Initialize Mondo Interrupt Vector Register | |
91 | ! VECTOR = 63 | |
92 | ||
93 | ncu_mondo_int_vec: | |
94 | set 63, %g1 | |
95 | setx MONDO_INT_VEC, %g2, %g3 | |
96 | stx %g1, [%g3] | |
97 | ||
98 | ! Clear Mondo Interrupt Busy registers. | |
99 | ||
100 | ncu_mondo_int_busy: | |
101 | setx MONDO_INT_BUSY, %g1, %g2 | |
102 | setx MONDO_INT_BUSY_STEP, %g1, %g3 | |
103 | setx MONDO_INT_BUSY_COUNT, %g1, %g4 | |
104 | ||
105 | ncu_mondo_int_busy_loop_top: | |
106 | stx %g0, [%g2] | |
107 | add %g2, %g3, %g2 | |
108 | cmp %g4, 1 | |
109 | bne ncu_mondo_int_busy_loop_top | |
110 | dec %g4 | |
111 | ||
112 | ! Initialize for INTA interrupt in PIU | |
113 | ! First clear INTA in case one pending. | |
114 | ||
115 | peu_inta_clear: | |
116 | setx PCI_E_INT_A_CLEAR_ADDR, %g1, %g2 | |
117 | set 1, %g3 | |
118 | stx %g3, [%g2] | |
119 | ||
120 | ! Also clear in Interrupt Clear reg. | |
121 | ||
122 | peu_intr_clear: | |
123 | setx PCI_E_INT_CLEAR_ADDR, %g1, %g2 | |
124 | stx %g0, [%g2] | |
125 | ||
126 | ! Now enable INTA in PIU and set destination thread | |
127 | ||
128 | peu_inta_enable: | |
129 | setx PCI_E_INT_MAP_ADDR, %g1, %g7 | |
130 | setx 0x80000040, %g1, %g6 ! valid = 1, thread id = 0 | |
131 | stx %g6, [%g7] ! interrupt controller = 1 | |
132 | ||
133 | ! Enable interrupts | |
134 | ||
135 | yes_intr: | |
136 | rdpr %pstate, %g7 | |
137 | or %g7, 0x2, %g7 ! Set interrupt enable | |
138 | wrpr %g7, %pstate | |
139 | ||
140 | ||
141 | /* Kick off the interrupt */ | |
142 | ||
143 | inta_intr: | |
144 | ! user event to generate ASSERT_INTA msg. | |
145 | nop ! $EV trig_pc_d(1, @VA(.MAIN.inta_intr)) -> EnablePCIeIgCmd ("INTA", 0, 0, "ASSERT", 64'd1, *, 1 ) | |
146 | ||
147 | /* Wait for two interrupts to occur */ | |
148 | ||
149 | intr_wait_2: | |
150 | setx 0x800, %g1, %g2 ! timeout count | |
151 | setx user_data_start, %g1, %g3 | |
152 | ||
153 | intr_wait_loop_top_2: | |
154 | ldx [%g3], %g5 | |
155 | cmp %g5, 2 | |
156 | be test_passed | |
157 | dec %g2 | |
158 | ||
159 | cmp %g2, 0 | |
160 | bne intr_wait_loop_top_2 | |
161 | nop | |
162 | ba local_test_failed | |
163 | nop | |
164 | ||
165 | test_passed: | |
166 | EXIT_GOOD | |
167 | ||
168 | local_test_failed: | |
169 | EXIT_BAD | |
170 | ||
171 | ||
172 | /********************************************************************** | |
173 | Interrupt trap handler. | |
174 | **********************************************************************/ | |
175 | ||
176 | .global my_trap_code | |
177 | ||
178 | my_trap_code: | |
179 | ||
180 | ! Get the thread id. | |
181 | ta T_RD_THID ! %o1 = thread id | |
182 | ||
183 | ! The next two registers are only checked on first interrupt | |
184 | ||
185 | trap_first_intr: | |
186 | setx user_data_start, %l2, %l6 ! Do not overwrite this %l6 ! | |
187 | ldx [%l6], %l7 ! Do not overwrite this %l7 ! | |
188 | cmp %l7, 0 | |
189 | be skip_deassert_msg | |
190 | nop | |
191 | ||
192 | ! On second interrupt send the deassert message. | |
193 | ||
194 | trap_send_deassert: | |
195 | nop ! $EV trig_pc_d(1, @VA(.MAIN.trap_send_deassert)) -> EnablePCIeIgCmd ("INTA", 0, 0, "DEASSERT", 64'd1, *, 1 ) | |
196 | ||
197 | skip_deassert_msg: | |
198 | nop | |
199 | ||
200 | ! Check Mondo Interrupt Busy reg. for this thread | |
201 | ||
202 | trap_mondo_busy: | |
203 | setx MONDO_INT_BUSY, %l1, %l2 | |
204 | setx MONDO_INT_BUSY_STEP, %l1, %l3 | |
205 | mulx %l3, %o1, %l3 | |
206 | add %l3, %l2, %l2 | |
207 | ldx [%l2], %l4 | |
208 | and %l4, 0x40, %l5 ! Is busy bit set? | |
209 | cmp %l5, 0 | |
210 | be local_test_failed | |
211 | nop | |
212 | ||
213 | ! Check Mondo Interrupt Alias Busy reg. | |
214 | ||
215 | trap_mondo_abusy: | |
216 | setx MONDO_INT_ABUSY, %l1, %l2 | |
217 | ldx [%l2], %l3 | |
218 | cmp %l3, %l4 ! ABUSY = BUSY ? | |
219 | bne local_test_failed | |
220 | nop | |
221 | ||
222 | ! Check Mondo Interrupt Data 0/1 against Mondo Interrupt Alias Data 0/1 | |
223 | ||
224 | trap_mondo_data0: | |
225 | setx MONDO_INT_DATA0, %l1, %l2 | |
226 | setx MONDO_INT_DATA0_STEP, %l1, %l3 | |
227 | mulx %l3, %o1, %l3 | |
228 | add %l3, %l2, %l2 | |
229 | ldx [%l2], %l0 ! %l0 = mondo_int_busy0 | |
230 | ||
231 | trap_mondo_adata0: | |
232 | setx MONDO_INT_ADATA0, %l1, %l4 ! %l5 = mondo_int_abusy0 | |
233 | ldx [%l4], %l5 | |
234 | cmp %l5, %l0 | |
235 | bne local_test_failed | |
236 | nop | |
237 | ||
238 | trap_mondo_data1: | |
239 | setx MONDO_INT_DATA1, %l1, %l2 | |
240 | setx MONDO_INT_DATA1_STEP, %l1, %l3 | |
241 | mulx %l3, %o1, %l3 | |
242 | add %l3, %l2, %l2 | |
243 | ldx [%l2], %l0 ! %l0 = mondo_int_busy1 | |
244 | ||
245 | trap_mondo_adata1: | |
246 | setx MONDO_INT_ADATA1, %l1, %l4 ! %l5 = mondo_int_abusy1 | |
247 | ldx [%l4], %l5 | |
248 | cmp %l5, %l0 | |
249 | bne local_test_failed | |
250 | nop | |
251 | ||
252 | ! Check INTA status in PIU | |
253 | ||
254 | ! Interrupt Clear reg. | |
255 | ||
256 | trap_peu_intr_clear: | |
257 | setx PCI_E_INT_CLEAR_ADDR, %l1, %l2 | |
258 | ldx [%l2], %l0 | |
259 | cmp %l0, 3 ! Should be in pending state | |
260 | bne local_test_failed | |
261 | nop | |
262 | ||
263 | ! Interrupt Status reg. 1 | |
264 | ||
265 | trap_peu_intr_status_1: | |
266 | setx PCI_E_INT_STATE_STATUS_1_ADDR, %l1, %l2 | |
267 | setx 0x30000000000, %l1, %l5 | |
268 | ldx [%l2], %l0 | |
269 | cmp %l0, %l5 | |
270 | bne local_test_failed | |
271 | nop | |
272 | ||
273 | ! INTX Status reg. | |
274 | ||
275 | ! Expected data will differ depending on | |
276 | ! if deassert has been sent yet | |
277 | ||
278 | cmp %l7, 0 | |
279 | be trap_no_deassert | |
280 | nop | |
281 | ||
282 | trap_yes_deassert: | |
283 | mov %g0, %l5 | |
284 | mov %g0, %l4 | |
285 | ba trap_peu_inta_status | |
286 | nop | |
287 | ||
288 | trap_no_deassert: | |
289 | set 1, %l5 | |
290 | set 8, %l4 | |
291 | ||
292 | trap_peu_inta_status: | |
293 | setx PCI_E_INTX_STATUS_ADDR, %l1, %l2 | |
294 | ldx [%l2], %l0 | |
295 | cmp %l0, %l4 | |
296 | bne local_test_failed | |
297 | nop | |
298 | ||
299 | ! INTA Clear reg. | |
300 | ||
301 | trap_peu_inta_clear: | |
302 | setx PCI_E_INT_A_CLEAR_ADDR, %l1, %l2 | |
303 | ldx [%l2], %l0 | |
304 | cmp %l0, %l5 | |
305 | bne local_test_failed | |
306 | nop | |
307 | ||
308 | ! Clear the INTA interrupt in the PIU, via Interrupt Clear reg. | |
309 | ||
310 | trap_inta_clear: | |
311 | setx PCI_E_INT_CLEAR_ADDR, %l0, %l2 | |
312 | stx %g0, [%l2] | |
313 | membar #Sync | |
314 | ||
315 | ! Clear the mondo interrupt in the NCU | |
316 | ||
317 | trap_mondo_intr_clear: | |
318 | setx MONDO_INT_ABUSY, %l0, %l1 | |
319 | stx %g0, [%l1] | |
320 | membar #Sync | |
321 | ||
322 | ldx [%l1], %l2 | |
323 | and %l2, 0x40, %l2 | |
324 | cmp %l2, 0 ! Busy should be cleared | |
325 | bne local_test_failed | |
326 | nop | |
327 | ||
328 | ! Clear the interrupt in the core | |
329 | ||
330 | trap_clear_asi_intr_r: | |
331 | ldxa [%g0]ASI_SWVR_INTR_R, %l5 | |
332 | cmp %l5, 63 ! check for correct vector number | |
333 | bne local_test_failed | |
334 | nop | |
335 | ||
336 | ! Indicate that the interrupt trap occured | |
337 | ||
338 | trap_flag: | |
339 | inc %l7 | |
340 | stx %l7, [%l6] | |
341 | membar #Sync | |
342 | ||
343 | ! Done. | |
344 | ||
345 | trap_done: | |
346 | jmpl %o7+0x8, %g0 | |
347 | nop | |
348 | ||
349 | ||
350 | ||
351 | /************************************************************************ | |
352 | Test case data start | |
353 | ************************************************************************/ | |
354 | ||
355 | .align 1024 | |
356 | .data | |
357 | user_data_start: | |
358 | .word 0x0 | |
359 | .word 0x0 | |
360 | .word 0x0 | |
361 | .word 0x0 | |
362 | user_data_end: | |
363 | .end | |
364 | ||
365 | /************************************************************************/ |