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