From 86517c531147aee1c41443c5af479d4e7f261d4a Mon Sep 17 00:00:00 2001 From: Herbert Poetzl Date: Thu, 11 Apr 2024 11:36:07 +0200 Subject: [PATCH] update memtool to the newest version from http://vserver.13thfloor.at/Stuff/memtool.c --- software/memtool/memtool.c | 387 ++++++++++++++++++++++++++----------- 1 file changed, 273 insertions(+), 114 deletions(-) diff --git a/software/memtool/memtool.c b/software/memtool/memtool.c index 98053aa..f8b3a2f 100644 --- a/software/memtool/memtool.c +++ b/software/memtool/memtool.c @@ -3,12 +3,16 @@ ** ** memtool.c ** -** SPDX-FileCopyrightText: © 2020 Herbert Poetzl +** SPDX-FileCopyrightText: © 2020-2023 Herbert Poetzl ** SPDX-License-Identifier: GPL-2.0-only ** ** Memory Tool ** ** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License version 2 as +** published by the Free Software Foundation. +** ***********************************************************************/ @@ -30,6 +34,7 @@ static char *cmd_name = NULL; static uint64_t num_fill = 0L; +static uint64_t num_mask = ~0L; static uint64_t num_wdat = 0L; static uint16_t num_cols = 0; @@ -70,10 +75,10 @@ static uint32_t mem_size = 0L; static uint32_t page_size = 0L; -typedef long long int (stoll_t)(const char *, char **, int); +typedef long long unsigned int (stoull_t)(const char *, char **, int); -long long int argtoll( - const char *str, const char **end, stoll_t stoll) +long long unsigned int argtoull( + const char *str, const char **end, stoull_t stoull) { int bit, inv = 0; long long int val = 0; @@ -81,8 +86,8 @@ long long int argtoll( if (!str) return -1; - if (!stoll) - stoll = strtoll; + if (!stoull) + stoull = strtoull; switch (*str) { case '~': @@ -100,10 +105,10 @@ long long int argtoll( val ^= (1LL << bit); break; case '&': - val &= stoll(str+1, &eptr, 0); + val &= stoull(str+1, &eptr, 0); break; case '|': - val |= stoll(str+1, &eptr, 0); + val |= stoull(str+1, &eptr, 0); break; case '-': case '+': @@ -112,7 +117,7 @@ long long int argtoll( case '/': break; default: - val = stoll(str, &eptr, 0); + val = stoull(str, &eptr, 0); break; } if (eptr == str) @@ -186,133 +191,237 @@ uint64_t lfsr_64(uint64_t val) } -static void fill_u8(uint8_t *ptr, uint32_t cnt, uint8_t val) +static void fill_u8(uint8_t *ptr, uint32_t cnt, uint8_t val, uint8_t mask) { - while (cnt--) - *ptr++ = val; + if (mask == ~0L) + while (cnt--) + *ptr++ = val; + else if (mask) + while (cnt--) + { *ptr = (*ptr & ~mask) | (val & mask); ptr++; }; } -static void fill_u16(uint16_t *ptr, uint32_t cnt, uint16_t val) +static void fill_u16(uint16_t *ptr, uint32_t cnt, uint16_t val, uint16_t mask) { - while (cnt--) - *ptr++ = val; + if (mask == ~0L) + while (cnt--) + *ptr++ = val; + else if (mask) + while (cnt--) + { *ptr = (*ptr & ~mask) | (val & mask); ptr++; }; } -static void fill_u32(uint32_t *ptr, uint32_t cnt, uint32_t val) +static void fill_u32(uint32_t *ptr, uint32_t cnt, uint32_t val, uint32_t mask) { - while (cnt--) - *ptr++ = val; + if (mask == ~0L) + while (cnt--) + *ptr++ = val; + else if (mask) + while (cnt--) + { *ptr = (*ptr & ~mask) | (val & mask); ptr++; }; } -static void fill_u64(uint64_t *ptr, uint32_t cnt, uint64_t val) +static void fill_u64(uint64_t *ptr, uint32_t cnt, uint64_t val, uint64_t mask) { - while (cnt--) - *ptr++ = val; + if (mask == ~0L) + while (cnt--) + *ptr++ = val; + else if (mask) + while (cnt--) + { *ptr = (*ptr & ~mask) | (val & mask); ptr++; }; } -static void lfsr_u8(uint8_t *ptr, uint32_t cnt, uint8_t val) +static void lfsr_u8(uint8_t *ptr, uint32_t cnt, uint8_t val, uint8_t mask) { - while (cnt--) { - *ptr++ = val; - val = lfsr_8(val); + if (mask == ~0L) { + while (cnt--) { + *ptr++ = val; + val = lfsr_8(val); + } + } else if (mask) { + while (cnt--) { + *ptr = (*ptr & ~mask) | (val & mask); + val = lfsr_8(val); + ptr++; + } } } -static void lfsr_u16(uint16_t *ptr, uint32_t cnt, uint16_t val) +static void lfsr_u16(uint16_t *ptr, uint32_t cnt, uint16_t val, uint16_t mask) { - while (cnt--) { - *ptr++ = val; - val = lfsr_16(val); + if (mask == ~0L) { + while (cnt--) { + *ptr++ = val; + val = lfsr_16(val); + } + } else if (mask) { + while (cnt--) { + *ptr = (*ptr & ~mask) | (val & mask); + val = lfsr_16(val); + ptr++; + } } } -static void lfsr_u32(uint32_t *ptr, uint32_t cnt, uint32_t val) +static void lfsr_u32(uint32_t *ptr, uint32_t cnt, uint32_t val, uint32_t mask) { - while (cnt--) { - *ptr++ = val; - val = lfsr_32(val); + if (mask == ~0L) { + while (cnt--) { + *ptr++ = val; + val = lfsr_32(val); + } + } else if (mask) { + while (cnt--) { + *ptr = (*ptr & ~mask) | (val & mask); + val = lfsr_32(val); + ptr++; + } } } -static void lfsr_u64(uint64_t *ptr, uint32_t cnt, uint64_t val) +static void lfsr_u64(uint64_t *ptr, uint32_t cnt, uint64_t val, uint64_t mask) { - while (cnt--) { - *ptr++ = val; - val = lfsr_64(val); + if (mask == ~0L) { + while (cnt--) { + *ptr++ = val; + val = lfsr_64(val); + } + } else if (mask) { + while (cnt--) { + *ptr = (*ptr & ~mask) | (val & mask); + val = lfsr_64(val); + ptr++; + } } } -static uint32_t check_u8(uint8_t *ptr, uint32_t cnt, uint8_t val) +static uint32_t check_u8(uint8_t *ptr, uint32_t cnt, uint8_t val, uint8_t mask) { - while (cnt--) - if (*ptr++ != val) - break; + if (mask == ~0L) { + while (cnt--) + if (*ptr++ != val) + break; + } else { + while (cnt--) + if ((*ptr++ & mask) != (val & mask)) + break; + } return cnt + 1; } -static uint32_t check_u16(uint16_t *ptr, uint32_t cnt, uint16_t val) +static uint32_t check_u16(uint16_t *ptr, uint32_t cnt, uint16_t val, uint16_t mask) { - while (cnt--) - if (*ptr++ != val) - break; + if (mask == ~0L) { + while (cnt--) + if (*ptr++ != val) + break; + } else { + while (cnt--) + if ((*ptr++ & mask) != (val & mask)) + break; + } return cnt + 1; } -static uint32_t check_u32(uint32_t *ptr, uint32_t cnt, uint32_t val) +static uint32_t check_u32(uint32_t *ptr, uint32_t cnt, uint32_t val, uint32_t mask) { - while (cnt--) - if (*ptr++ != val) - break; + if (mask == ~0L) { + while (cnt--) + if (*ptr++ != val) + break; + } else { + while (cnt--) + if ((*ptr++ & mask) != (val & mask)) + break; + } return cnt + 1; } -static uint32_t check_u64(uint64_t *ptr, uint32_t cnt, uint64_t val) +static uint32_t check_u64(uint64_t *ptr, uint32_t cnt, uint64_t val, uint64_t mask) { - while (cnt--) - if (*ptr++ != val) - break; + if (mask == ~0L) { + while (cnt--) + if (*ptr++ != val) + break; + } else { + while (cnt--) + if ((*ptr++ & mask) != (val & mask)) + break; + } return cnt + 1; } -static uint32_t clfsr_u8(uint8_t *ptr, uint32_t cnt, uint8_t val) +static uint32_t clfsr_u8(uint8_t *ptr, uint32_t cnt, uint8_t val, uint8_t mask) { - while (cnt--) { - if (*ptr++ != val) - break; - val = lfsr_8(val); + if (mask == ~0L) { + while (cnt--) { + if (*ptr++ != val) + break; + val = lfsr_8(val); + } + } else { + while (cnt--) { + if ((*ptr++ & mask) != (val & mask)) + break; + val = lfsr_8(val); + } } return cnt + 1; } -static uint32_t clfsr_u16(uint16_t *ptr, uint32_t cnt, uint16_t val) +static uint32_t clfsr_u16(uint16_t *ptr, uint32_t cnt, uint16_t val, uint16_t mask) { - while (cnt--) { - if (*ptr++ != val) - break; - val = lfsr_16(val); + if (mask == ~0L) { + while (cnt--) { + if (*ptr++ != val) + break; + val = lfsr_16(val); + } + } else { + while (cnt--) { + if ((*ptr++ & mask) != (val & mask)) + break; + val = lfsr_16(val); + } } return cnt + 1; } -static uint32_t clfsr_u32(uint32_t *ptr, uint32_t cnt, uint32_t val) +static uint32_t clfsr_u32(uint32_t *ptr, uint32_t cnt, uint32_t val, uint32_t mask) { - while (cnt--) { - if (*ptr++ != val) - break; - val = lfsr_32(val); + if (mask == ~0L) { + while (cnt--) { + if (*ptr++ != val) + break; + val = lfsr_32(val); + } + } else { + while (cnt--) { + if ((*ptr++ & mask) != (val & mask)) + break; + val = lfsr_32(val); + } } return cnt + 1; } -static uint32_t clfsr_u64(uint64_t *ptr, uint32_t cnt, uint64_t val) +static uint32_t clfsr_u64(uint64_t *ptr, uint32_t cnt, uint64_t val, uint64_t mask) { - while (cnt--) { - if (*ptr++ != val) - break; - val = lfsr_64(val); + if (mask == ~0L) { + while (cnt--) { + if (*ptr++ != val) + break; + val = lfsr_64(val); + } + } else { + while (cnt--) { + if ((*ptr++ & mask) != (val & mask)) + break; + val = lfsr_64(val); + } } return cnt + 1; } @@ -329,8 +438,8 @@ static void action(const char *name) } -#define VERSION "V0.4" -#define OPTIONS "h1248dlnqrvwC:F:N:RW:" +#define VERSION "V0.5" +#define OPTIONS "h1248dlnqrvwC:F:M:N:RW:" int main(int argc, char *argv[]) { @@ -359,6 +468,7 @@ int main(int argc, char *argv[]) "\t-w write data to memory\n" "\t-C check memory\n" "\t-F fill memory\n" + "\t-M mask for fill\n" "\t-N number of columns\n" "\t-R read memory location\n" "\t-W write memory location\n" @@ -402,22 +512,25 @@ int main(int argc, char *argv[]) case 'C': opt_check = true; - num_fill = argtoll(optarg, NULL, NULL); + num_fill = argtoull(optarg, NULL, NULL); break; case 'F': opt_fill = true; - num_fill = argtoll(optarg, NULL, NULL); + num_fill = argtoull(optarg, NULL, NULL); + break; + case 'M': + num_mask = argtoull(optarg, NULL, NULL); break; case 'N': opt_cols = true; - num_cols = argtoll(optarg, NULL, NULL); + num_cols = argtoull(optarg, NULL, NULL); break; case 'R': opt_rreg = true; break; case 'W': opt_wreg = true; - num_wdat = argtoll(optarg, NULL, NULL); + num_wdat = argtoull(optarg, NULL, NULL); break; default: @@ -427,13 +540,13 @@ int main(int argc, char *argv[]) } if (argc > optind) { - mem_addr = argtoll(argv[optind++], NULL, NULL); + mem_addr = argtoull(argv[optind++], NULL, NULL); } else { err_flag++; } if (argc > optind) { - mem_size = argtoll(argv[optind++], NULL, NULL); + mem_size = argtoull(argv[optind++], NULL, NULL); } if (err_flag) { @@ -516,30 +629,30 @@ int main(int argc, char *argv[]) switch (opt_ds) { case DS_8: if (opt_lfsr) - lfsr_u8(mem_ptr, mem_size, num_fill & 0xFF); + lfsr_u8(mem_ptr, mem_size, num_fill, num_mask); else - fill_u8(mem_ptr, mem_size, num_fill & 0xFF); + fill_u8(mem_ptr, mem_size, num_fill, num_mask); break; case DS_16: if (opt_lfsr) - lfsr_u16(mem_ptr, mem_size/2, num_fill & 0xFFFF); + lfsr_u16(mem_ptr, mem_size/2, num_fill, num_mask); else - fill_u16(mem_ptr, mem_size/2, num_fill & 0xFFFF); + fill_u16(mem_ptr, mem_size/2, num_fill, num_mask); break; case DS_32: if (opt_lfsr) - lfsr_u32(mem_ptr, mem_size/4, num_fill & 0xFFFFFFFF); + lfsr_u32(mem_ptr, mem_size/4, num_fill, num_mask); else - fill_u32(mem_ptr, mem_size/4, num_fill & 0xFFFFFFFF); + fill_u32(mem_ptr, mem_size/4, num_fill, num_mask); break; case DS_64: if (opt_lfsr) - lfsr_u64(mem_ptr, mem_size/8, num_fill); + lfsr_u64(mem_ptr, mem_size/8, num_fill, num_mask); else - fill_u64(mem_ptr, mem_size/8, num_fill); + fill_u64(mem_ptr, mem_size/8, num_fill, num_mask); break; default: @@ -548,21 +661,47 @@ int main(int argc, char *argv[]) } else if (opt_write) { ssize_t cnt = mem_size; - void *ptr = mem_ptr; + void *dst = mem_ptr; + ssize_t sze = opt_ds ? opt_ds >> 3 : cnt; + uint64_t buf; action("writing"); while (cnt > 0) { - ssize_t len = read(0, ptr, cnt); + void *ptr = opt_ds ? &buf : dst; + + ssize_t len = read(0, ptr, sze); - if (len == -1) { + if ((len == -1) || (len < sze)) { fprintf(stderr, "error reading from stdin.\n%s\n", strerror(errno)); exit(4); } - cnt -= len; - ptr += len; + + switch (opt_ds) { + case DS_8: + *(uint8_t *)dst = *(uint8_t *)ptr; + break; + + case DS_16: + *(uint16_t *)dst = *(uint16_t *)ptr; + break; + + case DS_32: + *(uint32_t *)dst = *(uint32_t *)ptr; + break; + + case DS_64: + *(uint64_t *)dst = *(uint64_t *)ptr; + break; + + default: + break; + } + + dst += sze; + cnt -= sze; } } @@ -574,38 +713,30 @@ int main(int argc, char *argv[]) switch (opt_ds) { case DS_8: if (opt_lfsr) - cnt = clfsr_u8(mem_ptr, mem_size, - num_fill & 0xFF); + cnt = clfsr_u8(mem_ptr, mem_size, num_fill, num_mask); else - cnt = check_u8(mem_ptr, mem_size, - num_fill & 0xFF); + cnt = check_u8(mem_ptr, mem_size, num_fill, num_mask); break; case DS_16: if (opt_lfsr) - cnt = clfsr_u16(mem_ptr, mem_size/2, - num_fill & 0xFFFF); + cnt = clfsr_u16(mem_ptr, mem_size/2, num_fill, num_mask); else - cnt = check_u16(mem_ptr, mem_size/2, - num_fill & 0xFFFF); + cnt = check_u16(mem_ptr, mem_size/2, num_fill, num_mask); break; case DS_32: if (opt_lfsr) - cnt = clfsr_u32(mem_ptr, mem_size/4, - num_fill & 0xFFFFFFFF); + cnt = clfsr_u32(mem_ptr, mem_size/4, num_fill, num_mask); else - cnt = check_u32(mem_ptr, mem_size/4, - num_fill & 0xFFFFFFFF); + cnt = check_u32(mem_ptr, mem_size/4, num_fill, num_mask); break; case DS_64: if (opt_lfsr) - cnt = clfsr_u64(mem_ptr, mem_size/8, - num_fill); + cnt = clfsr_u64(mem_ptr, mem_size/8, num_fill, num_mask); else - cnt = check_u64(mem_ptr, mem_size/8, - num_fill); + cnt = check_u64(mem_ptr, mem_size/8, num_fill, num_mask); break; default: @@ -671,20 +802,48 @@ int main(int argc, char *argv[]) } else if (opt_read) { ssize_t cnt = mem_size; - void *ptr = mem_ptr; + void *src = mem_ptr; + ssize_t sze = opt_ds ? opt_ds >> 3 : cnt; + uint64_t buf; action("reading"); while (cnt > 0) { - ssize_t len = write(1, ptr, cnt); + void *ptr = opt_ds ? &buf : src; + ssize_t len = 0; + + switch (opt_ds) { + case DS_8: + *(uint8_t *)ptr = *(uint8_t *)src; + break; + + case DS_16: + *(uint16_t *)ptr = *(uint16_t *)src; + break; + + case DS_32: + *(uint32_t *)ptr = *(uint32_t *)src; + break; + + case DS_64: + *(uint64_t *)ptr = *(uint64_t *)src; + break; + + default: + break; + } + + len = write(1, ptr, sze); + + src += sze; + cnt -= sze; - if (len == -1) { + if ((len == -1) || (len < sze)) { fprintf(stderr, "error writing to stdout.\n%s\n", strerror(errno)); exit(6); } - cnt -= len; } }