/* * Copyright (c) International Business Machines Corp., 2014 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * File: misc.c * Author: Shaun Wetzstein * Descr: * Note: * Date: 07/26/09 */ #include #include #include #include #include #include #include #include "misc.h" inline void prefetch(void *addr, size_t len, ...) { va_list v; va_start(v, len); int w = va_arg(v, int); int l = va_arg(v, int); va_end(v); while (0 < len) { if (w) { switch (l) { case 0: __builtin_prefetch(addr, 1, 0); break; case 1: __builtin_prefetch(addr, 1, 1); break; case 2: __builtin_prefetch(addr, 1, 2); break; } } else { switch (l) { case 0: __builtin_prefetch(addr, 0, 0); break; case 1: __builtin_prefetch(addr, 0, 1); break; case 2: __builtin_prefetch(addr, 0, 2); break; } } len -= sizeof addr; } } unsigned long align(unsigned long size, unsigned long offset) { --offset; return (size + offset) & ~offset; } void print_binary(FILE * __out, void *__data, size_t __len) { static const char *__ascii[] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111", }; if (__data == NULL) return; if (__out == NULL) __out = stdout; size_t i; for (i = 0; i < __len; i++) { unsigned char c = *(unsigned char *)(__data + i); fprintf(__out, "%4.4s%4.4s", __ascii[(c & 0xF0) >> 4], __ascii[c & 0x0F]); } } #if 0 void dump_memory(FILE * file, unsigned long addr, const void *buf, size_t size) { if (size <= 0 || buf == NULL) return; if (file == NULL) file = stdout; unsigned long *ul = (unsigned long *)buf; char hex[64] = { 0, }, ascii[32] = { 0,}, c; int hl = 0, al = 0; int cnt = size / sizeof(unsigned long); int i; for (i = 0; i < cnt; i++) { hl += snprintf(hex + hl, sizeof hex, "%08lx", ul[i]); c = (ul[i] & 0xFF000000) >> 24; al += snprintf(ascii + al, sizeof ascii, "%c", (isprint(c) ? c : '.')); c = (ul[i] & 0x00FF0000) >> 16; al += snprintf(ascii + al, sizeof ascii, "%c", (isprint(c) ? c : '.')); c = (ul[i] & 0x0000FF00) >> 8; al += snprintf(ascii + al, sizeof ascii, "%c", (isprint(c) ? c : '.')); c = (ul[i] & 0x000000FF) >> 0; al += snprintf(ascii + al, sizeof ascii, "%c", (isprint(c) ? c : '.')); if ((i + 1) % 4 == 0) { fprintf(file, " %08lx [%s] [%s]\n", addr, hex, ascii); addr += 4 * sizeof(unsigned long); hl = al = 0; memset(hex, 0, sizeof hex); memset(ascii, 0, sizeof ascii); } else { hl += snprintf(hex + hl, sizeof hex, " "); } } int j; for (j = 0; j < (i % 4); j++) { hl += snprintf(hex + hl, sizeof hex, "%08lx ", 0ul); al += snprintf(ascii + al, sizeof ascii, "%4.4s", "...."); } if (i % 4 != 0) { fprintf(file, " %08lx [%s] [%s]\n", addr, hex, ascii); } return; } #endif /* * "aaaaaaaa [wwwwwwww xxxxxxxx yyyyyyyy zzzzzzzz] [........ ........]" */ void dump_memory(FILE * __out, uint32_t __addr, const void *__restrict __buf, size_t __buf_sz) { if (__buf_sz <= 0 || __buf == NULL) return; if (__out == NULL) __out = stdout; size_t hex_size = 16 * 2; // 16 bytes per doubleword size_t ascii_size = 8 * 2; // 8 bytes per doubleword uint8_t hex[hex_size + 1], ascii[hex_size + 1]; memset(hex, '.', hex_size), memset(ascii, '.', ascii_size); void print_line(void) { fprintf(__out, "%08x ", __addr); fprintf(__out, "[%.8s %.8s %.8s %.8s] ", hex + 0, hex + 8, hex + 16, hex + 24); fprintf(__out, "[%.8s %.8s]\n", ascii + 0, ascii + 8); } size_t s = __addr % 16, i = 0; __addr &= ~0xF; for (i = s; i < __buf_sz + s; i++) { unsigned char c = ((unsigned char *)__buf)[i - s]; hex[((i << 1) + 0) % hex_size] = "0123456789abcdef"[c >> 4]; hex[((i << 1) + 1) % hex_size] = "0123456789abcdef"[c & 0xf]; ascii[i % ascii_size] = isprint(c) ? c : '.'; if (i == 0) continue; if ((i + 1) % ascii_size == 0) { print_line(); memset(hex, '.', hex_size), memset(ascii, '.', ascii_size); __addr += ascii_size; } } if (i % ascii_size) print_line(); return; } int __round_pow2(int size) { size--; size |= size >> 1; size |= size >> 2; size |= size >> 4; size |= size >> 8; size |= size >> 16; return ++size; }