12a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz/* provide some functions which dump the trace buffer, in a nice way for people
22a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * to read it, and understand what is going on
32a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz *
42a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * Copyright 2004-2010 Analog Devices Inc.
52a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz *
62a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * Licensed under the GPL-2 or later
72a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz */
82a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
92a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/kernel.h>
102a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/hardirq.h>
112a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/thread_info.h>
122a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/mm.h>
132214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov#include <linux/oom.h>
142214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov#include <linux/sched.h>
152a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/uaccess.h>
162a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/module.h>
172a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/kallsyms.h>
182a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/err.h>
192a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <linux/fs.h>
20df9ee29270c11dba7d0fe0b83ce47a4d8e8d2101David Howells#include <linux/irq.h>
212a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <asm/dma.h>
222a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <asm/trace.h>
232a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <asm/fixed_code.h>
242a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#include <asm/traps.h>
25d60805ad470aef52465f3dc982212f559d9f661bRobin Getz#include <asm/irq_handler.h>
263bed8d67469cc7129b0babc0211c32fa68408ce0David Howells#include <asm/pda.h>
272a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
282a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzvoid decode_address(char *buf, unsigned long address)
292a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
302a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	struct task_struct *p;
312a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	struct mm_struct *mm;
32af1be5a578a1ccc9961c55290f8c509a00a69036Anton Vorontsov	unsigned long offset;
332a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	struct rb_node *n;
342a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
352a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_KALLSYMS
362a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned long symsize;
372a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	const char *symname;
382a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	char *modname;
392a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	char *delim = ":";
402a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	char namebuf[128];
412a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
422a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
432a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	buf += sprintf(buf, "<0x%08lx> ", address);
442a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
452a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_KALLSYMS
462a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* look up the address and see if we are in kernel space */
472a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
482a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
492a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (symname) {
502a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		/* yeah! kernel space! */
512a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (!modname)
522a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			modname = delim = "";
532a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		sprintf(buf, "{ %s%s%s%s + 0x%lx }",
542a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			delim, modname, delim, symname,
552a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			(unsigned long)offset);
562a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
572a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
582a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
592a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (address >= FIXED_CODE_START && address < FIXED_CODE_END) {
612a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		/* Problem in fixed code section? */
622a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		strcat(buf, "/* Maybe fixed code section */");
632a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
642a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
652a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	} else if (address < CONFIG_BOOT_LOAD) {
662a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		/* Problem somewhere before the kernel start address */
672a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		strcat(buf, "/* Maybe null pointer? */");
682a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
692a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
702a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	} else if (address >= COREMMR_BASE) {
712a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		strcat(buf, "/* core mmrs */");
722a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
732a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
742a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	} else if (address >= SYSMMR_BASE) {
752a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		strcat(buf, "/* system mmrs */");
762a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
772a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
782a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	} else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) {
792a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		strcat(buf, "/* on-chip L1 ROM */");
802a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
819a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
829a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else if (address >= L1_SCRATCH_START && address < L1_SCRATCH_START + L1_SCRATCH_LENGTH) {
839a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		strcat(buf, "/* on-chip scratchpad */");
849a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return;
859a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
869a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else if (address >= physical_mem_end && address < ASYNC_BANK0_BASE) {
879a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		strcat(buf, "/* unconnected memory */");
889a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return;
899a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
909a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else if (address >= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE && address < BOOT_ROM_START) {
919a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		strcat(buf, "/* reserved memory */");
929a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return;
939a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
949a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else if (address >= L1_DATA_A_START && address < L1_DATA_A_START + L1_DATA_A_LENGTH) {
959a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		strcat(buf, "/* on-chip Data Bank A */");
969a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return;
979a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
989a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else if (address >= L1_DATA_B_START && address < L1_DATA_B_START + L1_DATA_B_LENGTH) {
999a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		strcat(buf, "/* on-chip Data Bank B */");
1009a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return;
1012a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
1022a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1032a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/*
1042a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * Don't walk any of the vmas if we are oopsing, it has been known
1052a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * to cause problems - corrupt vmas (kernel crashes) cause double faults
1062a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 */
1072a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (oops_in_progress) {
1082a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		strcat(buf, "/* kernel dynamic memory (maybe user-space) */");
1092a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return;
1102a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
1112a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1122a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* looks like we're off in user-land, so let's walk all the
1132a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * mappings of all our processes and see if we can't be a whee
1142a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * bit more specific
1152a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 */
116af1be5a578a1ccc9961c55290f8c509a00a69036Anton Vorontsov	read_lock(&tasklist_lock);
1172a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	for_each_process(p) {
1182214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov		struct task_struct *t;
1192a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1202214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov		t = find_lock_task_mm(p);
1212214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov		if (!t)
1222a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			continue;
1232214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov
1242214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov		mm = t->mm;
1252214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov		if (!down_read_trylock(&mm->mmap_sem))
1262214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov			goto __continue;
1272a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1282a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
1292a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			struct vm_area_struct *vma;
1302a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1312a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			vma = rb_entry(n, struct vm_area_struct, vm_rb);
1322a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1332a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			if (address >= vma->vm_start && address < vma->vm_end) {
1342a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				char _tmpbuf[256];
1352214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov				char *name = t->comm;
1362a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				struct file *file = vma->vm_file;
1372a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1382a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				if (file) {
1392a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					char *d_name = d_path(&file->f_path, _tmpbuf,
1402a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz						      sizeof(_tmpbuf));
1412a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					if (!IS_ERR(d_name))
1422a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz						name = d_name;
1432a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				}
1442a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1452a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				/* FLAT does not have its text aligned to the start of
1462a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				 * the map while FDPIC ELF does ...
1472a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				 */
1482a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1492a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				/* before we can check flat/fdpic, we need to
1502a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				 * make sure current is valid
1512a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				 */
1522a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				if ((unsigned long)current >= FIXED_CODE_START &&
1532a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				    !((unsigned long)current & 0x3)) {
1542a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					if (current->mm &&
1552a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					    (address > current->mm->start_code) &&
1562a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					    (address < current->mm->end_code))
1572a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz						offset = address - current->mm->start_code;
1582a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					else
1592a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz						offset = (address - vma->vm_start) +
1602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz							 (vma->vm_pgoff << PAGE_SHIFT);
1612a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1622a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					sprintf(buf, "[ %s + 0x%lx ]", name, offset);
1632a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				} else
1642a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
1652a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz						name, vma->vm_start, vma->vm_end);
1662a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1672a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				up_read(&mm->mmap_sem);
1682214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov				task_unlock(t);
1692a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1702a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				if (buf[0] == '\0')
1712a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz					sprintf(buf, "[ %s ] dynamic memory", name);
1722a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1732a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				goto done;
1742a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			}
1752a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		}
1762a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1772a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		up_read(&mm->mmap_sem);
1782214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov__continue:
1792214f707de257c35773d5cd68cec9e31b91e01caAnton Vorontsov		task_unlock(t);
1802a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
1812a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1822a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/*
1832a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * we were unable to find this address anywhere,
1842a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * or some MMs were skipped because they were in use.
1852a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 */
1862a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	sprintf(buf, "/* kernel dynamic memory */");
1872a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1882a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzdone:
189af1be5a578a1ccc9961c55290f8c509a00a69036Anton Vorontsov	read_unlock(&tasklist_lock);
1902a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
1912a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1922a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
1932a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
1942a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz/*
1952a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * Similar to get_user, do some address checking, then dereference
1962a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * Return true on success, false on bad address
1972a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz */
1989a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzbool get_mem16(unsigned short *val, unsigned short *address)
1992a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
2002a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned long addr = (unsigned long)address;
2012a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
2022a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* Check for odd addresses */
2032a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (addr & 0x1)
2042a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return false;
2052a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
2062a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	switch (bfin_mem_access_type(addr, 2)) {
2072a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	case BFIN_MEM_ACCESS_CORE:
2082a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	case BFIN_MEM_ACCESS_CORE_ONLY:
2092a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		*val = *address;
2102a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return true;
2112a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	case BFIN_MEM_ACCESS_DMA:
2122a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		dma_memcpy(val, address, 2);
2132a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return true;
2142a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	case BFIN_MEM_ACCESS_ITEST:
2152a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		isram_memcpy(val, address, 2);
2162a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return true;
2172a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	default: /* invalid access */
2182a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		return false;
2192a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
2202a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
2212a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
2229a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzbool get_instruction(unsigned int *val, unsigned short *address)
2239a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
2249a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	unsigned long addr = (unsigned long)address;
2259a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	unsigned short opcode0, opcode1;
2269a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2279a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	/* Check for odd addresses */
2289a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (addr & 0x1)
2299a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return false;
2309a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2319a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	/* MMR region will never have instructions */
2329a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (addr >= SYSMMR_BASE)
2339a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return false;
2349a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2359a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	/* Scratchpad will never have instructions */
2369a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (addr >= L1_SCRATCH_START && addr < L1_SCRATCH_START + L1_SCRATCH_LENGTH)
2379a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return false;
2389a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2399a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	/* Data banks will never have instructions */
2409a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (addr >= BOOT_ROM_START + BOOT_ROM_LENGTH && addr < L1_CODE_START)
2419a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return false;
2429a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2439a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (!get_mem16(&opcode0, address))
2449a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return false;
2459a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2469a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	/* was this a 32-bit instruction? If so, get the next 16 bits */
2479a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if ((opcode0 & 0xc000) == 0xc000) {
2489a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (!get_mem16(&opcode1, address + 1))
2499a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			return false;
2509a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		*val = (opcode0 << 16) + opcode1;
2519a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else
2529a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		*val = opcode0;
2539a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2549a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	return true;
2559a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
2569a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2579a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#if defined(CONFIG_DEBUG_BFIN_HWTRACE_ON)
2582a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz/*
2592a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * decode the instruction if we are printing out the trace, as it
2602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz * makes things easier to follow, without running it through objdump
2619a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz * Decode the change of flow, and the common load/store instructions
2629a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz * which are the main cause for faults, and discontinuities in the trace
2639a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz * buffer.
2642a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz */
2659a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2669a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_opcode         0x0000
2679a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_poprnd_bits    0
2689a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_poprnd_mask    0xf
2699a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_prgfunc_bits   4
2709a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_prgfunc_mask   0xf
2719a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_code_bits      8
2729a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define ProgCtrl_code_mask      0xff
2739a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2749a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_ProgCtrl_0(unsigned int opcode)
2759a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
2769a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int poprnd  = ((opcode >> ProgCtrl_poprnd_bits) & ProgCtrl_poprnd_mask);
2779a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int prgfunc = ((opcode >> ProgCtrl_prgfunc_bits) & ProgCtrl_prgfunc_mask);
2789a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
2799a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (prgfunc == 0 && poprnd == 0)
2809a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("NOP");
2819a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 1 && poprnd == 0)
2829a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("RTS");
2839a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 1 && poprnd == 1)
2849a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("RTI");
2859a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 1 && poprnd == 2)
2869a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("RTX");
2879a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 1 && poprnd == 3)
2889a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("RTN");
2899a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 1 && poprnd == 4)
2909a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("RTE");
2919a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 2 && poprnd == 0)
2929a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("IDLE");
2939a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 2 && poprnd == 3)
2949a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("CSYNC");
2959a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 2 && poprnd == 4)
2969a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("SSYNC");
2979a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 2 && poprnd == 5)
2989a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("EMUEXCPT");
2999a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 3)
3009a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("CLI R%i", poprnd);
3019a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 4)
3029a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("STI R%i", poprnd);
3039a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 5)
3049a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("JUMP (P%i)", poprnd);
3059a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 6)
3069a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("CALL (P%i)", poprnd);
3079a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 7)
3089a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("CALL (PC + P%i)", poprnd);
3099a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 8)
3109a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("JUMP (PC + P%i", poprnd);
3119a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 9)
3129a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("RAISE %i", poprnd);
3139a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (prgfunc == 10)
3149a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("EXCPT %i", poprnd);
3159a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else
3169a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("0x%04x", opcode);
3179a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3189a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
3199a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3209a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_opcode             0x1000
3219a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_offset_bits        0
3229a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_offset_mask        0x3ff
3239a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_B_bits             10
3249a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_B_mask             0x1
3259a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_T_bits             11
3269a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_T_mask             0x1
3279a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_code_bits          12
3289a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BRCC_code_mask          0xf
3299a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3309a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_BRCC_0(unsigned int opcode)
3312a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
3329a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int B = ((opcode >> BRCC_B_bits) & BRCC_B_mask);
3339a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int T = ((opcode >> BRCC_T_bits) & BRCC_T_mask);
3349a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3359a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	pr_cont("IF %sCC JUMP pcrel %s", T ? "" : "!", B ? "(BP)" : "");
3369a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
3379a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3389a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_opcode    0xe2000000
3399a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_addr_bits 0
3409a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_addr_mask 0xffffff
3419a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_S_bits    24
3429a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_S_mask    0x1
3439a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_code_bits 25
3449a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define CALLa_code_mask 0x7f
3459a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3469a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_CALLa_0(unsigned int opcode)
3479a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
3489a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int S   = ((opcode >> (CALLa_S_bits - 16)) & CALLa_S_mask);
3499a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3509a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (S)
3519a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("CALL pcrel");
3529a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else
3539a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("JUMP.L");
3549a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
3559a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3569a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_opcode                0xe0800000
3579a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_eoffset_bits          0
3589a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_eoffset_mask          0x3ff
3599a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_dontcare_bits         10
3609a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_dontcare_mask         0x3
3619a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_reg_bits              12
3629a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_reg_mask              0xf
3639a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_soffset_bits          16
3649a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_soffset_mask          0xf
3659a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_c_bits                20
3669a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_c_mask                0x1
3679a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_rop_bits              21
3689a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_rop_mask              0x3
3699a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_code_bits             23
3709a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LoopSetup_code_mask             0x1ff
3719a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3729a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_LoopSetup_0(unsigned int opcode)
3739a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
3749a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int c   = ((opcode >> LoopSetup_c_bits)   & LoopSetup_c_mask);
3759a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int reg = ((opcode >> LoopSetup_reg_bits) & LoopSetup_reg_mask);
3769a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int rop = ((opcode >> LoopSetup_rop_bits) & LoopSetup_rop_mask);
3779a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3789a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	pr_cont("LSETUP <> LC%i", c);
3799a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if ((rop & 1) == 1)
3809a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("= P%i", reg);
3819a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if ((rop & 2) == 2)
3829a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont(" >> 0x1");
3839a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
3849a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3859a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_opcode          0x9c00
3869a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_reg_bits        0
3879a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_reg_mask        0x7
3889a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_i_bits          3
3899a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_i_mask          0x3
3909a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_m_bits          5
3919a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_m_mask          0x3
3929a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_aop_bits        7
3939a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_aop_mask        0x3
3949a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_W_bits          9
3959a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_W_mask          0x1
3969a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_code_bits       10
3979a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define DspLDST_code_mask       0x3f
3989a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
3999a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_dspLDST_0(unsigned int opcode)
4009a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
4019a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int i   = ((opcode >> DspLDST_i_bits) & DspLDST_i_mask);
4029a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int m   = ((opcode >> DspLDST_m_bits) & DspLDST_m_mask);
4039a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int W   = ((opcode >> DspLDST_W_bits) & DspLDST_W_mask);
4049a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int aop = ((opcode >> DspLDST_aop_bits) & DspLDST_aop_mask);
4059a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int reg = ((opcode >> DspLDST_reg_bits) & DspLDST_reg_mask);
4069a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4079a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 0) {
4089a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("R%i", reg);
4099a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		switch (m) {
4109a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		case 0:
4119a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(" = ");
4129a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			break;
4139a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		case 1:
4149a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(".L = ");
4159a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			break;
4169a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		case 2:
4179a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(".W = ");
4189a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			break;
4199a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		}
4209a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
4219a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4229a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	pr_cont("[ I%i", i);
4239a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4249a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	switch (aop) {
4259a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	case 0:
4269a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("++ ]");
4279a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		break;
4289a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	case 1:
4299a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("-- ]");
4309a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		break;
4319a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
4329a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4339a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 1) {
4349a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont(" = R%i", reg);
4359a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		switch (m) {
4369a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		case 1:
4379a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(".L = ");
4389a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			break;
4399a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		case 2:
4409a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(".W = ");
4419a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			break;
4429a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		}
4439a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
4449a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
4459a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4469a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_opcode             0x9000
4479a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_reg_bits           0
4489a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_reg_mask           0x7
4499a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_ptr_bits           3
4509a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_ptr_mask           0x7
4519a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_Z_bits             6
4529a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_Z_mask             0x1
4539a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_aop_bits           7
4549a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_aop_mask           0x3
4559a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_W_bits             9
4569a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_W_mask             0x1
4579a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_sz_bits            10
4589a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_sz_mask            0x3
4599a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_code_bits          12
4609a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDST_code_mask          0xf
4619a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4629a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_LDST_0(unsigned int opcode)
4639a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
4649a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int Z   = ((opcode >> LDST_Z_bits) & LDST_Z_mask);
4659a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int W   = ((opcode >> LDST_W_bits) & LDST_W_mask);
4669a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int sz  = ((opcode >> LDST_sz_bits) & LDST_sz_mask);
4679a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int aop = ((opcode >> LDST_aop_bits) & LDST_aop_mask);
4689a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int reg = ((opcode >> LDST_reg_bits) & LDST_reg_mask);
4699a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int ptr = ((opcode >> LDST_ptr_bits) & LDST_ptr_mask);
4709a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4719a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 0)
4729a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("%s%i = ", (sz == 0 && Z == 1) ? "P" : "R", reg);
4739a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4749a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	switch (sz) {
4759a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	case 1:
4769a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("W");
4779a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		break;
4789a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	case 2:
4799a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("B");
4809a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		break;
4819a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
4829a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4839a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	pr_cont("[P%i", ptr);
4849a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4859a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	switch (aop) {
4869a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	case 0:
4879a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("++");
4889a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		break;
4899a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	case 1:
4909a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("--");
4919a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		break;
4929a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
4939a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	pr_cont("]");
4949a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4959a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 1)
4969a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont(" = %s%i ", (sz == 0 && Z == 1) ? "P" : "R", reg);
4979a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
4989a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (sz) {
4999a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (Z)
5009a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(" (X)");
5019a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		else
5029a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont(" (Z)");
5039a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
5049a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
5059a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5069a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_opcode           0xa000
5079a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_reg_bit          0
5089a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_reg_mask         0x7
5099a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_ptr_bit          3
5109a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_ptr_mask         0x7
5119a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_offset_bit       6
5129a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_offset_mask      0xf
5139a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_op_bit           10
5149a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_op_mask          0x3
5159a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_W_bit            12
5169a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_W_mask           0x1
5179a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_code_bit         13
5189a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTii_code_mask        0x7
5199a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5209a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_LDSTii_0(unsigned int opcode)
5219a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
5229a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int reg = ((opcode >> LDSTii_reg_bit) & LDSTii_reg_mask);
5239a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int ptr = ((opcode >> LDSTii_ptr_bit) & LDSTii_ptr_mask);
5249a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int offset = ((opcode >> LDSTii_offset_bit) & LDSTii_offset_mask);
5259a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int op = ((opcode >> LDSTii_op_bit) & LDSTii_op_mask);
5269a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int W = ((opcode >> LDSTii_W_bit) & LDSTii_W_mask);
5279a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5289a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 0) {
5299a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("%s%i = %s[P%i + %i]", op == 3 ? "R" : "P", reg,
5309a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			op == 1 || op == 2 ? "" : "W", ptr, offset);
5319a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (op == 2)
5329a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont("(Z)");
5339a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (op == 3)
5349a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont("(X)");
5359a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	} else {
5369a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("%s[P%i + %i] = %s%i", op == 0 ? "" : "W", ptr,
5379a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			offset, op == 3 ? "P" : "R", reg);
5389a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
5399a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
5409a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5419a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_opcode         0xe4000000
5429a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_offset_bits    0
5439a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_offset_mask    0xffff
5449a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_reg_bits       16
5459a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_reg_mask       0x7
5469a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_ptr_bits       19
5479a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_ptr_mask       0x7
5489a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_sz_bits        22
5499a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_sz_mask        0x3
5509a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_Z_bits         24
5519a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_Z_mask         0x1
5529a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_W_bits         25
5539a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_W_mask         0x1
5549a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_code_bits      26
5559a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define LDSTidxI_code_mask      0x3f
5569a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5579a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_LDSTidxI_0(unsigned int opcode)
5589a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
5599a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int Z      = ((opcode >> LDSTidxI_Z_bits)      & LDSTidxI_Z_mask);
5609a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int W      = ((opcode >> LDSTidxI_W_bits)      & LDSTidxI_W_mask);
5619a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int sz     = ((opcode >> LDSTidxI_sz_bits)     & LDSTidxI_sz_mask);
5629a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int reg    = ((opcode >> LDSTidxI_reg_bits)    & LDSTidxI_reg_mask);
5639a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int ptr    = ((opcode >> LDSTidxI_ptr_bits)    & LDSTidxI_ptr_mask);
5649a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	int offset = ((opcode >> LDSTidxI_offset_bits) & LDSTidxI_offset_mask);
5659a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5669a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 0)
5679a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("%s%i = ", sz == 0 && Z == 1 ? "P" : "R", reg);
5689a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5699a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (sz == 1)
5709a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("W");
5719a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (sz == 2)
5729a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("B");
5739a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5749a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	pr_cont("[P%i + %s0x%x]", ptr, offset & 0x20 ? "-" : "",
5759a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		(offset & 0x1f) << 2);
5769a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5779a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 0 && sz != 0) {
5789a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (Z)
5799a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont("(X)");
5802a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		else
5819a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			pr_cont("(Z)");
5822a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
5832a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
5849a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (W == 1)
5859a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("= %s%i", (sz == 0 && Z == 1) ? "P" : "R", reg);
5869a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5879a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
5889a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
5899a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_opcode(unsigned int opcode)
5909a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
5919a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#ifdef CONFIG_BUG
5929a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (opcode == BFIN_BUG_OPCODE)
5939a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("BUG");
5949a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else
5959a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#endif
5969a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if ((opcode & 0xffffff00) == ProgCtrl_opcode)
5979a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_ProgCtrl_0(opcode);
5989a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xfffff000) == BRCC_opcode)
5999a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_BRCC_0(opcode);
6009a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xfffff000) == 0x2000)
6019a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("JUMP.S");
6029a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xfe000000) == CALLa_opcode)
6039a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_CALLa_0(opcode);
6049a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xff8000C0) == LoopSetup_opcode)
6059a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_LoopSetup_0(opcode);
6069a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xfffffc00) == DspLDST_opcode)
6079a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_dspLDST_0(opcode);
6089a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xfffff000) == LDST_opcode)
6099a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_LDST_0(opcode);
6109a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xffffe000) == LDSTii_opcode)
6119a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_LDSTii_0(opcode);
6129a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if ((opcode & 0xfc000000) == LDSTidxI_opcode)
6139a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_LDSTidxI_0(opcode);
6149a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else if (opcode & 0xffff0000)
6159a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("0x%08x", opcode);
6169a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	else
6179a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont("0x%04x", opcode);
6189a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz}
6199a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
6209a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz#define BIT_MULTI_INS 0x08000000
6219a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getzstatic void decode_instruction(unsigned short *address)
6229a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz{
6239a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	unsigned int opcode;
6249a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
6259a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if (!get_instruction(&opcode, address))
6269a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		return;
6279a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
6289a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	decode_opcode(opcode);
6299a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz
6309a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	/* If things are a 32-bit instruction, it has the possibility of being
6319a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	 * a multi-issue instruction (a 32-bit, and 2 16 bit instrucitions)
6329a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	 * This test collidates with the unlink instruction, so disallow that
6339a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	 */
6349a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	if ((opcode & 0xc0000000) == 0xc0000000 &&
6359a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	    (opcode & BIT_MULTI_INS) &&
6369a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	    (opcode & 0xe8000000) != 0xe8000000) {
6379a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont(" || ");
6389a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (!get_instruction(&opcode, address + 2))
6399a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			return;
6409a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_opcode(opcode);
6419a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		pr_cont(" || ");
6429a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (!get_instruction(&opcode, address + 3))
6439a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz			return;
6449a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		decode_opcode(opcode);
6459a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz	}
6462a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
6472a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
6482a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
6492a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzvoid dump_bfin_trace_buffer(void)
6502a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
6512a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
652d60805ad470aef52465f3dc982212f559d9f661bRobin Getz	int tflags, i = 0, fault = 0;
6532a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	char buf[150];
6542a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned short *addr;
655d60805ad470aef52465f3dc982212f559d9f661bRobin Getz	unsigned int cpu = raw_smp_processor_id();
6562a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
6572a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	int j, index;
6582a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
6592a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
6602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	trace_buffer_save(tflags);
6612a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
662d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("Hardware Trace:\n");
6632a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
6642a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
665d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("WARNING: Expanded trace turned on - can not trace exceptions\n");
6662a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
6672a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
6682a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
6692a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
670d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			addr = (unsigned short *)bfin_read_TBUF();
671d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			decode_address(buf, (unsigned long)addr);
672d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("%4i Target : %s\n", i, buf);
673d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			/* Normally, the faulting instruction doesn't go into
674d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			 * the trace buffer, (since it doesn't commit), so
675d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			 * we print out the fault address here
676d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			 */
677a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz			if (!fault && addr == ((unsigned short *)evt_ivhw)) {
678a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				addr = (unsigned short *)bfin_read_TBUF();
679a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				decode_address(buf, (unsigned long)addr);
680a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				pr_notice("      FAULT : %s ", buf);
681a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				decode_instruction(addr);
682a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				pr_cont("\n");
683a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				fault = 1;
684a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz				continue;
685a80d5f449d1794d8e402f28cf3e1e9b57cb9f2d4Robin Getz			}
686d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			if (!fault && addr == (unsigned short *)trap &&
687d60805ad470aef52465f3dc982212f559d9f661bRobin Getz				(cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE) > VEC_EXCPT15) {
688d60805ad470aef52465f3dc982212f559d9f661bRobin Getz				decode_address(buf, cpu_pda[cpu].icplb_fault_addr);
689d60805ad470aef52465f3dc982212f559d9f661bRobin Getz				pr_notice("      FAULT : %s ", buf);
690d60805ad470aef52465f3dc982212f559d9f661bRobin Getz				decode_instruction((unsigned short *)cpu_pda[cpu].icplb_fault_addr);
691d60805ad470aef52465f3dc982212f559d9f661bRobin Getz				pr_cont("\n");
692d60805ad470aef52465f3dc982212f559d9f661bRobin Getz				fault = 1;
693d60805ad470aef52465f3dc982212f559d9f661bRobin Getz			}
6942a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			addr = (unsigned short *)bfin_read_TBUF();
6952a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			decode_address(buf, (unsigned long)addr);
696d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("     Source : %s ", buf);
6972a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			decode_instruction(addr);
698d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_cont("\n");
6992a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		}
7002a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
7012a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7022a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
7032a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (trace_buff_offset)
7042a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		index = trace_buff_offset / 4;
7052a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	else
7062a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		index = EXPAND_LEN;
7072a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7082a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128;
7092a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	while (j) {
7102a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		decode_address(buf, software_trace_buff[index]);
711d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("%4i Target : %s\n", i, buf);
7122a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		index -= 1;
7132a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (index < 0)
7142a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			index = EXPAND_LEN;
7152a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		decode_address(buf, software_trace_buff[index]);
716d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("     Source : %s ", buf);
7172a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		decode_instruction((unsigned short *)software_trace_buff[index]);
718d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_cont("\n");
7192a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		index -= 1;
7202a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (index < 0)
7212a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			index = EXPAND_LEN;
7222a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		j--;
7232a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		i++;
7242a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
7252a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
7262a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7272a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	trace_buffer_restore(tflags);
7282a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
7292a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
7302a12c4632db1c0c548a7023e63869b27c7789a92Robin GetzEXPORT_SYMBOL(dump_bfin_trace_buffer);
7312a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7322a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzvoid dump_bfin_process(struct pt_regs *fp)
7332a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
7342a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* We should be able to look at fp->ipend, but we don't push it on the
7352a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * stack all the time, so do this until we fix that */
7362a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned int context = bfin_read_IPEND();
7372a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7382a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (oops_in_progress)
739d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_emerg("Kernel OOPS in progress\n");
7402a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7412a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR)
742d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("HW Error context\n");
7432a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	else if (context & 0x0020)
744d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("Deferred Exception context\n");
7452a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	else if (context & 0x3FC0)
746d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("Interrupt context\n");
7472a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	else if (context & 0x4000)
748d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("Deferred Interrupt context\n");
7492a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	else if (context & 0x8000)
750d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("Kernel process context\n");
7512a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7522a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* Because we are crashing, and pointers could be bad, we check things
7532a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 * pretty closely before we use them
7542a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	 */
7552a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if ((unsigned long)current >= FIXED_CODE_START &&
7562a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	    !((unsigned long)current & 0x3) && current->pid) {
757d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("CURRENT PROCESS:\n");
7582a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (current->comm >= (char *)FIXED_CODE_START)
759d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("COMM=%s PID=%d",
7602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				current->comm, current->pid);
7612a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		else
762d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("COMM= invalid");
7632a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
764d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_cont("  CPU=%d\n", current_thread_info()->cpu);
765d28cff4b615c2da274922311cef024d52c839870Robin Getz		if (!((unsigned long)current->mm & 0x3) &&
766d28cff4b615c2da274922311cef024d52c839870Robin Getz			(unsigned long)current->mm >= FIXED_CODE_START) {
767d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("TEXT = 0x%p-0x%p        DATA = 0x%p-0x%p\n",
7682a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				(void *)current->mm->start_code,
7692a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				(void *)current->mm->end_code,
7702a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				(void *)current->mm->start_data,
771d28cff4b615c2da274922311cef024d52c839870Robin Getz				(void *)current->mm->end_data);
772d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice(" BSS = 0x%p-0x%p  USER-STACK = 0x%p\n\n",
7732a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				(void *)current->mm->end_data,
7742a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				(void *)current->mm->brk,
7752a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				(void *)current->mm->start_stack);
776d28cff4b615c2da274922311cef024d52c839870Robin Getz		} else
777d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("invalid mm\n");
7782a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	} else
779d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("No Valid process in current context\n");
7802a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
7812a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7822a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzvoid dump_bfin_mem(struct pt_regs *fp)
7832a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
7842a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned short *addr, *erraddr, val = 0, err = 0;
7852a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	char sti = 0, buf[6];
7862a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7872a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	erraddr = (void *)fp->pc;
7882a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
789d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("return address: [0x%p]; contents of:", erraddr);
7902a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7912a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10;
7922a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	     addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10;
7932a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	     addr++) {
7942a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (!((unsigned long)addr & 0xF))
795d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("0x%p: ", addr);
7962a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
7979a95e2f1008ee433c496a81628cdde67acc8e4b1Robin Getz		if (!get_mem16(&val, addr)) {
7982a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				val = 0;
7992a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				sprintf(buf, "????");
8002a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		} else
8012a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			sprintf(buf, "%04x", val);
8022a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
8032a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (addr == erraddr) {
804d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_cont("[%s]", buf);
8052a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			err = val;
8062a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		} else
807d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_cont(" %s ", buf);
8082a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
8092a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		/* Do any previous instructions turn on interrupts? */
8102a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (addr <= erraddr &&				/* in the past */
8112a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		    ((val >= 0x0040 && val <= 0x0047) ||	/* STI instruction */
8122a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		      val == 0x017b))				/* [SP++] = RETI */
8132a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			sti = 1;
8142a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
8152a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
816d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_cont("\n");
8172a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
8182a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* Hardware error interrupts can be deferred */
8192a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR &&
8202a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	    oops_in_progress)){
821d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("Looks like this was a deferred error - sorry\n");
8222a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifndef CONFIG_DEBUG_HWERR
823d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("The remaining message may be meaningless\n");
824d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n");
8252a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#else
8262a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		/* If we are handling only one peripheral interrupt
8272a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		 * and current mm and pid are valid, and the last error
8282a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		 * was in that user space process's text area
8292a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		 * print it out - because that is where the problem exists
8302a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		 */
8312a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) &&
8322a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		     (current->pid && current->mm)) {
8332a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			/* And the last RETI points to the current userspace context */
8342a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			if ((fp + 1)->pc >= current->mm->start_code &&
8352a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			    (fp + 1)->pc <= current->mm->end_code) {
836d28cff4b615c2da274922311cef024d52c839870Robin Getz				pr_notice("It might be better to look around here :\n");
837d28cff4b615c2da274922311cef024d52c839870Robin Getz				pr_notice("-------------------------------------------\n");
8382a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				show_regs(fp + 1);
839d28cff4b615c2da274922311cef024d52c839870Robin Getz				pr_notice("-------------------------------------------\n");
8402a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			}
8412a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		}
8422a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
8432a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
8442a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
8452a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
8462a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzvoid show_regs(struct pt_regs *fp)
8472a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz{
8482a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	char buf[150];
8492a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	struct irqaction *action;
8502a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned int i;
8512a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned long flags = 0;
8522a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned int cpu = raw_smp_processor_id();
8532a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
8542a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
855d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("\n");
856a43cb95d547a061ed5bf1acb28e0f5fd575e26c1Tejun Heo	show_regs_print_info(KERN_NOTICE);
857a43cb95d547a061ed5bf1acb28e0f5fd575e26c1Tejun Heo
8582a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (CPUID != bfin_cpuid())
859d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("Compiled for cpu family 0x%04x (Rev %d), "
8602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			"but running on:0x%04x (Rev %d)\n",
8612a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid());
8622a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
863d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("ADSP-%s-0.%d",
8642a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		CPU, bfin_compiled_revid());
8652a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
8662a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (bfin_compiled_revid() !=  bfin_revid())
867d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_cont("(Detected 0.%d)", bfin_revid());
8682a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
869d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_cont(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n",
8702a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		get_cclk()/1000000, get_sclk()/1000000,
8712a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef CONFIG_MPU
8722a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		"mpu on"
8732a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#else
8742a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		"mpu off"
8752a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
8762a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		);
8772a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
878d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("%s", linux_banner);
8792a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
880d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("\nSEQUENCER STATUS:\t\t%s\n", print_tainted());
881d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" SEQSTAT: %08lx  IPEND: %04lx  IMASK: %04lx  SYSCFG: %04lx\n",
8822a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		(long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg);
8832a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (fp->ipend & EVT_IRPTEN)
884d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("  Global Interrupts Disabled (IPEND[4])\n");
8852a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 |
8862a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR)))
887d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("  Peripheral interrupts masked off\n");
8882a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
889d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("  Kernel interrupts masked off\n");
8902a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
891d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("  HWERRCAUSE: 0x%lx\n",
8922a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
8932a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#ifdef EBIU_ERRMST
8942a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		/* If the error was from the EBIU, print it out */
8952a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (bfin_read_EBIU_ERRMST() & CORE_ERROR) {
896d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("  EBIU Error Reason  : 0x%04x\n",
8972a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				bfin_read_EBIU_ERRMST());
898d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("  EBIU Error Address : 0x%08x\n",
8992a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				bfin_read_EBIU_ERRADD());
9002a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		}
9012a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz#endif
9022a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
903d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("  EXCAUSE   : 0x%lx\n",
9042a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->seqstat & SEQSTAT_EXCAUSE);
9052a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	for (i = 2; i <= 15 ; i++) {
9062a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		if (fp->ipend & (1 << i)) {
9072a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			if (i != 4) {
9082a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				decode_address(buf, bfin_read32(EVT0 + 4*i));
909d28cff4b615c2da274922311cef024d52c839870Robin Getz				pr_notice("  physical IVG%i asserted : %s\n", i, buf);
9102a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			} else
911d28cff4b615c2da274922311cef024d52c839870Robin Getz				pr_notice("  interrupts disabled\n");
9122a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		}
9132a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
9142a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
9152a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	/* if no interrupts are going off, don't print this out */
9162a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (fp->ipend & ~0x3F) {
9172a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		for (i = 0; i < (NR_IRQS - 1); i++) {
91828a283aae3bdd5088246ca830247ec8393e3e06bThomas Gleixner			struct irq_desc *desc = irq_to_desc(i);
9192a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			if (!in_atomic)
92028a283aae3bdd5088246ca830247ec8393e3e06bThomas Gleixner				raw_spin_lock_irqsave(&desc->lock, flags);
9212a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
92228a283aae3bdd5088246ca830247ec8393e3e06bThomas Gleixner			action = desc->action;
9232a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			if (!action)
9242a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				goto unlock;
9252a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
9262a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			decode_address(buf, (unsigned int)action->handler);
927d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_notice("  logical irq %3d mapped  : %s", i, buf);
9282a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			for (action = action->next; action; action = action->next) {
9292a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz				decode_address(buf, (unsigned int)action->handler);
930d28cff4b615c2da274922311cef024d52c839870Robin Getz				pr_cont(", %s", buf);
9312a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			}
932d28cff4b615c2da274922311cef024d52c839870Robin Getz			pr_cont("\n");
9332a12c4632db1c0c548a7023e63869b27c7789a92Robin Getzunlock:
9342a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz			if (!in_atomic)
93528a283aae3bdd5088246ca830247ec8393e3e06bThomas Gleixner				raw_spin_unlock_irqrestore(&desc->lock, flags);
9362a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		}
9372a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
9382a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
9392a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	decode_address(buf, fp->rete);
940d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" RETE: %s\n", buf);
9412a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	decode_address(buf, fp->retn);
942d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" RETN: %s\n", buf);
9432a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	decode_address(buf, fp->retx);
944d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" RETX: %s\n", buf);
9452a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	decode_address(buf, fp->rets);
946d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" RETS: %s\n", buf);
9472a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	decode_address(buf, fp->pc);
948d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" PC  : %s\n", buf);
9492a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
9502a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) &&
9512a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	    (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) {
9522a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		decode_address(buf, cpu_pda[cpu].dcplb_fault_addr);
953d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("DCPLB_FAULT_ADDR: %s\n", buf);
9542a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		decode_address(buf, cpu_pda[cpu].icplb_fault_addr);
955d28cff4b615c2da274922311cef024d52c839870Robin Getz		pr_notice("ICPLB_FAULT_ADDR: %s\n", buf);
9562a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz	}
9572a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
958d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("PROCESSOR STATE:\n");
959d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" R0 : %08lx    R1 : %08lx    R2 : %08lx    R3 : %08lx\n",
9602a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->r0, fp->r1, fp->r2, fp->r3);
961d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" R4 : %08lx    R5 : %08lx    R6 : %08lx    R7 : %08lx\n",
9622a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->r4, fp->r5, fp->r6, fp->r7);
963d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" P0 : %08lx    P1 : %08lx    P2 : %08lx    P3 : %08lx\n",
9642a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->p0, fp->p1, fp->p2, fp->p3);
965d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" P4 : %08lx    P5 : %08lx    FP : %08lx    SP : %08lx\n",
9662a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->p4, fp->p5, fp->fp, (long)fp);
967d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" LB0: %08lx    LT0: %08lx    LC0: %08lx\n",
9682a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->lb0, fp->lt0, fp->lc0);
969d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" LB1: %08lx    LT1: %08lx    LC1: %08lx\n",
9702a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->lb1, fp->lt1, fp->lc1);
971d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" B0 : %08lx    L0 : %08lx    M0 : %08lx    I0 : %08lx\n",
9722a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->b0, fp->l0, fp->m0, fp->i0);
973d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" B1 : %08lx    L1 : %08lx    M1 : %08lx    I1 : %08lx\n",
9742a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->b1, fp->l1, fp->m1, fp->i1);
975d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" B2 : %08lx    L2 : %08lx    M2 : %08lx    I2 : %08lx\n",
9762a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->b2, fp->l2, fp->m2, fp->i2);
977d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice(" B3 : %08lx    L3 : %08lx    M3 : %08lx    I3 : %08lx\n",
9782a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->b3, fp->l3, fp->m3, fp->i3);
979d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("A0.w: %08lx   A0.x: %08lx   A1.w: %08lx   A1.x: %08lx\n",
9802a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		fp->a0w, fp->a0x, fp->a1w, fp->a1x);
9812a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
982d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("USP : %08lx  ASTAT: %08lx\n",
9832a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz		rdusp(), fp->astat);
9842a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz
985d28cff4b615c2da274922311cef024d52c839870Robin Getz	pr_notice("\n");
9862a12c4632db1c0c548a7023e63869b27c7789a92Robin Getz}
987