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