Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: interrupt_dmu_intr_reloc.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 | #define SYNC_THREADS 0xff | |
41 | ||
42 | #define H_HT0_Interrupt_0x60 | |
43 | #define My_HT0_Interrupt_0x60 \ | |
44 | call my_trap_code; \ | |
45 | nop; \ | |
46 | retry; \ | |
47 | nop; | |
48 | ||
49 | #include "hboot.s" | |
50 | #include "peu_defines.h" | |
51 | #include "ncu_defines.h" | |
52 | #include "cmp_macros.h" | |
53 | ||
54 | ||
55 | /************************************************************************ | |
56 | Test case code start | |
57 | ************************************************************************/ | |
58 | .text | |
59 | .global main | |
60 | ||
61 | main: | |
62 | ta T_CHANGE_HPRIV | |
63 | nop | |
64 | ||
65 | ! Initialize the global registers. | |
66 | mov %g0, %g1 | |
67 | mov %g0, %g2 | |
68 | mov %g0, %g3 | |
69 | mov %g0, %g4 | |
70 | mov %g0, %g5 | |
71 | mov %g0, %g6 | |
72 | mov %g0, %g7 | |
73 | ||
74 | ta T_RD_THID | |
75 | cmp %o1, 0x0 | |
76 | be main_t0 ! branch if tread 0 | |
77 | nop | |
78 | ba main_t1_to_t63 ! branch if not thread 0 | |
79 | nop | |
80 | ||
81 | ||
82 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
83 | ! | |
84 | ! Thread 0 Start Here | |
85 | ! | |
86 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
87 | ||
88 | main_t0: | |
89 | /* Initialize the NCU for the interrupt. */ | |
90 | ||
91 | ! Disable interrupts | |
92 | ||
93 | no_intr: | |
94 | rdpr %pstate, %g5 | |
95 | xor %g5, 0x2, %g5 ! Reset interrupt enable | |
96 | wrpr %g5, %pstate | |
97 | ||
98 | ! Initialize Mondo Interrupt Vector Register | |
99 | ! VECTOR = 63 | |
100 | ||
101 | ncu_mondo_int_vec: | |
102 | set 63, %g1 | |
103 | setx MONDO_INT_VEC, %g2, %g3 | |
104 | stx %g1, [%g3] | |
105 | ||
106 | ! Clear Mondo Interrupt Busy registers. | |
107 | ||
108 | ncu_mondo_int_busy: | |
109 | setx MONDO_INT_BUSY, %g1, %g2 | |
110 | setx MONDO_INT_BUSY_STEP, %g1, %g3 | |
111 | setx MONDO_INT_BUSY_COUNT, %g1, %g4 | |
112 | ||
113 | ncu_mondo_int_busy_loop_top: | |
114 | stx %g0, [%g2] | |
115 | add %g2, %g3, %g2 | |
116 | cmp %g4, 1 | |
117 | bne ncu_mondo_int_busy_loop_top | |
118 | dec %g4 | |
119 | ||
120 | ! Initialize for MSI interrupt in PIU | |
121 | ! First clear MSI in case one pending. | |
122 | ||
123 | peu_msi_clear: | |
124 | setx PCI_E_MSI_CLEAR_ADDR, %g1, %g2 | |
125 | setx 0x4000000000000000, %g1, %g3 | |
126 | stx %g3, [%g2] | |
127 | ||
128 | ! Also clear in Interrupt Clear reg. | |
129 | ||
130 | peu_intr_clear: | |
131 | setx PCI_E_INT_CLEAR_ADDR, %g1, %g2 | |
132 | set PCI_E_INT_CLEAR_STEP, %g1 | |
133 | sllx %g1, 2, %g1 | |
134 | add %g2, %g1, %g2 | |
135 | stx %g0, [%g2] | |
136 | ||
137 | ! Setup all the event queues. | |
138 | ||
139 | ! First the Event Queue Base Address reg. | |
140 | ! Formatted for a bypass address. | |
141 | ||
142 | peu_eq_base_addr: | |
143 | setx PCI_E_EV_QUE_BASE_ADDRESS_ADDR, %g1, %g2 | |
144 | setx user_data_start+0x80000, %g1, %g3 | |
145 | setx 0x7ffff80000, %g1, %g5 | |
146 | and %g3, %g5, %g3 | |
147 | setx 0xfffc000000000000, %g1, %g6 | |
148 | or %g3, %g6, %g3 | |
149 | stx %g3, [%g2] | |
150 | ||
151 | ! Event Queue Control Set reg.s | |
152 | ||
153 | peu_eq_ctl_set: | |
154 | setx PCI_E_EV_QUE_CTL_SET_ADDR, %g1, %g2 | |
155 | setx 0x100000000000, %g1, %g3 ! EN = 1 | |
156 | setx PCI_E_EV_QUE_CTL_SET_COUNT, %g1, %g4 | |
157 | setx PCI_E_EV_QUE_CTL_SET_STEP, %g1, %g5 | |
158 | ||
159 | peu_eq_clt_set_loop: | |
160 | stx %g3, [%g2] | |
161 | cmp %g4, 1 | |
162 | beq peu_msi_addr | |
163 | ||
164 | add %g2, %g5, %g2 | |
165 | ba peu_eq_clt_set_loop | |
166 | dec %g4 | |
167 | ||
168 | ! Now enable MSI interrupt | |
169 | ||
170 | ! First MSI addressing register | |
171 | ||
172 | peu_msi_addr: | |
173 | setx PCI_E_MSI_32_ADDRESS_ADDR, %g1, %g2 | |
174 | stx %g0, [%g2] | |
175 | setx PCI_E_MSI_64_ADDRESS_ADDR, %g1, %g2 | |
176 | stx %g0, [%g2] | |
177 | ||
178 | ! MSI Mapping register, only init. the first, the trap handler does the rest | |
179 | ||
180 | peu_msi_mapping: | |
181 | setx PCI_E_MSI_MAP_ADDR, %g1, %g2 | |
182 | setx 0x8000000000000000, %g1, %g3 ! V = 1, EQNUM = 0 | |
183 | stx %g3, [%g2] | |
184 | membar #Sync | |
185 | ||
186 | ! Now enable Mondo in PIU and set destination thread | |
187 | ! Interrupt Mapping register | |
188 | ||
189 | peu_int_map_enable: | |
190 | setx PCI_E_INT_MAP_ADDR, %g1, %g5 | |
191 | set PCI_E_INT_MAP_STEP, %g1 | |
192 | sllx %g1, 2, %g1 | |
193 | add %g5, %g1, %g5 | |
194 | setx 0x80000040, %g1, %g6 ! valid = 1, thread id = 0 | |
195 | stx %g6, [%g5] ! interrupt controller = 1 | |
196 | ||
197 | ! Enable interrupts | |
198 | ||
199 | yes_intr: | |
200 | rdpr %pstate, %g5 | |
201 | or %g5, 0x2, %g5 ! Set interrupt enable | |
202 | wrpr %g5, %pstate | |
203 | ||
204 | ||
205 | /* Sync up all the treads. */ | |
206 | ||
207 | sync_t0: | |
208 | SYNC_THREAD_MAIN( local_test_failed, %g1, %g2, %g3 ) | |
209 | ||
210 | ||
211 | /* Loop to kick off the MSI's */ | |
212 | /* Note that the interrupt trap handler will take care of doing the relocation */ | |
213 | ||
214 | gen_msis: | |
215 | setx PCI_E_EV_QUE_CTL_SET_COUNT, %g1, %g7 | |
216 | sllx %g7, 1, %g7 ! two interrupts per event queue | |
217 | #ifdef DMU_INTR_RELOC_VEC | |
218 | srlx %g7, 2, %g7 ! only do 1/4 of them for test vectors. | |
219 | #endif | |
220 | setx interrupt_flag, %g1, %g2 | |
221 | ||
222 | gen_msis_loop: | |
223 | st %g0, [%g2] ! clear interrupt occured flag | |
224 | ||
225 | gen_msi_user_event: | |
226 | ! user event to generate MSI msg. | |
227 | nop ! $EV trig_pc_d(1, @VA(.MAIN.gen_msi_user_event)) -> EnablePCIeIgCmd ("MSI32", 0, 0, 4, 1, *, 1 ) | |
228 | ||
229 | ||
230 | /* Wait for interrupt to occur. */ | |
231 | ||
232 | intr_wait: | |
233 | #ifdef DTM_ENABLED | |
234 | setx 0x2000, %g1, %g3 ! DTM timeout count | |
235 | #else | |
236 | setx 0x800, %g1, %g3 ! timeout count | |
237 | #endif | |
238 | ||
239 | intr_wait_loop: | |
240 | ld [%g2], %g5 | |
241 | cmp %g5, 1 | |
242 | be gen_msis_next | |
243 | dec %g3 | |
244 | ||
245 | cmp %g3, 0 | |
246 | bne intr_wait_loop | |
247 | nop | |
248 | ba local_test_failed | |
249 | nop | |
250 | ||
251 | /* Have all the needed MSI's been generated? */ | |
252 | ||
253 | gen_msis_next: | |
254 | dec %g7 | |
255 | cmp %g7, 0 | |
256 | bne gen_msis_loop | |
257 | nop | |
258 | ||
259 | #ifndef SKIP_EQ_CHECK | |
260 | /* Did each thread get the correct number of interrupts */ | |
261 | ||
262 | intr_check: | |
263 | setx interrupt_counts, %g1, %g2 | |
264 | set 8, %g7 | |
265 | ||
266 | intr_check_loop: | |
267 | ld [%g2], %g5 | |
268 | cmp %g5, 9 | |
269 | bne local_test_failed | |
270 | dec %g7 | |
271 | ||
272 | cmp %g7, 0 | |
273 | bne intr_check_loop | |
274 | add %g2, 4, %g2 | |
275 | #endif | |
276 | ||
277 | /* Tell the other threads we're done. */ | |
278 | ||
279 | t0_flag_done: | |
280 | setx done_flag, %g1, %g2 | |
281 | set 1, %g3 | |
282 | st %g3, [%g2] | |
283 | ||
284 | !Done | |
285 | t0_done: | |
286 | ba test_passed | |
287 | nop | |
288 | ||
289 | ||
290 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
291 | ! | |
292 | ! All Threads Except 0 Start Here | |
293 | ! | |
294 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
295 | ||
296 | ||
297 | main_t1_to_t63: | |
298 | mov %o1, %g6 | |
299 | SYNC_THREAD_OTHER( %g6,%g1,%g2 ) | |
300 | ||
301 | /* Wait thread 0 to indicate we're done. */ | |
302 | ||
303 | t1_t63_intr_wait: | |
304 | #ifdef DTM_ENABLED | |
305 | setx 0x10000, %g1, %g2 ! DTM timeout count | |
306 | #else | |
307 | setx 0x4000, %g1, %g2 ! timeout count | |
308 | #endif | |
309 | setx done_flag, %g1, %g7 | |
310 | ||
311 | t1_t63_intr_wait_loop_top: | |
312 | ld [%g7], %g5 | |
313 | cmp %g5, 1 | |
314 | be t1_t63_done | |
315 | dec %g2 | |
316 | ||
317 | cmp %g2, 0 | |
318 | bne t1_t63_intr_wait_loop_top | |
319 | nop | |
320 | ba local_test_failed | |
321 | nop | |
322 | ||
323 | !Done | |
324 | t1_t63_done: | |
325 | ba test_passed | |
326 | nop | |
327 | ||
328 | ||
329 | test_passed: | |
330 | EXIT_GOOD | |
331 | ||
332 | local_test_failed: | |
333 | EXIT_BAD | |
334 | ||
335 | ||
336 | /********************************************************************** | |
337 | Interrupt trap handler. | |
338 | **********************************************************************/ | |
339 | ||
340 | .global my_trap_code | |
341 | ||
342 | my_trap_code: | |
343 | ta T_RD_THID ! %o1 = thread id | |
344 | ||
345 | ! Check Mondo Interrupt Busy reg. for this thread | |
346 | ||
347 | trap_mondo_busy: | |
348 | setx MONDO_INT_BUSY, %l1, %l2 | |
349 | setx MONDO_INT_BUSY_STEP, %l1, %l3 | |
350 | mulx %l3, %o1, %l3 | |
351 | add %l3, %l2, %l2 | |
352 | ldx [%l2], %l4 | |
353 | and %l4, 0x40, %l5 ! Is busy bit set? | |
354 | cmp %l5, 0 | |
355 | be local_test_failed | |
356 | nop | |
357 | ||
358 | ! Check Mondo Interrupt Alias Busy reg. | |
359 | ||
360 | trap_mondo_abusy: | |
361 | setx MONDO_INT_ABUSY, %l1, %l2 | |
362 | ldx [%l2], %l3 | |
363 | cmp %l3, %l4 ! ABUSY = BUSY ? | |
364 | bne local_test_failed | |
365 | nop | |
366 | ||
367 | ! Check Mondo Interrupt Data 0/1 against Mondo Interrupt Alias Data 0/1 | |
368 | ||
369 | trap_mondo_data0: | |
370 | setx MONDO_INT_DATA0, %l1, %l2 | |
371 | setx MONDO_INT_DATA0_STEP, %l1, %l3 | |
372 | mulx %l3, %o1, %l3 | |
373 | add %l3, %l2, %l2 | |
374 | ldx [%l2], %l0 ! %l0 = mondo_int_busy0 | |
375 | ||
376 | trap_mondo_adata0: | |
377 | setx MONDO_INT_ADATA0, %l1, %l4 ! %l6 = mondo_int_abusy0, inc. INO | |
378 | ldx [%l4], %l6 | |
379 | cmp %l6, %l0 | |
380 | bne local_test_failed | |
381 | nop | |
382 | ||
383 | trap_mondo_data1: | |
384 | setx MONDO_INT_DATA1, %l1, %l2 | |
385 | setx MONDO_INT_DATA1_STEP, %l1, %l3 | |
386 | mulx %l3, %o1, %l3 | |
387 | add %l3, %l2, %l2 | |
388 | ldx [%l2], %l0 ! %l0 = mondo_int_busy1 | |
389 | ||
390 | trap_mondo_adata1: | |
391 | setx MONDO_INT_ADATA1, %l1, %l4 ! %l5 = mondo_int_abusy1 | |
392 | ldx [%l4], %l5 | |
393 | cmp %l5, %l0 | |
394 | bne local_test_failed | |
395 | nop | |
396 | ||
397 | ! Is this the INO expected? | |
398 | ||
399 | trap_ino_check: | |
400 | and %l6, 0x3f, %l6 ! %l6 = INO | |
401 | sub %l6, 24, %l6 ! %l6 = event queue number | |
402 | setx eq_num, %l1, %l2 ! Do NOT change %l6 until trap_inc_queue! | |
403 | ld [%l2], %l2 | |
404 | #ifndef SKIP_EQ_CHECK | |
405 | cmp %l2, %l6 | |
406 | bne local_test_failed | |
407 | nop | |
408 | #endif | |
409 | ||
410 | ! Was the correct event queue used? | |
411 | ||
412 | trap_eq_check1: | |
413 | setx PCI_E_MSI_MAP_ADDR, %l1, %l2 | |
414 | ldx [%l2], %l1 | |
415 | and %l1, 0x3f, %l1 | |
416 | cmp %l1, %l6 | |
417 | bne local_test_failed | |
418 | nop | |
419 | ||
420 | ! Check Mondo status in PIU | |
421 | ||
422 | ! Interrupt Clear reg. | |
423 | ||
424 | trap_peu_intr_clear: | |
425 | setx PCI_E_INT_CLEAR_ADDR, %l1, %l2 | |
426 | set PCI_E_INT_CLEAR_STEP, %l3 | |
427 | add %l6, 4, %l4 | |
428 | mulx %l3, %l4, %l3 | |
429 | add %l2, %l3, %l2 | |
430 | ldx [%l2], %l0 | |
431 | cmp %l0, 3 ! Should be in pending state | |
432 | bne local_test_failed | |
433 | nop | |
434 | ||
435 | ! MSI Mapping reg. | |
436 | ||
437 | trap_peu_msi_map: | |
438 | setx PCI_E_MSI_MAP_ADDR, %l1, %l2 | |
439 | setx 0xc000000000000000, %l1, %l4 ! V = 1, EQWR_N = %l6 | |
440 | or %l4, %l6, %l4 | |
441 | ldx [%l2], %l0 | |
442 | cmp %l0, %l4 | |
443 | bne local_test_failed | |
444 | nop | |
445 | ||
446 | ! Clear the Mondo interrupt in the PIU | |
447 | ||
448 | ! MSI Clear reg. | |
449 | ||
450 | trap_msi_clear: | |
451 | setx PCI_E_MSI_CLEAR_ADDR, %l1, %l2 | |
452 | setx 0x4000000000000000, %l1, %l3 | |
453 | stx %l3, [%l2] ! clear EQWR in MSI map reg. | |
454 | membar #Sync | |
455 | ||
456 | ! Disable Event Queue via Control Clear reg. | |
457 | ||
458 | trap_eq_control_clear: | |
459 | setx PCI_E_EV_QUE_CTL_CLEAR_ADDR, %l1, %l2 | |
460 | set PCI_E_EV_QUE_CTL_CLEAR_STEP, %l4 | |
461 | mulx %l4, %l6, %l4 | |
462 | add %l2, %l4, %l2 | |
463 | setx 0x100000000000, %l1, %l3 ! DIS = 1 | |
464 | stx %l3, [%l2] | |
465 | membar #Sync | |
466 | ||
467 | ! Set Event Queue Head = Event Queue Tail | |
468 | ! Also check that they are not equal. | |
469 | ||
470 | trap_mondo_clear: | |
471 | setx PCI_E_EV_QUE_TAIL_ADDR, %l1, %l2 | |
472 | set PCI_E_EV_QUE_TAIL_STEP, %l4 | |
473 | mulx %l4, %l6, %l4 | |
474 | add %l2, %l4, %l2 | |
475 | ldx [%l2], %l0 | |
476 | setx PCI_E_EV_QUE_HEAD_ADDR, %l1, %l2 | |
477 | set PCI_E_EV_QUE_HEAD_STEP, %l4 | |
478 | mulx %l4, %l6, %l4 | |
479 | add %l2, %l4, %l2 | |
480 | ldx [%l2], %l1 | |
481 | cmp %l0, %l1 | |
482 | be local_test_failed | |
483 | nop | |
484 | stx %l0, [%l2] | |
485 | membar #Sync | |
486 | ||
487 | ! Interrupt Clear reg. | |
488 | ||
489 | trap_intr_clear: | |
490 | setx PCI_E_INT_CLEAR_ADDR, %l1, %l2 | |
491 | set PCI_E_INT_CLEAR_STEP, %l3 | |
492 | add %l6, 4, %l1 | |
493 | mulx %l3, %l1, %l3 | |
494 | add %l2, %l3, %l2 | |
495 | stx %g0, [%l2] | |
496 | membar #Sync | |
497 | ||
498 | ! Clear the mondo interrupt in the NCU | |
499 | ||
500 | trap_mondo_intr_clear: | |
501 | setx MONDO_INT_ABUSY, %l0, %l1 | |
502 | stx %g0, [%l1] | |
503 | membar #Sync | |
504 | ||
505 | ldx [%l1], %l2 | |
506 | and %l2, 0x40, %l2 | |
507 | cmp %l2, 0 ! Busy should be cleared | |
508 | bne local_test_failed | |
509 | nop | |
510 | ||
511 | ! Clear the interrupt in the core | |
512 | ||
513 | trap_clear_asi_intr_r: | |
514 | ldxa [%g0]ASI_SWVR_INTR_R, %l5 | |
515 | cmp %l5, 63 ! check for correct vector number | |
516 | bne local_test_failed | |
517 | nop | |
518 | ||
519 | ! Set up to do relocation | |
520 | ||
521 | ! First are we done with the current event queue? | |
522 | ||
523 | trap_eq_check: | |
524 | setx odd_even, %l1, %l2 | |
525 | ld [%l2], %l0 | |
526 | cmp %l0, 0 | |
527 | bne trap_next_eq | |
528 | nop | |
529 | ||
530 | ! Keep same event queue, but do the relocation, | |
531 | ! i.e. change thread interrupt is sent to. | |
532 | ||
533 | set 1, %l1 | |
534 | st %l1, [%l2] | |
535 | ba trap_inc_thread | |
536 | nop | |
537 | ||
538 | ! Go to the next event queue | |
539 | ||
540 | trap_next_eq: | |
541 | st %g0, [%l2] | |
542 | setx eq_num, %l1, %l2 | |
543 | inc %l6 | |
544 | st %l6, [%l2] | |
545 | ||
546 | ! Initialize for the new event queue | |
547 | ||
548 | trap_inc_queue: | |
549 | setx PCI_E_MSI_MAP_ADDR, %l1, %l2 | |
550 | setx 0x8000000000000000, %l1, %l3 ! V = 1 | |
551 | or %l3, %l6, %l3 ! or in new event queue number | |
552 | stx %l3, [%l2] | |
553 | ||
554 | ! Increment the thread to send the next interrupt to | |
555 | ||
556 | trap_inc_thread: | |
557 | setx PCI_E_INT_MAP_ADDR, %l1, %l5 | |
558 | set PCI_E_INT_MAP_STEP, %l1 | |
559 | add %l6, 4, %l7 ! index = event queue # + 4 | |
560 | mulx %l1, %l7, %l1 | |
561 | add %l5, %l1, %l5 | |
562 | setx 0x80000040, %l1, %l2 ! valid = 1, intr. controller #1 | |
563 | add %o1, 1, %l7 | |
564 | and %l7, 0x7, %l7 | |
565 | sllx %l7, 25, %l4 | |
566 | or %l2, %l4, %l2 ! or in destination thread id | |
567 | stx %l2, [%l5] | |
568 | ||
569 | ! Enable the Event Queue | |
570 | ||
571 | trap_enable_eq: | |
572 | setx PCI_E_EV_QUE_CTL_SET_ADDR, %l1, %l2 | |
573 | setx PCI_E_EV_QUE_CTL_SET_STEP, %l1, %l4 | |
574 | mulx %l4, %l6, %l4 | |
575 | add %l2, %l4, %l2 | |
576 | setx 0x100000000000, %l1, %l3 ! EN = 1 | |
577 | stx %l3, [%l2] | |
578 | membar #Sync | |
579 | ||
580 | ! Increment thread's interrupt count. | |
581 | ||
582 | trap_inc_intr_count: | |
583 | sllx %o1, 2, %l7 | |
584 | setx interrupt_counts, %l1, %l3 | |
585 | add %l7, %l3, %l7 ! %l7 = pointer to thread's interrupt count | |
586 | ld [%l7], %l6 | |
587 | inc %l6 | |
588 | st %l6, [%l7] | |
589 | ||
590 | ! Flag that an interrupt occured | |
591 | ||
592 | trap_flag_intr: | |
593 | setx interrupt_flag, %l0, %l1 | |
594 | ld [%l1], %l2 | |
595 | inc %l2 | |
596 | st %l2, [%l1] | |
597 | ||
598 | ! Done. | |
599 | ||
600 | trap_done: | |
601 | jmpl %o7+0x8, %g0 | |
602 | nop | |
603 | ||
604 | ||
605 | ||
606 | /************************************************************************ | |
607 | Test case data start | |
608 | ************************************************************************/ | |
609 | ||
610 | .align 1024 | |
611 | .data | |
612 | user_data_start: | |
613 | .word 0xffffffff | |
614 | .word 0xffffffff | |
615 | .word 0xffffffff | |
616 | .word 0xffffffff | |
617 | ||
618 | /* 1 word per thread to count number of interrupts taken */ | |
619 | interrupt_counts: | |
620 | .word 0 | |
621 | .word 0 | |
622 | .word 0 | |
623 | .word 0 | |
624 | .word 0 | |
625 | .word 0 | |
626 | .word 0 | |
627 | .word 0 | |
628 | ||
629 | interrupt_flag: | |
630 | .word 0 | |
631 | .word 0 | |
632 | ||
633 | done_flag: | |
634 | .word 0x0 | |
635 | .word 0x0 | |
636 | ||
637 | odd_even: | |
638 | .word 0x0 | |
639 | .word 0x0 | |
640 | ||
641 | eq_num: | |
642 | .word 0x0 | |
643 | .word 0x0 | |
644 | ||
645 | user_data_end: | |
646 | .end | |
647 | ||
648 | /************************************************************************/ |