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