/* * Copyright (c) 2022 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * */ #include "ramstress_lib.h" #include #define RAMSTRESS_LOG(...) printf(__VA_ARGS__) struct ramfunc_list { int is_enable; char *info; int (*func)(uint32_t *buf1, uint32_t *buf2, uint32_t count); }; #include static uint32_t interface_random32(void) { return (uint32_t)rand(); } int ramstress_algo_fill_selfaddress(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1; volatile uint32_t *p2; uint32_t i, j; for (j = 0; j < 16; j++) { RAMSTRESS_LOG("fill_selfaddress: %u/%u\n", j, 16); p1 = buf1; p2 = buf2; for (i = 0; i < size; i++) { *p1 = ((j + i) & 0x01ul) ? (uint32_t)p1 : ~((uint32_t)p1); *p2 = ((j + i) & 0x01ul) ? (uint32_t)p2 : ~((uint32_t)p2); p1++; p2++; } p1 = buf1; p2 = buf2; volatile uint32_t *error_addr = 0; for (uint32_t i = 0; i < size; i++) { if (*p1 != (((j + i) & 0x01ul) ? (uint32_t)p1 : ~((uint32_t)p1))) { error_addr = p1; break; } else if (*p2 != (((j + i) & 0x01ul) ? (unsigned long)p2 : ~((unsigned long)p2))) { error_addr = p2; break; } else { p1++; p2++; } } if (error_addr) { RAMSTRESS_LOG("FAILURE: possible bad address at 0x%p.\n", error_addr); return -1; } } return 0; } static int ramstress_compare_buffer_result(volatile uint32_t *buf1, volatile uint32_t *buf2, uint32_t size) { while (size--) { if (*buf1 != *buf2) { RAMSTRESS_LOG("FAILURE: %X[at: %p] ! %X[at: %p]\n", *buf1, buf1, *buf2, buf2); return -1; } } return 0; } int ramstress_algo_random(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random; for (uint32_t i = 0; i < size; i++) { random = interface_random32(); *p1++ = random; *p2++ = random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_or(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); for (uint32_t i = 0; i < size; i++) { *p1++ |= random; *p2++ |= random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_xor(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); for (uint32_t i = 0; i < size; i++) { *p1++ ^= random; *p2++ ^= random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_and(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); for (uint32_t i = 0; i < size; i++) { *p1++ &= random; *p2++ &= random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_sub(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); for (uint32_t i = 0; i < size; i++) { *p1++ -= random; *p2++ -= random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_mul(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); for (uint32_t i = 0; i < size; i++) { *p1++ *= random; *p2++ *= random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_div(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); random = (random == 0) ? (random + 1) : random; for (uint32_t i = 0; i < size; i++) { *p1++ /= random; *p2++ /= random; } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_seqinc(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1 = buf1; volatile uint32_t *p2 = buf2; uint32_t random = interface_random32(); for (uint32_t i = 0; i < size; i++) { *p1++ = (i + random); *p2++ = (i + random); } return ramstress_compare_buffer_result(buf1, buf2, size); } int ramstress_algo_solidbits(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1; volatile uint32_t *p2; uint32_t i, j; uint32_t random; uint32_t all_one_bits = 0xfffffffful; for (j = 0; j < 64; j++) { p1 = buf1; p2 = buf2; random = (j & 0x01) == 0 ? all_one_bits : 0; RAMSTRESS_LOG("solidbits: random(%u/64) = 0x%X running...\n", j, random); for (i = 0; i < size; i++) { *p1++ = (i & 0x01) == 0 ? random : ~random; *p2++ = (i & 0x01) == 0 ? random : ~random; } if (ramstress_compare_buffer_result(buf1, buf2, size)) { return -1; } } return 0; } int ramstress_algo_checkerboard(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1; volatile uint32_t *p2; uint32_t i, j; uint32_t random; uint32_t checkerboard1 = 0x55555555ul; uint32_t checkerboard2 = 0xaaaaaaaaul; for (j = 0; j < 64; j++) { p1 = buf1; p2 = buf2; random = (j & 0x01) == 0 ? checkerboard1 : checkerboard2; RAMSTRESS_LOG("checkerboard: random(%u/64) = 0x%X running...\n", j, random); for (i = 0; i < size; i++) { *p1++ = (i & 0x01) == 0 ? random : ~random; *p2++ = (i & 0x01) == 0 ? random : ~random; } if (ramstress_compare_buffer_result(buf1, buf2, size)) { return -1; } } return 0; } int ramstress_algo_blockseq(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1; volatile uint32_t *p2; uint32_t i, j; uint32_t random; for (j = 0; j < 0xff; j++) { p1 = buf1; p2 = buf2; random = j<<24 | j<<16 | j<<8 | j; RAMSTRESS_LOG("blockseq: random(%u/256) = 0x%X running...\n", j, random); for (i = 0; i < size; i++) { *p1++ = random; *p2++ = random; } if (ramstress_compare_buffer_result(buf1, buf2, size)) { return -1; } } return 0; } int ramstress_algo_walkbits0(uint32_t *buf1, uint32_t *buf2, uint32_t size) { volatile uint32_t *p1; volatile uint32_t *p2; uint32_t i, j; uint32_t random; uint32_t bit_len = 32; for (j = 0; j < bit_len * 2; j++) { p1 = buf1; p2 = buf2; if (j < bit_len) { /* DIR: up */ random = 0x01ul<