cvmx-debug-handler.S revision 215976
1215976Sjmallett/***********************license start*************** 2215976Sjmallett * Copyright (c) 2003-2010 Cavium Networks (support@cavium.com). All rights 3215976Sjmallett * reserved. 4215976Sjmallett * 5215976Sjmallett * 6215976Sjmallett * Redistribution and use in source and binary forms, with or without 7215976Sjmallett * modification, are permitted provided that the following conditions are 8215976Sjmallett * met: 9215976Sjmallett * 10215976Sjmallett * * Redistributions of source code must retain the above copyright 11215976Sjmallett * notice, this list of conditions and the following disclaimer. 12215976Sjmallett * 13215976Sjmallett * * Redistributions in binary form must reproduce the above 14215976Sjmallett * copyright notice, this list of conditions and the following 15215976Sjmallett * disclaimer in the documentation and/or other materials provided 16215976Sjmallett * with the distribution. 17215976Sjmallett 18215976Sjmallett * * Neither the name of Cavium Networks nor the names of 19215976Sjmallett * its contributors may be used to endorse or promote products 20215976Sjmallett * derived from this software without specific prior written 21215976Sjmallett * permission. 22215976Sjmallett 23215976Sjmallett * This Software, including technical data, may be subject to U.S. export control 24215976Sjmallett * laws, including the U.S. Export Administration Act and its associated 25215976Sjmallett * regulations, and may be subject to export or import regulations in other 26215976Sjmallett * countries. 27215976Sjmallett 28215976Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29215976Sjmallett * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 30215976Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31215976Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32215976Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33215976Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34215976Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35215976Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36215976Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37215976Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38215976Sjmallett ***********************license end**************************************/ 39215976Sjmallett 40215976Sjmallett#undef __ASSEMBLY__ 41215976Sjmallett#define __ASSEMBLY__ 42215976Sjmallett 43215976Sjmallett#ifdef __linux__ 44215976Sjmallett#include <asm/asm.h> 45215976Sjmallett#include <asm/regdef.h> 46215976Sjmallett#else 47215976Sjmallett#include <machine/asm.h> 48215976Sjmallett#include <machine/regdef.h> 49215976Sjmallett#endif 50215976Sjmallett 51215976Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 52215976Sjmallett#include <asm/octeon/cvmx-asm.h> 53215976Sjmallett#include <asm/octeon/octeon-boot-info.h> 54215976Sjmallett#else 55215976Sjmallett#include "executive-config.h" 56215976Sjmallett#include "cvmx-asm.h" 57215976Sjmallett 58215976Sjmallett#ifndef __OCTEON_NEWLIB__ 59215976Sjmallett#include "../../bootloader/u-boot/include/octeon_mem_map.h" 60215976Sjmallett#else 61215976Sjmallett#include "octeon-boot-info.h" 62215976Sjmallett#endif 63215976Sjmallett 64215976Sjmallett#endif 65215976Sjmallett 66215976Sjmallett/* The registers saving/restoring is split into two because k0 is stored in the COP0_DESAVE register. */ 67215976Sjmallett#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 68215976Sjmallett#define REGS1 27,28,29,30,31 69215976Sjmallett 70215976Sjmallett#define SAVE_REGISTER(reg) \ 71215976Sjmallett sd reg, 0(k0); \ 72215976Sjmallett addi k0, 8 73215976Sjmallett 74215976Sjmallett#define RESTORE_REGISTER(reg) \ 75215976Sjmallett ld reg, -8(k0); \ 76215976Sjmallett addi k0, -8 77215976Sjmallett 78215976Sjmallett#define SAVE_COP0(reg) \ 79215976Sjmallett dmfc0 k1,reg; \ 80215976Sjmallett sd k1, 0(k0); \ 81215976Sjmallett addi k0, 8 82215976Sjmallett 83215976Sjmallett#define RESTORE_COP0(reg) \ 84215976Sjmallett ld k1, -8(k0); \ 85215976Sjmallett addi k0, -8; \ 86215976Sjmallett dmtc0 k1,reg 87215976Sjmallett 88215976Sjmallett#define SAVE_ADDRESS(addr) \ 89215976Sjmallett dli k1, addr; \ 90215976Sjmallett ld k1, 0(k1); \ 91215976Sjmallett sd k1, 0(k0); \ 92215976Sjmallett addi k0, 8 93215976Sjmallett 94215976Sjmallett#define RESTORE_ADDRESS(addr) \ 95215976Sjmallett dli t0, addr; \ 96215976Sjmallett ld k1, -8(k0); \ 97215976Sjmallett sd k1, 0(t0); \ 98215976Sjmallett addi k0, -8 99215976Sjmallett 100215976Sjmallett#define REG_SAVE_BASE_DIV_4 (BOOTLOADER_DEBUG_REG_SAVE_BASE >> 2) 101215976Sjmallett 102215976Sjmallett 103215976Sjmallett#define HW_INSTRUCTION_BREAKPOINT_STATUS (0xFFFFFFFFFF301000) 104215976Sjmallett#define HW_INSTRUCTION_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF301100 + 0x100 * (num)) 105215976Sjmallett#define HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF301108 + 0x100 * (num)) 106215976Sjmallett#define HW_INSTRUCTION_BREAKPOINT_ASID(num) (0xFFFFFFFFFF301110 + 0x100 * (num)) 107215976Sjmallett#define HW_INSTRUCTION_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF301118 + 0x100 * (num)) 108215976Sjmallett 109215976Sjmallett#define HW_DATA_BREAKPOINT_STATUS (0xFFFFFFFFFF302000) 110215976Sjmallett#define HW_DATA_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF302100 + 0x100 * (num)) 111215976Sjmallett#define HW_DATA_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF302108 + 0x100 * (num)) 112215976Sjmallett#define HW_DATA_BREAKPOINT_ASID(num) (0xFFFFFFFFFF302110 + 0x100 * (num)) 113215976Sjmallett#define HW_DATA_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF302118 + 0x100 * (num)) 114215976Sjmallett 115215976Sjmallett 116215976Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 117215976Sjmallett#define loadaddr(reg, addr, shift) \ 118215976Sjmallett dla reg, addr##_all; \ 119215976Sjmallett mfc0 $1, $15, 1; \ 120215976Sjmallett andi $1, 0xff; \ 121215976Sjmallett sll $1, shift; \ 122215976Sjmallett add reg, reg, $1 123215976Sjmallett#else 124215976Sjmallett#define loadaddr(reg, addr, shift) \ 125215976Sjmallett dla reg, addr 126215976Sjmallett#endif 127215976Sjmallett 128215976Sjmallett 129215976Sjmallett .set noreorder 130215976Sjmallett .set noat 131215976Sjmallett 132215976Sjmallett .text 133215976Sjmallett 134215976Sjmallett// Detect debug-mode exception, save all registers, create a stack and then 135215976Sjmallett// call the stage3 C function. 136215976Sjmallett 137215976Sjmallett .ent __cvmx_debug_handler_stage2 138215976Sjmallett .globl __cvmx_debug_handler_stage2 139215976Sjmallett__cvmx_debug_handler_stage2: 140215976Sjmallett // Save off k0 in COP0_DESAVE 141215976Sjmallett dmtc0 k0, COP0_DESAVE 142215976Sjmallett 143215976Sjmallett // Use reserved space in kseg0 to save off some temp regs 144215976Sjmallett mfc0 k0, $15, 1 // read exception base reg. 145215976Sjmallett andi k0, 0xff // mask off core ID 146215976Sjmallett sll k0, 12 // multiply by 4096 (512 dwords) DEBUG_NUMREGS 147215976Sjmallett 148215976Sjmallett addiu k0, REG_SAVE_BASE_DIV_4 149215976Sjmallett addiu k0, REG_SAVE_BASE_DIV_4 150215976Sjmallett addiu k0, REG_SAVE_BASE_DIV_4 151215976Sjmallett addiu k0, REG_SAVE_BASE_DIV_4 152215976Sjmallett // add base offset - after exeption vectors for all cores 153215976Sjmallett 154215976Sjmallett rotr k0, k0, 31 // set bit 31 for kseg0 access 155215976Sjmallett addi k0, 1 156215976Sjmallett rotr k0, k0, 1 157215976Sjmallett 158215976Sjmallett // save off k1 and at ($1) off to the bootloader reg save area 159215976Sjmallett // at is used by dla 160215976Sjmallett sd $1, 8(k0) // save at for temp usage 161215976Sjmallett sd k1, 216(k0) // save k1 for temp usage 162215976Sjmallett 163215976Sjmallett 164215976Sjmallett // Detect debug-mode exception. 165215976Sjmallett // If COP0_MULTICOREDEBUG[DExecC] is set, 166215976Sjmallett dmfc0 k1, COP0_MULTICOREDEBUG 167215976Sjmallett bbit0 k1, 16, noexc 168215976Sjmallett nop 169215976Sjmallett 170215976Sjmallett // COP0_DEBUG[DINT,DIB,DDBS,DBp,DSS] are not set and 171215976Sjmallett dmfc0 k1, COP0_DEBUG 172215976Sjmallett andi k1, 0x3f 173215976Sjmallett bnez k1, noexc 174215976Sjmallett nop 175215976Sjmallett 176215976Sjmallett // COP0_DEBUG[DExecC] is set. 177215976Sjmallett dmfc0 k1, COP0_DEBUG 178215976Sjmallett dext k1,k1,10,5 179215976Sjmallett beqz k1,noexc 180215976Sjmallett nop 181215976Sjmallett 182215976Sjmallett // We don't handle debug-mode exceptions in delay-slots so DEBUG[DBD] 183215976Sjmallett // should not be set. If yes spin forever. 184215976Sjmallett dmfc0 k1, COP0_DEBUG 185215976Sjmallett1: 186215976Sjmallett bbit1 k1, 31, 1b 187215976Sjmallett nop 188215976Sjmallett 189215976Sjmallett // It's a debug-mode exception. Flag the occurence. Also if it's 190215976Sjmallett // expected just ignore it but returning the subsequent instruction 191215976Sjmallett // after the fault. 192215976Sjmallett 193215976Sjmallett loadaddr (k1, __cvmx_debug_mode_exception_occured, 3) 194215976Sjmallett sd k1, 0(k1) 195215976Sjmallett 196215976Sjmallett loadaddr (k1, __cvmx_debug_mode_exception_ignore, 3) 197215976Sjmallett ld k1, 0(k1) 198215976Sjmallett beqz k1, noexc 199215976Sjmallett nop 200215976Sjmallett 201215976Sjmallett // Restore k1 and at from the bootloader reg save area 202215976Sjmallett ld $1, 8(k0) // save at for temp usage 203215976Sjmallett ld k1, 216(k0) // save k1 for temp usage 204215976Sjmallett 205215976Sjmallett dmfc0 k0, COP0_DEPC 206215976Sjmallett // Skip the faulting instruction. 207215976Sjmallett daddiu k0, 4 208215976Sjmallett jr k0 209215976Sjmallett dmfc0 k0, COP0_DESAVE 210215976Sjmallett 211215976Sjmallettnoexc: 212215976Sjmallett 213215976Sjmallett loadaddr (k1, __cvmx_debug_save_regs_area, 8) 214215976Sjmallett 215215976Sjmallett // Restore at 216215976Sjmallett ld $1, 8(k0) // restore at for temp usage 217215976Sjmallett 218215976Sjmallett .irp n, REGS0 219215976Sjmallett sd $\n, 0(k1) 220215976Sjmallett addiu k1, 8 221215976Sjmallett .endr 222215976Sjmallett 223215976Sjmallett move $25, k1 224215976Sjmallett ld k1, 216(k0) // restore k1 for temp usage 225215976Sjmallett move k0, $25 226215976Sjmallett 227215976Sjmallett // Store out k0, we can use $25 here because we just saved it 228215976Sjmallett dmfc0 $25, COP0_DESAVE 229215976Sjmallett sd $25, 0(k0) 230215976Sjmallett addiu k0, 8 231215976Sjmallett 232215976Sjmallett .irp n, REGS1 233215976Sjmallett sd $\n, 0(k0) 234215976Sjmallett addiu k0, 8 235215976Sjmallett .endr 236215976Sjmallett 237215976Sjmallett loadaddr(sp, __cvmx_debug_stack_top, 3) 238215976Sjmallett // Load the stack pointer as a pointer size. 239215976Sjmallett#ifdef _ABIN32 240215976Sjmallett lw sp,0(sp) 241215976Sjmallett#else 242215976Sjmallett ld sp,0(sp) 243215976Sjmallett#endif 244215976Sjmallett jal __cvmx_debug_handler_stage3 245215976Sjmallett nop 246215976Sjmallett 247215976Sjmallett loadaddr(k0, __cvmx_debug_save_regs_area, 8) 248215976Sjmallett 249215976Sjmallett .irp n, REGS0 250215976Sjmallett ld $\n, 0(k0) 251215976Sjmallett addiu k0, 8 252215976Sjmallett .endr 253215976Sjmallett 254215976Sjmallett // Restore k0 to COP0_DESAVE via k1 255215976Sjmallett ld k1, 0(k0) 256215976Sjmallett addiu k0, 8 257215976Sjmallett dmtc0 k1, COP0_DESAVE 258215976Sjmallett 259215976Sjmallett .irp n, REGS1 260215976Sjmallett ld $\n, 0(k0) 261215976Sjmallett addiu k0, 8 262215976Sjmallett .endr 263215976Sjmallett 264215976Sjmallett dmfc0 k0, COP0_DESAVE 265215976Sjmallett // Flush the icache; by adding and removing SW breakpoints we change 266215976Sjmallett // the instruction stream. 267215976Sjmallett synci 0($0) 268215976Sjmallett deret 269215976Sjmallett nop 270215976Sjmallett 271215976Sjmallett .end __cvmx_debug_handler_stage2 272