diff options
Diffstat (limited to 'powerpc/pmu/ebb/trace.c')
-rw-r--r-- | powerpc/pmu/ebb/trace.c | 300 |
1 files changed, 0 insertions, 300 deletions
diff --git a/powerpc/pmu/ebb/trace.c b/powerpc/pmu/ebb/trace.c deleted file mode 100644 index 251e66a..0000000 --- a/powerpc/pmu/ebb/trace.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2014, Michael Ellerman, IBM Corp. - * Licensed under GPLv2. - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> - -#include "trace.h" - - -struct trace_buffer *trace_buffer_allocate(u64 size) -{ - struct trace_buffer *tb; - - if (size < sizeof(*tb)) { - fprintf(stderr, "Error: trace buffer too small\n"); - return NULL; - } - - tb = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (tb == MAP_FAILED) { - perror("mmap"); - return NULL; - } - - tb->size = size; - tb->tail = tb->data; - tb->overflow = false; - - return tb; -} - -static bool trace_check_bounds(struct trace_buffer *tb, void *p) -{ - return p < ((void *)tb + tb->size); -} - -static bool trace_check_alloc(struct trace_buffer *tb, void *p) -{ - /* - * If we ever overflowed don't allow any more input. This prevents us - * from dropping a large item and then later logging a small one. The - * buffer should just stop when overflow happened, not be patchy. If - * you're overflowing, make your buffer bigger. - */ - if (tb->overflow) - return false; - - if (!trace_check_bounds(tb, p)) { - tb->overflow = true; - return false; - } - - return true; -} - -static void *trace_alloc(struct trace_buffer *tb, int bytes) -{ - void *p, *newtail; - - p = tb->tail; - newtail = tb->tail + bytes; - if (!trace_check_alloc(tb, newtail)) - return NULL; - - tb->tail = newtail; - - return p; -} - -static struct trace_entry *trace_alloc_entry(struct trace_buffer *tb, int payload_size) -{ - struct trace_entry *e; - - e = trace_alloc(tb, sizeof(*e) + payload_size); - if (e) - e->length = payload_size; - - return e; -} - -int trace_log_reg(struct trace_buffer *tb, u64 reg, u64 value) -{ - struct trace_entry *e; - u64 *p; - - e = trace_alloc_entry(tb, sizeof(reg) + sizeof(value)); - if (!e) - return -ENOSPC; - - e->type = TRACE_TYPE_REG; - p = (u64 *)e->data; - *p++ = reg; - *p++ = value; - - return 0; -} - -int trace_log_counter(struct trace_buffer *tb, u64 value) -{ - struct trace_entry *e; - u64 *p; - - e = trace_alloc_entry(tb, sizeof(value)); - if (!e) - return -ENOSPC; - - e->type = TRACE_TYPE_COUNTER; - p = (u64 *)e->data; - *p++ = value; - - return 0; -} - -int trace_log_string(struct trace_buffer *tb, char *str) -{ - struct trace_entry *e; - char *p; - int len; - - len = strlen(str); - - /* We NULL terminate to make printing easier */ - e = trace_alloc_entry(tb, len + 1); - if (!e) - return -ENOSPC; - - e->type = TRACE_TYPE_STRING; - p = (char *)e->data; - memcpy(p, str, len); - p += len; - *p = '\0'; - - return 0; -} - -int trace_log_indent(struct trace_buffer *tb) -{ - struct trace_entry *e; - - e = trace_alloc_entry(tb, 0); - if (!e) - return -ENOSPC; - - e->type = TRACE_TYPE_INDENT; - - return 0; -} - -int trace_log_outdent(struct trace_buffer *tb) -{ - struct trace_entry *e; - - e = trace_alloc_entry(tb, 0); - if (!e) - return -ENOSPC; - - e->type = TRACE_TYPE_OUTDENT; - - return 0; -} - -static void trace_print_header(int seq, int prefix) -{ - printf("%*s[%d]: ", prefix, "", seq); -} - -static char *trace_decode_reg(int reg) -{ - switch (reg) { - case 769: return "SPRN_MMCR2"; break; - case 770: return "SPRN_MMCRA"; break; - case 779: return "SPRN_MMCR0"; break; - case 804: return "SPRN_EBBHR"; break; - case 805: return "SPRN_EBBRR"; break; - case 806: return "SPRN_BESCR"; break; - case 800: return "SPRN_BESCRS"; break; - case 801: return "SPRN_BESCRSU"; break; - case 802: return "SPRN_BESCRR"; break; - case 803: return "SPRN_BESCRRU"; break; - case 771: return "SPRN_PMC1"; break; - case 772: return "SPRN_PMC2"; break; - case 773: return "SPRN_PMC3"; break; - case 774: return "SPRN_PMC4"; break; - case 775: return "SPRN_PMC5"; break; - case 776: return "SPRN_PMC6"; break; - case 780: return "SPRN_SIAR"; break; - case 781: return "SPRN_SDAR"; break; - case 768: return "SPRN_SIER"; break; - } - - return NULL; -} - -static void trace_print_reg(struct trace_entry *e) -{ - u64 *p, *reg, *value; - char *name; - - p = (u64 *)e->data; - reg = p++; - value = p; - - name = trace_decode_reg(*reg); - if (name) - printf("register %-10s = 0x%016llx\n", name, *value); - else - printf("register %lld = 0x%016llx\n", *reg, *value); -} - -static void trace_print_counter(struct trace_entry *e) -{ - u64 *value; - - value = (u64 *)e->data; - printf("counter = %lld\n", *value); -} - -static void trace_print_string(struct trace_entry *e) -{ - char *str; - - str = (char *)e->data; - puts(str); -} - -#define BASE_PREFIX 2 -#define PREFIX_DELTA 8 - -static void trace_print_entry(struct trace_entry *e, int seq, int *prefix) -{ - switch (e->type) { - case TRACE_TYPE_REG: - trace_print_header(seq, *prefix); - trace_print_reg(e); - break; - case TRACE_TYPE_COUNTER: - trace_print_header(seq, *prefix); - trace_print_counter(e); - break; - case TRACE_TYPE_STRING: - trace_print_header(seq, *prefix); - trace_print_string(e); - break; - case TRACE_TYPE_INDENT: - trace_print_header(seq, *prefix); - puts("{"); - *prefix += PREFIX_DELTA; - break; - case TRACE_TYPE_OUTDENT: - *prefix -= PREFIX_DELTA; - if (*prefix < BASE_PREFIX) - *prefix = BASE_PREFIX; - trace_print_header(seq, *prefix); - puts("}"); - break; - default: - trace_print_header(seq, *prefix); - printf("entry @ %p type %d\n", e, e->type); - break; - } -} - -void trace_buffer_print(struct trace_buffer *tb) -{ - struct trace_entry *e; - int i, prefix; - void *p; - - printf("Trace buffer dump:\n"); - printf(" address %p \n", tb); - printf(" tail %p\n", tb->tail); - printf(" size %llu\n", tb->size); - printf(" overflow %s\n", tb->overflow ? "TRUE" : "false"); - printf(" Content:\n"); - - p = tb->data; - - i = 0; - prefix = BASE_PREFIX; - - while (trace_check_bounds(tb, p) && p < tb->tail) { - e = p; - - trace_print_entry(e, i, &prefix); - - i++; - p = (void *)e + sizeof(*e) + e->length; - } -} - -void trace_print_location(struct trace_buffer *tb) -{ - printf("Trace buffer 0x%llx bytes @ %p\n", tb->size, tb); -} |