- added a PLD (programmable logic device) subsystem for FPGA, CPLD etc. configuration
[openocd.git] / src / helper / binarybuffer.c
1 /***************************************************************************
2 * Copyright (C) 2004, 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "types.h"
28 #include "log.h"
29
30 #include "binarybuffer.h"
31
32 int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value);
33 u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num);
34 u32 flip_u32(u32 value, unsigned int num);
35
36 const unsigned char bit_reverse_table256[] =
37 {
38 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
39 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
40 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
41 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
42 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
43 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
44 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
45 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
46 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
47 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
48 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
49 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
50 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
51 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
52 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
53 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
54 };
55
56 int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value)
57 {
58 unsigned int i;
59
60 if (!buffer)
61 return ERROR_INVALID_ARGUMENTS;
62
63 for (i=first; i<first+num; i++)
64 {
65 if (((value >> (i-first))&1) == 1)
66 buffer[i/8] |= 1 << (i%8);
67 else
68 buffer[i/8] &= ~(1 << (i%8));
69 }
70
71 return ERROR_OK;
72 }
73
74 u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num)
75 {
76 u32 result = 0;
77 unsigned int i;
78
79 if (!buffer)
80 {
81 ERROR("buffer not initialized");
82 return 0;
83 }
84
85 for (i=first; i<first+num; i++)
86 {
87 if (((buffer[i/8]>>(i%8))&1) == 1)
88 result |= 1 << (i-first);
89 }
90
91 return result;
92 }
93
94 u8* buf_cpy(u8 *from, u8 *to, int size)
95 {
96 int num_bytes = CEIL(size, 8);
97 unsigned int i;
98
99 if (from == NULL)
100 return NULL;
101
102 for (i = 0; i < num_bytes; i++)
103 to[i] = from[i];
104
105 return to;
106 }
107
108 int buf_cmp(u8 *buf1, u8 *buf2, int size)
109 {
110 int num_bytes = CEIL(size, 8);
111 int i;
112
113 if (!buf1 || !buf2)
114 return 1;
115
116 for (i = 0; i < num_bytes; i++)
117 {
118 /* last byte */
119 /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
120 if ((size % 8) && (i == num_bytes -1 ))
121 {
122 if ((buf1[i] & ((1 << (size % 8)) - 1)) != (buf2[i] & ((1 << (size % 8)) - 1)))
123 return 1;
124 }
125 else
126 {
127 if (buf1[i] != buf2[i])
128 return 1;
129 }
130 }
131
132 return 0;
133 }
134
135 int buf_cmp_mask(u8 *buf1, u8 *buf2, u8 *mask, int size)
136 {
137 int num_bytes = CEIL(size, 8);
138 int i;
139
140 for (i = 0; i < num_bytes; i++)
141 {
142 /* last byte */
143 /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
144 if ((size % 8) && (i == num_bytes -1 ))
145 {
146 if ((buf1[i] & ((1 << (size % 8)) - 1) & mask[i]) !=
147 (buf2[i] & ((1 << (size % 8)) - 1) & mask[i]))
148 return 1;
149 }
150 else
151 {
152 if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
153 return 1;
154 }
155 }
156
157 return 0;
158 }
159
160 u8* buf_set_ones(u8 *buf, int count)
161 {
162 int num_bytes = CEIL(count, 8);
163 int i;
164
165 for (i = 0; i < num_bytes; i++)
166 {
167 if (count >= 8)
168 buf[i] = 0xff;
169 else
170 buf[i] = (1 << count) - 1;
171
172 count -= 8;
173 }
174
175 return buf;
176 }
177
178 u8* buf_set_buf(u8 *src, int src_start, u8 *dst, int dst_start, int len)
179 {
180 int src_idx = src_start, dst_idx = dst_start;
181 int i;
182
183 for (i = 0; i < len; i++)
184 {
185 if (((src[src_idx/8] >> (src_idx % 8)) & 1) == 1)
186 dst[dst_idx/8] |= 1 << (dst_idx%8);
187 else
188 dst[dst_idx/8] &= ~(1 << (dst_idx%8));
189 dst_idx++;
190 src_idx++;
191 }
192
193 return dst;
194 }
195
196 u32 flip_u32(u32 value, unsigned int num)
197 {
198 u32 c;
199
200 c = (bit_reverse_table256[value & 0xff] << 24) |
201 (bit_reverse_table256[(value >> 8) & 0xff] << 16) |
202 (bit_reverse_table256[(value >> 16) & 0xff] << 8) |
203 (bit_reverse_table256[(value >> 24) & 0xff]);
204
205 if (num < 32)
206 c = c >> (32 - num);
207
208 return c;
209 }
210
211 int ceil_f_to_u32(float x)
212 {
213 u32 y;
214
215 if (x < 0) /* return zero for negative numbers */
216 return 0;
217
218 y = x; /* cut off fraction */
219
220 if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
221 y++;
222
223 return y;
224 }
225
226 char* buf_to_str(u8 *buf, int buf_len, int radix)
227 {
228 const char *DIGITS = "0123456789abcdef";
229 float factor;
230 char *str;
231 int str_len;
232 int b256_len = CEIL(buf_len, 8);
233 u32 tmp;
234
235 int j; /* base-256 digits */
236 int i; /* output digits (radix) */
237
238 if (radix == 16)
239 {
240 factor = 2.0; /* log(256) / log(16) = 2.0 */
241 }
242 else if (radix == 10)
243 {
244 factor = 2.40824; /* log(256) / log(10) = 2.40824 */
245 }
246 else if (radix == 8)
247 {
248 factor = 2.66667; /* log(256) / log(8) = 2.66667 */
249 }
250 else
251 return NULL;
252
253 str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
254 str = calloc(str_len + 1, 1);
255
256 for (i = b256_len - 1; i >= 0; i--)
257 {
258 tmp = buf[i];
259 if ((i == (buf_len / 8)) && (buf_len % 8))
260 tmp &= (0xff >> (8 - (buf_len % 8)));
261
262 for (j = str_len; j > 0; j--)
263 {
264 tmp += (u32)str[j-1] * 256;
265 str[j-1] = (u8)(tmp % radix);
266 tmp /= radix;
267 }
268 }
269
270 for (j = 0; j < str_len; j++)
271 str[j] = DIGITS[(int)str[j]];
272
273 return str;
274 }
275
276 int str_to_buf(char* str, int str_len, u8 *buf, int buf_len, int radix)
277 {
278 char *charbuf;
279 u32 tmp;
280 float factor;
281 u8 *b256_buf;
282 int b256_len;
283
284 int j; /* base-256 digits */
285 int i; /* input digits (ASCII) */
286
287 if (radix == 0)
288 {
289 /* identify radix, and skip radix-prefix (0, 0x or 0X) */
290 if ((str[0] == '0') && (str[1] && ((str[1] == 'x') || (str[1] == 'X'))))
291 {
292 radix = 16;
293 str += 2;
294 str_len -= 2;
295 }
296 else if ((str[0] == '0') && (str_len != 1))
297 {
298 radix = 8;
299 str += 1;
300 str_len -= 1;
301 }
302 else
303 {
304 radix = 10;
305 }
306 }
307
308 if (radix == 16)
309 factor = 0.5; /* log(16) / log(256) = 0.5 */
310 else if (radix == 10)
311 factor = 0.41524; /* log(10) / log(256) = 0.41524 */
312 else if (radix == 8)
313 factor = 0.375; /* log(8) / log(256) = 0.375 */
314 else
315 return 0;
316
317 /* copy to zero-terminated buffer */
318 charbuf = malloc(str_len + 1);
319 memcpy(charbuf, str, str_len);
320 charbuf[str_len] = '\0';
321
322 /* number of digits in base-256 notation */
323 b256_len = ceil_f_to_u32(str_len * factor);
324 b256_buf = calloc(b256_len, 1);
325
326 /* go through zero terminated buffer */
327 for (i = 0; charbuf[i]; i++)
328 {
329 tmp = charbuf[i];
330 if ((tmp >= '0') && (tmp <= '9'))
331 tmp = (tmp - '0');
332 else if ((tmp >= 'a') && (tmp <= 'f'))
333 tmp = (tmp - 'a' + 10);
334 else if ((tmp >= 'A') && (tmp <= 'F'))
335 tmp = (tmp - 'A' + 10);
336 else continue; /* skip characters other than [0-9,a-f,A-F] */
337
338 if (tmp >= radix)
339 continue; /* skip digits invalid for the current radix */
340
341 for (j = 0; j < b256_len; j++)
342 {
343 tmp += (u32)b256_buf[j] * radix;
344 b256_buf[j] = (u8)(tmp & 0xFF);
345 tmp >>= 8;
346 }
347
348 }
349
350 for (j = 0; j < CEIL(buf_len, 8); j++)
351 buf[j] = b256_buf[j];
352
353 /* mask out bits that don't belong to the buffer */
354 if (buf_len % 8)
355 buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
356
357 free(b256_buf);
358 free(charbuf);
359
360 return i;
361 }
362
363 int buf_to_u32_handler(u8 *in_buf, void *priv)
364 {
365 u32 *dest = priv;
366
367 *dest = buf_get_u32(in_buf, 0, 32);
368
369 return ERROR_OK;
370 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)