1751 lines
56 KiB
Diff
1751 lines
56 KiB
Diff
From bb9b6dd4e04e671c065090a1ccaebe67f7950cda Mon Sep 17 00:00:00 2001
|
|
From: YouMin Chen <cym@rock-chips.com>
|
|
Date: Sun, 22 Oct 2023 18:37:09 +0800
|
|
Subject: [PATCH] memtester: some changes for the Rockchip platform 20231020
|
|
|
|
base on:
|
|
memtester-4.5.1
|
|
merge from rockchip develop branch:
|
|
commit 2d622bb314fa2ed60a818c4bb6e920babe606d78
|
|
|
|
Signed-off-by: YouMin Chen <cym@rock-chips.com>
|
|
---
|
|
Makefile | 17 +-
|
|
cache.c | 28 +++
|
|
cache.h | 12 ++
|
|
io_map.c | 321 ++++++++++++++++++++++++++++++
|
|
io_map.h | 19 ++
|
|
memtester.c | 155 +++++++++++++--
|
|
sizes.h | 25 +--
|
|
tests.c | 548 +++++++++++++++++++++++++++++++++++++++-------------
|
|
tests.h | 37 ++--
|
|
types.h | 6 +-
|
|
va_2_pa.c | 76 ++++++++
|
|
va_2_pa.h | 15 ++
|
|
12 files changed, 1069 insertions(+), 190 deletions(-)
|
|
create mode 100644 cache.c
|
|
create mode 100644 cache.h
|
|
create mode 100644 io_map.c
|
|
create mode 100644 io_map.h
|
|
create mode 100644 va_2_pa.c
|
|
create mode 100644 va_2_pa.h
|
|
|
|
diff --git a/Makefile b/Makefile
|
|
index 123f7bc..272fd35 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -13,7 +13,7 @@
|
|
CC = $(shell head -n 1 conf-cc)
|
|
LD = $(shell head -n 1 conf-ld)
|
|
|
|
-SOURCES = memtester.c tests.c
|
|
+SOURCES = memtester.c tests.c io_map.c va_2_pa.c cache.c
|
|
OBJECTS = $(SOURCES:.c=.o)
|
|
HEADERS = memtester.h
|
|
TARGETS = *.o compile load auto-ccld.sh find-systype make-compile make-load systype extra-libs
|
|
@@ -75,11 +75,18 @@ clean:
|
|
rm -f memtester $(TARGETS) $(OBJECTS) core
|
|
|
|
memtester: \
|
|
-$(OBJECTS) memtester.c tests.h tests.c tests.h conf-cc Makefile load extra-libs
|
|
- ./load memtester tests.o `cat extra-libs`
|
|
+$(OBJECTS) memtester.c tests.h tests.c tests.h io_map.c io_map.h va_2_pa.c va_2_pa.h cache.c cache.h conf-cc Makefile load extra-libs
|
|
+ ./load memtester tests.o io_map.o va_2_pa.o cache.o `cat extra-libs`
|
|
|
|
-memtester.o: memtester.c tests.h conf-cc Makefile compile
|
|
+memtester.o: memtester.c tests.h io_map.h va_2_pa.h cache.h conf-cc Makefile compile
|
|
./compile memtester.c
|
|
|
|
-tests.o: tests.c tests.h conf-cc Makefile compile
|
|
+tests.o: tests.c tests.h io_map.h va_2_pa.h cache.h conf-cc Makefile compile
|
|
./compile tests.c
|
|
+io_map.o: io_map.c io_map.h conf-cc Makefile compile
|
|
+ ./compile io_map.c
|
|
+va_2_pa.o: va_2_pa.c va_2_pa.h conf-cc Makefile compile
|
|
+ ./compile va_2_pa.c
|
|
+
|
|
+cache.o: cache.c cache.h conf-cc Makefile compile
|
|
+ ./compile cache.c
|
|
diff --git a/cache.c b/cache.c
|
|
new file mode 100644
|
|
index 0000000..66230a3
|
|
--- /dev/null
|
|
+++ b/cache.c
|
|
@@ -0,0 +1,28 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
|
|
+ */
|
|
+
|
|
+#include <stdio.h>
|
|
+#include "types.h"
|
|
+#include "cache.h"
|
|
+#include <sys/syscall.h>
|
|
+
|
|
+void dcacheflush(ul start, ul end)
|
|
+{
|
|
+#if defined (__aarch64__)
|
|
+ ul cache_line;
|
|
+
|
|
+ __asm("mrs %0, ctr_el0":"+r" (cache_line):);
|
|
+ cache_line = 4 << ((cache_line >> 16) & 0xf);
|
|
+ printf("cache line:%u\n", cache_line);
|
|
+ start &= ~(cache_line - 1);
|
|
+
|
|
+ for (; start < end; start += cache_line) {
|
|
+ __asm("dc civac, %0":"+r" (start):);
|
|
+ }
|
|
+#else
|
|
+ printf("flush cache\n");
|
|
+ syscall(__ARM_NR_cacheflush, start, end, 0);
|
|
+#endif
|
|
+}
|
|
diff --git a/cache.h b/cache.h
|
|
new file mode 100644
|
|
index 0000000..5532bc0
|
|
--- /dev/null
|
|
+++ b/cache.h
|
|
@@ -0,0 +1,12 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
|
+ *
|
|
+ * SPDX-License-Identifier: GPL-2.0+
|
|
+ */
|
|
+
|
|
+#ifndef _CMD_MEMTESTER_CACHE_H
|
|
+#define _CMD_MEMTESTER_CACHE_H
|
|
+
|
|
+void dcacheflush(ul start, ul end);
|
|
+
|
|
+#endif /* _CMD_MEMTESTER_CACHE_H */
|
|
diff --git a/io_map.c b/io_map.c
|
|
new file mode 100644
|
|
index 0000000..836ea74
|
|
--- /dev/null
|
|
+++ b/io_map.c
|
|
@@ -0,0 +1,321 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
|
|
+ */
|
|
+
|
|
+#include <string.h>
|
|
+#include <strings.h>
|
|
+#include <stdio.h>
|
|
+#include <stdint.h>
|
|
+#include <fcntl.h>
|
|
+#include <unistd.h>
|
|
+#include <sys/mman.h>
|
|
+
|
|
+#include "types.h"
|
|
+#include "io_map.h"
|
|
+
|
|
+#define IO_TYPE_1_1_16 0
|
|
+#define IO_TYPE_1_1_32 1
|
|
+#define IO_TYPE_1_2 2
|
|
+#define IO_TYPE_2 3
|
|
+
|
|
+#define SYS_REG_DEC_BW(n, ch) (2 >> (((n) >> (2 + 16 * (ch))) & 0x3))
|
|
+
|
|
+static u32 io_type;
|
|
+
|
|
+u32 io_bw;
|
|
+
|
|
+struct chip_info {
|
|
+ char chip_name[10];
|
|
+ uint32_t osreg_addr;
|
|
+};
|
|
+
|
|
+struct chip_info chip_info[] = {
|
|
+ { .chip_name = "rv1106",
|
|
+ .osreg_addr = 0xff020208
|
|
+ },
|
|
+ { .chip_name = "rv1108",
|
|
+ .osreg_addr = 0x10300588
|
|
+ },
|
|
+ { .chip_name = "rv1109",
|
|
+ .osreg_addr = 0xfe020208
|
|
+ },
|
|
+ { .chip_name = "rv1126",
|
|
+ .osreg_addr = 0xfe020208
|
|
+ },
|
|
+ { .chip_name = "rk1808",
|
|
+ .osreg_addr = 0xfe020208
|
|
+ },
|
|
+ { .chip_name = "rk3036",
|
|
+ .osreg_addr = 0x200081cc
|
|
+ },
|
|
+ { .chip_name = "rk3126b",
|
|
+ .osreg_addr = 0x200081cc
|
|
+ },
|
|
+ { .chip_name = "rk3126c",
|
|
+ .osreg_addr = 0x200081cc
|
|
+ },
|
|
+ { .chip_name = "rk3126",
|
|
+ .osreg_addr = 0x200081cc
|
|
+ },
|
|
+ { .chip_name = "rk3128",
|
|
+ .osreg_addr = 0x200081cc
|
|
+ },
|
|
+ { .chip_name = "rk3188",
|
|
+ .osreg_addr = 0x20004048
|
|
+ },
|
|
+ { .chip_name = "rk3228h",
|
|
+ .osreg_addr = 0xff1005d0
|
|
+ },
|
|
+ { .chip_name = "rk3228",
|
|
+ .osreg_addr = 0x110005d0
|
|
+ },
|
|
+ { .chip_name = "rk3229",
|
|
+ .osreg_addr = 0x110005d0
|
|
+ },
|
|
+ { .chip_name = "rk3288",
|
|
+ .osreg_addr = 0xff73009c
|
|
+ },
|
|
+ { .chip_name = "rk3308",
|
|
+ .osreg_addr = 0xff000208
|
|
+ },
|
|
+ { .chip_name = "rk3326",
|
|
+ .osreg_addr = 0xff010208
|
|
+ },
|
|
+ { .chip_name = "px30",
|
|
+ .osreg_addr = 0xff010208
|
|
+ },
|
|
+ { .chip_name = "rk3328",
|
|
+ .osreg_addr = 0xff1005d0
|
|
+ },
|
|
+ { .chip_name = "rk3368",
|
|
+ .osreg_addr = 0xff738208
|
|
+ },
|
|
+ { .chip_name = "rk3399",
|
|
+ .osreg_addr = 0xff320308
|
|
+ },
|
|
+ { .chip_name = "rk3528",
|
|
+ .osreg_addr = 0xff370248
|
|
+ },
|
|
+ { .chip_name = "rk3562",
|
|
+ .osreg_addr = 0xff010208
|
|
+ },
|
|
+ { .chip_name = "rk3566",
|
|
+ .osreg_addr = 0xfdc20208
|
|
+ },
|
|
+ { .chip_name = "rk3568",
|
|
+ .osreg_addr = 0xfdc20208
|
|
+ },
|
|
+ { .chip_name = "rk3588",
|
|
+ .osreg_addr = 0xfd58a208
|
|
+ }
|
|
+};
|
|
+
|
|
+char* try_get_chip_name(void)
|
|
+{
|
|
+ FILE * file;
|
|
+ char *chip_name = NULL;
|
|
+ char buffer[100], buffer_new[100];
|
|
+ int i, j, bytes;
|
|
+
|
|
+ file = fopen("/proc/device-tree/compatible", "r");
|
|
+ if (file == NULL) {
|
|
+ printf("Failed to open /proc/device-tree/compatible\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ bytes = fread(buffer, sizeof(char), sizeof(buffer), file);
|
|
+ if (ferror(file)) {
|
|
+ printf("Failed to read /proc/device-tree/compatible.\n");
|
|
+ fclose(file);
|
|
+ goto out;
|
|
+ }
|
|
+ fclose(file);
|
|
+
|
|
+ for (i = 0, j = 0; i < bytes; i++) {
|
|
+ if ((buffer[i] == '\0') && (i < (bytes - 1)))
|
|
+ continue;
|
|
+ else
|
|
+ buffer_new[j++] = buffer[i];
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < (sizeof(chip_info) / sizeof(chip_info[0])); i++) {
|
|
+ if (strstr(buffer_new, chip_info[i].chip_name) != NULL) {
|
|
+ chip_name = chip_info[i].chip_name;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+out:
|
|
+ printf("get chip name: %s\n", chip_name);
|
|
+ return chip_name;
|
|
+}
|
|
+
|
|
+char* try_get_ddr_bw(char *chip_name)
|
|
+{
|
|
+ ull page_size;
|
|
+ char *ddr_bw = NULL;
|
|
+ int fd;
|
|
+ uint32_t reg_addr = 0, reg_val = 0;
|
|
+ uint32_t i, bw;
|
|
+
|
|
+ if (chip_name == NULL)
|
|
+ goto out;
|
|
+
|
|
+ for (i = 0; i < (sizeof(chip_info) / sizeof(chip_info[0])); i++) {
|
|
+ if (!strcasecmp(chip_name, chip_info[i].chip_name)) {
|
|
+ reg_addr = chip_info[i].osreg_addr;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (reg_addr == 0)
|
|
+ goto out;
|
|
+
|
|
+ page_size = getpagesize();
|
|
+
|
|
+ fd = open("/dev/mem", O_RDWR);
|
|
+ if (fd < 0) {
|
|
+ printf("Failed to open /dev/mem\n");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ void *map_base = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
|
|
+ reg_addr & ~(page_size - 1));
|
|
+ if (map_base == (void*)-1) {
|
|
+ printf("Failed to mmap /dev/mem\n");
|
|
+ close(fd);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ reg_val = (uint32_t)*(uint32_t *)(map_base + reg_addr % page_size);
|
|
+ if (munmap(map_base, page_size) == -1) {
|
|
+ printf("Failed to munmap /dev/mem");
|
|
+ close(fd);
|
|
+ goto out;
|
|
+ }
|
|
+ close(fd);
|
|
+
|
|
+ bw = 8 << SYS_REG_DEC_BW(reg_val, 0);
|
|
+ if (bw == 8)
|
|
+ ddr_bw = "bw_x8";
|
|
+ else if (bw == 16)
|
|
+ ddr_bw = "bw_x16";
|
|
+ else if (bw == 32)
|
|
+ ddr_bw = "bw_x32";
|
|
+
|
|
+out:
|
|
+ printf("get ddr bw: %s\n", ddr_bw);
|
|
+ return ddr_bw;
|
|
+}
|
|
+
|
|
+/* len should be 16byte align */
|
|
+int data_cpu_2_io(void *p, u32 len)
|
|
+{
|
|
+ uchar *val = p;
|
|
+ uchar buf[16];
|
|
+ u32 i, j;
|
|
+
|
|
+ if ((len % sizeof(buf)) || !len)
|
|
+ return -1;
|
|
+
|
|
+ if (io_type == IO_TYPE_1_2) {
|
|
+ len /= sizeof(buf);
|
|
+ for (j = 0; j < len; j++) {
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ for (i = 0; i < sizeof(buf); i++)
|
|
+ buf[i] = val[(i % 4) * 4 + i / 4 + j * sizeof(buf)];
|
|
+ memcpy(&val[j * sizeof(buf)], buf, sizeof(buf));
|
|
+ }
|
|
+ } else if (io_type == IO_TYPE_1_1_32) {
|
|
+ len /= 8;
|
|
+ for (j = 0; j < len; j++) {
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ for (i = 0; i < 8; i++)
|
|
+ buf[i] = val[(i % 4) * 2 + i / 4 + j * 8];
|
|
+ memcpy(&val[j * 8], buf, 8);
|
|
+ }
|
|
+ }
|
|
+ /* IO_TYPE_2 and IO_TYPE_1_1_16 do nothing*/
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void data_cpu_2_io_init(char *chip, char *ddr_bw)
|
|
+{
|
|
+ u32 osreg = 0;
|
|
+ u32 bw;
|
|
+
|
|
+ io_bw = IO_BW_32;
|
|
+ io_type = IO_TYPE_2;
|
|
+
|
|
+ if (chip == NULL) {
|
|
+ chip = try_get_chip_name();
|
|
+ if (chip == NULL)
|
|
+ goto bw_type;
|
|
+ }
|
|
+
|
|
+ if (!strcasecmp(chip, "rk3036") ||
|
|
+ !strcasecmp(chip, "rk3126") ||
|
|
+ !strcasecmp(chip, "rk3126b") ||
|
|
+ !strcasecmp(chip, "rk3126c")) {
|
|
+ io_type = IO_TYPE_1_1_16;
|
|
+ } else if (!strcasecmp(chip, "rk3228") ||
|
|
+ !strcasecmp(chip, "rk3229") ||
|
|
+ !strcasecmp(chip, "rk3368")) {
|
|
+ io_type = IO_TYPE_1_2;
|
|
+ } else if (!strcasecmp(chip, "rv1108") ||
|
|
+ !strcasecmp(chip, "rk3308")) {
|
|
+ io_type = IO_TYPE_1_2;
|
|
+ io_bw = IO_BW_16;
|
|
+ } else if (!strcasecmp(chip, "rk3128")) {
|
|
+ osreg = 0x200081cc;
|
|
+ } else if (!strcasecmp(chip, "rk3288")) {
|
|
+ osreg = 0xff73009c;
|
|
+ } else if (!strcasecmp(chip, "rk3188")) {
|
|
+ osreg = 0x20004048;
|
|
+ } else if (!strcasecmp(chip, "rk3328") ||
|
|
+ !strcasecmp(chip, "rk3228h")||
|
|
+ !strcasecmp(chip, "px30")||
|
|
+ !strcasecmp(chip, "rk3326")||
|
|
+ !strcasecmp(chip, "rk1808")||
|
|
+ !strcasecmp(chip, "rv1126")||
|
|
+ !strcasecmp(chip, "rv1109")) {
|
|
+ io_type = IO_TYPE_2;
|
|
+ } else {
|
|
+ /* default IO_TYPE_2 */
|
|
+ printf("no available chip info, using default maping\n");
|
|
+ io_type = IO_TYPE_2;
|
|
+ }
|
|
+
|
|
+ if (osreg) {
|
|
+ bw = (2 >> ((osreg >> 2) & 0x3));
|
|
+ if (bw == 2)
|
|
+ io_type = IO_TYPE_1_1_32;
|
|
+ else
|
|
+ io_type = IO_TYPE_1_1_16;
|
|
+ }
|
|
+
|
|
+bw_type:
|
|
+ if (ddr_bw == NULL) {
|
|
+ ddr_bw = try_get_ddr_bw(chip);
|
|
+ if (ddr_bw == NULL)
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!strcasecmp(ddr_bw, "bw_x32")) {
|
|
+ io_bw = IO_BW_32;
|
|
+ } else if (!strcasecmp(ddr_bw, "bw_x16")) {
|
|
+ io_bw = IO_BW_16;
|
|
+ } else if (!strcasecmp(ddr_bw, "bw_x8")) {
|
|
+ io_bw = IO_BW_8;
|
|
+ }
|
|
+
|
|
+out:
|
|
+ if (io_bw == IO_BW_32)
|
|
+ printf("io bw x32\n");
|
|
+ else if (io_bw == IO_BW_16)
|
|
+ printf("io bw x16\n");
|
|
+ else if (io_bw == IO_BW_8)
|
|
+ printf("io bw x8\n");
|
|
+}
|
|
+
|
|
diff --git a/io_map.h b/io_map.h
|
|
new file mode 100644
|
|
index 0000000..317b5bd
|
|
--- /dev/null
|
|
+++ b/io_map.h
|
|
@@ -0,0 +1,19 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
|
+ *
|
|
+ * SPDX-License-Identifier: GPL-2.0+
|
|
+ */
|
|
+
|
|
+#ifndef _CMD_MEMTESTER_IO_MAP_H
|
|
+#define _CMD_MEMTESTER_IO_MAP_H
|
|
+
|
|
+#define IO_BW_32 0
|
|
+#define IO_BW_16 1
|
|
+#define IO_BW_8 2
|
|
+
|
|
+extern u32 io_bw;
|
|
+
|
|
+int data_cpu_2_io(void *p, u32 len);
|
|
+void data_cpu_2_io_init(char *chip, char *ddr_bw);
|
|
+
|
|
+#endif /* _CMD_MEMTESTER_IO_MAP_H */
|
|
diff --git a/memtester.c b/memtester.c
|
|
index 44d331e..a867443 100644
|
|
--- a/memtester.c
|
|
+++ b/memtester.c
|
|
@@ -12,7 +12,7 @@
|
|
*
|
|
*/
|
|
|
|
-#define __version__ "4.5.1"
|
|
+#define __version__ "4.5.1_20231020"
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
@@ -24,15 +24,22 @@
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
+#include <signal.h>
|
|
|
|
#include "types.h"
|
|
#include "sizes.h"
|
|
#include "tests.h"
|
|
+#include "io_map.h"
|
|
+#include "va_2_pa.h"
|
|
+#include "cache.h"
|
|
|
|
#define EXIT_FAIL_NONSTARTER 0x01
|
|
#define EXIT_FAIL_ADDRESSLINES 0x02
|
|
#define EXIT_FAIL_OTHERTEST 0x04
|
|
|
|
+void sighandler(int);
|
|
+int exit_code = 0;
|
|
+
|
|
struct test tests[] = {
|
|
{ "Random Value", test_random_value },
|
|
{ "Compare XOR", test_xor_comparison },
|
|
@@ -102,7 +109,41 @@ off_t physaddrbase = 0;
|
|
/* Function definitions */
|
|
void usage(char *me) {
|
|
fprintf(stderr, "\n"
|
|
- "Usage: %s [-p physaddrbase [-d device]] <mem>[B|K|M|G] [loops]\n",
|
|
+ "Usage: %s [-p physaddrbase [-d device]] [-e exit_when_error]"
|
|
+ "[-t test_pattern] [-c chip name]<mem>[B|K|M|G] [loops]\n"
|
|
+ "-p testing phys address\n"
|
|
+ "-e if not 0, exit immediately when test fail\n"
|
|
+ "-f fixed bit to a exact level, 1: high, 0: low, which bits are depend on level(-l) bits\n"
|
|
+ "-b fix bits, 1: fix bit level, 0: do not fix level\n"
|
|
+ " example: -f 0x1 -b 0x1000: fix cpu bit 12 to high\n"
|
|
+ " -f 0x0 -b 0x1000: fix cpu bit 12 to low\n"
|
|
+ " when doing bitflip, bitspread, walkbits1,\n"
|
|
+ " walkbits0, blockseq, checkerboard and solidbits tests.\n"
|
|
+ "-t testing pattern mask, if null or 0 enable all test pattern\n"
|
|
+ " bit0: Random Value\n"
|
|
+ " bit1: Compare XOR\n"
|
|
+ " bit2: Compare SUB\n"
|
|
+ " bit3: Compare MUL\n"
|
|
+ " bit4: Compare DIV\n"
|
|
+ " bit5: Compare OR\n"
|
|
+ " bit6: Compare AND\n"
|
|
+ " bit7: Sequential Increment\n"
|
|
+ " bit8: Solid Bits\n"
|
|
+ " bit9: Block Sequential\n"
|
|
+ " bit10: Checkerboard\n"
|
|
+ " bit11: Bit Spread\n"
|
|
+ " bit12: Bit Flip\n"
|
|
+ " bit13: Walking Ones\n"
|
|
+ " bit14: Walking Zeroes\n"
|
|
+ " bit15: 8-bit Writes\n"
|
|
+ " bit16: 16-bit Writes\n"
|
|
+ " example: -t 0x1000,enable Bit Flip only\n"
|
|
+ "-c chip name include:\n"
|
|
+ " rk3036, rk3126, rk3228, rk3229, rv1108, rk3368, rk3128,"
|
|
+ " rk3188, rk3288, rk3228h, rk3328, rk3326, px30, rk1808, rv1109,"
|
|
+ " rv1126, rk3308\n"
|
|
+ "-w ddr bus width, include:\n"
|
|
+ " bw_x8, bw_x16, bw_x32\n",
|
|
me);
|
|
exit(EXIT_FAIL_NONSTARTER);
|
|
}
|
|
@@ -112,11 +153,15 @@ int main(int argc, char **argv) {
|
|
size_t pagesize, wantraw, wantmb, wantbytes, wantbytes_orig, bufsize,
|
|
halflen, count;
|
|
char *memsuffix, *addrsuffix, *loopsuffix;
|
|
+ char *chip_name = NULL;
|
|
+ char *ddr_bw = NULL;
|
|
ptrdiff_t pagesizemask;
|
|
void volatile *buf, *aligned;
|
|
- ulv *bufa, *bufb;
|
|
+ u32v *bufa, *bufb;
|
|
int do_mlock = 1, done_mem = 0;
|
|
- int exit_code = 0;
|
|
+ ul error_exit = 0;
|
|
+ ul test_pattern = 0;
|
|
+ ul stuck_addr = 1;
|
|
int memfd, opt, memshift;
|
|
size_t maxbytes = -1; /* addressable memory, in bytes */
|
|
size_t maxmb = (maxbytes >> 20) + 1; /* addressable memory, in MB */
|
|
@@ -126,6 +171,7 @@ int main(int argc, char **argv) {
|
|
int device_specified = 0;
|
|
char *env_testmask = 0;
|
|
ul testmask = 0;
|
|
+ u32 fix_level = 0, fix_bit = 0;
|
|
|
|
printf("memtester version " __version__ " (%d-bit)\n", UL_LEN);
|
|
printf("Copyright (C) 2001-2020 Charles Cazabon.\n");
|
|
@@ -150,7 +196,7 @@ int main(int argc, char **argv) {
|
|
printf("using testmask 0x%lx\n", testmask);
|
|
}
|
|
|
|
- while ((opt = getopt(argc, argv, "p:d:")) != -1) {
|
|
+ while ((opt = getopt(argc, argv, "p:d:e:f:b:t:c:w:")) != -1) {
|
|
switch (opt) {
|
|
case 'p':
|
|
errno = 0;
|
|
@@ -192,7 +238,54 @@ int main(int argc, char **argv) {
|
|
device_specified = 1;
|
|
}
|
|
}
|
|
- break;
|
|
+ break;
|
|
+ case 'e':
|
|
+ errno = 0;
|
|
+ error_exit = strtoull(optarg, NULL, 0);
|
|
+ if (errno != 0) {
|
|
+ fprintf(stderr,
|
|
+ "failed to parse exit_when_error arg;\n");
|
|
+ usage(argv[0]); /* doesn't return */
|
|
+ }
|
|
+ break;
|
|
+ case 'f':
|
|
+ errno = 0;
|
|
+ fix_level = strtoull(optarg, NULL, 0);
|
|
+ if (errno != 0) {
|
|
+ fprintf(stderr,
|
|
+ "failed to parse test_pattern arg;\n");
|
|
+ usage(argv[0]); /* doesn't return */
|
|
+ }
|
|
+ break;
|
|
+ case 'b':
|
|
+ errno = 0;
|
|
+ fix_bit = strtoull(optarg, NULL, 0);
|
|
+ if (errno != 0) {
|
|
+ fprintf(stderr,
|
|
+ "failed to parse test_pattern arg;\n");
|
|
+ usage(argv[0]); /* doesn't return */
|
|
+ }
|
|
+ break;
|
|
+ case 't':
|
|
+ errno = 0;
|
|
+ test_pattern = strtoull(optarg, NULL, 0);
|
|
+ if (errno != 0) {
|
|
+ fprintf(stderr,
|
|
+ "failed to parse test_pattern arg;\n");
|
|
+ usage(argv[0]); /* doesn't return */
|
|
+ }
|
|
+ /* must add random value first */
|
|
+ if (test_pattern & 0x7e)
|
|
+ test_pattern |= 0x1;
|
|
+ if (test_pattern)
|
|
+ stuck_addr = 0;
|
|
+ break;
|
|
+ case 'c':
|
|
+ chip_name = optarg;
|
|
+ break;
|
|
+ case 'w':
|
|
+ ddr_bw = optarg;
|
|
+ break;
|
|
default: /* '?' */
|
|
usage(argv[0]); /* doesn't return */
|
|
}
|
|
@@ -372,10 +465,16 @@ int main(int argc, char **argv) {
|
|
aligned = buf;
|
|
}
|
|
|
|
+ if (!use_phys)
|
|
+ printf("testing from phyaddress:0x%lx\n", read_pagemap((ul)aligned));
|
|
+
|
|
+ data_cpu_2_io_init(chip_name, ddr_bw);
|
|
halflen = bufsize / 2;
|
|
- count = halflen / sizeof(ul);
|
|
- bufa = (ulv *) aligned;
|
|
- bufb = (ulv *) ((size_t) aligned + halflen);
|
|
+ count = halflen / sizeof(u32);
|
|
+ bufa = (u32v *) aligned;
|
|
+ bufb = (u32v *) ((size_t) aligned + halflen);
|
|
+
|
|
+ signal(SIGINT, sighandler);
|
|
|
|
for(loop=1; ((!loops) || loop <= loops); loop++) {
|
|
printf("Loop %lu", loop);
|
|
@@ -383,12 +482,19 @@ int main(int argc, char **argv) {
|
|
printf("/%lu", loops);
|
|
}
|
|
printf(":\n");
|
|
- printf(" %-20s: ", "Stuck Address");
|
|
- fflush(stdout);
|
|
- if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
|
|
- printf("ok\n");
|
|
- } else {
|
|
- exit_code |= EXIT_FAIL_ADDRESSLINES;
|
|
+ if (stuck_addr != 0) {
|
|
+ printf(" %-20s: ", "Stuck Address");
|
|
+ fflush(stdout);
|
|
+ if (!test_stuck_address(aligned, bufsize / sizeof(u32))) {
|
|
+ printf("ok\n");
|
|
+ } else {
|
|
+ exit_code |= EXIT_FAIL_ADDRESSLINES;
|
|
+ if (error_exit) {
|
|
+ printf("EXIT_FAIL_ADDRESSLINES\n");
|
|
+ fflush(stdout);
|
|
+ exit(exit_code);
|
|
+ }
|
|
+ }
|
|
}
|
|
for (i=0;;i++) {
|
|
if (!tests[i].name) break;
|
|
@@ -398,11 +504,17 @@ int main(int argc, char **argv) {
|
|
if (testmask && (!((1 << i) & testmask))) {
|
|
continue;
|
|
}
|
|
+ if (test_pattern && (!((1 << i) & test_pattern)))
|
|
+ continue;
|
|
printf(" %-20s: ", tests[i].name);
|
|
- if (!tests[i].fp(bufa, bufb, count)) {
|
|
+ if (!tests[i].fp(bufa, bufb, count, fix_bit, fix_level)) {
|
|
printf("ok\n");
|
|
} else {
|
|
exit_code |= EXIT_FAIL_OTHERTEST;
|
|
+ if (error_exit) {
|
|
+ printf("EXIT_FAIL_OTHERTEST\n");
|
|
+ goto out;
|
|
+ }
|
|
}
|
|
fflush(stdout);
|
|
/* clear buffer */
|
|
@@ -412,7 +524,14 @@ int main(int argc, char **argv) {
|
|
fflush(stdout);
|
|
}
|
|
if (do_mlock) munlock((void *) aligned, bufsize);
|
|
- printf("Done.\n");
|
|
+out:
|
|
fflush(stdout);
|
|
- exit(exit_code);
|
|
+ exit_result(exit_code);
|
|
}
|
|
+
|
|
+void sighandler(int signum)
|
|
+{
|
|
+ fflush(stdout);
|
|
+ exit_result(exit_code);
|
|
+}
|
|
+
|
|
diff --git a/sizes.h b/sizes.h
|
|
index cd1c3ad..5a4a994 100644
|
|
--- a/sizes.h
|
|
+++ b/sizes.h
|
|
@@ -16,23 +16,10 @@
|
|
|
|
#define rand32() ((unsigned int) rand() | ( (unsigned int) rand() << 16))
|
|
|
|
-#if (ULONG_MAX == 4294967295UL)
|
|
- #define rand_ul() rand32()
|
|
- #define UL_ONEBITS 0xffffffff
|
|
- #define UL_LEN 32
|
|
- #define CHECKERBOARD1 0x55555555
|
|
- #define CHECKERBOARD2 0xaaaaaaaa
|
|
- #define UL_BYTE(x) ((x | x << 8 | x << 16 | x << 24))
|
|
-#elif (ULONG_MAX == 18446744073709551615ULL)
|
|
- #define rand64() (((ul) rand32()) << 32 | ((ul) rand32()))
|
|
- #define rand_ul() rand64()
|
|
- #define UL_ONEBITS 0xffffffffffffffffUL
|
|
- #define UL_LEN 64
|
|
- #define CHECKERBOARD1 0x5555555555555555
|
|
- #define CHECKERBOARD2 0xaaaaaaaaaaaaaaaa
|
|
- #define UL_BYTE(x) (((ul)x | (ul)x<<8 | (ul)x<<16 | (ul)x<<24 | (ul)x<<32 | (ul)x<<40 | (ul)x<<48 | (ul)x<<56))
|
|
-#else
|
|
- #error long on this platform is not 32 or 64 bits
|
|
-#endif
|
|
-
|
|
+#define rand_ul() rand32()
|
|
+#define UL_ONEBITS 0xffffffff
|
|
+#define UL_LEN 32
|
|
+#define CHECKERBOARD1 0x55555555
|
|
+#define CHECKERBOARD2 0xaaaaaaaa
|
|
+#define UL_BYTE(x) ((x | x << 8 | x << 16 | x << 24))
|
|
|
|
diff --git a/tests.c b/tests.c
|
|
index 4970350..8cbcaaf 100644
|
|
--- a/tests.c
|
|
+++ b/tests.c
|
|
@@ -21,6 +21,9 @@
|
|
#include "types.h"
|
|
#include "sizes.h"
|
|
#include "memtester.h"
|
|
+#include "io_map.h"
|
|
+#include "va_2_pa.h"
|
|
+#include "cache.h"
|
|
|
|
char progress[] = "-\\|/";
|
|
#define PROGRESSLEN 4
|
|
@@ -29,45 +32,67 @@ char progress[] = "-\\|/";
|
|
|
|
union {
|
|
unsigned char bytes[UL_LEN/8];
|
|
- ul val;
|
|
+ u32 val;
|
|
} mword8;
|
|
|
|
union {
|
|
unsigned short u16s[UL_LEN/16];
|
|
- ul val;
|
|
+ u32 val;
|
|
} mword16;
|
|
|
|
+u32 fault_cnt = 0;
|
|
/* Function definitions. */
|
|
|
|
-int compare_regions(ulv *bufa, ulv *bufb, size_t count) {
|
|
+__attribute__((weak)) void dcacheflush(ul start, ul end)
|
|
+{
|
|
+ return;
|
|
+}
|
|
+
|
|
+int compare_regions(u32v *bufa, u32v *bufb, size_t count) {
|
|
int r = 0;
|
|
size_t i;
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
+ u32 read[2];
|
|
+ u32 reread[2];
|
|
off_t physaddr;
|
|
|
|
for (i = 0; i < count; i++, p1++, p2++) {
|
|
- if (*p1 != *p2) {
|
|
+ read[0] = *p1;
|
|
+ read[1] = *p2;
|
|
+ if (read[0] != read[1]) {
|
|
+ dcacheflush((ul)p1, (ul)p1 + 4);
|
|
+ dcacheflush((ul)p2, (ul)p2 + 4);
|
|
+ reread[0] = *p1;
|
|
+ reread[1] = *p2;
|
|
if (use_phys) {
|
|
- physaddr = physaddrbase + (i * sizeof(ul));
|
|
- fprintf(stderr,
|
|
- "FAILURE: 0x%08lx != 0x%08lx at physical address "
|
|
- "0x%08lx.\n",
|
|
- (ul) *p1, (ul) *p2, physaddr);
|
|
+ physaddr = physaddrbase + (i * sizeof(u32v));
|
|
+ fprintf(stdout,
|
|
+ "FAILURE: 0x%08x != 0x%08x (readA^readB:0x%08x) at physical address "
|
|
+ "0x%08lx, reread:0x%08x, 0x%08x (rereadA^readA:0x%08x, rereadB^readB:0x%08x).\n",
|
|
+ read[0], read[1], read[0] ^ read[1], physaddr,
|
|
+ reread[0], reread[1], reread[0] ^ read[0], reread[1] ^ read[1]);
|
|
} else {
|
|
- fprintf(stderr,
|
|
- "FAILURE: 0x%08lx != 0x%08lx at offset 0x%08lx.\n",
|
|
- (ul) *p1, (ul) *p2, (ul) (i * sizeof(ul)));
|
|
+ fprintf(stdout,
|
|
+ "FAILURE: 0x%08x != 0x%08x (readA^readB:0x%08x) at offset 0x%08lx.\n"
|
|
+ "physical address: 0x%08lx, 0x%08lx, "
|
|
+ "reread:0x%08x, 0x%08x (rereadA^readA:0x%08x, rereadB^readB:0x%08x).\n",
|
|
+ read[0], read[1], read[0] ^ read[1], (ul) (i * sizeof(u32v)),
|
|
+ read_pagemap((ul)p1), read_pagemap((ul)p2),
|
|
+ reread[0], reread[1], reread[0] ^ read[0], reread[1] ^ read[1]);
|
|
}
|
|
/* printf("Skipping to next test..."); */
|
|
r = -1;
|
|
+ fault_cnt++;
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
-int test_stuck_address(ulv *bufa, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
+int test_stuck_address(u32v *bufa, size_t count) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32 read, expect;
|
|
+ u32 reread;
|
|
unsigned int j;
|
|
size_t i;
|
|
off_t physaddr;
|
|
@@ -76,33 +101,41 @@ int test_stuck_address(ulv *bufa, size_t count) {
|
|
fflush(stdout);
|
|
for (j = 0; j < 16; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- p1 = (ulv *) bufa;
|
|
+ p1 = (u32v *) bufa;
|
|
printf("setting %3u", j);
|
|
fflush(stdout);
|
|
for (i = 0; i < count; i++) {
|
|
- *p1 = ((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1);
|
|
+ *p1 = ((j + i) % 2) == 0 ? (u32)(ul) p1 : ~((u32)(ul) p1);
|
|
*p1++;
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
fflush(stdout);
|
|
- p1 = (ulv *) bufa;
|
|
+ p1 = (u32v *) bufa;
|
|
for (i = 0; i < count; i++, p1++) {
|
|
- if (*p1 != (((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1))) {
|
|
+ read = *p1;
|
|
+ expect = ((j + i) % 2) == 0 ? (u32)(ul) p1 : ~((u32)(ul) p1);
|
|
+ if (read != expect) {
|
|
+ dcacheflush((ul)p1, (ul)p1 + 4);
|
|
+ reread = *p1;
|
|
if (use_phys) {
|
|
- physaddr = physaddrbase + (i * sizeof(ul));
|
|
- fprintf(stderr,
|
|
+ physaddr = physaddrbase + (i * sizeof(u32));
|
|
+ fprintf(stdout,
|
|
"FAILURE: possible bad address line at physical "
|
|
- "address 0x%08lx.\n",
|
|
- physaddr);
|
|
+ "address 0x%08lx:0x%08x != 0x%08x (0x%08x), reread:0x%08x(reread^read:0x%08x).\n",
|
|
+ physaddr, read, expect, read ^ expect, reread, reread ^ read);
|
|
} else {
|
|
- fprintf(stderr,
|
|
+ fprintf(stdout,
|
|
"FAILURE: possible bad address line at offset "
|
|
- "0x%08lx.\n",
|
|
- (ul) (i * sizeof(ul)));
|
|
+ "0x%08lx.\n"
|
|
+ "physical address 0x%08lx:0x%08x != 0x%08x (0x%08x),"
|
|
+ "reread:0x%08x(reread^read:0x%08x).\n",
|
|
+ (ul) (i * sizeof(u32)), read_pagemap((ul)p1),
|
|
+ read, expect, read ^ expect, reread, reread ^ read);
|
|
}
|
|
printf("Skipping to next test...\n");
|
|
fflush(stdout);
|
|
+ fault_cnt++;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -112,9 +145,9 @@ int test_stuck_address(ulv *bufa, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_random_value(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_random_value(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
ul j = 0;
|
|
size_t i;
|
|
|
|
@@ -133,11 +166,11 @@ int test_random_value(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_xor_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_xor_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*p1++ ^= q;
|
|
@@ -146,11 +179,11 @@ int test_xor_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_sub_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_sub_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*p1++ -= q;
|
|
@@ -159,11 +192,11 @@ int test_sub_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_mul_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_mul_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*p1++ *= q;
|
|
@@ -172,11 +205,11 @@ int test_mul_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_div_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_div_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
if (!q) {
|
|
@@ -188,11 +221,11 @@ int test_div_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_or_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_or_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*p1++ |= q;
|
|
@@ -201,11 +234,11 @@ int test_or_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_and_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_and_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*p1++ &= q;
|
|
@@ -214,11 +247,11 @@ int test_and_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_seqinc_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_seqinc_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
size_t i;
|
|
- ul q = rand_ul();
|
|
+ u32 q = rand_ul();
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*p1++ = *p2++ = (i + q);
|
|
@@ -226,24 +259,55 @@ int test_seqinc_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return compare_regions(bufa, bufb, count);
|
|
}
|
|
|
|
-int test_solidbits_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_solidbits_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j;
|
|
- ul q;
|
|
+ u32 q;
|
|
+ u32 data[4];
|
|
size_t i;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
for (j = 0; j < 64; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- q = (j % 2) == 0 ? UL_ONEBITS : 0;
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ q = (j % 2) == 0 ? UL_ONEBITS : 0;
|
|
+ if (fix_level)
|
|
+ q |= fix_bit;
|
|
+ else
|
|
+ q &= ~fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ q = (j % 2) == 0 ? (UL_ONEBITS & 0x0000ffff) : (0 & 0xffff0000);
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ q = (j % 2) == 0 ? (UL_ONEBITS & 0x00ff00ff) : (0 & 0xff00ff00);
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) | ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) | ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+
|
|
+ data[0] = data[2] = q;
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level) {
|
|
+ data[1] = data[3] = (~q) | fix_bit;
|
|
+ } else {
|
|
+ data[1] = data[3] = (~q) & (~fix_bit);
|
|
+ }
|
|
+ } else {
|
|
+ data[1] = data[3] = q;
|
|
+ }
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
printf("setting %3u", j);
|
|
fflush(stdout);
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
for (i = 0; i < count; i++) {
|
|
- *p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
@@ -257,24 +321,54 @@ int test_solidbits_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_checkerboard_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_checkerboard_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j;
|
|
- ul q;
|
|
+ u32 q;
|
|
+ u32 data[4];
|
|
size_t i;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
for (j = 0; j < 64; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2;
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2;
|
|
+ if (fix_level)
|
|
+ q |= fix_bit;
|
|
+ else
|
|
+ q &= ~fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ q = ((CHECKERBOARD1 & 0x0000ffff) | (CHECKERBOARD2 & 0xffff0000));
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ q = ((CHECKERBOARD1 & 0x00ff00ff) | (CHECKERBOARD2 & 0xff00ff00));
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) | ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) | ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+ data[0] = data[2] = q;
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level) {
|
|
+ data[1] = data[3] = (~q) | fix_bit;
|
|
+ } else {
|
|
+ data[1] = data[3] = (~q) & (~fix_bit);
|
|
+ }
|
|
+ } else {
|
|
+ data[1] = data[3] = q;
|
|
+ }
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
printf("setting %3u", j);
|
|
fflush(stdout);
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
for (i = 0; i < count; i++) {
|
|
- *p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
@@ -288,22 +382,48 @@ int test_checkerboard_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_blockseq_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_blockseq_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j;
|
|
+ u32 data[4];
|
|
+ u32 q;
|
|
size_t i;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
for (j = 0; j < 256; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
printf("setting %3u", j);
|
|
fflush(stdout);
|
|
+ q = (u32)UL_BYTE(j);
|
|
+
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level)
|
|
+ q |= fix_bit;
|
|
+ else
|
|
+ q &= ~fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) | ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) | ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+
|
|
+ data[0] = q;
|
|
+ data[1] = q;
|
|
+ data[2] = q;
|
|
+ data[3] = q;
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
for (i = 0; i < count; i++) {
|
|
- *p1++ = *p2++ = (ul) UL_BYTE(j);
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
@@ -317,26 +437,53 @@ int test_blockseq_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_walkbits0_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_walkbits0_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j;
|
|
+ u32 data[4];
|
|
+ u32 q;
|
|
size_t i;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
for (j = 0; j < UL_LEN * 2; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
printf("setting %3u", j);
|
|
fflush(stdout);
|
|
+ if (j < UL_LEN)
|
|
+ q = ONE << j;
|
|
+ else
|
|
+ q = ONE << (UL_LEN * 2 - j - 1);
|
|
+
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level)
|
|
+ q |= fix_bit;
|
|
+ else
|
|
+ q &= ~fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) | ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) | ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+
|
|
+ data[0] = q;
|
|
+ data[1] = q;
|
|
+ data[2] = q;
|
|
+ data[3] = q;
|
|
+
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
+
|
|
for (i = 0; i < count; i++) {
|
|
- if (j < UL_LEN) { /* Walk it up. */
|
|
- *p1++ = *p2++ = ONE << j;
|
|
- } else { /* Walk it back down. */
|
|
- *p1++ = *p2++ = ONE << (UL_LEN * 2 - j - 1);
|
|
- }
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
@@ -350,26 +497,55 @@ int test_walkbits0_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_walkbits1_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_walkbits1_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j;
|
|
+ u32 data[4];
|
|
+ u32 q;
|
|
size_t i;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
+
|
|
for (j = 0; j < UL_LEN * 2; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
printf("setting %3u", j);
|
|
+
|
|
+ if (j < UL_LEN)
|
|
+ q = UL_ONEBITS ^ (ONE << j);
|
|
+ else
|
|
+ q = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - j - 1));
|
|
+
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level)
|
|
+ q |= fix_bit;
|
|
+ else
|
|
+ q &= ~fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) | ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) | ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+
|
|
+ data[0] = q;
|
|
+ data[1] = q;
|
|
+ data[2] = q;
|
|
+ data[3] = q;
|
|
+
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
+
|
|
fflush(stdout);
|
|
for (i = 0; i < count; i++) {
|
|
- if (j < UL_LEN) { /* Walk it up. */
|
|
- *p1++ = *p2++ = UL_ONEBITS ^ (ONE << j);
|
|
- } else { /* Walk it back down. */
|
|
- *p1++ = *p2++ = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - j - 1));
|
|
- }
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
@@ -383,32 +559,80 @@ int test_walkbits1_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_bitspread_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_bitspread_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j;
|
|
+ u32 data[4];
|
|
size_t i;
|
|
+ u32 length;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
+
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ length = UL_LEN;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ length = UL_LEN / 2;
|
|
+ } else {
|
|
+ length = UL_LEN / 4;
|
|
+ }
|
|
+
|
|
for (j = 0; j < UL_LEN * 2; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
printf("setting %3u", j);
|
|
+
|
|
+ if (j < length) {
|
|
+ data[0] = (ONE << j) | (ONE << (j + 2));
|
|
+ data[1] = UL_ONEBITS ^ ((ONE << j) | (ONE << (j + 2)));
|
|
+ } else {
|
|
+ data[0] = (ONE << (length * 2 - 1 - j)) |
|
|
+ (ONE << (length * 2 + 1 - j));
|
|
+ data[1] = UL_ONEBITS ^ (ONE << (length * 2 - 1 - j)
|
|
+ | (ONE << (length * 2 + 1 - j)));
|
|
+ }
|
|
+ if (io_bw == IO_BW_16) {
|
|
+ data[1] = data[0] = (data[0] & 0x0000ffff) | ((data[1] & 0x0000ffff) << 16);
|
|
+ } else if (io_bw == IO_BW_8) {
|
|
+ data[1] = data[0] = (data[0] & 0x000000ff) | ((data[1] & 0x000000ff) << 8) |
|
|
+ ((data[0] & 0x000000ff) << 16) | ((data[1] & 0x000000ff) << 24);
|
|
+ }
|
|
+ if (fix_level) {
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ data[0] |= fix_bit;
|
|
+ data[1] |= fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ data[0] |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ data[1] |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ data[0] |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) |
|
|
+ ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ data[1] |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) |
|
|
+ ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+ } else {
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ data[0] &= ~fix_bit;
|
|
+ data[1] &= ~fix_bit;
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ data[0] &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ data[1] &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ data[0] &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) |
|
|
+ ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ data[1] &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) |
|
|
+ ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
+ }
|
|
+ data[2] = data[0];
|
|
+ data[3] = data[1];
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
+
|
|
fflush(stdout);
|
|
for (i = 0; i < count; i++) {
|
|
- if (j < UL_LEN) { /* Walk it up. */
|
|
- *p1++ = *p2++ = (i % 2 == 0)
|
|
- ? (ONE << j) | (ONE << (j + 2))
|
|
- : UL_ONEBITS ^ ((ONE << j)
|
|
- | (ONE << (j + 2)));
|
|
- } else { /* Walk it back down. */
|
|
- *p1++ = *p2++ = (i % 2 == 0)
|
|
- ? (ONE << (UL_LEN * 2 - 1 - j)) | (ONE << (UL_LEN * 2 + 1 - j))
|
|
- : UL_ONEBITS ^ (ONE << (UL_LEN * 2 - 1 - j)
|
|
- | (ONE << (UL_LEN * 2 + 1 - j)));
|
|
- }
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", j);
|
|
@@ -422,26 +646,64 @@ int test_bitspread_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_bitflip_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
- ulv *p1 = bufa;
|
|
- ulv *p2 = bufb;
|
|
+int test_bitflip_comparison(u32v *bufa, u32v *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
+ u32v *p1 = bufa;
|
|
+ u32v *p2 = bufb;
|
|
unsigned int j, k;
|
|
- ul q;
|
|
+ u32 q;
|
|
+ u32 data[4];
|
|
size_t i;
|
|
|
|
printf(" ");
|
|
fflush(stdout);
|
|
for (k = 0; k < UL_LEN; k++) {
|
|
- q = ONE << k;
|
|
+ if (io_bw == IO_BW_32)
|
|
+ q = ONE << k;
|
|
+ else if (io_bw == IO_BW_16)
|
|
+ q = ONE << (k % 16);
|
|
+ else
|
|
+ q = ONE << (k % 8);
|
|
for (j = 0; j < 8; j++) {
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
- q = ~q;
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level) {
|
|
+ q = (~q) | fix_bit;
|
|
+ } else {
|
|
+ q = (~q) & (~fix_bit);
|
|
+ }
|
|
+ } else if (io_bw == IO_BW_16) {
|
|
+ q = (q & 0x0000ffff) | ((~q & 0x0000ffff) << 16);
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x0000ffff) | ((fix_bit & 0x0000ffff) << 16);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x0000ffff) | ((~fix_bit & 0x0000ffff) << 16);
|
|
+ } else {
|
|
+ q = (q & 0x000000ff) | ((~q & 0x000000ff) << 8) |
|
|
+ ((q & 0x000000ff) << 16) | ((~q & 0x000000ff) << 24);
|
|
+ if (fix_level)
|
|
+ q |= (fix_bit & 0x000000ff) | ((fix_bit & 0x000000ff) << 8) |
|
|
+ ((fix_bit & 0x000000ff) << 16) | ((fix_bit & 0x000000ff) << 24);
|
|
+ else
|
|
+ q &= (~fix_bit & 0x000000ff) | ((~fix_bit & 0x000000ff) << 8) |
|
|
+ ((~fix_bit & 0x000000ff) << 16) | ((~fix_bit & 0x000000ff) << 24);
|
|
+ }
|
|
printf("setting %3u", k * 8 + j);
|
|
fflush(stdout);
|
|
- p1 = (ulv *) bufa;
|
|
- p2 = (ulv *) bufb;
|
|
+ data[0] = data[2] = q;
|
|
+ if (io_bw == IO_BW_32) {
|
|
+ if (fix_level) {
|
|
+ data[1] = data[3] = (~q) | fix_bit;
|
|
+ } else {
|
|
+ data[1] = data[3] = (~q) & (~fix_bit);
|
|
+ }
|
|
+ } else {
|
|
+ data[1] = data[3] = q;
|
|
+ }
|
|
+ data_cpu_2_io(data, sizeof(data));
|
|
+ p1 = (u32v *) bufa;
|
|
+ p2 = (u32v *) bufb;
|
|
for (i = 0; i < count; i++) {
|
|
- *p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
|
|
+ *p1++ = *p2++ = data[i & 3];
|
|
}
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
printf("testing %3u", k * 8 + j);
|
|
@@ -457,9 +719,9 @@ int test_bitflip_comparison(ulv *bufa, ulv *bufb, size_t count) {
|
|
}
|
|
|
|
#ifdef TEST_NARROW_WRITES
|
|
-int test_8bit_wide_random(ulv* bufa, ulv* bufb, size_t count) {
|
|
+int test_8bit_wide_random(u32v* bufa, u32v* bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
u8v *p1, *t;
|
|
- ulv *p2;
|
|
+ u32v *p2;
|
|
int attempt;
|
|
unsigned int b, j = 0;
|
|
size_t i;
|
|
@@ -495,9 +757,9 @@ int test_8bit_wide_random(ulv* bufa, ulv* bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
|
|
-int test_16bit_wide_random(ulv* bufa, ulv* bufb, size_t count) {
|
|
+int test_16bit_wide_random(u32v* bufa, u32v* bufb, size_t count, unsigned int fix_bit, unsigned int fix_level) {
|
|
u16v *p1, *t;
|
|
- ulv *p2;
|
|
+ u32v *p2;
|
|
int attempt;
|
|
unsigned int b, j = 0;
|
|
size_t i;
|
|
@@ -533,3 +795,31 @@ int test_16bit_wide_random(ulv* bufa, ulv* bufb, size_t count) {
|
|
return 0;
|
|
}
|
|
#endif
|
|
+
|
|
+void exit_result(int exit_code)
|
|
+{
|
|
+ printf("\n*************************************************************\n");
|
|
+ printf("memtester result:\n");
|
|
+ printf("Log: had found %u failures.\n", fault_cnt);
|
|
+ printf("\nStatus: ");
|
|
+ if (!fault_cnt) {
|
|
+ printf("PASS.\n");
|
|
+ } else {
|
|
+ printf("FAIL - ");
|
|
+ switch (exit_code) {
|
|
+ EXIT_FAIL_NONSTARTER:
|
|
+ printf("EXIT_FAIL_NONSTARTER\n");
|
|
+ break;
|
|
+ EXIT_FAIL_ADDRESSLINES:
|
|
+ printf("EXIT_FAIL_ADDRESSLINES\n");
|
|
+ break;
|
|
+ EXIT_FAIL_OTHERTEST:
|
|
+ default:
|
|
+ printf("EXIT_FAIL_OTHERTEST\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ printf("\n*************************************************************\n");
|
|
+ exit(exit_code);
|
|
+}
|
|
+
|
|
diff --git a/tests.h b/tests.h
|
|
index e8b2f5f..1559065 100644
|
|
--- a/tests.h
|
|
+++ b/tests.h
|
|
@@ -16,24 +16,25 @@
|
|
|
|
/* Function declaration. */
|
|
|
|
-int test_stuck_address(unsigned long volatile *bufa, size_t count);
|
|
-int test_random_value(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_xor_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_sub_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_mul_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_div_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_or_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_and_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_seqinc_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_solidbits_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_checkerboard_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_blockseq_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_walkbits0_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_walkbits1_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_bitspread_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_bitflip_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
+int test_stuck_address(unsigned int volatile *bufa, size_t count);
|
|
+int test_random_value(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_xor_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_sub_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_mul_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_div_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_or_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_and_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_seqinc_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_solidbits_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_checkerboard_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_blockseq_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_walkbits0_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_walkbits1_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_bitspread_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_bitflip_comparison(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
#ifdef TEST_NARROW_WRITES
|
|
-int test_8bit_wide_random(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
-int test_16bit_wide_random(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
|
|
+int test_8bit_wide_random(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
+int test_16bit_wide_random(unsigned int volatile *bufa, unsigned int volatile *bufb, size_t count, unsigned int fix_bit, unsigned int fix_level);
|
|
#endif
|
|
+void exit_result(int exit_code);
|
|
|
|
diff --git a/types.h b/types.h
|
|
index 4cb41c3..e2d86f0 100644
|
|
--- a/types.h
|
|
+++ b/types.h
|
|
@@ -14,9 +14,12 @@
|
|
|
|
#include "sizes.h"
|
|
|
|
+typedef unsigned char uchar;
|
|
+typedef unsigned int u32;
|
|
typedef unsigned long ul;
|
|
typedef unsigned long long ull;
|
|
-typedef unsigned long volatile ulv;
|
|
+/* for all rk chip, dram bandwidth both 32bit */
|
|
+typedef unsigned int volatile u32v;
|
|
typedef unsigned char volatile u8v;
|
|
typedef unsigned short volatile u16v;
|
|
|
|
@@ -24,3 +27,4 @@ struct test {
|
|
char *name;
|
|
int (*fp)();
|
|
};
|
|
+
|
|
diff --git a/va_2_pa.c b/va_2_pa.c
|
|
new file mode 100644
|
|
index 0000000..5c42f42
|
|
--- /dev/null
|
|
+++ b/va_2_pa.c
|
|
@@ -0,0 +1,76 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
|
|
+ */
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <unistd.h>
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+#include <stdint.h>
|
|
+#include <string.h>
|
|
+#include "types.h"
|
|
+#include "va_2_pa.h"
|
|
+
|
|
+#define PAGEMAP_ENTRY 8
|
|
+#define GET_BIT(X,Y) (X & ((unsigned long long)1<<Y)) >> Y
|
|
+#define GET_PFN(X) X & 0x7FFFFFFFFFFFFF
|
|
+
|
|
+const int __endian_bit = 1;
|
|
+#define is_bigendian() ( (*(char*)&__endian_bit) == 0 )
|
|
+
|
|
+unsigned long read_pagemap(unsigned long virt_addr)
|
|
+{
|
|
+ FILE * f;
|
|
+ unsigned char c_buf[PAGEMAP_ENTRY];
|
|
+ unsigned int status, i, c;
|
|
+ ull page_size, file_offset;
|
|
+ unsigned long phy_addr = 0, page;
|
|
+
|
|
+ f = fopen("/proc/self/pagemap", "rb");
|
|
+ if (!f) {
|
|
+ printf("Error! Cannot open /proc/self/pagemap\n");
|
|
+ return -1;
|
|
+ }
|
|
+ page_size = getpagesize();
|
|
+
|
|
+ file_offset = virt_addr / page_size * PAGEMAP_ENTRY;
|
|
+ //printf("Vaddr: 0x%lx, Page_size: %lld, Entry_size: %d\n", virt_addr, page_size, PAGEMAP_ENTRY);
|
|
+ ///printf("Reading %s at 0x%llx\n", "/proc/self/pagemap", (unsigned long long)file_offset);
|
|
+ status = fseek(f, file_offset, SEEK_SET);
|
|
+ if (status) {
|
|
+ perror("Failed to do fseek for get physical address!\n");
|
|
+ return -1;
|
|
+ }
|
|
+ errno = 0;
|
|
+ page = 0;
|
|
+ for(i=0; i < PAGEMAP_ENTRY; i++){
|
|
+ c = getc(f);
|
|
+ if (c==EOF) {
|
|
+ printf("\nReached end of the file\n");
|
|
+ return -1;
|
|
+ }
|
|
+ if (is_bigendian())
|
|
+ c_buf[i] = c;
|
|
+ else
|
|
+ c_buf[PAGEMAP_ENTRY - i - 1] = c;
|
|
+ //printf("[%d]0x%x ", i, c);
|
|
+ }
|
|
+ for(i=0; i < PAGEMAP_ENTRY; i++){
|
|
+ //printf("%d ",c_buf[i]);
|
|
+ page = (page << 8) + c_buf[i];
|
|
+ }
|
|
+ //printf("Result: 0x%llx\n", (unsigned long long) page);
|
|
+ if(GET_BIT(page, 63)) {
|
|
+ uint64_t pfn = GET_PFN(page);
|
|
+ phy_addr = pfn * page_size + virt_addr % page_size;
|
|
+ //printf("PFN: 0x%llx (0x%llx)\n", pfn, phy_addr);
|
|
+ } else {
|
|
+ printf("Page not present\n");
|
|
+ }
|
|
+ if(GET_BIT(page, 62))
|
|
+ printf("Page swapped\n");
|
|
+ fclose(f);
|
|
+ return phy_addr;
|
|
+}
|
|
diff --git a/va_2_pa.h b/va_2_pa.h
|
|
new file mode 100644
|
|
index 0000000..dab38e9
|
|
--- /dev/null
|
|
+++ b/va_2_pa.h
|
|
@@ -0,0 +1,15 @@
|
|
+/*
|
|
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
|
|
+ *
|
|
+ * SPDX-License-Identifier: GPL-2.0+
|
|
+ */
|
|
+
|
|
+#ifndef _VA_2_PA_H
|
|
+#define _VA_2_PA_H
|
|
+
|
|
+int data_cpu_2_io(void *p, u32 len);
|
|
+void data_cpu_2_io_init(char *chip, char *ddr_bw);
|
|
+
|
|
+unsigned long read_pagemap(unsigned long virt_addr);
|
|
+
|
|
+#endif /* _VA_2_PA_H */
|
|
--
|
|
2.38.0
|
|
|