/*
 * PMU emulation helpers for TCG IBM POWER chips
 *
 *  Copyright IBM Corp. 2021
 *
 * Authors:
 *  Daniel Henrique Barboza      <danielhb413@gmail.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "helper_regs.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "hw/ppc/ppc.h"
#include "power8-pmu.h"

#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)

static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn)
{
    if (sprn == SPR_POWER_PMC1) {
        return env->spr[SPR_POWER_MMCR0] & MMCR0_PMC1CE;
    }

    return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
}

/*
 * Called after MMCR0 or MMCR1 changes to update pmc_ins_cnt and pmc_cyc_cnt.
 * hflags must subsequently be updated.
 */
static void pmu_update_summaries(CPUPPCState *env)
{
    target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
    target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
    int ins_cnt = 0;
    int cyc_cnt = 0;

    if (mmcr0 & MMCR0_FC) {
        goto out;
    }

    if (!(mmcr0 & MMCR0_FC14) && mmcr1 != 0) {
        target_ulong sel;

        sel = extract64(mmcr1, MMCR1_PMC1EVT_EXTR, MMCR1_EVT_SIZE);
        switch (sel) {
        case 0x02:
        case 0xfe:
            ins_cnt |= 1 << 1;
            break;
        case 0x1e:
        case 0xf0:
            cyc_cnt |= 1 << 1;
            break;
        }

        sel = extract64(mmcr1, MMCR1_PMC2EVT_EXTR, MMCR1_EVT_SIZE);
        ins_cnt |= (sel == 0x02) << 2;
        cyc_cnt |= (sel == 0x1e) << 2;

        sel = extract64(mmcr1, MMCR1_PMC3EVT_EXTR, MMCR1_EVT_SIZE);
        ins_cnt |= (sel == 0x02) << 3;
        cyc_cnt |= (sel == 0x1e) << 3;

        sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
        ins_cnt |= ((sel == 0xfa) || (sel == 0x2)) << 4;
        cyc_cnt |= (sel == 0x1e) << 4;
    }

    ins_cnt |= !(mmcr0 & MMCR0_FC56) << 5;
    cyc_cnt |= !(mmcr0 & MMCR0_FC56) << 6;

 out:
    env->pmc_ins_cnt = ins_cnt;
    env->pmc_cyc_cnt = cyc_cnt;
}

static void hreg_bhrb_filter_update(CPUPPCState *env)
{
    target_long ifm;

    if (!(env->spr[SPR_POWER_MMCR0] & MMCR0_PMAE)) {
        /* disable recording to BHRB */
        env->bhrb_filter = BHRB_TYPE_NORECORD;
        return;
    }

    ifm = (env->spr[SPR_POWER_MMCRA] & MMCRA_IFM_MASK) >> MMCRA_IFM_SHIFT;
    switch (ifm) {
    case 0:
        /* record all branches */
        env->bhrb_filter = -1;
        break;
    case 1:
        /* only record calls (LK = 1) */
        env->bhrb_filter = BHRB_TYPE_CALL;
        break;
    case 2:
        /* only record indirect branches */
        env->bhrb_filter = BHRB_TYPE_INDIRECT;
        break;
    case 3:
        /* only record conditional branches */
        env->bhrb_filter = BHRB_TYPE_COND;
        break;
    }
}

void pmu_mmcr01a_updated(CPUPPCState *env)
{
    PowerPCCPU *cpu = env_archcpu(env);

    pmu_update_summaries(env);
    hreg_update_pmu_hflags(env);

    if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMAO) {
        ppc_set_irq(cpu, PPC_INTERRUPT_PERFM, 1);
    } else {
        ppc_set_irq(cpu, PPC_INTERRUPT_PERFM, 0);
    }

    hreg_bhrb_filter_update(env);

    /*
     * Should this update overflow timers (if mmcr0 is updated) so they
     * get set in cpu_post_load?
     */
}

static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns)
{
    target_ulong mmcr0 = env->spr[SPR_POWER_MMCR0];
    unsigned ins_cnt = env->pmc_ins_cnt;
    bool overflow_triggered = false;
    target_ulong tmp;

    if (ins_cnt & (1 << 1)) {
        tmp = env->spr[SPR_POWER_PMC1];
        tmp += num_insns;
        if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) {
            tmp = PMC_COUNTER_NEGATIVE_VAL;
            overflow_triggered = true;
        }
        env->spr[SPR_POWER_PMC1] = tmp;
    }

    if (ins_cnt & (1 << 2)) {
        tmp = env->spr[SPR_POWER_PMC2];
        tmp += num_insns;
        if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
            tmp = PMC_COUNTER_NEGATIVE_VAL;
            overflow_triggered = true;
        }
        env->spr[SPR_POWER_PMC2] = tmp;
    }

    if (ins_cnt & (1 << 3)) {
        tmp = env->spr[SPR_POWER_PMC3];
        tmp += num_insns;
        if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
            tmp = PMC_COUNTER_NEGATIVE_VAL;
            overflow_triggered = true;
        }
        env->spr[SPR_POWER_PMC3] = tmp;
    }

    if (ins_cnt & (1 << 4)) {
        target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1];
        int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE);
        if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) {
            tmp = env->spr[SPR_POWER_PMC4];
            tmp += num_insns;
            if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
                tmp = PMC_COUNTER_NEGATIVE_VAL;
                overflow_triggered = true;
            }
            env->spr[SPR_POWER_PMC4] = tmp;
        }
    }

    if (ins_cnt & (1 << 5)) {
        tmp = env->spr[SPR_POWER_PMC5];
        tmp += num_insns;
        if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) {
            tmp = PMC_COUNTER_NEGATIVE_VAL;
            overflow_triggered = true;
        }
        env->spr[SPR_POWER_PMC5] = tmp;
    }

    return overflow_triggered;
}

