adb.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
- /*
- * BK Id: SCCS/s.adb.c 1.5 05/17/01 18:14:23 cort
- */
- /*
- * 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.%.7dn", 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 timeoutn");
- return -1;
- }
- return 0;
- }
- void
- adb_readin(void)
- {
- int i, j;
- unsigned char d[64];
- if (ADB_B & 8) {
- printf("ADB_B: %xn", 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 bytesn", j);
- while (adb_bitwait(8, 0, 0, 0) == 0)
- adb_readin();
- break;
- case 'l':
- dump_adb_log();
- break;
- }
- }