Loading files
4443d3b3aThis file is pinned to the selected release. Download the original to open it in your design tool.
// SPDX-License-Identifier: BSD-Source-Code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <libbase/memtest.h>
#include <generated/csr.h>
#include <generated/mem.h>
#include "../command.h"
#include "../helpers.h"
/**
* Command "mem_list"
*
* Memory list
*
*/
static void mem_list_handler(int nb_params, char **params)
{
printf("Available memory regions:\n");
#ifdef MEM_REGIONS_DETAILS
puts(MEM_REGIONS_DETAILS);
#else
puts(MEM_REGIONS);
#endif
}
define_command(mem_list, mem_list_handler, "List available memory regions", MEM_CMDS);
/**
* Command "mem_read"
*
* Memory read
*
*/
static void mem_read_handler(int nb_params, char **params)
{
char *c;
unsigned int *addr;
unsigned int length;
if (nb_params < 1) {
printf("mem_read <address> [length]\n");
return;
}
addr = (unsigned int *)strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Error: invalid address\n");
return;
}
if (nb_params == 1) {
length = 4;
} else {
length = strtoul(params[1], &c, 0);
if(*c != 0) {
printf("Error: invalid length\n");
return;
}
}
dump_bytes(addr, length, (unsigned long)addr);
}
define_command(mem_read, mem_read_handler, "Read address space", MEM_CMDS);
/**
* Command "mem_write"
*
* Memory write
*
*/
static void mem_write_handler(int nb_params, char **params)
{
char *c;
void *addr;
unsigned int value;
unsigned int count;
unsigned int size;
unsigned int i;
if (nb_params < 2) {
printf("mem_write <address> <value> [count] [size]\n");
return;
}
size = 4;
addr = (void *)strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Error: invalid address\n");
return;
}
value = strtoul(params[1], &c, 0);
if(*c != 0) {
printf("Error: invalid value\n");
return;
}
if (nb_params == 2) {
count = 1;
} else {
count = strtoul(params[2], &c, 0);
if(*c != 0) {
printf("Error: invalid count\n");
return;
}
}
if (nb_params == 4) {
size = strtoul(params[3], &c, 0);
if (*c != 0) {
printf("Error: invalid size\n");
return;
}
}
if ((size != 1) && (size != 2) && (size != 4)) {
printf("Error: invalid size (1, 2 or 4)\n");
return;
}
for (i = 0; i < count; i++) {
switch (size) {
case 1:
*(uint8_t *)addr = value;
addr += 1;
break;
case 2:
*(uint16_t *)addr = value;
addr += 2;
break;
case 4:
*(uint32_t *)addr = value;
addr += 4;
break;
}
}
}
define_command(mem_write, mem_write_handler, "Write address space", MEM_CMDS);
/**
* Command "mem_copy"
*
* Memory copy
*
*/
static void mem_copy_handler(int nb_params, char **params)
{
char *c;
unsigned int *dstaddr;
unsigned int *srcaddr;
unsigned int count;
unsigned int i;
if (nb_params < 2) {
printf("mem_copy <dst> <src> [count (32-bit words)]\n");
return;
}
dstaddr = (unsigned int *)strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Error: invalid destination address\n");
return;
}
srcaddr = (unsigned int *)strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Error: invalid source address\n");
return;
}
if (nb_params == 2) {
count = 1;
} else {
count = strtoul(params[2], &c, 0);
if (*c != 0) {
printf("Error: invalid count\n");
return;
}
}
for (i = 0; i < count; i++)
*dstaddr++ = *srcaddr++;
}
define_command(mem_copy, mem_copy_handler, "Copy address space", MEM_CMDS);
/**
* Command "mem_test"
*
* Memory Test
*
*/
static void mem_test_handler(int nb_params, char **params)
{
char *c;
unsigned int *addr;
/* Default to the same bounded size as the boot-time memtest: testing
"everything" from addr would write over the BIOS data/stack. */
unsigned long maxsize = MEMTEST_DATA_SIZE;
if (nb_params < 1) {
printf("mem_test <addr> [maxsize]\n");
return;
}
addr = (unsigned int *)strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Error: invalid address\n");
return;
}
if (nb_params >= 2) {
maxsize = strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Error: invalid size\n");
return;
}
}
memtest(addr, maxsize);
}
define_command(mem_test, mem_test_handler, "Test memory access", MEM_CMDS);
/**
* Command "mem_speed"
*
* Memory Speed
*
*/
static void mem_speed_handler(int nb_params, char **params)
{
char *c;
unsigned int *addr;
unsigned long size;
bool read_only = false;
bool random = false;
if (nb_params < 2) {
printf("mem_speed <addr> <size> [readonly] [random]\n");
return;
}
addr = (unsigned int *)strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Error: invalid address\n");
return;
}
size = strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Error: invalid size\n");
return;
}
if (nb_params >= 3) {
read_only = (bool) strtoul(params[2], &c, 0);
if (*c != 0) {
printf("Error: invalid readonly value\n");
return;
}
}
if (nb_params >= 4) {
random = (bool) strtoul(params[3], &c, 0);
if (*c != 0) {
printf("Error: invalid random value\n");
return;
}
}
memspeed(addr, size, read_only, random);
}
define_command(mem_speed, mem_speed_handler, "Test memory speed", MEM_CMDS);
/**
* Command "mem_cmp"
*
* Memory Compare
*
*/
static void mem_cmp_handler(int nb_params, char **params)
{
char *c;
unsigned int *addr1;
unsigned int *addr2;
unsigned int count;
unsigned int i;
bool same = true;
if (nb_params < 3) {
printf("mem_cmp <addr1> <addr2> <count (32-bit words)>\n");
return;
}
addr1 = (unsigned int *)strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Error: invalid addr1\n");
return;
}
addr2 = (unsigned int *)strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Error: invalid addr2\n");
return;
}
count = strtoul(params[2], &c, 0);
if (*c != 0) {
printf("Error: invalid count\n");
return;
}
for (i = 0; i < count; i++) {
if (*addr1++ != *addr2++) {
printf("Different memory content:\naddr1: 0x%08lx, content: 0x%08x\naddr2: 0x%08lx, content: 0x%08x\n",
(long unsigned int)(addr1 - 1), *(addr1 - 1),
(long unsigned int)(addr2 - 1), *(addr2 - 1));
same = false;
}
}
if (same)
printf("mem_cmp finished, same content.\n");
else
printf("mem_cmp finished, different content.\n");
}
define_command(mem_cmp, mem_cmp_handler, "Compare memory content", MEM_CMDS);