2 * arch/blackfin/kernel/kgdb.c - Blackfin kgdb pieces
4 * Copyright 2005-2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/ptrace.h> /* for linux pt_regs struct */
10 #include <linux/kgdb.h>
11 #include <linux/uaccess.h>
12 #include <asm/irq_regs.h>
14 void pt_regs_to_gdb_regs(unsigned long *gdb_regs
, struct pt_regs
*regs
)
16 gdb_regs
[BFIN_R0
] = regs
->r0
;
17 gdb_regs
[BFIN_R1
] = regs
->r1
;
18 gdb_regs
[BFIN_R2
] = regs
->r2
;
19 gdb_regs
[BFIN_R3
] = regs
->r3
;
20 gdb_regs
[BFIN_R4
] = regs
->r4
;
21 gdb_regs
[BFIN_R5
] = regs
->r5
;
22 gdb_regs
[BFIN_R6
] = regs
->r6
;
23 gdb_regs
[BFIN_R7
] = regs
->r7
;
24 gdb_regs
[BFIN_P0
] = regs
->p0
;
25 gdb_regs
[BFIN_P1
] = regs
->p1
;
26 gdb_regs
[BFIN_P2
] = regs
->p2
;
27 gdb_regs
[BFIN_P3
] = regs
->p3
;
28 gdb_regs
[BFIN_P4
] = regs
->p4
;
29 gdb_regs
[BFIN_P5
] = regs
->p5
;
30 gdb_regs
[BFIN_SP
] = regs
->reserved
;
31 gdb_regs
[BFIN_FP
] = regs
->fp
;
32 gdb_regs
[BFIN_I0
] = regs
->i0
;
33 gdb_regs
[BFIN_I1
] = regs
->i1
;
34 gdb_regs
[BFIN_I2
] = regs
->i2
;
35 gdb_regs
[BFIN_I3
] = regs
->i3
;
36 gdb_regs
[BFIN_M0
] = regs
->m0
;
37 gdb_regs
[BFIN_M1
] = regs
->m1
;
38 gdb_regs
[BFIN_M2
] = regs
->m2
;
39 gdb_regs
[BFIN_M3
] = regs
->m3
;
40 gdb_regs
[BFIN_B0
] = regs
->b0
;
41 gdb_regs
[BFIN_B1
] = regs
->b1
;
42 gdb_regs
[BFIN_B2
] = regs
->b2
;
43 gdb_regs
[BFIN_B3
] = regs
->b3
;
44 gdb_regs
[BFIN_L0
] = regs
->l0
;
45 gdb_regs
[BFIN_L1
] = regs
->l1
;
46 gdb_regs
[BFIN_L2
] = regs
->l2
;
47 gdb_regs
[BFIN_L3
] = regs
->l3
;
48 gdb_regs
[BFIN_A0_DOT_X
] = regs
->a0x
;
49 gdb_regs
[BFIN_A0_DOT_W
] = regs
->a0w
;
50 gdb_regs
[BFIN_A1_DOT_X
] = regs
->a1x
;
51 gdb_regs
[BFIN_A1_DOT_W
] = regs
->a1w
;
52 gdb_regs
[BFIN_ASTAT
] = regs
->astat
;
53 gdb_regs
[BFIN_RETS
] = regs
->rets
;
54 gdb_regs
[BFIN_LC0
] = regs
->lc0
;
55 gdb_regs
[BFIN_LT0
] = regs
->lt0
;
56 gdb_regs
[BFIN_LB0
] = regs
->lb0
;
57 gdb_regs
[BFIN_LC1
] = regs
->lc1
;
58 gdb_regs
[BFIN_LT1
] = regs
->lt1
;
59 gdb_regs
[BFIN_LB1
] = regs
->lb1
;
60 gdb_regs
[BFIN_CYCLES
] = 0;
61 gdb_regs
[BFIN_CYCLES2
] = 0;
62 gdb_regs
[BFIN_USP
] = regs
->usp
;
63 gdb_regs
[BFIN_SEQSTAT
] = regs
->seqstat
;
64 gdb_regs
[BFIN_SYSCFG
] = regs
->syscfg
;
65 gdb_regs
[BFIN_RETI
] = regs
->pc
;
66 gdb_regs
[BFIN_RETX
] = regs
->retx
;
67 gdb_regs
[BFIN_RETN
] = regs
->retn
;
68 gdb_regs
[BFIN_RETE
] = regs
->rete
;
69 gdb_regs
[BFIN_PC
] = regs
->pc
;
70 gdb_regs
[BFIN_CC
] = (regs
->astat
>> 5) & 1;
71 gdb_regs
[BFIN_EXTRA1
] = 0;
72 gdb_regs
[BFIN_EXTRA2
] = 0;
73 gdb_regs
[BFIN_EXTRA3
] = 0;
74 gdb_regs
[BFIN_IPEND
] = regs
->ipend
;
78 * Extracts ebp, esp and eip values understandable by gdb from the values
80 * thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp
81 * prior to entering switch_to is 8 greater than the value that is saved.
82 * If switch_to changes, change following code appropriately.
84 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs
, struct task_struct
*p
)
86 gdb_regs
[BFIN_SP
] = p
->thread
.ksp
;
87 gdb_regs
[BFIN_PC
] = p
->thread
.pc
;
88 gdb_regs
[BFIN_SEQSTAT
] = p
->thread
.seqstat
;
91 void gdb_regs_to_pt_regs(unsigned long *gdb_regs
, struct pt_regs
*regs
)
93 regs
->r0
= gdb_regs
[BFIN_R0
];
94 regs
->r1
= gdb_regs
[BFIN_R1
];
95 regs
->r2
= gdb_regs
[BFIN_R2
];
96 regs
->r3
= gdb_regs
[BFIN_R3
];
97 regs
->r4
= gdb_regs
[BFIN_R4
];
98 regs
->r5
= gdb_regs
[BFIN_R5
];
99 regs
->r6
= gdb_regs
[BFIN_R6
];
100 regs
->r7
= gdb_regs
[BFIN_R7
];
101 regs
->p0
= gdb_regs
[BFIN_P0
];
102 regs
->p1
= gdb_regs
[BFIN_P1
];
103 regs
->p2
= gdb_regs
[BFIN_P2
];
104 regs
->p3
= gdb_regs
[BFIN_P3
];
105 regs
->p4
= gdb_regs
[BFIN_P4
];
106 regs
->p5
= gdb_regs
[BFIN_P5
];
107 regs
->fp
= gdb_regs
[BFIN_FP
];
108 regs
->i0
= gdb_regs
[BFIN_I0
];
109 regs
->i1
= gdb_regs
[BFIN_I1
];
110 regs
->i2
= gdb_regs
[BFIN_I2
];
111 regs
->i3
= gdb_regs
[BFIN_I3
];
112 regs
->m0
= gdb_regs
[BFIN_M0
];
113 regs
->m1
= gdb_regs
[BFIN_M1
];
114 regs
->m2
= gdb_regs
[BFIN_M2
];
115 regs
->m3
= gdb_regs
[BFIN_M3
];
116 regs
->b0
= gdb_regs
[BFIN_B0
];
117 regs
->b1
= gdb_regs
[BFIN_B1
];
118 regs
->b2
= gdb_regs
[BFIN_B2
];
119 regs
->b3
= gdb_regs
[BFIN_B3
];
120 regs
->l0
= gdb_regs
[BFIN_L0
];
121 regs
->l1
= gdb_regs
[BFIN_L1
];
122 regs
->l2
= gdb_regs
[BFIN_L2
];
123 regs
->l3
= gdb_regs
[BFIN_L3
];
124 regs
->a0x
= gdb_regs
[BFIN_A0_DOT_X
];
125 regs
->a0w
= gdb_regs
[BFIN_A0_DOT_W
];
126 regs
->a1x
= gdb_regs
[BFIN_A1_DOT_X
];
127 regs
->a1w
= gdb_regs
[BFIN_A1_DOT_W
];
128 regs
->rets
= gdb_regs
[BFIN_RETS
];
129 regs
->lc0
= gdb_regs
[BFIN_LC0
];
130 regs
->lt0
= gdb_regs
[BFIN_LT0
];
131 regs
->lb0
= gdb_regs
[BFIN_LB0
];
132 regs
->lc1
= gdb_regs
[BFIN_LC1
];
133 regs
->lt1
= gdb_regs
[BFIN_LT1
];
134 regs
->lb1
= gdb_regs
[BFIN_LB1
];
135 regs
->usp
= gdb_regs
[BFIN_USP
];
136 regs
->syscfg
= gdb_regs
[BFIN_SYSCFG
];
137 regs
->retx
= gdb_regs
[BFIN_RETX
];
138 regs
->retn
= gdb_regs
[BFIN_RETN
];
139 regs
->rete
= gdb_regs
[BFIN_RETE
];
140 regs
->pc
= gdb_regs
[BFIN_PC
];
142 #if 0 /* can't change these */
143 regs
->astat
= gdb_regs
[BFIN_ASTAT
];
144 regs
->seqstat
= gdb_regs
[BFIN_SEQSTAT
];
145 regs
->ipend
= gdb_regs
[BFIN_IPEND
];
149 static struct hw_breakpoint
{
150 unsigned int occupied
:1;
152 unsigned int enabled
:1;
154 unsigned int dataacc
:2;
155 unsigned short count
;
157 } breakinfo
[HW_WATCHPOINT_NUM
];
159 static int bfin_set_hw_break(unsigned long addr
, int len
, enum kgdb_bptype type
)
166 case BP_HARDWARE_BREAKPOINT
:
167 bfin_type
= TYPE_INST_WATCHPOINT
;
169 case BP_WRITE_WATCHPOINT
:
171 bfin_type
= TYPE_DATA_WATCHPOINT
;
173 case BP_READ_WATCHPOINT
:
175 bfin_type
= TYPE_DATA_WATCHPOINT
;
177 case BP_ACCESS_WATCHPOINT
:
179 bfin_type
= TYPE_DATA_WATCHPOINT
;
185 /* Because hardware data watchpoint impelemented in current
186 * Blackfin can not trigger an exception event as the hardware
187 * instrction watchpoint does, we ignaore all data watch point here.
188 * They can be turned on easily after future blackfin design
189 * supports this feature.
191 for (breakno
= 0; breakno
< HW_INST_WATCHPOINT_NUM
; breakno
++)
192 if (bfin_type
== breakinfo
[breakno
].type
193 && !breakinfo
[breakno
].occupied
) {
194 breakinfo
[breakno
].occupied
= 1;
195 breakinfo
[breakno
].skip
= 0;
196 breakinfo
[breakno
].enabled
= 1;
197 breakinfo
[breakno
].addr
= addr
;
198 breakinfo
[breakno
].dataacc
= dataacc
;
199 breakinfo
[breakno
].count
= 0;
206 static int bfin_remove_hw_break(unsigned long addr
, int len
, enum kgdb_bptype type
)
212 case BP_HARDWARE_BREAKPOINT
:
213 bfin_type
= TYPE_INST_WATCHPOINT
;
215 case BP_WRITE_WATCHPOINT
:
216 case BP_READ_WATCHPOINT
:
217 case BP_ACCESS_WATCHPOINT
:
218 bfin_type
= TYPE_DATA_WATCHPOINT
;
223 for (breakno
= 0; breakno
< HW_WATCHPOINT_NUM
; breakno
++)
224 if (bfin_type
== breakinfo
[breakno
].type
225 && breakinfo
[breakno
].occupied
226 && breakinfo
[breakno
].addr
== addr
) {
227 breakinfo
[breakno
].occupied
= 0;
228 breakinfo
[breakno
].enabled
= 0;
234 static void bfin_remove_all_hw_break(void)
238 memset(breakinfo
, 0, sizeof(struct hw_breakpoint
)*HW_WATCHPOINT_NUM
);
240 for (breakno
= 0; breakno
< HW_INST_WATCHPOINT_NUM
; breakno
++)
241 breakinfo
[breakno
].type
= TYPE_INST_WATCHPOINT
;
242 for (; breakno
< HW_WATCHPOINT_NUM
; breakno
++)
243 breakinfo
[breakno
].type
= TYPE_DATA_WATCHPOINT
;
246 static void bfin_correct_hw_break(void)
249 unsigned int wpiactl
= 0;
250 unsigned int wpdactl
= 0;
253 for (breakno
= 0; breakno
< HW_WATCHPOINT_NUM
; breakno
++)
254 if (breakinfo
[breakno
].enabled
) {
259 wpiactl
|= WPIAEN0
|WPICNTEN0
;
260 bfin_write_WPIA0(breakinfo
[breakno
].addr
);
261 bfin_write_WPIACNT0(breakinfo
[breakno
].count
265 wpiactl
|= WPIAEN1
|WPICNTEN1
;
266 bfin_write_WPIA1(breakinfo
[breakno
].addr
);
267 bfin_write_WPIACNT1(breakinfo
[breakno
].count
271 wpiactl
|= WPIAEN2
|WPICNTEN2
;
272 bfin_write_WPIA2(breakinfo
[breakno
].addr
);
273 bfin_write_WPIACNT2(breakinfo
[breakno
].count
277 wpiactl
|= WPIAEN3
|WPICNTEN3
;
278 bfin_write_WPIA3(breakinfo
[breakno
].addr
);
279 bfin_write_WPIACNT3(breakinfo
[breakno
].count
283 wpiactl
|= WPIAEN4
|WPICNTEN4
;
284 bfin_write_WPIA4(breakinfo
[breakno
].addr
);
285 bfin_write_WPIACNT4(breakinfo
[breakno
].count
289 wpiactl
|= WPIAEN5
|WPICNTEN5
;
290 bfin_write_WPIA5(breakinfo
[breakno
].addr
);
291 bfin_write_WPIACNT5(breakinfo
[breakno
].count
295 wpdactl
|= WPDAEN0
|WPDCNTEN0
|WPDSRC0
;
296 wpdactl
|= breakinfo
[breakno
].dataacc
298 bfin_write_WPDA0(breakinfo
[breakno
].addr
);
299 bfin_write_WPDACNT0(breakinfo
[breakno
].count
303 wpdactl
|= WPDAEN1
|WPDCNTEN1
|WPDSRC1
;
304 wpdactl
|= breakinfo
[breakno
].dataacc
306 bfin_write_WPDA1(breakinfo
[breakno
].addr
);
307 bfin_write_WPDACNT1(breakinfo
[breakno
].count
313 /* Should enable WPPWR bit first before set any other
314 * WPIACTL and WPDACTL bits */
316 bfin_write_WPIACTL(WPPWR
);
318 bfin_write_WPIACTL(wpiactl
|WPPWR
);
319 bfin_write_WPDACTL(wpdactl
);
324 static void bfin_disable_hw_debug(struct pt_regs
*regs
)
326 /* Disable hardware debugging while we are in kgdb */
327 bfin_write_WPIACTL(0);
328 bfin_write_WPDACTL(0);
333 extern void generic_exec_single(int cpu
, struct call_single_data
*data
, int wait
);
334 static struct call_single_data kgdb_smp_ipi_data
[NR_CPUS
];
336 void kgdb_passive_cpu_callback(void *info
)
338 kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
341 void kgdb_roundup_cpus(unsigned long flags
)
345 for (cpu
= cpumask_first(cpu_online_mask
); cpu
< nr_cpu_ids
;
346 cpu
= cpumask_next(cpu
, cpu_online_mask
)) {
347 kgdb_smp_ipi_data
[cpu
].func
= kgdb_passive_cpu_callback
;
348 generic_exec_single(cpu
, &kgdb_smp_ipi_data
[cpu
], 0);
352 void kgdb_roundup_cpu(int cpu
, unsigned long flags
)
354 generic_exec_single(cpu
, &kgdb_smp_ipi_data
[cpu
], 0);
359 static unsigned long kgdb_arch_imask
;
362 void kgdb_post_primary_code(struct pt_regs
*regs
, int e_vector
, int err_code
)
364 if (kgdb_single_step
)
368 if (kgdb_arch_imask
) {
369 cpu_pda
[raw_smp_processor_id()].ex_imask
= kgdb_arch_imask
;
375 int kgdb_arch_handle_exception(int vector
, int signo
,
376 int err_code
, char *remcom_in_buffer
,
377 char *remcom_out_buffer
,
378 struct pt_regs
*regs
)
385 switch (remcom_in_buffer
[0]) {
388 if (kgdb_contthread
&& kgdb_contthread
!= current
) {
389 strcpy(remcom_out_buffer
, "E00");
393 kgdb_contthread
= NULL
;
395 /* try to read optional parameter, pc unchanged if no parm */
396 ptr
= &remcom_in_buffer
[1];
397 if (kgdb_hex2long(&ptr
, &addr
)) {
402 /* clear the trace bit */
403 regs
->syscfg
&= 0xfffffffe;
405 /* set the trace bit if we're stepping */
406 if (remcom_in_buffer
[0] == 's') {
408 kgdb_single_step
= regs
->ipend
;
409 kgdb_single_step
>>= 6;
410 for (i
= 10; i
> 0; i
--, kgdb_single_step
>>= 1)
411 if (kgdb_single_step
& 1)
413 /* i indicate event priority of current stopped instruction
414 * user space instruction is 0, IVG15 is 1, IVTMR is 10.
415 * kgdb_single_step > 0 means in single step mode
417 kgdb_single_step
= i
+ 1;
421 kgdb_arch_imask
= cpu_pda
[raw_smp_processor_id()].ex_imask
;
422 cpu_pda
[raw_smp_processor_id()].ex_imask
= 0;
426 bfin_correct_hw_break();
430 return -1; /* this means that we do not want to exit from the handler */
433 struct kgdb_arch arch_kgdb_ops
= {
434 .gdb_bpt_instr
= {0xa1},
435 .flags
= KGDB_HW_BREAKPOINT
,
436 .set_hw_breakpoint
= bfin_set_hw_break
,
437 .remove_hw_breakpoint
= bfin_remove_hw_break
,
438 .disable_hw_break
= bfin_disable_hw_debug
,
439 .remove_all_hw_break
= bfin_remove_all_hw_break
,
440 .correct_hw_break
= bfin_correct_hw_break
,
443 #define IN_MEM(addr, size, l1_addr, l1_size) \
445 unsigned long __addr = (unsigned long)(addr); \
446 (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
448 #define ASYNC_BANK_SIZE \
449 (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
450 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
452 int kgdb_validate_break_address(unsigned long addr
)
454 int cpu
= raw_smp_processor_id();
456 if (addr
>= 0x1000 && (addr
+ BREAK_INSTR_SIZE
) <= physical_mem_end
)
458 if (IN_MEM(addr
, BREAK_INSTR_SIZE
, ASYNC_BANK0_BASE
, ASYNC_BANK_SIZE
))
460 if (cpu
== 0 && IN_MEM(addr
, BREAK_INSTR_SIZE
, L1_CODE_START
, L1_CODE_LENGTH
))
463 else if (cpu
== 1 && IN_MEM(addr
, BREAK_INSTR_SIZE
, COREB_L1_CODE_START
, L1_CODE_LENGTH
))
466 if (IN_MEM(addr
, BREAK_INSTR_SIZE
, L2_START
, L2_LENGTH
))
472 void kgdb_arch_set_pc(struct pt_regs
*regs
, unsigned long ip
)
477 int kgdb_arch_init(void)
479 kgdb_single_step
= 0;
484 bfin_remove_all_hw_break();
488 void kgdb_arch_exit(void)