patch-2.2.12 linux/arch/ppc/xmon/adb.c

Next file: linux/arch/ppc/xmon/ansidecl.h
Previous file: linux/arch/ppc/xmon/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.11/linux/arch/ppc/xmon/adb.c linux/arch/ppc/xmon/adb.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include "nonstdio.h"
+#include "privinst.h"
+
+#define scanhex	xmon_scanhex
+#define skipbl	xmon_skipbl
+
+#define ADB_B		(*(volatile unsigned char *)0xf3016000)
+#define ADB_SR		(*(volatile unsigned char *)0xf3017400)
+#define ADB_ACR		(*(volatile unsigned char *)0xf3017600)
+#define ADB_IFR		(*(volatile unsigned char *)0xf3017a00)
+
+static inline void eieio(void) { asm volatile ("eieio" : :); }
+
+#define N_ADB_LOG	1000
+struct adb_log {
+    unsigned char b;
+    unsigned char ifr;
+    unsigned char acr;
+    unsigned int time;
+} adb_log[N_ADB_LOG];
+int n_adb_log;
+
+void
+init_adb_log(void)
+{
+    adb_log[0].b = ADB_B;
+    adb_log[0].ifr = ADB_IFR;
+    adb_log[0].acr = ADB_ACR;
+    adb_log[0].time = get_dec();
+    n_adb_log = 0;
+}
+
+void
+dump_adb_log(void)
+{
+    unsigned t, t0;
+    struct adb_log *ap;
+    int i;
+
+    ap = adb_log;
+    t0 = ap->time;
+    for (i = 0; i <= n_adb_log; ++i, ++ap) {
+	t = t0 - ap->time;
+	printf("b=%x ifr=%x acr=%x at %d.%.7d\n", ap->b, ap->ifr, ap->acr,
+	       t / 1000000000, (t % 1000000000) / 100);
+    }
+}
+
+void
+adb_chklog(void)
+{
+    struct adb_log *ap = &adb_log[n_adb_log + 1];
+
+    ap->b = ADB_B;
+    ap->ifr = ADB_IFR;
+    ap->acr = ADB_ACR;
+    if (ap->b != ap[-1].b || (ap->ifr & 4) != (ap[-1].ifr & 4)
+	|| ap->acr != ap[-1].acr) {
+	ap->time = get_dec();
+	++n_adb_log;
+    }
+}
+
+int
+adb_bitwait(int bmask, int bval, int fmask, int fval)
+{
+    int i;
+    struct adb_log *ap;
+
+    for (i = 10000; i > 0; --i) {
+	adb_chklog();
+	ap = &adb_log[n_adb_log];
+	if ((ap->b & bmask) == bval && (ap->ifr & fmask) == fval)
+	    return 0;
+    }
+    return -1;
+}
+
+int
+adb_wait(void)
+{
+    if (adb_bitwait(0, 0, 4, 4) < 0) {
+	printf("adb: ready wait timeout\n");
+	return -1;
+    }
+    return 0;
+}
+
+void
+adb_readin(void)
+{
+    int i, j;
+    unsigned char d[64];
+
+    if (ADB_B & 8) {
+	printf("ADB_B: %x\n", ADB_B);
+	return;
+    }
+    i = 0;
+    adb_wait();
+    j = ADB_SR;
+    eieio();
+    ADB_B &= ~0x20;
+    eieio();
+    for (;;) {
+	if (adb_wait() < 0)
+	    break;
+	d[i++] = ADB_SR;
+	eieio();
+	if (ADB_B & 8)
+	    break;
+	ADB_B ^= 0x10;
+	eieio();
+    }
+    ADB_B |= 0x30;
+    if (adb_wait() == 0)
+	j = ADB_SR;
+    for (j = 0; j < i; ++j)
+	printf("%.2x ", d[j]);
+    printf("\n");
+}
+
+int
+adb_write(unsigned char *d, int i)
+{
+    int j;
+    unsigned x;
+
+    if ((ADB_B & 8) == 0) {
+	printf("r: ");
+	adb_readin();
+    }
+    for (;;) {
+	ADB_ACR = 0x1c;
+	eieio();
+	ADB_SR = d[0];
+	eieio();
+	ADB_B &= ~0x20;
+	eieio();
+	if (ADB_B & 8)
+	    break;
+	ADB_ACR = 0xc;
+	eieio();
+	ADB_B |= 0x20;
+	eieio();
+	adb_readin();
+    }
+    adb_wait();
+    for (j = 1; j < i; ++j) {
+	ADB_SR = d[j];
+	eieio();
+	ADB_B ^= 0x10;
+	eieio();
+	if (adb_wait() < 0)
+	    break;
+    }
+    ADB_ACR = 0xc;
+    eieio();
+    x = ADB_SR;
+    eieio();
+    ADB_B |= 0x30;
+    return j;
+}
+
+void
+adbcmds(void)
+{
+    char cmd;
+    unsigned rtcu, rtcl, dec, pdec, x;
+    int i, j;
+    unsigned char d[64];
+
+    cmd = skipbl();
+    switch (cmd) {
+    case 't':
+	for (;;) {
+	    rtcl = get_rtcl();
+	    rtcu = get_rtcu();
+	    dec = get_dec();
+	    printf("rtc u=%u l=%u dec=%x (%d = %d.%.7d)\n",
+		   rtcu, rtcl, dec, pdec - dec, (pdec - dec) / 1000000000,
+		   ((pdec - dec) % 1000000000) / 100);
+	    pdec = dec;
+	    if (cmd == 'x')
+		break;
+	    while (xmon_read(stdin, &cmd, 1) != 1)
+		;
+	}
+	break;
+    case 'r':
+	init_adb_log();
+	while (adb_bitwait(8, 0, 0, 0) == 0)
+	    adb_readin();
+	break;
+    case 'w':
+	i = 0;
+	while (scanhex(&x))
+	    d[i++] = x;
+	init_adb_log();
+	j = adb_write(d, i);
+	printf("sent %d bytes\n", j);
+	while (adb_bitwait(8, 0, 0, 0) == 0)
+	    adb_readin();
+	break;
+    case 'l':
+	dump_adb_log();
+	break;
+    }
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)