~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc/kernel/sun4v_ivec.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/sparc/kernel/sun4v_ivec.S (Architecture sparc64) and /arch/sparc/kernel/sun4v_ivec.S (Architecture sparc)


  1 /* SPDX-License-Identifier: GPL-2.0 */              1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /* sun4v_ivec.S: Sun4v interrupt vector handli      2 /* sun4v_ivec.S: Sun4v interrupt vector handling.
  3  *                                                  3  *
  4  * Copyright (C) 2006 <davem@davemloft.net>          4  * Copyright (C) 2006 <davem@davemloft.net>
  5  */                                                 5  */
  6                                                     6 
  7 #include <asm/cpudata.h>                            7 #include <asm/cpudata.h>
  8 #include <asm/intr_queue.h>                         8 #include <asm/intr_queue.h>
  9 #include <asm/pil.h>                                9 #include <asm/pil.h>
 10                                                    10 
 11         .text                                      11         .text
 12         .align  32                                 12         .align  32
 13                                                    13 
 14 sun4v_cpu_mondo:                                   14 sun4v_cpu_mondo:
 15         /* Head offset in %g2, tail offset in      15         /* Head offset in %g2, tail offset in %g4.
 16          * If they are the same, no work.          16          * If they are the same, no work.
 17          */                                        17          */
 18         mov     INTRQ_CPU_MONDO_HEAD, %g2          18         mov     INTRQ_CPU_MONDO_HEAD, %g2
 19         ldxa    [%g2] ASI_QUEUE, %g2               19         ldxa    [%g2] ASI_QUEUE, %g2
 20         mov     INTRQ_CPU_MONDO_TAIL, %g4          20         mov     INTRQ_CPU_MONDO_TAIL, %g4
 21         ldxa    [%g4] ASI_QUEUE, %g4               21         ldxa    [%g4] ASI_QUEUE, %g4
 22         cmp     %g2, %g4                           22         cmp     %g2, %g4
 23         be,pn   %xcc, sun4v_cpu_mondo_queue_em     23         be,pn   %xcc, sun4v_cpu_mondo_queue_empty
 24          nop                                       24          nop
 25                                                    25 
 26         /* Get &trap_block[smp_processor_id()]     26         /* Get &trap_block[smp_processor_id()] into %g4.  */
 27         ldxa    [%g0] ASI_SCRATCHPAD, %g4          27         ldxa    [%g0] ASI_SCRATCHPAD, %g4
 28         sub     %g4, TRAP_PER_CPU_FAULT_INFO,      28         sub     %g4, TRAP_PER_CPU_FAULT_INFO, %g4
 29                                                    29 
 30         /* Get smp_processor_id() into %g3 */      30         /* Get smp_processor_id() into %g3 */
 31         sethi   %hi(trap_block), %g5               31         sethi   %hi(trap_block), %g5
 32         or      %g5, %lo(trap_block), %g5          32         or      %g5, %lo(trap_block), %g5
 33         sub     %g4, %g5, %g3                      33         sub     %g4, %g5, %g3
 34         srlx    %g3, TRAP_BLOCK_SZ_SHIFT, %g3      34         srlx    %g3, TRAP_BLOCK_SZ_SHIFT, %g3
 35                                                    35 
 36         /* Increment cpu_mondo_counter[smp_pro     36         /* Increment cpu_mondo_counter[smp_processor_id()] */
 37         sethi   %hi(cpu_mondo_counter), %g5        37         sethi   %hi(cpu_mondo_counter), %g5
 38         or      %g5, %lo(cpu_mondo_counter), %     38         or      %g5, %lo(cpu_mondo_counter), %g5
 39         sllx    %g3, 3, %g3                        39         sllx    %g3, 3, %g3
 40         add     %g5, %g3, %g5                      40         add     %g5, %g3, %g5
 41         ldx     [%g5], %g3                         41         ldx     [%g5], %g3
 42         add     %g3, 1, %g3                        42         add     %g3, 1, %g3
 43         stx     %g3, [%g5]                         43         stx     %g3, [%g5]
 44                                                    44 
 45         /* Get CPU mondo queue base phys addre     45         /* Get CPU mondo queue base phys address into %g7.  */
 46         ldx     [%g4 + TRAP_PER_CPU_CPU_MONDO_     46         ldx     [%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
 47                                                    47 
 48         /* Now get the cross-call arguments an     48         /* Now get the cross-call arguments and handler PC, same
 49          * layout as sun4u:                        49          * layout as sun4u:
 50          *                                         50          *
 51          * 1st 64-bit word: low half is 32-bit     51          * 1st 64-bit word: low half is 32-bit PC, put into %g3 and jmpl to it
 52          *                  high half is conte     52          *                  high half is context arg to MMU flushes, into %g5
 53          * 2nd 64-bit word: 64-bit arg, load i     53          * 2nd 64-bit word: 64-bit arg, load into %g1
 54          * 3rd 64-bit word: 64-bit arg, load i     54          * 3rd 64-bit word: 64-bit arg, load into %g7
 55          */                                        55          */
 56         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %     56         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %g3
 57         add     %g2, 0x8, %g2                      57         add     %g2, 0x8, %g2
 58         srlx    %g3, 32, %g5                       58         srlx    %g3, 32, %g5
 59         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %     59         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %g1
 60         add     %g2, 0x8, %g2                      60         add     %g2, 0x8, %g2
 61         srl     %g3, 0, %g3                        61         srl     %g3, 0, %g3
 62         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %     62         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %g7
 63         add     %g2, 0x40 - 0x8 - 0x8, %g2         63         add     %g2, 0x40 - 0x8 - 0x8, %g2
 64                                                    64 
 65         /* Update queue head pointer.  */          65         /* Update queue head pointer.  */
 66         lduw    [%g4 + TRAP_PER_CPU_CPU_MONDO_     66         lduw    [%g4 + TRAP_PER_CPU_CPU_MONDO_QMASK], %g4
 67         and     %g2, %g4, %g2                      67         and     %g2, %g4, %g2
 68                                                    68 
 69         mov     INTRQ_CPU_MONDO_HEAD, %g4          69         mov     INTRQ_CPU_MONDO_HEAD, %g4
 70         stxa    %g2, [%g4] ASI_QUEUE               70         stxa    %g2, [%g4] ASI_QUEUE
 71         membar  #Sync                              71         membar  #Sync
 72                                                    72 
 73         jmpl    %g3, %g0                           73         jmpl    %g3, %g0
 74          nop                                       74          nop
 75                                                    75 
 76 sun4v_cpu_mondo_queue_empty:                       76 sun4v_cpu_mondo_queue_empty:
 77         retry                                      77         retry
 78                                                    78 
 79 sun4v_dev_mondo:                                   79 sun4v_dev_mondo:
 80         /* Head offset in %g2, tail offset in      80         /* Head offset in %g2, tail offset in %g4.  */
 81         mov     INTRQ_DEVICE_MONDO_HEAD, %g2       81         mov     INTRQ_DEVICE_MONDO_HEAD, %g2
 82         ldxa    [%g2] ASI_QUEUE, %g2               82         ldxa    [%g2] ASI_QUEUE, %g2
 83         mov     INTRQ_DEVICE_MONDO_TAIL, %g4       83         mov     INTRQ_DEVICE_MONDO_TAIL, %g4
 84         ldxa    [%g4] ASI_QUEUE, %g4               84         ldxa    [%g4] ASI_QUEUE, %g4
 85         cmp     %g2, %g4                           85         cmp     %g2, %g4
 86         be,pn   %xcc, sun4v_dev_mondo_queue_em     86         be,pn   %xcc, sun4v_dev_mondo_queue_empty
 87          nop                                       87          nop
 88                                                    88 
 89         /* Get &trap_block[smp_processor_id()]     89         /* Get &trap_block[smp_processor_id()] into %g4.  */
 90         ldxa    [%g0] ASI_SCRATCHPAD, %g4          90         ldxa    [%g0] ASI_SCRATCHPAD, %g4
 91         sub     %g4, TRAP_PER_CPU_FAULT_INFO,      91         sub     %g4, TRAP_PER_CPU_FAULT_INFO, %g4
 92                                                    92 
 93         /* Get DEV mondo queue base phys addre     93         /* Get DEV mondo queue base phys address into %g5.  */
 94         ldx     [%g4 + TRAP_PER_CPU_DEV_MONDO_     94         ldx     [%g4 + TRAP_PER_CPU_DEV_MONDO_PA], %g5
 95                                                    95 
 96         /* Load IVEC into %g3.  */                 96         /* Load IVEC into %g3.  */
 97         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %     97         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
 98         add     %g2, 0x40, %g2                     98         add     %g2, 0x40, %g2
 99                                                    99 
100         /* XXX There can be a full 64-byte blo    100         /* XXX There can be a full 64-byte block of data here.
101          * XXX This is how we can get at MSI v    101          * XXX This is how we can get at MSI vector data.
102          * XXX Current we do not capture this,    102          * XXX Current we do not capture this, but when we do we'll
103          * XXX need to add a 64-byte storage a    103          * XXX need to add a 64-byte storage area in the struct ino_bucket
104          * XXX or the struct irq_desc.            104          * XXX or the struct irq_desc.
105          */                                       105          */
106                                                   106 
107         /* Update queue head pointer, this fre    107         /* Update queue head pointer, this frees up some registers.  */
108         lduw    [%g4 + TRAP_PER_CPU_DEV_MONDO_    108         lduw    [%g4 + TRAP_PER_CPU_DEV_MONDO_QMASK], %g4
109         and     %g2, %g4, %g2                     109         and     %g2, %g4, %g2
110                                                   110 
111         mov     INTRQ_DEVICE_MONDO_HEAD, %g4      111         mov     INTRQ_DEVICE_MONDO_HEAD, %g4
112         stxa    %g2, [%g4] ASI_QUEUE              112         stxa    %g2, [%g4] ASI_QUEUE
113         membar  #Sync                             113         membar  #Sync
114                                                   114 
115         TRAP_LOAD_IRQ_WORK_PA(%g1, %g4)           115         TRAP_LOAD_IRQ_WORK_PA(%g1, %g4)
116                                                   116 
117         /* For VIRQs, cookie is encoded as ~bu    117         /* For VIRQs, cookie is encoded as ~bucket_phys_addr  */
118         brlz,pt %g3, 1f                           118         brlz,pt %g3, 1f
119          xnor   %g3, %g0, %g4                     119          xnor   %g3, %g0, %g4
120                                                   120 
121         /* Get __pa(&ivector_table[IVEC]) into    121         /* Get __pa(&ivector_table[IVEC]) into %g4.  */
122         sethi   %hi(ivector_table_pa), %g4        122         sethi   %hi(ivector_table_pa), %g4
123         ldx     [%g4 + %lo(ivector_table_pa)],    123         ldx     [%g4 + %lo(ivector_table_pa)], %g4
124         sllx    %g3, 4, %g3                       124         sllx    %g3, 4, %g3
125         add     %g4, %g3, %g4                     125         add     %g4, %g3, %g4
126                                                   126 
127 1:      ldx     [%g1], %g2                        127 1:      ldx     [%g1], %g2
128         stxa    %g2, [%g4] ASI_PHYS_USE_EC        128         stxa    %g2, [%g4] ASI_PHYS_USE_EC
129         stx     %g4, [%g1]                        129         stx     %g4, [%g1]
130                                                   130 
131         /* Signal the interrupt by setting (1     131         /* Signal the interrupt by setting (1 << pil) in %softint.  */
132         wr      %g0, 1 << PIL_DEVICE_IRQ, %set    132         wr      %g0, 1 << PIL_DEVICE_IRQ, %set_softint
133                                                   133 
134 sun4v_dev_mondo_queue_empty:                      134 sun4v_dev_mondo_queue_empty:
135         retry                                     135         retry
136                                                   136 
137 sun4v_res_mondo:                                  137 sun4v_res_mondo:
138         /* Head offset in %g2, tail offset in     138         /* Head offset in %g2, tail offset in %g4.  */
139         mov     INTRQ_RESUM_MONDO_HEAD, %g2       139         mov     INTRQ_RESUM_MONDO_HEAD, %g2
140         ldxa    [%g2] ASI_QUEUE, %g2              140         ldxa    [%g2] ASI_QUEUE, %g2
141         mov     INTRQ_RESUM_MONDO_TAIL, %g4       141         mov     INTRQ_RESUM_MONDO_TAIL, %g4
142         ldxa    [%g4] ASI_QUEUE, %g4              142         ldxa    [%g4] ASI_QUEUE, %g4
143         cmp     %g2, %g4                          143         cmp     %g2, %g4
144         be,pn   %xcc, sun4v_res_mondo_queue_em    144         be,pn   %xcc, sun4v_res_mondo_queue_empty
145          nop                                      145          nop
146                                                   146 
147         /* Get &trap_block[smp_processor_id()]    147         /* Get &trap_block[smp_processor_id()] into %g3.  */
148         ldxa    [%g0] ASI_SCRATCHPAD, %g3         148         ldxa    [%g0] ASI_SCRATCHPAD, %g3
149         sub     %g3, TRAP_PER_CPU_FAULT_INFO,     149         sub     %g3, TRAP_PER_CPU_FAULT_INFO, %g3
150                                                   150 
151         /* Get RES mondo queue base phys addre    151         /* Get RES mondo queue base phys address into %g5.  */
152         ldx     [%g3 + TRAP_PER_CPU_RESUM_MOND    152         ldx     [%g3 + TRAP_PER_CPU_RESUM_MONDO_PA], %g5
153                                                   153 
154         /* Get RES kernel buffer base phys add    154         /* Get RES kernel buffer base phys address into %g7.  */
155         ldx     [%g3 + TRAP_PER_CPU_RESUM_KBUF    155         ldx     [%g3 + TRAP_PER_CPU_RESUM_KBUF_PA], %g7
156                                                   156 
157         /* If the first word is non-zero, queu    157         /* If the first word is non-zero, queue is full.  */
158         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %    158         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %g1
159         brnz,pn %g1, sun4v_res_mondo_queue_ful    159         brnz,pn %g1, sun4v_res_mondo_queue_full
160          nop                                      160          nop
161                                                   161 
162         lduw    [%g3 + TRAP_PER_CPU_RESUM_QMAS    162         lduw    [%g3 + TRAP_PER_CPU_RESUM_QMASK], %g4
163                                                   163 
164         /* Remember this entry's offset in %g1    164         /* Remember this entry's offset in %g1.  */
165         mov     %g2, %g1                          165         mov     %g2, %g1
166                                                   166 
167         /* Copy 64-byte queue entry into kerne    167         /* Copy 64-byte queue entry into kernel buffer.  */
168         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    168         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
169         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    169         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
170         add     %g2, 0x08, %g2                    170         add     %g2, 0x08, %g2
171         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    171         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
172         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    172         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
173         add     %g2, 0x08, %g2                    173         add     %g2, 0x08, %g2
174         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    174         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
175         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    175         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
176         add     %g2, 0x08, %g2                    176         add     %g2, 0x08, %g2
177         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    177         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
178         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    178         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
179         add     %g2, 0x08, %g2                    179         add     %g2, 0x08, %g2
180         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    180         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
181         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    181         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
182         add     %g2, 0x08, %g2                    182         add     %g2, 0x08, %g2
183         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    183         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
184         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    184         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
185         add     %g2, 0x08, %g2                    185         add     %g2, 0x08, %g2
186         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    186         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
187         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    187         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
188         add     %g2, 0x08, %g2                    188         add     %g2, 0x08, %g2
189         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    189         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
190         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    190         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
191         add     %g2, 0x08, %g2                    191         add     %g2, 0x08, %g2
192                                                   192 
193         /* Update queue head pointer.  */         193         /* Update queue head pointer.  */
194         and     %g2, %g4, %g2                     194         and     %g2, %g4, %g2
195                                                   195 
196         mov     INTRQ_RESUM_MONDO_HEAD, %g4       196         mov     INTRQ_RESUM_MONDO_HEAD, %g4
197         stxa    %g2, [%g4] ASI_QUEUE              197         stxa    %g2, [%g4] ASI_QUEUE
198         membar  #Sync                             198         membar  #Sync
199                                                   199 
200         /* Disable interrupts and save registe    200         /* Disable interrupts and save register state so we can call
201          * C code.  The etrap handling will le    201          * C code.  The etrap handling will leave %g4 in %l4 for us
202          * when it's done.                        202          * when it's done.
203          */                                       203          */
204         rdpr    %pil, %g2                         204         rdpr    %pil, %g2
205         wrpr    %g0, PIL_NORMAL_MAX, %pil         205         wrpr    %g0, PIL_NORMAL_MAX, %pil
206         mov     %g1, %g4                          206         mov     %g1, %g4
207         ba,pt   %xcc, etrap_irq                   207         ba,pt   %xcc, etrap_irq
208          rd     %pc, %g7                          208          rd     %pc, %g7
209 #ifdef CONFIG_TRACE_IRQFLAGS                      209 #ifdef CONFIG_TRACE_IRQFLAGS
210         call            trace_hardirqs_off        210         call            trace_hardirqs_off
211          nop                                      211          nop
212 #endif                                            212 #endif
213         /* Log the event.  */                     213         /* Log the event.  */
214         add     %sp, PTREGS_OFF, %o0              214         add     %sp, PTREGS_OFF, %o0
215         call    sun4v_resum_error                 215         call    sun4v_resum_error
216          mov    %l4, %o1                          216          mov    %l4, %o1
217                                                   217 
218         /* Return from trap.  */                  218         /* Return from trap.  */
219         ba,pt   %xcc, rtrap_irq                   219         ba,pt   %xcc, rtrap_irq
220          nop                                      220          nop
221                                                   221 
222 sun4v_res_mondo_queue_empty:                      222 sun4v_res_mondo_queue_empty:
223         retry                                     223         retry
224                                                   224 
225 sun4v_res_mondo_queue_full:                       225 sun4v_res_mondo_queue_full:
226         /* The queue is full, consolidate our     226         /* The queue is full, consolidate our damage by setting
227          * the head equal to the tail.  We'll     227          * the head equal to the tail.  We'll just trap again otherwise.
228          * Call C code to log the event.          228          * Call C code to log the event.
229          */                                       229          */
230         mov     INTRQ_RESUM_MONDO_HEAD, %g2       230         mov     INTRQ_RESUM_MONDO_HEAD, %g2
231         stxa    %g4, [%g2] ASI_QUEUE              231         stxa    %g4, [%g2] ASI_QUEUE
232         membar  #Sync                             232         membar  #Sync
233                                                   233 
234         rdpr    %pil, %g2                         234         rdpr    %pil, %g2
235         wrpr    %g0, PIL_NORMAL_MAX, %pil         235         wrpr    %g0, PIL_NORMAL_MAX, %pil
236         ba,pt   %xcc, etrap_irq                   236         ba,pt   %xcc, etrap_irq
237          rd     %pc, %g7                          237          rd     %pc, %g7
238 #ifdef CONFIG_TRACE_IRQFLAGS                      238 #ifdef CONFIG_TRACE_IRQFLAGS
239         call            trace_hardirqs_off        239         call            trace_hardirqs_off
240          nop                                      240          nop
241 #endif                                            241 #endif
242         call    sun4v_resum_overflow              242         call    sun4v_resum_overflow
243          add    %sp, PTREGS_OFF, %o0              243          add    %sp, PTREGS_OFF, %o0
244                                                   244 
245         ba,pt   %xcc, rtrap_irq                   245         ba,pt   %xcc, rtrap_irq
246          nop                                      246          nop
247                                                   247 
248 sun4v_nonres_mondo:                               248 sun4v_nonres_mondo:
249         /* Head offset in %g2, tail offset in     249         /* Head offset in %g2, tail offset in %g4.  */
250         mov     INTRQ_NONRESUM_MONDO_HEAD, %g2    250         mov     INTRQ_NONRESUM_MONDO_HEAD, %g2
251         ldxa    [%g2] ASI_QUEUE, %g2              251         ldxa    [%g2] ASI_QUEUE, %g2
252         mov     INTRQ_NONRESUM_MONDO_TAIL, %g4    252         mov     INTRQ_NONRESUM_MONDO_TAIL, %g4
253         ldxa    [%g4] ASI_QUEUE, %g4              253         ldxa    [%g4] ASI_QUEUE, %g4
254         cmp     %g2, %g4                          254         cmp     %g2, %g4
255         be,pn   %xcc, sun4v_nonres_mondo_queue    255         be,pn   %xcc, sun4v_nonres_mondo_queue_empty
256          nop                                      256          nop
257                                                   257 
258         /* Get &trap_block[smp_processor_id()]    258         /* Get &trap_block[smp_processor_id()] into %g3.  */
259         ldxa    [%g0] ASI_SCRATCHPAD, %g3         259         ldxa    [%g0] ASI_SCRATCHPAD, %g3
260         sub     %g3, TRAP_PER_CPU_FAULT_INFO,     260         sub     %g3, TRAP_PER_CPU_FAULT_INFO, %g3
261                                                   261 
262         /* Get RES mondo queue base phys addre    262         /* Get RES mondo queue base phys address into %g5.  */
263         ldx     [%g3 + TRAP_PER_CPU_NONRESUM_M    263         ldx     [%g3 + TRAP_PER_CPU_NONRESUM_MONDO_PA], %g5
264                                                   264 
265         /* Get RES kernel buffer base phys add    265         /* Get RES kernel buffer base phys address into %g7.  */
266         ldx     [%g3 + TRAP_PER_CPU_NONRESUM_K    266         ldx     [%g3 + TRAP_PER_CPU_NONRESUM_KBUF_PA], %g7
267                                                   267 
268         /* If the first word is non-zero, queu    268         /* If the first word is non-zero, queue is full.  */
269         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %    269         ldxa    [%g7 + %g2] ASI_PHYS_USE_EC, %g1
270         brnz,pn %g1, sun4v_nonres_mondo_queue_    270         brnz,pn %g1, sun4v_nonres_mondo_queue_full
271          nop                                      271          nop
272                                                   272 
273         lduw    [%g3 + TRAP_PER_CPU_NONRESUM_Q    273         lduw    [%g3 + TRAP_PER_CPU_NONRESUM_QMASK], %g4
274                                                   274 
275         /* Remember this entry's offset in %g1    275         /* Remember this entry's offset in %g1.  */
276         mov     %g2, %g1                          276         mov     %g2, %g1
277                                                   277 
278         /* Copy 64-byte queue entry into kerne    278         /* Copy 64-byte queue entry into kernel buffer.  */
279         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    279         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
280         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    280         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
281         add     %g2, 0x08, %g2                    281         add     %g2, 0x08, %g2
282         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    282         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
283         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    283         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
284         add     %g2, 0x08, %g2                    284         add     %g2, 0x08, %g2
285         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    285         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
286         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    286         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
287         add     %g2, 0x08, %g2                    287         add     %g2, 0x08, %g2
288         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    288         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
289         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    289         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
290         add     %g2, 0x08, %g2                    290         add     %g2, 0x08, %g2
291         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    291         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
292         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    292         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
293         add     %g2, 0x08, %g2                    293         add     %g2, 0x08, %g2
294         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    294         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
295         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    295         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
296         add     %g2, 0x08, %g2                    296         add     %g2, 0x08, %g2
297         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    297         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
298         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    298         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
299         add     %g2, 0x08, %g2                    299         add     %g2, 0x08, %g2
300         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %    300         ldxa    [%g5 + %g2] ASI_PHYS_USE_EC, %g3
301         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_    301         stxa    %g3, [%g7 + %g2] ASI_PHYS_USE_EC
302         add     %g2, 0x08, %g2                    302         add     %g2, 0x08, %g2
303                                                   303 
304         /* Update queue head pointer.  */         304         /* Update queue head pointer.  */
305         and     %g2, %g4, %g2                     305         and     %g2, %g4, %g2
306                                                   306 
307         mov     INTRQ_NONRESUM_MONDO_HEAD, %g4    307         mov     INTRQ_NONRESUM_MONDO_HEAD, %g4
308         stxa    %g2, [%g4] ASI_QUEUE              308         stxa    %g2, [%g4] ASI_QUEUE
309         membar  #Sync                             309         membar  #Sync
310                                                   310 
311         /* Disable interrupts and save registe    311         /* Disable interrupts and save register state so we can call
312          * C code.  The etrap handling will le    312          * C code.  The etrap handling will leave %g4 in %l4 for us
313          * when it's done.                        313          * when it's done.
314          */                                       314          */
315         rdpr    %pil, %g2                         315         rdpr    %pil, %g2
316         wrpr    %g0, PIL_NORMAL_MAX, %pil         316         wrpr    %g0, PIL_NORMAL_MAX, %pil
317         mov     %g1, %g4                          317         mov     %g1, %g4
318         ba,pt   %xcc, etrap_irq                   318         ba,pt   %xcc, etrap_irq
319          rd     %pc, %g7                          319          rd     %pc, %g7
320 #ifdef CONFIG_TRACE_IRQFLAGS                      320 #ifdef CONFIG_TRACE_IRQFLAGS
321         call            trace_hardirqs_off        321         call            trace_hardirqs_off
322          nop                                      322          nop
323 #endif                                            323 #endif
324         /* Log the event.  */                     324         /* Log the event.  */
325         add     %sp, PTREGS_OFF, %o0              325         add     %sp, PTREGS_OFF, %o0
326         call    sun4v_nonresum_error              326         call    sun4v_nonresum_error
327          mov    %l4, %o1                          327          mov    %l4, %o1
328                                                   328 
329         /* Return from trap.  */                  329         /* Return from trap.  */
330         ba,pt   %xcc, rtrap_irq                   330         ba,pt   %xcc, rtrap_irq
331          nop                                      331          nop
332                                                   332 
333 sun4v_nonres_mondo_queue_empty:                   333 sun4v_nonres_mondo_queue_empty:
334         retry                                     334         retry
335                                                   335 
336 sun4v_nonres_mondo_queue_full:                    336 sun4v_nonres_mondo_queue_full:
337         /* The queue is full, consolidate our     337         /* The queue is full, consolidate our damage by setting
338          * the head equal to the tail.  We'll     338          * the head equal to the tail.  We'll just trap again otherwise.
339          * Call C code to log the event.          339          * Call C code to log the event.
340          */                                       340          */
341         mov     INTRQ_NONRESUM_MONDO_HEAD, %g2    341         mov     INTRQ_NONRESUM_MONDO_HEAD, %g2
342         stxa    %g4, [%g2] ASI_QUEUE              342         stxa    %g4, [%g2] ASI_QUEUE
343         membar  #Sync                             343         membar  #Sync
344                                                   344 
345         rdpr    %pil, %g2                         345         rdpr    %pil, %g2
346         wrpr    %g0, PIL_NORMAL_MAX, %pil         346         wrpr    %g0, PIL_NORMAL_MAX, %pil
347         ba,pt   %xcc, etrap_irq                   347         ba,pt   %xcc, etrap_irq
348          rd     %pc, %g7                          348          rd     %pc, %g7
349 #ifdef CONFIG_TRACE_IRQFLAGS                      349 #ifdef CONFIG_TRACE_IRQFLAGS
350         call            trace_hardirqs_off        350         call            trace_hardirqs_off
351          nop                                      351          nop
352 #endif                                            352 #endif
353         call    sun4v_nonresum_overflow           353         call    sun4v_nonresum_overflow
354          add    %sp, PTREGS_OFF, %o0              354          add    %sp, PTREGS_OFF, %o0
355                                                   355 
356         ba,pt   %xcc, rtrap_irq                   356         ba,pt   %xcc, rtrap_irq
357          nop                                      357          nop
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php