Merge commit 'origin' into master
[linux-2.6] / arch / sparc64 / kernel / ivec.S
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