]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/octeon-sdk/cvmx-debug-handler.S
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / octeon-sdk / cvmx-debug-handler.S
1 /***********************license start***************
2  * Copyright (c) 2003-2010  Cavium Networks (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 Networks 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  NETWORKS 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 #include "executive-config.h"
56 #include "cvmx-asm.h"
57
58 #ifndef __OCTEON_NEWLIB__
59 #include "../../bootloader/u-boot/include/octeon_mem_map.h"
60 #else
61 #include "octeon-boot-info.h"
62 #endif
63
64 #endif
65
66 /* The registers saving/restoring is split into two because k0 is stored in the COP0_DESAVE register.  */
67 #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
68 #define REGS1 27,28,29,30,31
69
70 #define SAVE_REGISTER(reg)      \
71         sd reg, 0(k0);          \
72         addi k0, 8
73
74 #define RESTORE_REGISTER(reg)   \
75         ld reg, -8(k0);         \
76         addi k0, -8
77
78 #define SAVE_COP0(reg)          \
79         dmfc0 k1,reg;           \
80         sd k1, 0(k0);           \
81         addi k0, 8
82
83 #define RESTORE_COP0(reg)       \
84         ld k1, -8(k0);          \
85         addi k0, -8;            \
86         dmtc0 k1,reg    
87
88 #define SAVE_ADDRESS(addr)      \
89         dli k1, addr;           \
90         ld k1, 0(k1);           \
91         sd k1, 0(k0);           \
92         addi k0, 8
93
94 #define RESTORE_ADDRESS(addr)   \
95         dli t0, addr;           \
96         ld k1, -8(k0);          \
97         sd k1, 0(t0);           \
98         addi k0, -8
99
100 #define REG_SAVE_BASE_DIV_4  (BOOTLOADER_DEBUG_REG_SAVE_BASE >> 2)
101
102
103 #define HW_INSTRUCTION_BREAKPOINT_STATUS            (0xFFFFFFFFFF301000)
104 #define HW_INSTRUCTION_BREAKPOINT_ADDRESS(num)      (0xFFFFFFFFFF301100 + 0x100 * (num))
105 #define HW_INSTRUCTION_BREAKPOINT_ADDRESS_MASK(num) (0xFFFFFFFFFF301108 + 0x100 * (num))
106 #define HW_INSTRUCTION_BREAKPOINT_ASID(num)         (0xFFFFFFFFFF301110 + 0x100 * (num))
107 #define HW_INSTRUCTION_BREAKPOINT_CONTROL(num)      (0xFFFFFFFFFF301118 + 0x100 * (num))
108
109 #define HW_DATA_BREAKPOINT_STATUS                   (0xFFFFFFFFFF302000)
110 #define HW_DATA_BREAKPOINT_ADDRESS(num)             (0xFFFFFFFFFF302100 + 0x100 * (num))
111 #define HW_DATA_BREAKPOINT_ADDRESS_MASK(num)        (0xFFFFFFFFFF302108 + 0x100 * (num))
112 #define HW_DATA_BREAKPOINT_ASID(num)                (0xFFFFFFFFFF302110 + 0x100 * (num))
113 #define HW_DATA_BREAKPOINT_CONTROL(num)             (0xFFFFFFFFFF302118 + 0x100 * (num))
114
115
116 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
117 #define loadaddr(reg, addr, shift) \
118         dla     reg, addr##_all; \
119         mfc0    $1, $15, 1; \
120         andi    $1, 0xff; \
121         sll     $1, shift; \
122         add     reg, reg, $1
123 #else
124 #define loadaddr(reg, addr, shift) \
125         dla     reg, addr
126 #endif
127
128
129         .set    noreorder
130         .set    noat
131
132         .text
133
134 // Detect debug-mode exception, save all registers, create a stack and then
135 // call the stage3 C function.
136
137         .ent    __cvmx_debug_handler_stage2
138         .globl  __cvmx_debug_handler_stage2
139 __cvmx_debug_handler_stage2:
140         // Save off k0 in COP0_DESAVE
141         dmtc0   k0, COP0_DESAVE
142
143         // Use reserved space in kseg0 to save off some temp regs
144         mfc0    k0, $15, 1  // read exception base reg.
145         andi    k0, 0xff    // mask off core ID
146         sll     k0, 12      // multiply by 4096 (512 dwords) DEBUG_NUMREGS
147
148         addiu   k0,  REG_SAVE_BASE_DIV_4    
149         addiu   k0,  REG_SAVE_BASE_DIV_4
150         addiu   k0,  REG_SAVE_BASE_DIV_4
151         addiu   k0,  REG_SAVE_BASE_DIV_4
152                 // add base offset - after exeption vectors for all cores
153
154         rotr    k0, k0, 31   // set bit 31 for kseg0 access
155         addi    k0, 1
156         rotr    k0, k0, 1
157
158         // save off k1 and at ($1) off to the bootloader reg save area
159         // at is used by dla
160         sd      $1, 8(k0)       // save at for temp usage
161         sd      k1, 216(k0)     // save k1 for temp usage
162
163
164         // Detect debug-mode exception.
165         // If COP0_MULTICOREDEBUG[DExecC] is set,
166         dmfc0   k1, COP0_MULTICOREDEBUG
167         bbit0   k1, 16, noexc
168         nop
169
170         // COP0_DEBUG[DINT,DIB,DDBS,DBp,DSS] are not set and
171         dmfc0   k1, COP0_DEBUG
172         andi    k1, 0x3f
173         bnez    k1, noexc
174         nop
175
176         // COP0_DEBUG[DExecC] is set.
177         dmfc0   k1, COP0_DEBUG
178         dext    k1,k1,10,5
179         beqz    k1,noexc
180         nop
181         
182         // We don't handle debug-mode exceptions in delay-slots so DEBUG[DBD]
183         // should not be set.  If yes spin forever.
184         dmfc0   k1, COP0_DEBUG
185 1:
186         bbit1   k1, 31, 1b
187         nop
188
189         // It's a debug-mode exception.  Flag the occurence.  Also if it's
190         // expected just ignore it but returning the subsequent instruction
191         // after the fault.
192         
193         loadaddr (k1, __cvmx_debug_mode_exception_occured, 3)
194         sd      k1, 0(k1)
195
196         loadaddr (k1, __cvmx_debug_mode_exception_ignore, 3)
197         ld      k1, 0(k1)
198         beqz    k1, noexc
199         nop
200
201         // Restore k1 and at from the bootloader reg save area
202         ld      $1, 8(k0)       // save at for temp usage
203         ld      k1, 216(k0)     // save k1 for temp usage
204
205         dmfc0   k0, COP0_DEPC
206         // Skip the faulting instruction.
207         daddiu  k0, 4
208         jr      k0
209         dmfc0   k0, COP0_DESAVE
210
211 noexc:  
212
213         loadaddr (k1, __cvmx_debug_save_regs_area, 8)
214
215         // Restore at
216         ld      $1, 8(k0)       // restore at for temp usage
217
218         .irp    n, REGS0
219         sd      $\n, 0(k1)
220         addiu   k1, 8
221         .endr
222
223         move    $25, k1
224         ld      k1, 216(k0)     // restore k1 for temp usage
225         move    k0, $25
226
227         // Store out k0, we can use $25 here because we just saved it
228         dmfc0   $25, COP0_DESAVE
229         sd      $25, 0(k0)
230         addiu   k0, 8
231
232         .irp    n, REGS1
233         sd      $\n, 0(k0)
234         addiu   k0, 8
235         .endr
236
237         loadaddr(sp, __cvmx_debug_stack_top, 3)
238         // Load the stack pointer as a pointer size.
239 #ifdef _ABIN32
240         lw      sp,0(sp)
241 #else
242         ld      sp,0(sp)
243 #endif
244         jal     __cvmx_debug_handler_stage3
245         nop
246
247         loadaddr(k0, __cvmx_debug_save_regs_area, 8)
248
249         .irp    n, REGS0
250         ld      $\n, 0(k0)
251         addiu   k0, 8
252         .endr
253
254         // Restore k0 to COP0_DESAVE via k1
255         ld      k1, 0(k0)
256         addiu   k0, 8
257         dmtc0   k1, COP0_DESAVE
258
259         .irp    n, REGS1
260         ld      $\n, 0(k0)
261         addiu   k0, 8
262         .endr
263         
264         dmfc0   k0, COP0_DESAVE
265         // Flush the icache; by adding and removing SW breakpoints we change
266         // the instruction stream.
267         synci   0($0)
268         deret
269         nop
270
271         .end    __cvmx_debug_handler_stage2