blob: d156f5f62f52f8c3ff929a1a972c974a1906b5dd [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <utils/debug.h>
#include <stdint.h>
#include <utils/arith.h>
#include <utils/util.h>
#include <utils/zf_log.h>
#include <string.h>
#include <inttypes.h>
#define MD_BYTES_PER_LINE (sizeof(uint32_t) * 4)
#define MD_GROUPING 4
static void md_print_line(void *address, int word_size)
{
uint8_t line[MD_BYTES_PER_LINE];
unsigned num_objects = MD_BYTES_PER_LINE / word_size;
unsigned object;
printf("%p: ", address);
for (object = 0; object < num_objects; object++) {
int object_offset = object * word_size;
if (MD_GROUPING > word_size && object % ((MD_GROUPING) / word_size) == 0) {
putchar(' ');
}
switch (word_size) {
case 1: {
uint8_t temp = *(volatile uint8_t *)((uintptr_t)address + object_offset);
printf("0x%02x ", temp);
memcpy(&line[object_offset], &temp, sizeof(temp));
break;
}
case 2: {
uint16_t temp = *(volatile uint16_t *)((uintptr_t)address + object_offset);
printf("0x%04x ", temp);
memcpy(&line[object_offset], &temp, sizeof(temp));
break;
}
case 4: {
uint32_t temp = *(volatile uint32_t *)((uintptr_t)address + object_offset);
printf("0x%08x ", temp);
memcpy(&line[object_offset], &temp, sizeof(temp));
break;
}
case 8: {
uint64_t temp = *(volatile uint64_t *)((uintptr_t)address + object_offset);
printf("0x%016"PRIx64" ", temp);
memcpy(&line[object_offset], &temp, sizeof(temp));
break;
}
}
}
/* Print ASCII string */
printf(" |");
for (object = 0; object < MD_BYTES_PER_LINE; object++) {
if (line[object] < 32 || line[object] > 126) {
putchar('.');
} else {
putchar(line[object]);
}
}
printf("|\n");
}
void utils_memory_dump(void *address, size_t bytes, int word_size)
{
if (word_size == 1 || word_size == 2 || word_size == 4 || word_size == 8) {
/* Notify the caller if 'bytes' is not a multple of MD_BYTES_PER_LINE */
if (bytes % MD_BYTES_PER_LINE) {
int extra_bytes = MD_BYTES_PER_LINE - (bytes % MD_BYTES_PER_LINE);
ZF_LOGI("Rounding displayed bytes from %zu up to %zu", bytes, bytes + extra_bytes);
bytes += extra_bytes;
}
/* Print each line */
for (size_t i = 0; i < bytes; i += MD_BYTES_PER_LINE) {
md_print_line(&((uint8_t *)address)[i], word_size);
}
} else {
ZF_LOGE("Invalid word size (%d). Valid options are [1, 2, 4, 8]", word_size);
}
}