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 55LEAF(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 60END(cvmx_interrupt_stage1) 61 62#define STACK_SIZE (36*8) 63LEAF(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 158END(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 168LEAF(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 178not_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 185not_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 196END(cvmx_interrupt_cache_error) 197 198