diff options
Diffstat (limited to 'sys/contrib/octeon-sdk/cvmx-interrupt-handler.S')
-rw-r--r-- | sys/contrib/octeon-sdk/cvmx-interrupt-handler.S | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/sys/contrib/octeon-sdk/cvmx-interrupt-handler.S b/sys/contrib/octeon-sdk/cvmx-interrupt-handler.S new file mode 100644 index 0000000..b2b1837 --- /dev/null +++ b/sys/contrib/octeon-sdk/cvmx-interrupt-handler.S @@ -0,0 +1,197 @@ +/***********************license start*************** + * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights + * reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + + * * Neither the name of Cavium Inc. nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + + * This Software, including technical data, may be subject to U.S. export control + * laws, including the U.S. Export Administration Act and its associated + * regulations, and may be subject to export or import regulations in other + * countries. + + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" + * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR + * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO + * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR + * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM + * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, + * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF + * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR + * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR + * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. + ***********************license end**************************************/ + + + + + + + + + + +#include <machine/asm.h> +#include <machine/regdef.h> + +.set noreorder +.set noat + +LEAF(cvmx_interrupt_stage1) + dla k0, cvmx_interrupt_stage2 + jalr k1, k0 // Save our address in k1, so we can tell which + // vector we are coming from. + nop +END(cvmx_interrupt_stage1) + +#define STACK_SIZE (36*8) +LEAF(cvmx_interrupt_stage2) + dsubu sp, sp, STACK_SIZE + sd zero, 0(sp) // Just a place holder + sd $1, 8(sp) // start saving registers + sd $2, 16(sp) + sd $3, 24(sp) + sd $4, 32(sp) + sd $5, 40(sp) + sd $6, 48(sp) + sd $7, 56(sp) + sd $8, 64(sp) + sd $9, 72(sp) + sd $10, 80(sp) + sd $11, 88(sp) + sd $12, 96(sp) + sd $13, 104(sp) + sd $14, 112(sp) + sd $15, 120(sp) + sd $16, 128(sp) + sd $17, 136(sp) + sd $18, 144(sp) + sd $19, 152(sp) + sd $20, 160(sp) + sd $21, 168(sp) + sd $22, 176(sp) + sd $23, 184(sp) + sd $24, 192(sp) + sd $25, 200(sp) + sd $26, 208(sp) + sd $27, 216(sp) + mfhi k0 // Reading lo and high takes multiple cycles + mflo k1 // Do it here so it completes by the time we need it + sd $28, 224(sp) + daddu $1, sp, STACK_SIZE // Correct the SP for the space we used + sd $1, 232(sp) + sd $30, 240(sp) + sd $31, 248(sp) // saved all general purpose registers + sd k0, 256(sp) // save hi + sd k1, 264(sp) // save lo + /* Save DCACHE error register early, since any non-errored DCACHE accesses will clear + ** error bit */ + dmfc0 k0, $27, 1 + sd k0, 272(sp) + /* Store EPC for GCC's frame unwinder. */ + dmfc0 k0, $14 + sd k0, 280(sp) + + dla k0, cvmx_interrupt_in_isr + li k1, 1 + sw k1, 0(k0) + + dla k0, cvmx_interrupt_do_irq + jal k0 + dadd a0, sp, 0 // First argument is array of registers + + dla k0, cvmx_interrupt_in_isr + sw $0, 0(k0) + + ld k0, 256(sp) // read hi + ld k1, 264(sp) // read lo + mthi k0 // restore hi + mtlo k1 // restore lo + + ld $1, 8(sp) // start restoring registers + ld $2, 16(sp) + ld $3, 24(sp) + ld $4, 32(sp) + ld $5, 40(sp) + ld $6, 48(sp) + ld $7, 56(sp) + ld $8, 64(sp) + ld $9, 72(sp) + ld $10, 80(sp) + ld $11, 88(sp) + ld $12, 96(sp) + ld $13, 104(sp) + ld $14, 112(sp) + ld $15, 120(sp) + ld $16, 128(sp) + ld $17, 136(sp) + ld $18, 144(sp) + ld $19, 152(sp) + ld $20, 160(sp) + ld $21, 168(sp) + ld $22, 176(sp) + ld $23, 184(sp) + ld $24, 192(sp) + ld $25, 200(sp) + ld $26, 208(sp) + ld $28, 224(sp) + ld $30, 240(sp) + ld $31, 248(sp) // restored all general purpose registers + ld $29, 232(sp) // No need to correct for STACK_SIZE + eret + nop +END(cvmx_interrupt_stage2) + +// Icache and Dcache exception handler. This code is executed +// with ERL set so we can't us virtual addresses. We save and restore +// K0 to a global memory location so we can handle cache errors from exception +// context. This means that if two cores get a cache exception at the same time +// the K0 might be corrupted. This entire handler MUST fit in 128 bytes. +#define K0_STORE_LOCATION 8 +#define DCACHE_ERROR_COUNT 16 +#define ICACHE_ERROR_COUNT 24 +LEAF(cvmx_interrupt_cache_error) + .set push + .set noreorder + sd k0, K0_STORE_LOCATION($0) // Store K0 into global loc in case we're in an exception + dmfc0 k0, $27, 1 // Get Dcache error status before any loads + bbit0 k0, 0, not_dcache_error // Skip dcache count if no error + dmtc0 k0, $27, 1 // Clear any Dcache errors + ld k0, DCACHE_ERROR_COUNT($0) // Load the dcache error count + daddu k0, 1 // Increment the dcache error count + sd k0, DCACHE_ERROR_COUNT($0) // Store the dcache error count +not_dcache_error: + dmfc0 k0, $27, 0 // Get the Icache error status + bbit0 k0, 0, not_icache_error // Skip Icache count if no error + dmtc0 k0, $27, 0 // Clear any Icache errors + ld k0, ICACHE_ERROR_COUNT($0) // Load the icache error count + daddu k0, 1 // Increment the icache error count + sd k0, ICACHE_ERROR_COUNT($0) // Store the icache error count +not_icache_error: + ld k0, K0_STORE_LOCATION($0) // Restore K0 since we might have been in an exception + nop + nop + nop + nop + nop + nop // Keep the ERET 8 instructions away + nop // from a branch target. + eret // Return from the Icache exception + .set pop +END(cvmx_interrupt_cache_error) + |