xref: /plan9-contrib/sys/src/cmd/jtagfs/chain.c (revision dedb130315e7b691e306ee069395ee1f0b18e4d4)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "lebo.h"
5 #include "bebo.h"
6 #include "debug.h"
7 #include "chain.h"
8 
9 /* functions to deal with bit chains, weird bit orderings an such */
10 
11 #define Upper(byte, nbits)	((byte)>>(nbits))
12 #define Lower(byte, nbits)	((bytes)&MSK(nbits))
13 #define IsCut(bbits, ebits)		(((ebits)/8 - (bbits)/8) > 0)
14 
15 /* 8: H L | 8: Next */
16 /* Put at most 8 bits*/
17 static void
put8bits(Chain * ch,void * p,int nbits)18 put8bits(Chain *ch, void *p, int nbits)
19 {
20 	int e, nbye, nbie, nle;
21 	uchar low, high, byte;
22 
23 	byte = *(uchar *)p;
24 	e = ch->e+nbits-1;	/* offset of last bit to put in */
25 	nbie = ch->e%8;
26 	nbye = ch->e/8;
27 	nle = 8 - nbie;
28 
29 
30 	if(IsCut(ch->e, e))
31 		ch->buf[nbye + 1] = byte >> nle;
32 
33 	high = (byte & MSK(nle)) << nbie;
34 	low = ch->buf[nbye]&MSK(nbie);
35 
36 
37 	ch->buf[nbye] = low|high;
38 	ch->e += nbits;
39 }
40 
41 /* Get at most 8 bits*/
42 static uchar
get8bits(Chain * ch,int nbits)43 get8bits(Chain *ch, int nbits)
44 {
45 	int b, nbyb, nbib, nlb;
46 	uchar low, high, res;
47 
48 	b = ch->b+nbits-1;
49 	nbib = ch->b % 8;
50 	nbyb = ch->b / 8;
51 	nlb = 8 - nbib;
52 	if(nlb > nbits)
53 		nlb = nbits;
54 
55 	low = MSK(nlb) & (ch->buf[nbyb] >> nbib);
56 	if(IsCut(ch->b, b))
57 		high = (ch->buf[nbyb + 1] & MSK(nbib)) << nlb;
58 	else
59 		high = 0;
60 	res = MSK(nbits)&(high | low);
61 	ch->b += nbits;
62 	return res;
63 }
64 
65 /*
66  * Putbits and getbits could be made more efficient
67  * simply by using memmove in the special case where
68  * a bunch of bytes is aligned, but I don't care.
69  * Packing in words would also help the so inclined.
70  */
71 void
putbits(Chain * ch,void * p,int nbits)72 putbits(Chain *ch, void *p, int nbits)
73 {
74 	int nby, nbi, i;
75 	uchar *vp;
76 
77 	vp = p;
78 	nby = nbits / 8;
79 	nbi = nbits % 8;
80 
81 	for(i = 0; i < nby; i++)
82 		put8bits(ch, vp++, 8);
83 
84 	if(nbi != 0)
85 		put8bits(ch, vp, nbi);
86 }
87 
88 void
getbits(void * p,Chain * ch,int nbits)89 getbits(void *p, Chain *ch, int nbits)
90 {
91 	int nby, nbi, i;
92 	uchar *vp;
93 
94 	assert(ch->e >= ch->b);
95 	nby = nbits / 8;
96 	nbi = nbits % 8;
97 
98 	vp = p;
99 	for(i = 0; i < nby; i++)
100 		*vp++ = get8bits(ch, 8);
101 
102 	if(nbi != 0)
103 		*vp = get8bits(ch, nbi);
104 }
105 
106 static void
revbych(Chain * ch)107 revbych(Chain *ch)
108 {
109 	int i, nb;
110 
111 	nb = (ch->e-ch->b+7)/8;
112 
113 	for(i = 0; i < nb; i++)
114 		ch->buf[i] = rtab[ch->buf[i]];
115 }
116 
117 void
printchain(Chain * ch)118 printchain(Chain *ch)
119 {
120 	int i, ng, nb;
121 	uchar msk, c;
122 	Chain *ch2;
123 
124 	fprint(2, "chain buf:%#p b:%d e:%d\n", ch->buf, ch->b, ch->e);
125 	ch2 = malloc(sizeof(Chain));
126 	if(ch2 == nil)
127 		sysfatal("no memory");
128 	memmove(ch2, ch, sizeof(Chain));
129 
130 
131 	ng = 8;
132 	nb = (ch2->e-ch2->b+7)/8;
133 
134 	for(i = 0; i < nb; i++){
135 		if(ch2->e - ch2->b < ng)
136 			ng = ch2->e - ch2->b;
137 		getbits(&c, ch2, ng);
138 		if(i != 0 && i%15 == 0)
139 			fprint(2, "\n");
140 		if(ng < 8){
141 			msk = MSK(ng);
142 			fprint(2, "%#2.2x ", c&msk);
143 		}
144 		else
145 			fprint(2, "%#2.2x ", c);
146 
147 	}
148 	if(i%16 != 0)
149 		fprint(2, "\n");
150 
151 	free(ch2);
152 }
153 
154 /* Good for debugging */
155 static void
printchslice(Chain * ch,int b,int e)156 printchslice(Chain *ch, int b, int e)
157 {
158 	Chain *ch2;
159 
160 	fprint(2, "Slice [%d, %d], b:%d e:%d\n", b, e, ch->b, ch->e);
161 	ch2 = malloc(sizeof(Chain));
162 	if(ch2 == nil)
163 		sysfatal("memory");
164 	memmove(ch2, ch, sizeof(Chain));
165 	if(b > e){
166 		fprint(2, "bad args in region\n");
167 		return;
168 	}
169 	if(b < ch2->b || b > ch2->e || e > ch2-> e || e < ch2->b){
170 		fprint(2, "bad region\n");
171 		return;
172 	}
173 	ch2->b = b;
174 	ch2->e = e;
175 
176 	fprint(2, "Slice - ");
177 	printchain(ch2);
178 	free(ch2);
179 }
180 
181 
182 static u32int
revbytes(u32int * v)183 revbytes(u32int *v)
184 {
185 	u32int rv;
186 	uchar *a, *b;
187 
188 	a = (uchar *)v;
189 	b = (uchar *)&rv;
190 
191 	b[3] = rtab[a[3]];
192 	b[2] = rtab[a[2]];
193 	b[1] = rtab[a[1]];
194 	b[0] = rtab[a[0]];
195 
196 	return rv;
197 }
198 
199 u32int
hmsbputl(u32int * v)200 hmsbputl(u32int *v)
201 {
202 	u32int rv, bev;
203 
204 	hbeputl(&bev, *v);
205 	rv = revbytes(&bev);
206 
207 	return rv;
208 }
209 
210 u32int
msbhgetl(u32int * v)211 msbhgetl(u32int *v)
212 {
213 	u32int rv, rev;
214 
215 	rev = revbytes(v);
216 	rv = lehgetl(&rev);
217 	return rv;
218 }
219 
220