1/* 2 * BK Id: SCCS/s.adb.c 1.5 05/17/01 18:14:23 cort 3 */ 4/* 5 * Copyright (C) 1996 Paul Mackerras. 6 */ 7#include "nonstdio.h" 8#include "privinst.h" 9 10#define scanhex xmon_scanhex 11#define skipbl xmon_skipbl 12 13#define ADB_B (*(volatile unsigned char *)0xf3016000) 14#define ADB_SR (*(volatile unsigned char *)0xf3017400) 15#define ADB_ACR (*(volatile unsigned char *)0xf3017600) 16#define ADB_IFR (*(volatile unsigned char *)0xf3017a00) 17 18static inline void eieio(void) { asm volatile ("eieio" : :); } 19 20#define N_ADB_LOG 1000 21struct adb_log { 22 unsigned char b; 23 unsigned char ifr; 24 unsigned char acr; 25 unsigned int time; 26} adb_log[N_ADB_LOG]; 27int n_adb_log; 28 29void 30init_adb_log(void) 31{ 32 adb_log[0].b = ADB_B; 33 adb_log[0].ifr = ADB_IFR; 34 adb_log[0].acr = ADB_ACR; 35 adb_log[0].time = get_dec(); 36 n_adb_log = 0; 37} 38 39void 40dump_adb_log(void) 41{ 42 unsigned t, t0; 43 struct adb_log *ap; 44 int i; 45 46 ap = adb_log; 47 t0 = ap->time; 48 for (i = 0; i <= n_adb_log; ++i, ++ap) { 49 t = t0 - ap->time; 50 printf("b=%x ifr=%x acr=%x at %d.%.7d\n", ap->b, ap->ifr, ap->acr, 51 t / 1000000000, (t % 1000000000) / 100); 52 } 53} 54 55void 56adb_chklog(void) 57{ 58 struct adb_log *ap = &adb_log[n_adb_log + 1]; 59 60 ap->b = ADB_B; 61 ap->ifr = ADB_IFR; 62 ap->acr = ADB_ACR; 63 if (ap->b != ap[-1].b || (ap->ifr & 4) != (ap[-1].ifr & 4) 64 || ap->acr != ap[-1].acr) { 65 ap->time = get_dec(); 66 ++n_adb_log; 67 } 68} 69 70int 71adb_bitwait(int bmask, int bval, int fmask, int fval) 72{ 73 int i; 74 struct adb_log *ap; 75 76 for (i = 10000; i > 0; --i) { 77 adb_chklog(); 78 ap = &adb_log[n_adb_log]; 79 if ((ap->b & bmask) == bval && (ap->ifr & fmask) == fval) 80 return 0; 81 } 82 return -1; 83} 84 85int 86adb_wait(void) 87{ 88 if (adb_bitwait(0, 0, 4, 4) < 0) { 89 printf("adb: ready wait timeout\n"); 90 return -1; 91 } 92 return 0; 93} 94 95void 96adb_readin(void) 97{ 98 int i, j; 99 unsigned char d[64]; 100 101 if (ADB_B & 8) { 102 printf("ADB_B: %x\n", ADB_B); 103 return; 104 } 105 i = 0; 106 adb_wait(); 107 j = ADB_SR; 108 eieio(); 109 ADB_B &= ~0x20; 110 eieio(); 111 for (;;) { 112 if (adb_wait() < 0) 113 break; 114 d[i++] = ADB_SR; 115 eieio(); 116 if (ADB_B & 8) 117 break; 118 ADB_B ^= 0x10; 119 eieio(); 120 } 121 ADB_B |= 0x30; 122 if (adb_wait() == 0) 123 j = ADB_SR; 124 for (j = 0; j < i; ++j) 125 printf("%.2x ", d[j]); 126 printf("\n"); 127} 128 129int 130adb_write(unsigned char *d, int i) 131{ 132 int j; 133 unsigned x; 134 135 if ((ADB_B & 8) == 0) { 136 printf("r: "); 137 adb_readin(); 138 } 139 for (;;) { 140 ADB_ACR = 0x1c; 141 eieio(); 142 ADB_SR = d[0]; 143 eieio(); 144 ADB_B &= ~0x20; 145 eieio(); 146 if (ADB_B & 8) 147 break; 148 ADB_ACR = 0xc; 149 eieio(); 150 ADB_B |= 0x20; 151 eieio(); 152 adb_readin(); 153 } 154 adb_wait(); 155 for (j = 1; j < i; ++j) { 156 ADB_SR = d[j]; 157 eieio(); 158 ADB_B ^= 0x10; 159 eieio(); 160 if (adb_wait() < 0) 161 break; 162 } 163 ADB_ACR = 0xc; 164 eieio(); 165 x = ADB_SR; 166 eieio(); 167 ADB_B |= 0x30; 168 return j; 169} 170 171void 172adbcmds(void) 173{ 174 char cmd; 175 unsigned rtcu, rtcl, dec, pdec, x; 176 int i, j; 177 unsigned char d[64]; 178 179 cmd = skipbl(); 180 switch (cmd) { 181 case 't': 182 for (;;) { 183 rtcl = get_rtcl(); 184 rtcu = get_rtcu(); 185 dec = get_dec(); 186 printf("rtc u=%u l=%u dec=%x (%d = %d.%.7d)\n", 187 rtcu, rtcl, dec, pdec - dec, (pdec - dec) / 1000000000, 188 ((pdec - dec) % 1000000000) / 100); 189 pdec = dec; 190 if (cmd == 'x') 191 break; 192 while (xmon_read(stdin, &cmd, 1) != 1) 193 ; 194 } 195 break; 196 case 'r': 197 init_adb_log(); 198 while (adb_bitwait(8, 0, 0, 0) == 0) 199 adb_readin(); 200 break; 201 case 'w': 202 i = 0; 203 while (scanhex(&x)) 204 d[i++] = x; 205 init_adb_log(); 206 j = adb_write(d, i); 207 printf("sent %d bytes\n", j); 208 while (adb_bitwait(8, 0, 0, 0) == 0) 209 adb_readin(); 210 break; 211 case 'l': 212 dump_adb_log(); 213 break; 214 } 215} 216