1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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
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
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**************************************/
45 #include <asm/regdef.h>
47 #include <machine/asm.h>
48 #include <machine/regdef.h>
51 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
52 #include <asm/octeon/cvmx-asm.h>
53 #include <asm/octeon/octeon-boot-info.h>
58 #ifndef _OCTEON_TOOLCHAIN_RUNTIME
59 #include <octeon_mem_map.h>
61 #include "cvmx-platform.h"
62 #include "octeon-boot-info.h"
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
71 #define SAVE_REGISTER(reg) \
75 #define RESTORE_REGISTER(reg) \
79 #define SAVE_COP0(reg) \
84 #define RESTORE_COP0(reg) \
89 #define SAVE_ADDRESS(addr) \
95 #define RESTORE_ADDRESS(addr) \
101 #define REG_SAVE_BASE_DIV_8 (BOOTLOADER_DEBUG_REG_SAVE_BASE >> 3)
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))
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))
117 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
118 #define loadaddr(reg, addr, shift) \
119 dla reg, addr##_all; \
125 #define loadaddr(reg, addr, shift) \
135 // Detect debug-mode exception, save all registers, create a stack and then
136 // call the stage3 C function.
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
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
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
159 rotr k0, k0, 31 // set bit 31 for kseg0 access
163 // save off k1 and at ($1) off to the bootloader reg save area
165 sd $1, 8(k0) // save at for temp usage
166 sd k1, 216(k0) // save k1 for temp usage
169 // Detect debug-mode exception.
170 // If COP0_MULTICOREDEBUG[DExecC] is set,
171 dmfc0 k1, COP0_MULTICOREDEBUG
175 // COP0_DEBUG[DINT,DIB,DDBS,DBp,DSS] are not set and
181 // COP0_DEBUG[DExecC] is set.
187 // We don't handle debug-mode exceptions in delay-slots so DEBUG[DBD]
188 // should not be set. If yes spin forever.
194 // It's a debug-mode exception. Flag the occurence. Also if it's
195 // expected just ignore it but returning the subsequent instruction
198 loadaddr (k1, __cvmx_debug_mode_exception_occured, 3)
201 loadaddr (k1, __cvmx_debug_mode_exception_ignore, 3)
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
211 // Skip the faulting instruction.
214 dmfc0 k0, COP0_DESAVE
218 loadaddr (k1, __cvmx_debug_save_regs_area, 8)
221 ld $1, 8(k0) // restore at for temp usage
229 ld k1, 216(k0) // restore k1 for temp usage
232 // Store out k0, we can use $25 here because we just saved it
233 dmfc0 $25, COP0_DESAVE
242 loadaddr(sp, __cvmx_debug_stack_top, 3)
243 // Load the stack pointer as a pointer size.
251 jal __cvmx_debug_handler_stage3
254 loadaddr(k0, __cvmx_debug_save_regs_area, 8)
261 // Restore k0 to COP0_DESAVE via k1
264 dmtc0 k1, COP0_DESAVE
271 dmfc0 k0, COP0_DESAVE
272 // Flush the icache; by adding and removing SW breakpoints we change
273 // the instruction stream.
278 .end __cvmx_debug_handler_stage2