]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/octeon-sdk/cvmx-interrupt-handler.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / octeon-sdk / cvmx-interrupt-handler.S
1 /***********************license start***************
2  * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights 
3  * reserved.
4  *
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *   * Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  *
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17
18  *   * Neither the name of Cavium Inc. nor the names of
19  *     its contributors may be used to endorse or promote products
20  *     derived from this software without specific prior written
21  *     permission.  
22
23  * This Software, including technical data, may be subject to U.S. export  control
24  * laws, including the U.S. Export Administration Act and its  associated
25  * regulations, and may be subject to export or import  regulations in other
26  * countries. 
27
28  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 
29  * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30  * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31  * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32  * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33  * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34  * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35  * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36  * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37  * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38  ***********************license end**************************************/
39
40
41
42
43
44
45
46
47
48
49 #include <machine/asm.h>
50 #include <machine/regdef.h>
51
52 .set noreorder
53 .set noat
54
55 LEAF(cvmx_interrupt_stage1)
56         dla     k0, cvmx_interrupt_stage2
57         jalr    k1, k0   // Save our address in k1, so we can tell which
58                          // vector we are coming from.
59         nop
60 END(cvmx_interrupt_stage1)
61
62 #define STACK_SIZE  (36*8)
63 LEAF(cvmx_interrupt_stage2)
64         dsubu   sp, sp, STACK_SIZE
65         sd      zero, 0(sp)     // Just a place holder
66         sd      $1, 8(sp)       // start saving registers
67         sd      $2, 16(sp)
68         sd      $3, 24(sp)
69         sd      $4, 32(sp)
70         sd      $5, 40(sp)
71         sd      $6, 48(sp)
72         sd      $7, 56(sp)
73         sd      $8, 64(sp)
74         sd      $9, 72(sp)
75         sd      $10, 80(sp)
76         sd      $11, 88(sp)
77         sd      $12, 96(sp)
78         sd      $13, 104(sp)
79         sd      $14, 112(sp)
80         sd      $15, 120(sp)
81         sd      $16, 128(sp)
82         sd      $17, 136(sp)
83         sd      $18, 144(sp)
84         sd      $19, 152(sp)
85         sd      $20, 160(sp)
86         sd      $21, 168(sp)
87         sd      $22, 176(sp)
88         sd      $23, 184(sp)
89         sd      $24, 192(sp)
90         sd      $25, 200(sp)
91         sd      $26, 208(sp)
92         sd      $27, 216(sp)
93         mfhi    k0              // Reading lo and high takes multiple cycles
94         mflo    k1              // Do it here so it completes by the time we need it
95         sd      $28, 224(sp)
96         daddu   $1, sp, STACK_SIZE // Correct the SP for the space we used
97         sd      $1, 232(sp)
98         sd      $30, 240(sp)
99         sd      $31, 248(sp)    // saved all general purpose registers
100         sd      k0, 256(sp)     // save hi
101         sd      k1, 264(sp)     // save lo
102         /* Save DCACHE error register early, since any non-errored DCACHE accesses will clear
103         ** error bit */
104         dmfc0   k0, $27, 1
105         sd      k0, 272(sp)
106         /* Store EPC for GCC's frame unwinder. */
107         dmfc0   k0, $14
108         sd      k0, 280(sp)
109
110         dla     k0, cvmx_interrupt_in_isr
111         li      k1, 1
112         sw      k1, 0(k0)
113
114         dla     k0, cvmx_interrupt_do_irq
115         jal     k0
116         dadd    a0, sp, 0       // First argument is array of registers
117
118         dla     k0, cvmx_interrupt_in_isr
119         sw      $0, 0(k0)
120
121         ld      k0, 256(sp)     // read hi
122         ld      k1, 264(sp)     // read lo
123         mthi    k0              // restore hi
124         mtlo    k1              // restore lo
125
126         ld      $1, 8(sp)       // start restoring registers
127         ld      $2, 16(sp)
128         ld      $3, 24(sp)
129         ld      $4, 32(sp)
130         ld      $5, 40(sp)
131         ld      $6, 48(sp)
132         ld      $7, 56(sp)
133         ld      $8, 64(sp)
134         ld      $9, 72(sp)
135         ld      $10, 80(sp)
136         ld      $11, 88(sp)
137         ld      $12, 96(sp)
138         ld      $13, 104(sp)
139         ld      $14, 112(sp)
140         ld      $15, 120(sp)
141         ld      $16, 128(sp)
142         ld      $17, 136(sp)
143         ld      $18, 144(sp)
144         ld      $19, 152(sp)
145         ld      $20, 160(sp)
146         ld      $21, 168(sp)
147         ld      $22, 176(sp)
148         ld      $23, 184(sp)
149         ld      $24, 192(sp)
150         ld      $25, 200(sp)
151         ld      $26, 208(sp)
152         ld      $28, 224(sp)
153         ld      $30, 240(sp)
154         ld      $31, 248(sp)    // restored all general purpose registers
155         ld      $29, 232(sp)    // No need to correct for STACK_SIZE
156         eret
157         nop
158 END(cvmx_interrupt_stage2)
159
160 // Icache and Dcache exception handler. This code is executed
161 // with ERL set so we can't us virtual addresses. We save and restore
162 // K0 to a global memory location so we can handle cache errors from exception
163 // context. This means that if two cores get a cache exception at the same time
164 // the K0 might be corrupted. This entire handler MUST fit in 128 bytes.
165 #define K0_STORE_LOCATION       8
166 #define DCACHE_ERROR_COUNT      16
167 #define ICACHE_ERROR_COUNT      24
168 LEAF(cvmx_interrupt_cache_error)
169         .set push
170         .set noreorder
171         sd      k0, K0_STORE_LOCATION($0)       // Store K0 into global loc in case we're in an exception
172         dmfc0   k0, $27, 1                      // Get Dcache error status before any loads
173         bbit0   k0, 0, not_dcache_error         // Skip dcache count if no error
174          dmtc0  k0, $27, 1                      // Clear any Dcache errors
175         ld      k0, DCACHE_ERROR_COUNT($0)      // Load the dcache error count
176         daddu   k0, 1                           // Increment the dcache error count
177         sd      k0, DCACHE_ERROR_COUNT($0)      // Store the dcache error count
178 not_dcache_error:
179         dmfc0   k0, $27, 0                      // Get the Icache error status
180         bbit0   k0, 0, not_icache_error         // Skip Icache count if no error
181          dmtc0  k0, $27, 0                      // Clear any Icache errors
182         ld      k0, ICACHE_ERROR_COUNT($0)      // Load the icache error count
183         daddu   k0, 1                           // Increment the icache error count
184         sd      k0, ICACHE_ERROR_COUNT($0)      // Store the icache error count
185 not_icache_error:
186         ld      k0, K0_STORE_LOCATION($0)       // Restore K0 since we might have been in an exception
187         nop
188         nop
189         nop
190         nop
191         nop
192         nop                                     // Keep the ERET 8 instructions away
193         nop                                     // from a branch target.
194         eret                                    // Return from the Icache exception
195         .set pop
196 END(cvmx_interrupt_cache_error)
197