| /* |
| * 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); |
| } |
| } |