summaryrefslogtreecommitdiffstats
path: root/sys/contrib/octeon-sdk/cvmx-debug-handler.S
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/octeon-sdk/cvmx-debug-handler.S')
-rw-r--r--sys/contrib/octeon-sdk/cvmx-debug-handler.S271
1 files changed, 271 insertions, 0 deletions
diff --git a/sys/contrib/octeon-sdk/cvmx-debug-handler.S b/sys/contrib/octeon-sdk/cvmx-debug-handler.S
new file mode 100644
index 0000000..35389cc
--- /dev/null
+++ b/sys/contrib/octeon-sdk/cvmx-debug-handler.S
@@ -0,0 +1,271 @@
+/***********************license start***************
+ * Copyright (c) 2003-2010 Cavium Networks (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 Networks 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 NETWORKS 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**************************************/
+
+#undef __ASSEMBLY__
+#define __ASSEMBLY__
+
+#ifdef __linux__
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#else
+#include <machine/asm.h>
+#include <machine/regdef.h>
+#endif
+
+#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
+#include <asm/octeon/cvmx-asm.h>
+#include <asm/octeon/octeon-boot-info.h>
+#else
+#include "executive-config.h"
+#include "cvmx-asm.h"
+
+#ifndef __OCTEON_NEWLIB__
+#include "../../bootloader/u-boot/include/octeon_mem_map.h"
+#else
+#include "octeon-boot-info.h"
+#endif
+
+#endif
+
+/* The registers saving/restoring is split into two because k0 is stored in the COP0_DESAVE register. */
+#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
+#define REGS1 27,28,29,30,31
+
+#define SAVE_REGISTER(reg) \
+ sd reg, 0(k0); \
+ addi k0, 8
+
+#define RESTORE_REGISTER(reg) \
+ ld reg, -8(k0); \
+ addi k0, -8
+
+#define SAVE_COP0(reg) \
+ dmfc0 k1,reg; \
+ sd k1, 0(k0); \
+ addi k0, 8
+
+#define RESTORE_COP0(reg) \
+ ld k1, -8(k0); \
+ addi k0, -8; \
+ dmtc0 k1,reg
+
+#define SAVE_ADDRESS(addr) \
+ dli k1, addr; \
+ ld k1, 0(k1); \
+ sd k1, 0(k0); \
+ addi k0, 8
+
+#define RESTORE_ADDRESS(addr) \
+ dli t0, addr; \
+ ld k1, -8(k0); \
+ sd k1, 0(t0); \
+ addi k0, -8
+
+#define REG_SAVE_BASE_DIV_4 (BOOTLOADER_DEBUG_REG_SAVE_BASE >> 2)
+
+
+#define HW_INSTRUCTION_BREAKPOINT_STATUS (0xFFFFFFFFFF301000)
+#define HW_INSTRUCTION_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF301100 + 0x100 * (num))
+#define HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF301108 + 0x100 * (num))
+#define HW_INSTRUCTION_BREAKPOINT_ASID(num) (0xFFFFFFFFFF301110 + 0x100 * (num))
+#define HW_INSTRUCTION_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF301118 + 0x100 * (num))
+
+#define HW_DATA_BREAKPOINT_STATUS (0xFFFFFFFFFF302000)
+#define HW_DATA_BREAKPOINT_ADDRESS(num) (0xFFFFFFFFFF302100 + 0x100 * (num))
+#define HW_DATA_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF302108 + 0x100 * (num))
+#define HW_DATA_BREAKPOINT_ASID(num) (0xFFFFFFFFFF302110 + 0x100 * (num))
+#define HW_DATA_BREAKPOINT_CONTROL(num) (0xFFFFFFFFFF302118 + 0x100 * (num))
+
+
+#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
+#define loadaddr(reg, addr, shift) \
+ dla reg, addr##_all; \
+ mfc0 $1, $15, 1; \
+ andi $1, 0xff; \
+ sll $1, shift; \
+ add reg, reg, $1
+#else
+#define loadaddr(reg, addr, shift) \
+ dla reg, addr
+#endif
+
+
+ .set noreorder
+ .set noat
+
+ .text
+
+// Detect debug-mode exception, save all registers, create a stack and then
+// call the stage3 C function.
+
+ .ent __cvmx_debug_handler_stage2
+ .globl __cvmx_debug_handler_stage2
+__cvmx_debug_handler_stage2:
+ // Save off k0 in COP0_DESAVE
+ dmtc0 k0, COP0_DESAVE
+
+ // Use reserved space in kseg0 to save off some temp regs
+ mfc0 k0, $15, 1 // read exception base reg.
+ andi k0, 0xff // mask off core ID
+ sll k0, 12 // multiply by 4096 (512 dwords) DEBUG_NUMREGS
+
+ addiu k0, REG_SAVE_BASE_DIV_4
+ addiu k0, REG_SAVE_BASE_DIV_4
+ addiu k0, REG_SAVE_BASE_DIV_4
+ addiu k0, REG_SAVE_BASE_DIV_4
+ // add base offset - after exeption vectors for all cores
+
+ rotr k0, k0, 31 // set bit 31 for kseg0 access
+ addi k0, 1
+ rotr k0, k0, 1
+
+ // save off k1 and at ($1) off to the bootloader reg save area
+ // at is used by dla
+ sd $1, 8(k0) // save at for temp usage
+ sd k1, 216(k0) // save k1 for temp usage
+
+
+ // Detect debug-mode exception.
+ // If COP0_MULTICOREDEBUG[DExecC] is set,
+ dmfc0 k1, COP0_MULTICOREDEBUG
+ bbit0 k1, 16, noexc
+ nop
+
+ // COP0_DEBUG[DINT,DIB,DDBS,DBp,DSS] are not set and
+ dmfc0 k1, COP0_DEBUG
+ andi k1, 0x3f
+ bnez k1, noexc
+ nop
+
+ // COP0_DEBUG[DExecC] is set.
+ dmfc0 k1, COP0_DEBUG
+ dext k1,k1,10,5
+ beqz k1,noexc
+ nop
+
+ // We don't handle debug-mode exceptions in delay-slots so DEBUG[DBD]
+ // should not be set. If yes spin forever.
+ dmfc0 k1, COP0_DEBUG
+1:
+ bbit1 k1, 31, 1b
+ nop
+
+ // It's a debug-mode exception. Flag the occurence. Also if it's
+ // expected just ignore it but returning the subsequent instruction
+ // after the fault.
+
+ loadaddr (k1, __cvmx_debug_mode_exception_occured, 3)
+ sd k1, 0(k1)
+
+ loadaddr (k1, __cvmx_debug_mode_exception_ignore, 3)
+ ld k1, 0(k1)
+ beqz k1, noexc
+ nop
+
+ // Restore k1 and at from the bootloader reg save area
+ ld $1, 8(k0) // save at for temp usage
+ ld k1, 216(k0) // save k1 for temp usage
+
+ dmfc0 k0, COP0_DEPC
+ // Skip the faulting instruction.
+ daddiu k0, 4
+ jr k0
+ dmfc0 k0, COP0_DESAVE
+
+noexc:
+
+ loadaddr (k1, __cvmx_debug_save_regs_area, 8)
+
+ // Restore at
+ ld $1, 8(k0) // restore at for temp usage
+
+ .irp n, REGS0
+ sd $\n, 0(k1)
+ addiu k1, 8
+ .endr
+
+ move $25, k1
+ ld k1, 216(k0) // restore k1 for temp usage
+ move k0, $25
+
+ // Store out k0, we can use $25 here because we just saved it
+ dmfc0 $25, COP0_DESAVE
+ sd $25, 0(k0)
+ addiu k0, 8
+
+ .irp n, REGS1
+ sd $\n, 0(k0)
+ addiu k0, 8
+ .endr
+
+ loadaddr(sp, __cvmx_debug_stack_top, 3)
+ // Load the stack pointer as a pointer size.
+#ifdef _ABIN32
+ lw sp,0(sp)
+#else
+ ld sp,0(sp)
+#endif
+ jal __cvmx_debug_handler_stage3
+ nop
+
+ loadaddr(k0, __cvmx_debug_save_regs_area, 8)
+
+ .irp n, REGS0
+ ld $\n, 0(k0)
+ addiu k0, 8
+ .endr
+
+ // Restore k0 to COP0_DESAVE via k1
+ ld k1, 0(k0)
+ addiu k0, 8
+ dmtc0 k1, COP0_DESAVE
+
+ .irp n, REGS1
+ ld $\n, 0(k0)
+ addiu k0, 8
+ .endr
+
+ dmfc0 k0, COP0_DESAVE
+ // Flush the icache; by adding and removing SW breakpoints we change
+ // the instruction stream.
+ synci 0($0)
+ deret
+ nop
+
+ .end __cvmx_debug_handler_stage2
OpenPOWER on IntegriCloud