]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/octeon-sdk/cvmx-debug-handler.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / octeon-sdk / cvmx-debug-handler.S
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
190 1:
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
216 noexc:  
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