You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

165 lines
6.1 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2004, 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2007,2008 √ėyvind Harboe *
  6. * oyvind.harboe@zylin.com *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. #ifndef BINARYBUFFER_H
  24. #define BINARYBUFFER_H
  25. #include "list.h"
  26. /** @file
  27. * Support functions to access arbitrary bits in a byte array
  28. */
  29. /**
  30. * Sets @c num bits in @c _buffer, starting at the @c first bit,
  31. * using the bits in @c value. This routine fast-paths writes
  32. * of little-endian, byte-aligned, 32-bit words.
  33. * @param _buffer The buffer whose bits will be set.
  34. * @param first The bit offset in @c _buffer to start writing (0-31).
  35. * @param num The number of bits from @c value to copy (1-32).
  36. * @param value Up to 32 bits that will be copied to _buffer.
  37. */
  38. static inline void buf_set_u32(void *_buffer,
  39. unsigned first, unsigned num, uint32_t value)
  40. {
  41. uint8_t *buffer = (uint8_t *)_buffer;
  42. if ((num == 32) && (first == 0)) {
  43. buffer[3] = (value >> 24) & 0xff;
  44. buffer[2] = (value >> 16) & 0xff;
  45. buffer[1] = (value >> 8) & 0xff;
  46. buffer[0] = (value >> 0) & 0xff;
  47. } else {
  48. for (unsigned i = first; i < first + num; i++) {
  49. if (((value >> (i - first)) & 1) == 1)
  50. buffer[i / 8] |= 1 << (i % 8);
  51. else
  52. buffer[i / 8] &= ~(1 << (i % 8));
  53. }
  54. }
  55. }
  56. /**
  57. * Retrieves @c num bits from @c _buffer, starting at the @c first bit,
  58. * returning the bits in a 32-bit word. This routine fast-paths reads
  59. * of little-endian, byte-aligned, 32-bit words.
  60. * @param _buffer The buffer whose bits will be read.
  61. * @param first The bit offset in @c _buffer to start reading (0-31).
  62. * @param num The number of bits from @c _buffer to read (1-32).
  63. * @returns Up to 32-bits that were read from @c _buffer.
  64. */
  65. static inline uint32_t buf_get_u32(const void *_buffer,
  66. unsigned first, unsigned num)
  67. {
  68. uint8_t *buffer = (uint8_t *)_buffer;
  69. if ((num == 32) && (first == 0)) {
  70. return (((uint32_t)buffer[3]) << 24) |
  71. (((uint32_t)buffer[2]) << 16) |
  72. (((uint32_t)buffer[1]) << 8) |
  73. (((uint32_t)buffer[0]) << 0);
  74. } else {
  75. uint32_t result = 0;
  76. for (unsigned i = first; i < first + num; i++) {
  77. if (((buffer[i / 8] >> (i % 8)) & 1) == 1)
  78. result |= 1 << (i - first);
  79. }
  80. return result;
  81. }
  82. }
  83. /**
  84. * Inverts the ordering of bits inside a 32-bit word (e.g. 31..0 -> 0..31).
  85. * This routine can be used to flip smaller data types by using smaller
  86. * values for @c width.
  87. * @param value The word to flip.
  88. * @param width The number of bits in value (2-32).
  89. * @returns A 32-bit word with @c value in reversed bit-order.
  90. */
  91. uint32_t flip_u32(uint32_t value, unsigned width);
  92. bool buf_cmp(const void *buf1, const void *buf2, unsigned size);
  93. bool buf_cmp_mask(const void *buf1, const void *buf2,
  94. const void *mask, unsigned size);
  95. /**
  96. * Copies @c size bits out of @c from and into @c to. Any extra
  97. * bits in the final byte will be set to zero.
  98. * @param from The buffer to copy into @c to.
  99. * @param to The buffer that will receive the copy of @c from.
  100. * @param size The number of bits to copy.
  101. */
  102. void *buf_cpy(const void *from, void *to, unsigned size);
  103. /**
  104. * Set the contents of @c buf with @c count bits, all set to 1.
  105. * @param buf The buffer to fill with ones.
  106. * @param size The number of bits.
  107. * @returns The original buffer (@c buf).
  108. */
  109. void *buf_set_ones(void *buf, unsigned size);
  110. void *buf_set_buf(const void *src, unsigned src_start,
  111. void *dst, unsigned dst_start, unsigned len);
  112. int str_to_buf(const char *str, unsigned len,
  113. void *bin_buf, unsigned buf_size, unsigned radix);
  114. char *buf_to_str(const void *buf, unsigned size, unsigned radix);
  115. /* read a uint32_t from a buffer in target memory endianness */
  116. static inline uint32_t fast_target_buffer_get_u32(const void *p, bool le)
  117. {
  118. return le ? le_to_h_u32(p) : be_to_h_u32(p);
  119. }
  120. static inline void bit_copy(uint8_t *dst, unsigned dst_offset, const uint8_t *src,
  121. unsigned src_offset, unsigned bit_count)
  122. {
  123. buf_set_buf(src, src_offset, dst, dst_offset, bit_count);
  124. }
  125. struct bit_copy_queue {
  126. struct list_head list;
  127. };
  128. struct bit_copy_queue_entry {
  129. uint8_t *dst;
  130. unsigned dst_offset;
  131. const uint8_t *src;
  132. unsigned src_offset;
  133. unsigned bit_count;
  134. struct list_head list;
  135. };
  136. void bit_copy_queue_init(struct bit_copy_queue *q);
  137. int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,
  138. unsigned src_offset, unsigned bit_count);
  139. void bit_copy_execute(struct bit_copy_queue *q);
  140. void bit_copy_discard(struct bit_copy_queue *q);
  141. /* functions to convert to/from hex encoded buffer
  142. * used in ti-icdi driver and gdb server */
  143. int unhexify(char *bin, const char *hex, int count);
  144. int hexify(char *hex, const char *bin, int count, int out_maxlen);
  145. #endif /* BINARYBUFFER_H */