diff options
Diffstat (limited to 'arch/sparc64/kernel/ivec.S')
-rw-r--r-- | arch/sparc64/kernel/ivec.S | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/ivec.S b/arch/sparc64/kernel/ivec.S new file mode 100644 index 000000000000..d29f92ebca5e --- /dev/null +++ b/arch/sparc64/kernel/ivec.S | |||
@@ -0,0 +1,51 @@ | |||
1 | /* The registers for cross calls will be: | ||
2 | * | ||
3 | * DATA 0: [low 32-bits] Address of function to call, jmp to this | ||
4 | * [high 32-bits] MMU Context Argument 0, place in %g5 | ||
5 | * DATA 1: Address Argument 1, place in %g1 | ||
6 | * DATA 2: Address Argument 2, place in %g7 | ||
7 | * | ||
8 | * With this method we can do most of the cross-call tlb/cache | ||
9 | * flushing very quickly. | ||
10 | */ | ||
11 | .align 32 | ||
12 | .globl do_ivec | ||
13 | .type do_ivec,#function | ||
14 | do_ivec: | ||
15 | mov 0x40, %g3 | ||
16 | ldxa [%g3 + %g0] ASI_INTR_R, %g3 | ||
17 | sethi %hi(KERNBASE), %g4 | ||
18 | cmp %g3, %g4 | ||
19 | bgeu,pn %xcc, do_ivec_xcall | ||
20 | srlx %g3, 32, %g5 | ||
21 | stxa %g0, [%g0] ASI_INTR_RECEIVE | ||
22 | membar #Sync | ||
23 | |||
24 | sethi %hi(ivector_table_pa), %g2 | ||
25 | ldx [%g2 + %lo(ivector_table_pa)], %g2 | ||
26 | sllx %g3, 4, %g3 | ||
27 | add %g2, %g3, %g3 | ||
28 | |||
29 | TRAP_LOAD_IRQ_WORK_PA(%g6, %g1) | ||
30 | |||
31 | ldx [%g6], %g5 | ||
32 | stxa %g5, [%g3] ASI_PHYS_USE_EC | ||
33 | stx %g3, [%g6] | ||
34 | wr %g0, 1 << PIL_DEVICE_IRQ, %set_softint | ||
35 | retry | ||
36 | do_ivec_xcall: | ||
37 | mov 0x50, %g1 | ||
38 | ldxa [%g1 + %g0] ASI_INTR_R, %g1 | ||
39 | srl %g3, 0, %g3 | ||
40 | |||
41 | mov 0x60, %g7 | ||
42 | ldxa [%g7 + %g0] ASI_INTR_R, %g7 | ||
43 | stxa %g0, [%g0] ASI_INTR_RECEIVE | ||
44 | membar #Sync | ||
45 | ba,pt %xcc, 1f | ||
46 | nop | ||
47 | |||
48 | .align 32 | ||
49 | 1: jmpl %g3, %g0 | ||
50 | nop | ||
51 | .size do_ivec,.-do_ivec | ||