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