static void pmu_update_cycles(CPUPPCState *env)
{
    uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    uint64_t time_delta = now - env->pmu_base_time;
    int sprn, cyc_cnt = env->pmc_cyc_cnt;

    for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
        if (cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) {
            /*
             * The pseries and powernv clock runs at 1Ghz, meaning
             * that 1 nanosec equals 1 cycle.
             */
            env->spr[sprn] += time_delta;
        }
    }

    /* Update base_time for future calculations */
    env->pmu_base_time = now;
}

/*
 * Helper function to retrieve the cycle overflow timer of the
 * 'sprn' counter.
 */
static QEMUTimer *get_cyc_overflow_timer(CPUPPCState *env, int sprn)
{
    return env->pmu_cyc_overflow_timers[sprn - SPR_POWER_PMC1];
}

static void pmc_update_overflow_timer(CPUPPCState *env, int sprn)
{
    QEMUTimer *pmc_overflow_timer = get_cyc_overflow_timer(env, sprn);
    int64_t timeout;

    /*
     * PMC5 does not have an overflow timer and this pointer
     * will be NULL.
     */
    if (!pmc_overflow_timer) {
        return;
    }

    if (!(env->pmc_cyc_cnt & (1 << (sprn - SPR_POWER_PMC1 + 1))) ||
        !pmc_has_overflow_enabled(env, sprn)) {
        /* Overflow timer is not needed for this counter */
        timer_del(pmc_overflow_timer);
        return;
    }

    if (env->spr[sprn] >= PMC_COUNTER_NEGATIVE_VAL) {
        timeout = 0;
    } else {
        timeout = PMC_COUNTER_NEGATIVE_VAL - env->spr[sprn];
    }

    /*
     * Use timer_mod_anticipate() because an overflow timer might
     * be already running for this PMC.
     */
    timer_mod_anticipate(pmc_overflow_timer, env->pmu_base_time + timeout);
}

static void pmu_update_overflow_timers(CPUPPCState *env)
{
    int sprn;

    /*
     * Scroll through all PMCs and start counter overflow timers for
     * PM_CYC events, if needed.
     */
    for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
        pmc_update_overflow_timer(env, sprn);
    }
}

static void pmu_delete_timers(CPUPPCState *env)
{
    QEMUTimer *pmc_overflow_timer;
    int sprn;

    for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
        pmc_overflow_timer = get_cyc_overflow_timer(env, sprn);

        if (pmc_overflow_timer) {
            timer_del(pmc_overflow_timer);
        }
    }
}

void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
{
    pmu_update_cycles(env);

    env->spr[SPR_POWER_MMCR0] = value;

    pmu_mmcr01a_updated(env);

    /* Update cycle overflow timers with the current MMCR0 state */
    pmu_update_overflow_timers(env);
}

void helper_store_mmcr1(CPUPPCState *env, uint64_t value)
{
    pmu_update_cycles(env);

    env->spr[SPR_POWER_MMCR1] = value;

    pmu_mmcr01a_updated(env);
}

void helper_store_mmcrA(CPUPPCState *env, uint64_t value)
{
    env->spr[SPR_POWER_MMCRA] = value;

    pmu_mmcr01a_updated(env);
}

target_ulong helper_read_pmc(CPUPPCState *env, uint32_t sprn)
{
    pmu_update_cycles(env);

    return env->spr[sprn];
}

void helper_store_pmc(CPUPPCState *env, uint32_t sprn, uint64_t value)
{
    pmu_update_cycles(env);

    env->spr[sprn] = (uint32_t)value;

    pmc_update_overflow_timer(env, sprn);
}

static void perfm_alert(PowerPCCPU *cpu)
{
    CPUPPCState *env = &cpu->env;

    pmu_update_cycles(env);

    if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCECE) {
        env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;

        /* Changing MMCR0_FC requires summaries and hflags update */
        pmu_mmcr01a_updated(env);

        /*
         * Delete all pending timers if we need to freeze
         * the PMC. We'll restart them when the PMC starts
         * running again.
         */
        pmu_delete_timers(env);
    }

    if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMAE) {
        /* These MMCR0 bits do not require summaries or hflags update. */
        env->spr[SPR_POWER_MMCR0] &= ~MMCR0_PMAE;
        env->spr[SPR_POWER_MMCR0] |= MMCR0_PMAO;
        ppc_set_irq(cpu, PPC_INTERRUPT_PERFM, 1);
    }

    raise_ebb_perfm_exception(env);
}

void helper_handle_pmc5_overflow(CPUPPCState *env)
{
    env->spr[SPR_POWER_PMC5] = PMC_COUNTER_NEGATIVE_VAL;
    perfm_alert(env_archcpu(env));
}

/* This helper assumes that the PMC is running. */
void helper_insns_inc(CPUPPCState *env, uint32_t num_insns)
{
    bool overflow_triggered;

    overflow_triggered = pmu_increment_insns(env, num_insns);
    if (overflow_triggered) {
        perfm_alert(env_archcpu(env));
    }
}

static void cpu_ppc_pmu_timer_cb(void *opaque)
{
    PowerPCCPU *cpu = opaque;

    perfm_alert(cpu);
}

void cpu_ppc_pmu_init(CPUPPCState *env)
{
    PowerPCCPU *cpu = env_archcpu(env);
    int i, sprn;

    for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC6; sprn++) {
        if (sprn == SPR_POWER_PMC5) {
            continue;
        }

        i = sprn - SPR_POWER_PMC1;

        env->pmu_cyc_overflow_timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                                       &cpu_ppc_pmu_timer_cb,
                                                       cpu);
    }
}
#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
