aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2010-03-15 13:42:07 -0400
committerMike Frysinger <vapier@gentoo.org>2010-05-21 09:40:19 -0400
commit9a95e2f1008ee433c496a81628cdde67acc8e4b1 (patch)
tree44f08c82c40a664f6757da01e3f9e7b7f719afab /arch/blackfin
parentd60805ad470aef52465f3dc982212f559d9f661b (diff)
Blackfin: make hardware trace output a little more useful
Decode the vast majority of insns that appear in the trace buffer to get a better idea of what's going on at a glance. Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/include/asm/trace.h6
-rw-r--r--arch/blackfin/kernel/dumpstack.c15
-rw-r--r--arch/blackfin/kernel/trace.c490
-rw-r--r--arch/blackfin/kernel/traps.c2
4 files changed, 446 insertions, 67 deletions
diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h
index 91179395baa8..33589a29b8d8 100644
--- a/arch/blackfin/include/asm/trace.h
+++ b/arch/blackfin/include/asm/trace.h
@@ -25,10 +25,10 @@ extern unsigned long trace_buff_offset;
25extern unsigned long software_trace_buff[]; 25extern unsigned long software_trace_buff[];
26#if defined(CONFIG_DEBUG_VERBOSE) 26#if defined(CONFIG_DEBUG_VERBOSE)
27extern void decode_address(char *buf, unsigned long address); 27extern void decode_address(char *buf, unsigned long address);
28extern bool get_instruction(unsigned short *val, unsigned short *address); 28extern bool get_instruction(unsigned int *val, unsigned short *address);
29#else 29#else
30#define decode_address(buf, address) 30static inline void decode_address(char *buf, unsigned long address) { }
31#define get_instruction(val, address) 0 31static inline bool get_instruction(unsigned int *val, unsigned short *address) { return false; }
32#endif 32#endif
33 33
34/* Trace Macros for C files */ 34/* Trace Macros for C files */
diff --git a/arch/blackfin/kernel/dumpstack.c b/arch/blackfin/kernel/dumpstack.c
index e81392c9d1db..5cfbaa298211 100644
--- a/arch/blackfin/kernel/dumpstack.c
+++ b/arch/blackfin/kernel/dumpstack.c
@@ -18,21 +18,14 @@
18 */ 18 */
19static bool is_bfin_call(unsigned short *addr) 19static bool is_bfin_call(unsigned short *addr)
20{ 20{
21 unsigned short opcode = 0, *ins_addr; 21 unsigned int opcode;
22 ins_addr = (unsigned short *)addr;
23 22
24 if (!get_instruction(&opcode, ins_addr)) 23 if (!get_instruction(&opcode, addr))
25 return false; 24 return false;
26 25
27 if ((opcode >= 0x0060 && opcode <= 0x0067) || 26 if ((opcode >= 0x0060 && opcode <= 0x0067) ||
28 (opcode >= 0x0070 && opcode <= 0x0077)) 27 (opcode >= 0x0070 && opcode <= 0x0077) ||
29 return true; 28 (opcode >= 0xE3000000 && opcode <= 0xE3FFFFFF))
30
31 ins_addr--;
32 if (!get_instruction(&opcode, ins_addr))
33 return false;
34
35 if (opcode >= 0xE300 && opcode <= 0xE3FF)
36 return true; 29 return true;
37 30
38 return false; 31 return false;
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 5aa0d5e4e704..317d4273ca60 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -75,6 +75,26 @@ void decode_address(char *buf, unsigned long address)
75 } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { 75 } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) {
76 strcat(buf, "/* on-chip L1 ROM */"); 76 strcat(buf, "/* on-chip L1 ROM */");
77 return; 77 return;
78
79 } else if (address >= L1_SCRATCH_START && address < L1_SCRATCH_START + L1_SCRATCH_LENGTH) {
80 strcat(buf, "/* on-chip scratchpad */");
81 return;
82
83 } else if (address >= physical_mem_end && address < ASYNC_BANK0_BASE) {
84 strcat(buf, "/* unconnected memory */");
85 return;
86
87 } else if (address >= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE && address < BOOT_ROM_START) {
88 strcat(buf, "/* reserved memory */");
89 return;
90
91 } else if (address >= L1_DATA_A_START && address < L1_DATA_A_START + L1_DATA_A_LENGTH) {
92 strcat(buf, "/* on-chip Data Bank A */");
93 return;
94
95 } else if (address >= L1_DATA_B_START && address < L1_DATA_B_START + L1_DATA_B_LENGTH) {
96 strcat(buf, "/* on-chip Data Bank B */");
97 return;
78 } 98 }
79 99
80 /* 100 /*
@@ -173,7 +193,7 @@ done:
173 * Similar to get_user, do some address checking, then dereference 193 * Similar to get_user, do some address checking, then dereference
174 * Return true on success, false on bad address 194 * Return true on success, false on bad address
175 */ 195 */
176bool get_instruction(unsigned short *val, unsigned short *address) 196bool get_mem16(unsigned short *val, unsigned short *address)
177{ 197{
178 unsigned long addr = (unsigned long)address; 198 unsigned long addr = (unsigned long)address;
179 199
@@ -181,10 +201,6 @@ bool get_instruction(unsigned short *val, unsigned short *address)
181 if (addr & 0x1) 201 if (addr & 0x1)
182 return false; 202 return false;
183 203
184 /* MMR region will never have instructions */
185 if (addr >= SYSMMR_BASE)
186 return false;
187
188 switch (bfin_mem_access_type(addr, 2)) { 204 switch (bfin_mem_access_type(addr, 2)) {
189 case BFIN_MEM_ACCESS_CORE: 205 case BFIN_MEM_ACCESS_CORE:
190 case BFIN_MEM_ACCESS_CORE_ONLY: 206 case BFIN_MEM_ACCESS_CORE_ONLY:
@@ -201,60 +217,430 @@ bool get_instruction(unsigned short *val, unsigned short *address)
201 } 217 }
202} 218}
203 219
220bool get_instruction(unsigned int *val, unsigned short *address)
221{
222 unsigned long addr = (unsigned long)address;
223 unsigned short opcode0, opcode1;
224
225 /* Check for odd addresses */
226 if (addr & 0x1)
227 return false;
228
229 /* MMR region will never have instructions */
230 if (addr >= SYSMMR_BASE)
231 return false;
232
233 /* Scratchpad will never have instructions */
234 if (addr >= L1_SCRATCH_START && addr < L1_SCRATCH_START + L1_SCRATCH_LENGTH)
235 return false;
236
237 /* Data banks will never have instructions */
238 if (addr >= BOOT_ROM_START + BOOT_ROM_LENGTH && addr < L1_CODE_START)
239 return false;
240
241 if (!get_mem16(&opcode0, address))
242 return false;
243
244 /* was this a 32-bit instruction? If so, get the next 16 bits */
245 if ((opcode0 & 0xc000) == 0xc000) {
246 if (!get_mem16(&opcode1, address + 1))
247 return false;
248 *val = (opcode0 << 16) + opcode1;
249 } else
250 *val = opcode0;
251
252 return true;
253}
254
255#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON)
204/* 256/*
205 * decode the instruction if we are printing out the trace, as it 257 * decode the instruction if we are printing out the trace, as it
206 * makes things easier to follow, without running it through objdump 258 * makes things easier to follow, without running it through objdump
207 * These are the normal instructions which cause change of flow, which 259 * Decode the change of flow, and the common load/store instructions
208 * would be at the source of the trace buffer 260 * which are the main cause for faults, and discontinuities in the trace
261 * buffer.
209 */ 262 */
210#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) 263
211static void decode_instruction(unsigned short *address) 264#define ProgCtrl_opcode 0x0000
265#define ProgCtrl_poprnd_bits 0
266#define ProgCtrl_poprnd_mask 0xf
267#define ProgCtrl_prgfunc_bits 4
268#define ProgCtrl_prgfunc_mask 0xf
269#define ProgCtrl_code_bits 8
270#define ProgCtrl_code_mask 0xff
271
272static void decode_ProgCtrl_0(unsigned int opcode)
273{
274 int poprnd = ((opcode >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
275 int prgfunc = ((opcode >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
276
277 if (prgfunc == 0 && poprnd == 0)
278 pr_cont("NOP");
279 else if (prgfunc == 1 && poprnd == 0)
280 pr_cont("RTS");
281 else if (prgfunc == 1 && poprnd == 1)
282 pr_cont("RTI");
283 else if (prgfunc == 1 && poprnd == 2)
284 pr_cont("RTX");
285 else if (prgfunc == 1 && poprnd == 3)
286 pr_cont("RTN");
287 else if (prgfunc == 1 && poprnd == 4)
288 pr_cont("RTE");
289 else if (prgfunc == 2 && poprnd == 0)
290 pr_cont("IDLE");
291 else if (prgfunc == 2 && poprnd == 3)
292 pr_cont("CSYNC");
293 else if (prgfunc == 2 && poprnd == 4)
294 pr_cont("SSYNC");
295 else if (prgfunc == 2 && poprnd == 5)
296 pr_cont("EMUEXCPT");
297 else if (prgfunc == 3)
298 pr_cont("CLI R%i", poprnd);
299 else if (prgfunc == 4)
300 pr_cont("STI R%i", poprnd);
301 else if (prgfunc == 5)
302 pr_cont("JUMP (P%i)", poprnd);
303 else if (prgfunc == 6)
304 pr_cont("CALL (P%i)", poprnd);
305 else if (prgfunc == 7)
306 pr_cont("CALL (PC + P%i)", poprnd);
307 else if (prgfunc == 8)
308 pr_cont("JUMP (PC + P%i", poprnd);
309 else if (prgfunc == 9)
310 pr_cont("RAISE %i", poprnd);
311 else if (prgfunc == 10)
312 pr_cont("EXCPT %i", poprnd);
313 else
314 pr_cont("0x%04x", opcode);
315
316}
317
318#define BRCC_opcode 0x1000
319#define BRCC_offset_bits 0
320#define BRCC_offset_mask 0x3ff
321#define BRCC_B_bits 10
322#define BRCC_B_mask 0x1
323#define BRCC_T_bits 11
324#define BRCC_T_mask 0x1
325#define BRCC_code_bits 12
326#define BRCC_code_mask 0xf
327
328static void decode_BRCC_0(unsigned int opcode)
212{ 329{
213 unsigned short opcode; 330 int B = ((opcode >> BRCC_B_bits) & BRCC_B_mask);
214 331 int T = ((opcode >> BRCC_T_bits) & BRCC_T_mask);
215 if (get_instruction(&opcode, address)) { 332
216 if (opcode == 0x0010) 333 pr_cont("IF %sCC JUMP pcrel %s", T ? "" : "!", B ? "(BP)" : "");
217 pr_cont("RTS"); 334}
218 else if (opcode == 0x0011) 335
219 pr_cont("RTI"); 336#define CALLa_opcode 0xe2000000
220 else if (opcode == 0x0012) 337#define CALLa_addr_bits 0
221 pr_cont("RTX"); 338#define CALLa_addr_mask 0xffffff
222 else if (opcode == 0x0013) 339#define CALLa_S_bits 24
223 pr_cont("RTN"); 340#define CALLa_S_mask 0x1
224 else if (opcode == 0x0014) 341#define CALLa_code_bits 25
225 pr_cont("RTE"); 342#define CALLa_code_mask 0x7f
226 else if (opcode == 0x0025) 343
227 pr_cont("EMUEXCPT"); 344static void decode_CALLa_0(unsigned int opcode)
228 else if (opcode >= 0x0040 && opcode <= 0x0047) 345{
229 pr_cont("STI R%i", opcode & 7); 346 int S = ((opcode >> (CALLa_S_bits - 16)) & CALLa_S_mask);
230 else if (opcode >= 0x0050 && opcode <= 0x0057) 347
231 pr_cont("JUMP (P%i)", opcode & 7); 348 if (S)
232 else if (opcode >= 0x0060 && opcode <= 0x0067) 349 pr_cont("CALL pcrel");
233 pr_cont("CALL (P%i)", opcode & 7); 350 else
234 else if (opcode >= 0x0070 && opcode <= 0x0077) 351 pr_cont("JUMP.L");
235 pr_cont("CALL (PC+P%i)", opcode & 7); 352}
236 else if (opcode >= 0x0080 && opcode <= 0x0087) 353
237 pr_cont("JUMP (PC+P%i)", opcode & 7); 354#define LoopSetup_opcode 0xe0800000
238 else if (opcode >= 0x0090 && opcode <= 0x009F) 355#define LoopSetup_eoffset_bits 0
239 pr_cont("RAISE 0x%x", opcode & 0xF); 356#define LoopSetup_eoffset_mask 0x3ff
240 else if (opcode >= 0x00A0 && opcode <= 0x00AF) 357#define LoopSetup_dontcare_bits 10
241 pr_cont("EXCPT 0x%x", opcode & 0xF); 358#define LoopSetup_dontcare_mask 0x3
242 else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) 359#define LoopSetup_reg_bits 12
243 pr_cont("IF !CC JUMP"); 360#define LoopSetup_reg_mask 0xf
244 else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) 361#define LoopSetup_soffset_bits 16
245 pr_cont("IF CC JUMP"); 362#define LoopSetup_soffset_mask 0xf
246 else if (opcode >= 0x2000 && opcode <= 0x2fff) 363#define LoopSetup_c_bits 20
247 pr_cont("JUMP.S"); 364#define LoopSetup_c_mask 0x1
248 else if (opcode >= 0xe080 && opcode <= 0xe0ff) 365#define LoopSetup_rop_bits 21
249 pr_cont("LSETUP"); 366#define LoopSetup_rop_mask 0x3
250 else if (opcode >= 0xe200 && opcode <= 0xe2ff) 367#define LoopSetup_code_bits 23
251 pr_cont("JUMP.L"); 368#define LoopSetup_code_mask 0x1ff
252 else if (opcode >= 0xe300 && opcode <= 0xe3ff) 369
253 pr_cont("CALL pcrel"); 370static void decode_LoopSetup_0(unsigned int opcode)
371{
372 int c = ((opcode >> LoopSetup_c_bits) & LoopSetup_c_mask);
373 int reg = ((opcode >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
374 int rop = ((opcode >> LoopSetup_rop_bits) & LoopSetup_rop_mask);
375
376 pr_cont("LSETUP <> LC%i", c);
377 if ((rop & 1) == 1)
378 pr_cont("= P%i", reg);
379 if ((rop & 2) == 2)
380 pr_cont(" >> 0x1");
381}
382
383#define DspLDST_opcode 0x9c00
384#define DspLDST_reg_bits 0
385#define DspLDST_reg_mask 0x7
386#define DspLDST_i_bits 3
387#define DspLDST_i_mask 0x3
388#define DspLDST_m_bits 5
389#define DspLDST_m_mask 0x3
390#define DspLDST_aop_bits 7
391#define DspLDST_aop_mask 0x3
392#define DspLDST_W_bits 9
393#define DspLDST_W_mask 0x1
394#define DspLDST_code_bits 10
395#define DspLDST_code_mask 0x3f
396
397static void decode_dspLDST_0(unsigned int opcode)
398{
399 int i = ((opcode >> DspLDST_i_bits) & DspLDST_i_mask);
400 int m = ((opcode >> DspLDST_m_bits) & DspLDST_m_mask);
401 int W = ((opcode >> DspLDST_W_bits) & DspLDST_W_mask);
402 int aop = ((opcode >> DspLDST_aop_bits) & DspLDST_aop_mask);
403 int reg = ((opcode >> DspLDST_reg_bits) & DspLDST_reg_mask);
404
405 if (W == 0) {
406 pr_cont("R%i", reg);
407 switch (m) {
408 case 0:
409 pr_cont(" = ");
410 break;
411 case 1:
412 pr_cont(".L = ");
413 break;
414 case 2:
415 pr_cont(".W = ");
416 break;
417 }
418 }
419
420 pr_cont("[ I%i", i);
421
422 switch (aop) {
423 case 0:
424 pr_cont("++ ]");
425 break;
426 case 1:
427 pr_cont("-- ]");
428 break;
429 }
430
431 if (W == 1) {
432 pr_cont(" = R%i", reg);
433 switch (m) {
434 case 1:
435 pr_cont(".L = ");
436 break;
437 case 2:
438 pr_cont(".W = ");
439 break;
440 }
441 }
442}
443
444#define LDST_opcode 0x9000
445#define LDST_reg_bits 0
446#define LDST_reg_mask 0x7
447#define LDST_ptr_bits 3
448#define LDST_ptr_mask 0x7
449#define LDST_Z_bits 6
450#define LDST_Z_mask 0x1
451#define LDST_aop_bits 7
452#define LDST_aop_mask 0x3
453#define LDST_W_bits 9
454#define LDST_W_mask 0x1
455#define LDST_sz_bits 10
456#define LDST_sz_mask 0x3
457#define LDST_code_bits 12
458#define LDST_code_mask 0xf
459
460static void decode_LDST_0(unsigned int opcode)
461{
462 int Z = ((opcode >> LDST_Z_bits) & LDST_Z_mask);
463 int W = ((opcode >> LDST_W_bits) & LDST_W_mask);
464 int sz = ((opcode >> LDST_sz_bits) & LDST_sz_mask);
465 int aop = ((opcode >> LDST_aop_bits) & LDST_aop_mask);
466 int reg = ((opcode >> LDST_reg_bits) & LDST_reg_mask);
467 int ptr = ((opcode >> LDST_ptr_bits) & LDST_ptr_mask);
468
469 if (W == 0)
470 pr_cont("%s%i = ", (sz == 0 && Z == 1) ? "P" : "R", reg);
471
472 switch (sz) {
473 case 1:
474 pr_cont("W");
475 break;
476 case 2:
477 pr_cont("B");
478 break;
479 }
480
481 pr_cont("[P%i", ptr);
482
483 switch (aop) {
484 case 0:
485 pr_cont("++");
486 break;
487 case 1:
488 pr_cont("--");
489 break;
490 }
491 pr_cont("]");
492
493 if (W == 1)
494 pr_cont(" = %s%i ", (sz == 0 && Z == 1) ? "P" : "R", reg);
495
496 if (sz) {
497 if (Z)
498 pr_cont(" (X)");
499 else
500 pr_cont(" (Z)");
501 }
502}
503
504#define LDSTii_opcode 0xa000
505#define LDSTii_reg_bit 0
506#define LDSTii_reg_mask 0x7
507#define LDSTii_ptr_bit 3
508#define LDSTii_ptr_mask 0x7
509#define LDSTii_offset_bit 6
510#define LDSTii_offset_mask 0xf
511#define LDSTii_op_bit 10
512#define LDSTii_op_mask 0x3
513#define LDSTii_W_bit 12
514#define LDSTii_W_mask 0x1
515#define LDSTii_code_bit 13
516#define LDSTii_code_mask 0x7
517
518static void decode_LDSTii_0(unsigned int opcode)
519{
520 int reg = ((opcode >> LDSTii_reg_bit) & LDSTii_reg_mask);
521 int ptr = ((opcode >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
522 int offset = ((opcode >> LDSTii_offset_bit) & LDSTii_offset_mask);
523 int op = ((opcode >> LDSTii_op_bit) & LDSTii_op_mask);
524 int W = ((opcode >> LDSTii_W_bit) & LDSTii_W_mask);
525
526 if (W == 0) {
527 pr_cont("%s%i = %s[P%i + %i]", op == 3 ? "R" : "P", reg,
528 op == 1 || op == 2 ? "" : "W", ptr, offset);
529 if (op == 2)
530 pr_cont("(Z)");
531 if (op == 3)
532 pr_cont("(X)");
533 } else {
534 pr_cont("%s[P%i + %i] = %s%i", op == 0 ? "" : "W", ptr,
535 offset, op == 3 ? "P" : "R", reg);
536 }
537}
538
539#define LDSTidxI_opcode 0xe4000000
540#define LDSTidxI_offset_bits 0
541#define LDSTidxI_offset_mask 0xffff
542#define LDSTidxI_reg_bits 16
543#define LDSTidxI_reg_mask 0x7
544#define LDSTidxI_ptr_bits 19
545#define LDSTidxI_ptr_mask 0x7
546#define LDSTidxI_sz_bits 22
547#define LDSTidxI_sz_mask 0x3
548#define LDSTidxI_Z_bits 24
549#define LDSTidxI_Z_mask 0x1
550#define LDSTidxI_W_bits 25
551#define LDSTidxI_W_mask 0x1
552#define LDSTidxI_code_bits 26
553#define LDSTidxI_code_mask 0x3f
554
555static void decode_LDSTidxI_0(unsigned int opcode)
556{
557 int Z = ((opcode >> LDSTidxI_Z_bits) & LDSTidxI_Z_mask);
558 int W = ((opcode >> LDSTidxI_W_bits) & LDSTidxI_W_mask);
559 int sz = ((opcode >> LDSTidxI_sz_bits) & LDSTidxI_sz_mask);
560 int reg = ((opcode >> LDSTidxI_reg_bits) & LDSTidxI_reg_mask);
561 int ptr = ((opcode >> LDSTidxI_ptr_bits) & LDSTidxI_ptr_mask);
562 int offset = ((opcode >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
563
564 if (W == 0)
565 pr_cont("%s%i = ", sz == 0 && Z == 1 ? "P" : "R", reg);
566
567 if (sz == 1)
568 pr_cont("W");
569 if (sz == 2)
570 pr_cont("B");
571
572 pr_cont("[P%i + %s0x%x]", ptr, offset & 0x20 ? "-" : "",
573 (offset & 0x1f) << 2);
574
575 if (W == 0 && sz != 0) {
576 if (Z)
577 pr_cont("(X)");
254 else 578 else
255 pr_cont("0x%04x", opcode); 579 pr_cont("(Z)");
256 } 580 }
257 581
582 if (W == 1)
583 pr_cont("= %s%i", (sz == 0 && Z == 1) ? "P" : "R", reg);
584
585}
586
587static void decode_opcode(unsigned int opcode)
588{
589#ifdef CONFIG_BUG
590 if (opcode == BFIN_BUG_OPCODE)
591 pr_cont("BUG");
592 else
593#endif
594 if ((opcode & 0xffffff00) == ProgCtrl_opcode)
595 decode_ProgCtrl_0(opcode);
596 else if ((opcode & 0xfffff000) == BRCC_opcode)
597 decode_BRCC_0(opcode);
598 else if ((opcode & 0xfffff000) == 0x2000)
599 pr_cont("JUMP.S");
600 else if ((opcode & 0xfe000000) == CALLa_opcode)
601 decode_CALLa_0(opcode);
602 else if ((opcode & 0xff8000C0) == LoopSetup_opcode)
603 decode_LoopSetup_0(opcode);
604 else if ((opcode & 0xfffffc00) == DspLDST_opcode)
605 decode_dspLDST_0(opcode);
606 else if ((opcode & 0xfffff000) == LDST_opcode)
607 decode_LDST_0(opcode);
608 else if ((opcode & 0xffffe000) == LDSTii_opcode)
609 decode_LDSTii_0(opcode);
610 else if ((opcode & 0xfc000000) == LDSTidxI_opcode)
611 decode_LDSTidxI_0(opcode);
612 else if (opcode & 0xffff0000)
613 pr_cont("0x%08x", opcode);
614 else
615 pr_cont("0x%04x", opcode);
616}
617
618#define BIT_MULTI_INS 0x08000000
619static void decode_instruction(unsigned short *address)
620{
621 unsigned int opcode;
622
623 if (!get_instruction(&opcode, address))
624 return;
625
626 decode_opcode(opcode);
627
628 /* If things are a 32-bit instruction, it has the possibility of being
629 * a multi-issue instruction (a 32-bit, and 2 16 bit instrucitions)
630 * This test collidates with the unlink instruction, so disallow that
631 */
632 if ((opcode & 0xc0000000) == 0xc0000000 &&
633 (opcode & BIT_MULTI_INS) &&
634 (opcode & 0xe8000000) != 0xe8000000) {
635 pr_cont(" || ");
636 if (!get_instruction(&opcode, address + 2))
637 return;
638 decode_opcode(opcode);
639 pr_cont(" || ");
640 if (!get_instruction(&opcode, address + 3))
641 return;
642 decode_opcode(opcode);
643 }
258} 644}
259#endif 645#endif
260 646
@@ -397,7 +783,7 @@ void dump_bfin_mem(struct pt_regs *fp)
397 if (!((unsigned long)addr & 0xF)) 783 if (!((unsigned long)addr & 0xF))
398 pr_notice("0x%p: ", addr); 784 pr_notice("0x%p: ", addr);
399 785
400 if (!get_instruction(&val, addr)) { 786 if (!get_mem16(&val, addr)) {
401 val = 0; 787 val = 0;
402 sprintf(buf, "????"); 788 sprintf(buf, "????");
403 } else 789 } else
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 7c31a3d7af22..fffcf8a516bf 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -546,7 +546,7 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
546#ifdef CONFIG_BUG 546#ifdef CONFIG_BUG
547int is_valid_bugaddr(unsigned long addr) 547int is_valid_bugaddr(unsigned long addr)
548{ 548{
549 unsigned short opcode; 549 unsigned int opcode;
550 550
551 if (!get_instruction(&opcode, (unsigned short *)addr)) 551 if (!get_instruction(&opcode, (unsigned short *)addr))
552 return 0; 552 return 0;