1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12#include <utils/debug.h> 13#include <stdint.h> 14#include <utils/arith.h> 15#include <utils/util.h> 16#include <utils/zf_log.h> 17#include <string.h> 18#include <inttypes.h> 19 20#define MD_BYTES_PER_LINE (sizeof(uint32_t) * 4) 21#define MD_GROUPING 4 22 23static void 24md_print_line(void* address, int word_size) 25{ 26 uint8_t line[MD_BYTES_PER_LINE]; 27 int num_objects = MD_BYTES_PER_LINE / word_size; 28 int object; 29 printf("%p: ", address); 30 for (object = 0; object < num_objects; object++) { 31 int object_offset = object * word_size; 32 if (MD_GROUPING > word_size && object % ((MD_GROUPING) / word_size) == 0) { 33 putchar(' '); 34 } 35 switch (word_size) { 36 case 1: { 37 uint8_t temp = *(volatile uint8_t*)(address + object_offset); 38 printf("0x%02x ", temp); 39 memcpy(&line[object_offset], &temp, sizeof(temp)); 40 break; 41 } 42 case 2: { 43 uint16_t temp = *(volatile uint16_t*)(address + object_offset); 44 printf("0x%04x ", temp); 45 memcpy(&line[object_offset], &temp, sizeof(temp)); 46 break; 47 } 48 case 4: { 49 uint32_t temp = *(volatile uint32_t*)(address + object_offset); 50 printf("0x%08x ", temp); 51 memcpy(&line[object_offset], &temp, sizeof(temp)); 52 break; 53 } 54 case 8: { 55 uint64_t temp = *(volatile uint64_t*)(address + object_offset); 56 printf("0x%016"PRIx64" ", temp); 57 memcpy(&line[object_offset], &temp, sizeof(temp)); 58 break; 59 } 60 } 61 } 62 /* Print ASCII string */ 63 printf(" |"); 64 for (object = 0; object < MD_BYTES_PER_LINE; object++) { 65 if (line[object] < 32 || line[object] > 126) { 66 putchar('.'); 67 } else { 68 putchar(line[object]); 69 } 70 } 71 printf("|\n"); 72} 73 74void 75utils_memory_dump(void* address, size_t bytes, int word_size) 76{ 77 void* a; 78 if (word_size == 1 || word_size == 2 || word_size == 4 || word_size == 8) { 79 /* Notify the caller if 'bytes' is not a multple of MD_BYTES_PER_LINE */ 80 if (bytes % MD_BYTES_PER_LINE) { 81 int extra_bytes = MD_BYTES_PER_LINE - (bytes % MD_BYTES_PER_LINE); 82 LOG_INFO("Rounding displayed bytes from %zu up to %zu", bytes, bytes + extra_bytes); 83 bytes += extra_bytes; 84 } 85 /* Print each line */ 86 for (a = address; a < address + bytes; a += MD_BYTES_PER_LINE) { 87 md_print_line(a, word_size); 88 } 89 } else { 90 LOG_ERROR("Invalid word size (%d). Valid options are [1, 2, 4, 8]", word_size); 91 } 92} 93