Add support for 64 bit parameter to irscan
Change-Id: I89e0422456c59ee86c4b6d9bd3b3ad32051b31ac Signed-off-by: Evan Hunter <ehunter@broadcom.com> Reviewed-on: http://openocd.zylin.com/831 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
This commit is contained in:
parent
18e15390df
commit
7641fb6ac6
|
@ -58,6 +58,45 @@ static inline void buf_set_u32(void *_buffer,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets @c num bits in @c _buffer, starting at the @c first bit,
|
||||
* using the bits in @c value. This routine fast-paths writes
|
||||
* of little-endian, byte-aligned, 64-bit words.
|
||||
* @param _buffer The buffer whose bits will be set.
|
||||
* @param first The bit offset in @c _buffer to start writing (0-63).
|
||||
* @param num The number of bits from @c value to copy (1-64).
|
||||
* @param value Up to 64 bits that will be copied to _buffer.
|
||||
*/
|
||||
static inline void buf_set_u64(void *_buffer,
|
||||
unsigned first, unsigned num, uint64_t value)
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)_buffer;
|
||||
|
||||
if ((num == 32) && (first == 0)) {
|
||||
buffer[3] = (value >> 24) & 0xff;
|
||||
buffer[2] = (value >> 16) & 0xff;
|
||||
buffer[1] = (value >> 8) & 0xff;
|
||||
buffer[0] = (value >> 0) & 0xff;
|
||||
} else if ((num == 64) && (first == 0)) {
|
||||
buffer[7] = (value >> 56) & 0xff;
|
||||
buffer[6] = (value >> 48) & 0xff;
|
||||
buffer[5] = (value >> 40) & 0xff;
|
||||
buffer[4] = (value >> 32) & 0xff;
|
||||
buffer[3] = (value >> 24) & 0xff;
|
||||
buffer[2] = (value >> 16) & 0xff;
|
||||
buffer[1] = (value >> 8) & 0xff;
|
||||
buffer[0] = (value >> 0) & 0xff;
|
||||
} else {
|
||||
for (unsigned i = first; i < first + num; i++) {
|
||||
if (((value >> (i - first)) & 1) == 1)
|
||||
buffer[i / 8] |= 1 << (i % 8);
|
||||
else
|
||||
buffer[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves @c num bits from @c _buffer, starting at the @c first bit,
|
||||
* returning the bits in a 32-bit word. This routine fast-paths reads
|
||||
|
@ -87,6 +126,45 @@ static inline uint32_t buf_get_u32(const void *_buffer,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves @c num bits from @c _buffer, starting at the @c first bit,
|
||||
* returning the bits in a 64-bit word. This routine fast-paths reads
|
||||
* of little-endian, byte-aligned, 64-bit words.
|
||||
* @param _buffer The buffer whose bits will be read.
|
||||
* @param first The bit offset in @c _buffer to start reading (0-63).
|
||||
* @param num The number of bits from @c _buffer to read (1-64).
|
||||
* @returns Up to 64-bits that were read from @c _buffer.
|
||||
*/
|
||||
static inline uint64_t buf_get_u64(const void *_buffer,
|
||||
unsigned first, unsigned num)
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)_buffer;
|
||||
|
||||
if ((num == 32) && (first == 0)) {
|
||||
return 0 + ((((uint32_t)buffer[3]) << 24) | /* Note - zero plus is to avoid a checkpatch bug */
|
||||
(((uint32_t)buffer[2]) << 16) |
|
||||
(((uint32_t)buffer[1]) << 8) |
|
||||
(((uint32_t)buffer[0]) << 0));
|
||||
} else if ((num == 64) && (first == 0)) {
|
||||
return 0 + ((((uint64_t)buffer[7]) << 56) | /* Note - zero plus is to avoid a checkpatch bug */
|
||||
(((uint64_t)buffer[6]) << 48) |
|
||||
(((uint64_t)buffer[5]) << 40) |
|
||||
(((uint64_t)buffer[4]) << 32) |
|
||||
(((uint64_t)buffer[3]) << 24) |
|
||||
(((uint64_t)buffer[2]) << 16) |
|
||||
(((uint64_t)buffer[1]) << 8) |
|
||||
(((uint64_t)buffer[0]) << 0));
|
||||
} else {
|
||||
uint64_t result = 0;
|
||||
for (unsigned i = first; i < first + num; i++) {
|
||||
if (((buffer[i / 8] >> (i % 8)) & 1) == 1)
|
||||
result = result | ((uint64_t)1 << (uint64_t)(i - first));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverts the ordering of bits inside a 32-bit word (e.g. 31..0 -> 0..31).
|
||||
* This routine can be used to flip smaller data types by using smaller
|
||||
|
|
|
@ -1404,19 +1404,21 @@ DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX)
|
|||
return ERROR_OK; \
|
||||
}
|
||||
|
||||
#define DEFINE_PARSE_ULONG(name, type, min, max) \
|
||||
DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long, _ulong)
|
||||
DEFINE_PARSE_ULONG(_uint, unsigned, 0, UINT_MAX)
|
||||
DEFINE_PARSE_ULONG(_u32, uint32_t, 0, UINT32_MAX)
|
||||
DEFINE_PARSE_ULONG(_u16, uint16_t, 0, UINT16_MAX)
|
||||
DEFINE_PARSE_ULONG(_u8, uint8_t, 0, UINT8_MAX)
|
||||
#define DEFINE_PARSE_ULONGLONG(name, type, min, max) \
|
||||
DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong)
|
||||
DEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX)
|
||||
DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX)
|
||||
DEFINE_PARSE_ULONGLONG(_u32, uint32_t, 0, UINT32_MAX)
|
||||
DEFINE_PARSE_ULONGLONG(_u16, uint16_t, 0, UINT16_MAX)
|
||||
DEFINE_PARSE_ULONGLONG(_u8, uint8_t, 0, UINT8_MAX)
|
||||
|
||||
#define DEFINE_PARSE_LONG(name, type, min, max) \
|
||||
DEFINE_PARSE_WRAPPER(name, type, min, max, long, _long)
|
||||
DEFINE_PARSE_LONG(_int, int, n < INT_MIN, INT_MAX)
|
||||
DEFINE_PARSE_LONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)
|
||||
DEFINE_PARSE_LONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)
|
||||
DEFINE_PARSE_LONG(_s8, int8_t, n < INT8_MIN, INT8_MAX)
|
||||
#define DEFINE_PARSE_LONGLONG(name, type, min, max) \
|
||||
DEFINE_PARSE_WRAPPER(name, type, min, max, long long, _llong)
|
||||
DEFINE_PARSE_LONGLONG(_int, int, n < INT_MIN, INT_MAX)
|
||||
DEFINE_PARSE_LONGLONG(_s64, int64_t, n < INT64_MIN, INT64_MAX)
|
||||
DEFINE_PARSE_LONGLONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)
|
||||
DEFINE_PARSE_LONGLONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)
|
||||
DEFINE_PARSE_LONGLONG(_s8, int8_t, n < INT8_MIN, INT8_MAX)
|
||||
|
||||
static int command_parse_bool(const char *in, bool *out,
|
||||
const char *on, const char *off)
|
||||
|
|
|
@ -353,6 +353,7 @@ int parse_llong(const char *str, long long *ul);
|
|||
int parse ## name(const char *str, type * ul)
|
||||
|
||||
DECLARE_PARSE_WRAPPER(_uint, unsigned);
|
||||
DECLARE_PARSE_WRAPPER(_u64, uint64_t);
|
||||
DECLARE_PARSE_WRAPPER(_u32, uint32_t);
|
||||
DECLARE_PARSE_WRAPPER(_u16, uint16_t);
|
||||
DECLARE_PARSE_WRAPPER(_u8, uint8_t);
|
||||
|
|
|
@ -1141,12 +1141,12 @@ COMMAND_HANDLER(handle_irscan_command)
|
|||
fields[i].num_bits = field_size;
|
||||
fields[i].out_value = malloc(DIV_ROUND_UP(field_size, 8));
|
||||
|
||||
uint32_t value;
|
||||
retval = parse_u32(CMD_ARGV[i * 2 + 1], &value);
|
||||
uint64_t value;
|
||||
retval = parse_u64(CMD_ARGV[i * 2 + 1], &value);
|
||||
if (ERROR_OK != retval)
|
||||
goto error_return;
|
||||
void *v = (void *)fields[i].out_value;
|
||||
buf_set_u32(v, 0, field_size, value);
|
||||
buf_set_u64(v, 0, field_size, value);
|
||||
fields[i].in_value = NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue