1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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
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
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM NETWORKS 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**************************************/
49 #include <machine/asm.h>
50 #include <machine/regdef.h>
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.
60 END(cvmx_interrupt_stage1)
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
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
96 daddu $1, sp, STACK_SIZE // Correct the SP for the space we used
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
106 /* Store DEPC for GCC's frame unwinder. */
110 dla k0, cvmx_interrupt_in_isr
114 dla k0, cvmx_interrupt_do_irq
116 dadd a0, sp, 0 // First argument is array of registers
118 dla k0, cvmx_interrupt_in_isr
121 ld k0, 256(sp) // read hi
122 ld k1, 264(sp) // read lo
123 mthi k0 // restore hi
124 mtlo k1 // restore lo
126 ld $1, 8(sp) // start restoring registers
154 ld $31, 248(sp) // restored all general purpose registers
155 ld $29, 232(sp) // No need to correct for STACK_SIZE
158 END(cvmx_interrupt_stage2)
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)
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
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
186 ld k0, K0_STORE_LOCATION($0) // Restore K0 since we might have been in an exception
187 eret // Return from the Icache exception
189 END(cvmx_interrupt_cache_error)