OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [sparc64/] [kernel/] [sun4v_ivec.S] - Blame information for rev 3

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.