File: /usr/src/linux/arch/ppc/xmon/adb.c
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
18 static inline void eieio(void) { asm volatile ("eieio" : :); }
19
20 #define N_ADB_LOG 1000
21 struct adb_log {
22 unsigned char b;
23 unsigned char ifr;
24 unsigned char acr;
25 unsigned int time;
26 } adb_log[N_ADB_LOG];
27 int n_adb_log;
28
29 void
30 init_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
39 void
40 dump_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
55 void
56 adb_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
70 int
71 adb_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
85 int
86 adb_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
95 void
96 adb_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
129 int
130 adb_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
171 void
172 adbcmds(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