patch-2.3.43 linux/arch/ppc/xmon/start.c
Next file: linux/arch/ppc/xmon/xmon.c
Previous file: linux/arch/ppc/mm/init.c
Back to the patch index
Back to the overall index
- Lines: 278
- Date:
Wed Feb 9 19:43:47 2000
- Orig file:
v2.3.42/linux/arch/ppc/xmon/start.c
- Orig date:
Fri Jan 28 15:09:07 2000
diff -u --recursive --new-file v2.3.42/linux/arch/ppc/xmon/start.c linux/arch/ppc/xmon/start.c
@@ -8,19 +8,34 @@
#include <asm/page.h>
#include <linux/adb.h>
#include <linux/pmu.h>
+#include <linux/kernel.h>
#include <asm/prom.h>
#include <asm/bootx.h>
+#include <asm/feature.h>
#include <asm/processor.h>
static volatile unsigned char *sccc, *sccd;
unsigned long TXRDY, RXRDY;
extern void xmon_printf(const char *fmt, ...);
-extern void map_bootx_text(void);
extern void drawchar(char);
extern void drawstring(const char *str);
+static int xmon_expect(const char *str, unsigned int timeout);
static int console = 0;
static int use_screen = 0;
+static int via_modem = 0;
+static int xmon_use_sccb = 0;
+static struct device_node *macio_node;
+
+#define TB_SPEED 25000000
+
+static inline unsigned int readtb(void)
+{
+ unsigned int ret;
+
+ asm volatile("mftb %0" : "=r" (ret) :);
+ return ret;
+}
void buf_access(void)
{
@@ -36,17 +51,19 @@
if ( _machine == _MACH_Pmac )
{
struct device_node *np;
- extern boot_infos_t *boot_infos;
unsigned long addr;
-
#ifdef CONFIG_BOOTX_TEXT
- if (boot_infos != 0 && find_via_pmu()) {
- printk("xmon uses screen and keyboard\n");
+ extern boot_infos_t *disp_bi;
+
+ /* needs to be hacked if xmon_printk is to be used
+ from within find_via_pmu() */
+ if (!via_modem && disp_bi && find_via_pmu()) {
+ drawstring("xmon uses screen and keyboard\n");
use_screen = 1;
- map_bootx_text();
return;
}
#endif
+
#ifdef CHRP_ESCC
addr = 0xc1013020;
#else
@@ -57,9 +74,10 @@
np = find_devices("mac-io");
if (np && np->n_addrs) {
+ macio_node = np;
addr = np->addrs[0].address + 0x13000;
- /* use the B channel on the iMac, A channel on others */
- if (addr >= 0xf0000000)
+ /* use the B channel on the iMac */
+ if (!xmon_use_sccb)
addr += 0x20; /* use A channel */
}
base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
@@ -70,22 +88,22 @@
sccd = sccc + (0xf3013030 - 0xf3013020);
#endif
}
- else if ( _machine & _MACH_chrp )
+ else if ( _machine & _MACH_gemini )
{
/* should already be mapped by the kernel boot */
- sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
- sccd = (volatile unsigned char *) (isa_io_base + 0x3f8);
+ sccc = (volatile unsigned char *) 0xffeffb0d;
+ sccd = (volatile unsigned char *) 0xffeffb08;
TXRDY = 0x20;
RXRDY = 1;
+ console = 1;
}
- else if ( _machine & _MACH_gemini )
+ else
{
/* should already be mapped by the kernel boot */
- sccc = (volatile unsigned char *) 0xffeffb0d;
- sccd = (volatile unsigned char *) 0xffeffb08;
+ sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
+ sccd = (volatile unsigned char *) (isa_io_base + 0x3f8);
TXRDY = 0x20;
RXRDY = 1;
- console = 1;
}
}
@@ -98,7 +116,7 @@
xmon_write(void *handle, void *ptr, int nb)
{
char *p = ptr;
- int i, ct;
+ int i, c, ct;
#ifdef CONFIG_BOOTX_TEXT
if (use_screen) {
@@ -111,20 +129,26 @@
if (!scc_initialized)
xmon_init_scc();
for (i = 0; i < nb; ++i) {
-#ifdef CONFIG_ADB
+ ct = 0;
while ((*sccc & TXRDY) == 0)
+#ifdef CONFIG_ADB
if (sys_ctrler == SYS_CTRLER_PMU)
pmu_poll();
+#else
+ ;
#endif /* CONFIG_ADB */
- buf_access();
- if ( console && (*p != '\r'))
- printk("%c", *p);
- ct = 0;
- if ( *p == '\n')
+ c = p[i];
+ if (c == '\n' && !ct) {
+ c = '\r';
ct = 1;
- *sccd = *p++;
- if ( ct )
- xmon_write(handle, "\r", 1);
+ --i;
+ } else {
+ if (console)
+ printk("%c", c);
+ ct = 0;
+ }
+ buf_access();
+ *sccd = c;
}
return i;
}
@@ -206,36 +230,49 @@
if (!scc_initialized)
xmon_init_scc();
for (i = 0; i < nb; ++i) {
-#ifdef CONFIG_ADB
while ((*sccc & RXRDY) == 0)
+#ifdef CONFIG_ADB
if (sys_ctrler == SYS_CTRLER_PMU)
pmu_poll();
+#else
+ ;
#endif /* CONFIG_ADB */
buf_access();
-#if 0
- if ( 0/*console*/ )
- *p++ = ppc_md.kbd_getkeycode();
- else
-#endif
*p++ = *sccd;
}
return i;
}
+int
+xmon_read_poll(void)
+{
+ if ((*sccc & RXRDY) == 0) {
+#ifdef CONFIG_ADB
+ if (sys_ctrler == SYS_CTRLER_PMU)
+ pmu_poll();
+#else
+ ;
+#endif
+ return -1;
+ }
+ buf_access();
+ return *sccd;
+}
+
static unsigned char scc_inittab[] = {
13, 0, /* set baud rate divisor */
12, 1,
14, 1, /* baud rate gen enable, src=rtxc */
11, 0x50, /* clocks = br gen */
- 5, 0x6a, /* tx 8 bits, assert RTS */
- 4, 0x44, /* x16 clock, 1 stop */
+ 5, 0xea, /* tx 8 bits, assert DTR & RTS */
+ 4, 0x46, /* x16 clock, 1 stop */
3, 0xc1, /* rx enable, 8 bits */
};
void
xmon_init_scc()
{
- if ( _machine & (_MACH_chrp|_MACH_gemini) )
+ if ( _machine == _MACH_chrp )
{
sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
sccd[0] = 3; eieio(); /* DLL = 38400 baud */
@@ -248,6 +285,14 @@
{
int i, x;
+ if (macio_node != 0) {
+ unsigned int t0;
+
+ feature_set(macio_node, FEATURE_Modem_power);
+ t0 = readtb();
+ while (readtb() - t0 < 3*TB_SPEED)
+ eieio();
+ }
for (i = 20000; i != 0; --i) {
x = *sccc; eieio();
}
@@ -259,6 +304,18 @@
}
}
scc_initialized = 1;
+ if (via_modem) {
+ for (;;) {
+ xmon_write(0, "ATE1V1\r", 7);
+ if (xmon_expect("OK", 5)) {
+ xmon_write(0, "ATA\r", 4);
+ if (xmon_expect("CONNECT", 40))
+ break;
+ }
+ xmon_write(0, "+++", 3);
+ xmon_expect("OK", 3);
+ }
+ }
}
#if 0
@@ -330,6 +387,35 @@
static char line[256];
static char *lineptr;
static int lineleft;
+
+int xmon_expect(const char *str, unsigned int timeout)
+{
+ int c;
+ unsigned int t0;
+
+ timeout *= TB_SPEED;
+ t0 = readtb();
+ do {
+ lineptr = line;
+ for (;;) {
+ c = xmon_read_poll();
+ if (c == -1) {
+ if (readtb() - t0 > timeout) {
+ printk("timeout\n");
+ return 0;
+ }
+ continue;
+ }
+ if (c == '\n')
+ break;
+ printk("%c", c);
+ if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+ *lineptr++ = c;
+ }
+ *lineptr = 0;
+ } while (strstr(line, str) == NULL);
+ return 1;
+}
int
xmon_getchar(void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)