linux/arch/sparc/kernel/ivec.S
<<
>>
Prefs
   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
  14do_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
  36do_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
  491:      jmpl            %g3, %g0
  50         nop
  51        .size           do_ivec,.-do_ivec
  52