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