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#undef __ASSEMBLY__ 41#define __ASSEMBLY__ 42 43#ifdef __linux__ 44#include <asm/asm.h> 45#include <asm/regdef.h> 46#else 47#include <machine/asm.h> 48#include <machine/regdef.h> 49#endif 50 51#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 52#include <asm/octeon/cvmx-asm.h> 53#include <asm/octeon/octeon-boot-info.h> 54#else 55 56#include "cvmx-asm.h" 57 58#ifndef _OCTEON_TOOLCHAIN_RUNTIME 59#include <octeon_mem_map.h> 60#else 61#include "cvmx-platform.h" 62#include "octeon-boot-info.h" 63#endif 64 65#endif 66 67/* The registers saving/restoring is split into two because k0 is stored in the COP0_DESAVE register. */ 68#define REGS0 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 69#define REGS1 27,28,29,30,31 70 71#define SAVE_REGISTER(reg) \ 72 sd reg, 0(k0); \ 73 addi k0, 8 74 75#define RESTORE_REGISTER(reg) \ 76 ld reg, -8(k0); \ 77 addi k0, -8 78 79#define SAVE_COP0(reg) \ 80 dmfc0 k1,reg; \ 81 sd k1, 0(k0); \ 82 addi k0, 8 83 84#define RESTORE_COP0(reg) \ 85 ld k1, -8(k0); \ 86 addi k0, -8; \ 87 dmtc0 k1,reg 88 89#define SAVE_ADDRESS(addr) \ 90 dli k1, addr; \ 91 ld k1, 0(k1); \ 92 sd k1, 0(k0); \ 93 addi k0, 8 94 95#define RESTORE_ADDRESS(addr) \ 96 dli t0, addr; \ 97 ld k1, -8(k0); \ 98 sd k1, 0(t0); \ 99 addi k0, -8 100 101#define REG_SAVE_BASE_DIV_8 (BOOTLOADER_DEBUG_REG_SAVE_BASE >> 3) 102 103 104#define HW_INSTRUCTION_BREAKPOINT_STATUS (0xFFFFFFFFFF301000) 105#define HW_INSTRUCTION_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF301100 + 0x100 * (num)) 106#define HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF301108 + 0x100 * (num)) 107#define HW_INSTRUCTION_BREAKPOINT_ASID(num) (0xFFFFFFFFFF301110 + 0x100 * (num)) 108#define HW_INSTRUCTION_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF301118 + 0x100 * (num)) 109 110#define HW_DATA_BREAKPOINT_STATUS (0xFFFFFFFFFF302000) 111#define HW_DATA_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF302100 + 0x100 * (num)) 112#define HW_DATA_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF302108 + 0x100 * (num)) 113#define HW_DATA_BREAKPOINT_ASID(num) (0xFFFFFFFFFF302110 + 0x100 * (num)) 114#define HW_DATA_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF302118 + 0x100 * (num)) 115 116 117#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 118#define loadaddr(reg, addr, shift) \ 119 dla reg, addr##_all; \ 120 mfc0 $1, $15, 1; \ 121 andi $1, 0xff; \ 122 sll $1, shift; \ 123 add reg, reg, $1 124#else 125#define loadaddr(reg, addr, shift) \ 126 dla reg, addr 127#endif 128 129 130 .set noreorder 131 .set noat 132 133 .text 134 135// Detect debug-mode exception, save all registers, create a stack and then 136// call the stage3 C function. 137 138 .ent __cvmx_debug_handler_stage2 139 .globl __cvmx_debug_handler_stage2 140__cvmx_debug_handler_stage2: 141 // Save off k0 in COP0_DESAVE 142 dmtc0 k0, COP0_DESAVE 143 144 // Use reserved space in kseg0 to save off some temp regs 145 mfc0 k0, $15, 1 // read exception base reg. 146 andi k0, 0xff // mask off core ID 147 sll k0, 12 // multiply by 4096 (512 dwords) DEBUG_NUMREGS 148 149 addiu k0, REG_SAVE_BASE_DIV_8 150 addiu k0, REG_SAVE_BASE_DIV_8 151 addiu k0, REG_SAVE_BASE_DIV_8 152 addiu k0, REG_SAVE_BASE_DIV_8 153 addiu k0, REG_SAVE_BASE_DIV_8 154 addiu k0, REG_SAVE_BASE_DIV_8 155 addiu k0, REG_SAVE_BASE_DIV_8 156 addiu k0, REG_SAVE_BASE_DIV_8 157 // add base offset - after exeption vectors for all cores 158 159 rotr k0, k0, 31 // set bit 31 for kseg0 access 160 addi k0, 1 161 rotr k0, k0, 1 162 163 // save off k1 and at ($1) off to the bootloader reg save area 164 // at is used by dla 165 sd $1, 8(k0) // save at for temp usage 166 sd k1, 216(k0) // save k1 for temp usage 167 168 169 // Detect debug-mode exception. 170 // If COP0_MULTICOREDEBUG[DExecC] is set, 171 dmfc0 k1, COP0_MULTICOREDEBUG 172 bbit0 k1, 16, noexc 173 nop 174 175 // COP0_DEBUG[DINT,DIB,DDBS,DBp,DSS] are not set and 176 dmfc0 k1, COP0_DEBUG 177 andi k1, 0x3f 178 bnez k1, noexc 179 nop 180 181 // COP0_DEBUG[DExecC] is set. 182 dmfc0 k1, COP0_DEBUG 183 dext k1,k1,10,5 184 beqz k1,noexc 185 nop 186 187 // We don't handle debug-mode exceptions in delay-slots so DEBUG[DBD] 188 // should not be set. If yes spin forever. 189 dmfc0 k1, COP0_DEBUG 1901: 191 bbit1 k1, 31, 1b 192 nop 193 194 // It's a debug-mode exception. Flag the occurence. Also if it's 195 // expected just ignore it but returning the subsequent instruction 196 // after the fault. 197 198 loadaddr (k1, __cvmx_debug_mode_exception_occured, 3) 199 sd k1, 0(k1) 200 201 loadaddr (k1, __cvmx_debug_mode_exception_ignore, 3) 202 ld k1, 0(k1) 203 beqz k1, noexc 204 nop 205 206 // Restore k1 and at from the bootloader reg save area 207 ld $1, 8(k0) // save at for temp usage 208 ld k1, 216(k0) // save k1 for temp usage 209 210 dmfc0 k0, COP0_DEPC 211 // Skip the faulting instruction. 212 daddiu k0, 4 213 jr k0 214 dmfc0 k0, COP0_DESAVE 215 216noexc: 217 218 loadaddr (k1, __cvmx_debug_save_regs_area, 8) 219 220 // Restore at 221 ld $1, 8(k0) // restore at for temp usage 222 223 .irp n, REGS0 224 sd $\n, 0(k1) 225 addiu k1, 8 226 .endr 227 228 move $25, k1 229 ld k1, 216(k0) // restore k1 for temp usage 230 move k0, $25 231 232 // Store out k0, we can use $25 here because we just saved it 233 dmfc0 $25, COP0_DESAVE 234 sd $25, 0(k0) 235 addiu k0, 8 236 237 .irp n, REGS1 238 sd $\n, 0(k0) 239 addiu k0, 8 240 .endr 241 242 loadaddr(sp, __cvmx_debug_stack_top, 3) 243 // Load the stack pointer as a pointer size. 244#ifdef _ABIN32 245 lw sp,0(sp) 246#else 247 ld sp,0(sp) 248#endif 249 mflo $4 250 mfhi $5 251 jal __cvmx_debug_handler_stage3 252 nop 253 254 loadaddr(k0, __cvmx_debug_save_regs_area, 8) 255 256 .irp n, REGS0 257 ld $\n, 0(k0) 258 addiu k0, 8 259 .endr 260 261 // Restore k0 to COP0_DESAVE via k1 262 ld k1, 0(k0) 263 addiu k0, 8 264 dmtc0 k1, COP0_DESAVE 265 266 .irp n, REGS1 267 ld $\n, 0(k0) 268 addiu k0, 8 269 .endr 270 271 dmfc0 k0, COP0_DESAVE 272 // Flush the icache; by adding and removing SW breakpoints we change 273 // the instruction stream. 274 synci 0($0) 275 deret 276 nop 277 278 .end __cvmx_debug_handler_stage2 279