/*
 * Copyright (C) 2019, Alex Bennée <alex.bennee@linaro.org>
 *
 * Hot Pages - show which pages saw the most memory accesses.
 *
 * License: GNU GPL, version 2 or later.
 *   See the COPYING file in the top-level directory.
 */

#include <inttypes.h>
#include <assert.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <glib.h>

#include <qemu-plugin.h>

QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

static uint64_t page_size = 4096;
static uint64_t page_mask;
static int limit = 50;
static enum qemu_plugin_mem_rw rw = QEMU_PLUGIN_MEM_RW;
static bool track_io;

enum sort_type {
    SORT_RW = 0,
    SORT_R,
    SORT_W,
    SORT_A
};

static int sort_by = SORT_RW;

typedef struct {
    uint64_t page_address;
    int cpu_read;
    int cpu_write;
    uint64_t reads;
    uint64_t writes;
} PageCounters;

static GMutex lock;
static GHashTable *pages;

static gint cmp_access_count(gconstpointer a, gconstpointer b)
{
    PageCounters *ea = (PageCounters *) a;
    PageCounters *eb = (PageCounters *) b;
    int r;
    switch (sort_by) {
    case SORT_RW:
        r = (ea->reads + ea->writes) > (eb->reads + eb->writes) ? -1 : 1;
        break;
    case SORT_R:
        r = ea->reads > eb->reads ? -1 : 1;
        break;
    case SORT_W:
        r = ea->writes > eb->writes ? -1 : 1;
        break;
    case SORT_A:
        r = ea->page_address > eb->page_address ? -1 : 1;
        break;
    default:
        g_assert_not_reached();
    }
    return r;
}


static void plugin_exit(qemu_plugin_id_t id, void *p)
{
    g_autoptr(GString) report = g_string_new("Addr, RCPUs, Reads, WCPUs, Writes\n");
    int i;
    GList *counts;

    counts = g_hash_table_get_values(pages);
    if (counts && g_list_next(counts)) {
        GList *it;

        it = g_list_sort(counts, cmp_access_count);

        for (i = 0; i < limit && it->next; i++, it = it->next) {
            PageCounters *rec = (PageCounters *) it->data;
            g_string_append_printf(report,
                                   "%#016"PRIx64", 0x%04x, %"PRId64
                                   ", 0x%04x, %"PRId64"\n",
                                   rec->page_address,
                                   rec->cpu_read, rec->reads,
                                   rec->cpu_write, rec->writes);
        }
        g_list_free(it);
    }

    qemu_plugin_outs(report->str);
}

static void plugin_init(void)
{
    page_mask = (page_size - 1);
    pages = g_hash_table_new(NULL, g_direct_equal);
}

static void vcpu_haddr(unsigned int cpu_index, qemu_plugin_meminfo_t meminfo,
                       uint64_t vaddr, void *udata)
{
    struct qemu_plugin_hwaddr *hwaddr = qemu_plugin_get_hwaddr(meminfo, vaddr);
    uint64_t page;
    PageCounters *count;

    /* We only get a hwaddr for system emulation */
    if (track_io) {
        if (hwaddr && qemu_plugin_hwaddr_is_io(hwaddr)) {
            page = vaddr;
        } else {
            return;
        }
    } else {
        if (hwaddr && !qemu_plugin_hwaddr_is_io(hwaddr)) {
            page = (uint64_t) qemu_plugin_hwaddr_device_offset(hwaddr);
        } else {
            page = vaddr;
        }
    }
    page &= ~page_mask;

    g_mutex_lock(&lock);
    count = (PageCounters *) g_hash_table_lookup(pages, GUINT_TO_POINTER(page));

    if (!count) {
        count = g_new0(PageCounters, 1);
        count->page_address = page;
        g_hash_table_insert(pages, GUINT_TO_POINTER(page), (gpointer) count);
    }
    if (qemu_plugin_mem_is_store(meminfo)) {
        count->writes++;
        count->cpu_write |= (1 << cpu_index);
    } else {
        count->reads++;
        count->cpu_read |= (1 << cpu_index);
    }

    g_mutex_unlock(&lock);
}

static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
{
    size_t n = qemu_plugin_tb_n_insns(tb);
    size_t i;

    for (i = 0; i < n; i++) {
        struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
        qemu_plugin_register_vcpu_mem_cb(insn, vcpu_haddr,
                                         QEMU_PLUGIN_CB_NO_REGS,
                                         rw, NULL);
    }
}

QEMU_PLUGIN_EXPORT
int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
                        int argc, char **argv)
{
    int i;

    for (i = 0; i < argc; i++) {
        char *opt = argv[i];
        if (g_strcmp0(opt, "reads") == 0) {
            sort_by = SORT_R;
        } else if (g_strcmp0(opt, "writes") == 0) {
            sort_by = SORT_W;
        } else if (g_strcmp0(opt, "address") == 0) {
            sort_by = SORT_A;
        } else if (g_strcmp0(opt, "io") == 0) {
            track_io = true;
        } else if (g_str_has_prefix(opt, "pagesize=")) {
            page_size = g_ascii_strtoull(opt + 9, NULL, 10);
        } else {
            fprintf(stderr, "option parsing failed: %s\n", opt);
            return -1;
        }
    }

    plugin_init();

    qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
    qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
    return 0;
}
