10ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz/*
296f1050d3df105c9ae6c6ac224f370199ea82fcdRobin Getz * allow a console to be used for early printk
396f1050d3df105c9ae6c6ac224f370199ea82fcdRobin Getz * derived from arch/x86/kernel/early_printk.c
40ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz *
596f1050d3df105c9ae6c6ac224f370199ea82fcdRobin Getz * Copyright 2007-2009 Analog Devices Inc.
60ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz *
796f1050d3df105c9ae6c6ac224f370199ea82fcdRobin Getz * Licensed under the GPL-2
80ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz */
90ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
100ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <linux/kernel.h>
110ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <linux/init.h>
120ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <linux/serial_core.h>
130ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <linux/console.h>
140ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <linux/string.h>
15837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz#include <linux/reboot.h>
160ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <asm/blackfin.h>
170ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <asm/irq_handler.h>
180ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#include <asm/early_printk.h>
190ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
200ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#ifdef CONFIG_SERIAL_BFIN
210ae53640b54f2c30e52044f7102ba08915b988a7Robin Getzextern struct console *bfin_earlyserial_init(unsigned int port,
220ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz						unsigned int cflag);
230ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#endif
24a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger#ifdef CONFIG_BFIN_JTAG_COMM
25a88c71e4367aada2065c5e247477c891d2ca952fMike Frysingerextern struct console *bfin_jc_early_init(void);
26a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger#endif
270ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
28337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz/* Default console */
290ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#define DEFAULT_PORT 0
300ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#define DEFAULT_CFLAG CS8|B57600
310ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
32337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz/* Default console for early crashes */
33337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz#define DEFAULT_EARLY_PORT "serial,uart0,57600"
34337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
350ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#ifdef CONFIG_SERIAL_CORE
360ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz/* What should get here is "0,57600" */
370ae53640b54f2c30e52044f7102ba08915b988a7Robin Getzstatic struct console * __init earlyserial_init(char *buf)
380ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz{
390ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	int baud, bit;
400ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	char parity;
410ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	unsigned int serial_port = DEFAULT_PORT;
420ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	unsigned int cflag = DEFAULT_CFLAG;
430ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
440ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	serial_port = simple_strtoul(buf, &buf, 10);
450ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	buf++;
460ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
470ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	cflag = 0;
480ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	baud = simple_strtoul(buf, &buf, 10);
490ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	switch (baud) {
500ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 1200:
510ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B1200;
520ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
530ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 2400:
540ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B2400;
550ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
560ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 4800:
570ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B4800;
580ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
590ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 9600:
600ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B9600;
610ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
620ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 19200:
630ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B19200;
640ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
650ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 38400:
660ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B38400;
670ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
680ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 115200:
690ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B115200;
700ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
710ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	default:
720ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= B57600;
730ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	}
740ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
750ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	parity = buf[0];
760ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	buf++;
770ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	switch (parity) {
780ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 'e':
790ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= PARENB;
800ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
810ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 'o':
820ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= PARODD;
830ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
840ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	}
850ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
860ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	bit = simple_strtoul(buf, &buf, 10);
870ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	switch (bit) {
880ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 5:
890ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= CS5;
900ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
910ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 6:
9209b7f4ad507bacd9c24d57966d23c4c715240ddaMike Frysinger		cflag |= CS6;
930ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
940ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	case 7:
9509b7f4ad507bacd9c24d57966d23c4c715240ddaMike Frysinger		cflag |= CS7;
960ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		break;
970ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	default:
980ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		cflag |= CS8;
990ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	}
1000ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1010ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#ifdef CONFIG_SERIAL_BFIN
1020ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	return bfin_earlyserial_init(serial_port, cflag);
1030ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#else
1040ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	return NULL;
1050ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#endif
1060ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1070ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz}
1080ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#endif
1090ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1100ae53640b54f2c30e52044f7102ba08915b988a7Robin Getzint __init setup_early_printk(char *buf)
1110ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz{
1120ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1130ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	/* Crashing in here would be really bad, so check both the var
1140ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	   and the pointer before we start using it
1150ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	 */
1160ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	if (!buf)
1170ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		return 0;
1180ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1190ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	if (!*buf)
1200ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		return 0;
1210ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1220ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	if (early_console != NULL)
1230ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		return 0;
1240ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1250ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#ifdef CONFIG_SERIAL_BFIN
1260ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	/* Check for Blackfin Serial */
1270ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	if (!strncmp(buf, "serial,uart", 11)) {
1280ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		buf += 11;
1290ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		early_console = earlyserial_init(buf);
1300ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	}
1310ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#endif
132a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger
133a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger#ifdef CONFIG_BFIN_JTAG_COMM
134a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger	/* Check for Blackfin JTAG */
135a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger	if (!strncmp(buf, "jtag", 4)) {
136a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger		buf += 4;
137a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger		early_console = bfin_jc_early_init();
138a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger	}
139a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger#endif
140a88c71e4367aada2065c5e247477c891d2ca952fMike Frysinger
1410ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#ifdef CONFIG_FB
1420ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		/* TODO: add framebuffer console support */
1430ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz#endif
1440ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1450ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	if (likely(early_console)) {
1460ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		early_console->flags |= CON_BOOT;
1470ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1480ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		register_console(early_console);
1490ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz		printk(KERN_INFO "early printk enabled on %s%d\n",
1500ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz			early_console->name,
1510ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz			early_console->index);
1520ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	}
1530ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
1540ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz	return 0;
1550ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz}
1560ae53640b54f2c30e52044f7102ba08915b988a7Robin Getz
157337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz/*
158337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz * Set up a temporary Event Vector Table, so if something bad happens before
159337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz * the kernel is fully started, it doesn't vector off into somewhere we don't
160337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz * know
161337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz */
162337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
163337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getzasmlinkage void __init init_early_exception_vectors(void)
164337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz{
165685a694f0653b7db49f663b2cd6953695214fb30Mike Frysinger	u32 evt;
166337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	SSYNC();
167337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
168837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	/*
169837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	 * This starts up the shadow buffer, incase anything crashes before
170837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	 * setup arch
171837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	 */
172837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	mark_shadow_error();
173837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	early_shadow_puts(linux_banner);
174837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	early_shadow_stamp();
175837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz
176837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	if (CPUID != bfin_cpuid()) {
177837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("Running on wrong machine type, expected");
178837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_reg(CPUID, 16);
179837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts(", but running on");
180837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_reg(bfin_cpuid(), 16);
181837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("\n");
182837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	}
183837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz
184337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	/* cannot program in software:
185337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 * evt0 - emulation (jtag)
186337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 * evt1 - reset
187337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 */
188685a694f0653b7db49f663b2cd6953695214fb30Mike Frysinger	for (evt = EVT2; evt <= EVT15; evt += 4)
189685a694f0653b7db49f663b2cd6953695214fb30Mike Frysinger		bfin_write32(evt, early_trap);
190337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	CSYNC();
191337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
19279f1ec862ae2e693b85fd7c94654ba1779ff5863Joe Perches	/* Set all the return from interrupt, exception, NMI to a known place
193337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
194337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 * Note - don't change RETS - we are in a subroutine, or
195337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 * RETE - since it might screw up if emulator is attached
196337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 */
197337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	asm("\tRETI = %0; RETX = %0; RETN = %0;\n"
198337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz		: : "p"(early_trap));
199337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
200337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz}
201337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
202837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz__attribute__((__noreturn__))
203337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getzasmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
204337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz{
205337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	/* This can happen before the uart is initialized, so initialize
20654ebae7166275a618f0228138e67ff7d10a3b9d0Robin Getz	 * the UART now (but only if we are running on the processor we think
20754ebae7166275a618f0228138e67ff7d10a3b9d0Robin Getz	 * we are compiled for - otherwise we write to MMRs that don't exist,
20854ebae7166275a618f0228138e67ff7d10a3b9d0Robin Getz	 * and cause other problems. Nothing comes out the UART, but it does
20954ebae7166275a618f0228138e67ff7d10a3b9d0Robin Getz	 * end up in the __buf_log.
210337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	 */
21154ebae7166275a618f0228138e67ff7d10a3b9d0Robin Getz	if (likely(early_console == NULL) && CPUID == bfin_cpuid())
212337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz		setup_early_printk(DEFAULT_EARLY_PORT);
213337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
214837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	if (!shadow_console_enabled()) {
215837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		/* crap - we crashed before setup_arch() */
216837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("panic before setup_arch\n");
217837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("IPEND:");
218837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_reg(fp->ipend, 16);
219837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		if (fp->seqstat & SEQSTAT_EXCAUSE) {
220837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_puts("\nEXCAUSE:");
221837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8);
222837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		}
223837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		if (fp->seqstat & SEQSTAT_HWERRCAUSE) {
224837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_puts("\nHWERRCAUSE:");
225837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_reg(
226837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz				(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8);
227837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		}
228837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("\nErr @");
229837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		if (fp->ipend & EVT_EVX)
230837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_reg(fp->retx, 32);
231837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		else
232837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_reg(fp->pc, 32);
233837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
234837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("\nTrace:");
235837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
236837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			while (bfin_read_TBUFSTAT() & TBUFCNT) {
237837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz				early_shadow_puts("\nT  :");
238837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz				early_shadow_reg(bfin_read_TBUF(), 32);
239837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz				early_shadow_puts("\n S :");
240837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz				early_shadow_reg(bfin_read_TBUF(), 32);
241837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			}
242837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		}
243837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz#endif
244837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("\nUse bfin-elf-addr2line to determine "
245837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			"function names\n");
246837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		/*
247837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		 * We should panic(), but we can't - since panic calls printk,
248837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		 * and printk uses memcpy.
249837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		 * we want to reboot, but if the machine type is different,
250837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		 * can't due to machine specific reboot sequences
251837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		 */
252837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		if (CPUID == bfin_cpuid()) {
253837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			early_shadow_puts("Trying to restart\n");
254837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			machine_restart("");
255837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		}
256837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz
257837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		early_shadow_puts("Halting, since it is not safe to restart\n");
258837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		while (1)
259837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz			asm volatile ("EMUEXCPT; IDLE;\n");
260837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz
261837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	} else {
262837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		printk(KERN_EMERG "Early panic\n");
263837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		show_regs(fp);
264837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz		dump_bfin_trace_buffer();
265837ec2d56c41640d1f1238e52c350b2a516d29baRobin Getz	}
266337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
267337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz	panic("Died early");
268337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz}
269337d390b3a9c1ce92a12bdb77b9ae6ded6273b12Robin Getz
2700ae53640b54f2c30e52044f7102ba08915b988a7Robin Getzearly_param("earlyprintk", setup_early_printk);
271