/*
 *  HPPA interrupt helper routines
 *
 *  Copyright (c) 2017 Richard Henderson
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "migration/cpu.h"


static int get_psw(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field)
{
    CPUHPPAState *env = opaque;
    cpu_hppa_put_psw(env, qemu_get_be64(f));
    return 0;
}

static int put_psw(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field, JSONWriter *vmdesc)
{
    CPUHPPAState *env = opaque;
    qemu_put_be64(f, cpu_hppa_get_psw(env));
    return 0;
}

static const VMStateInfo vmstate_psw = {
    .name = "psw",
    .get = get_psw,
    .put = put_psw,
};

static int get_tlb(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field)
{
    HPPATLBEntry *ent = opaque;
    uint64_t val;

    ent->itree.start = qemu_get_be64(f);
    ent->itree.last = qemu_get_be64(f);
    ent->pa = qemu_get_be64(f);
    val = qemu_get_be64(f);

    if (val) {
        ent->t = extract64(val, 61, 1);
        ent->d = extract64(val, 60, 1);
        ent->b = extract64(val, 59, 1);
        ent->ar_type = extract64(val, 56, 3);
        ent->ar_pl1 = extract64(val, 54, 2);
        ent->ar_pl2 = extract64(val, 52, 2);
        ent->u = extract64(val, 51, 1);
        /* o = bit 50 */
        /* p = bit 49 */
        ent->access_id = extract64(val, 1, 31);
        ent->entry_valid = 1;
    }
    return 0;
}

static int put_tlb(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field, JSONWriter *vmdesc)
{
    HPPATLBEntry *ent = opaque;
    uint64_t val = 0;

    if (ent->entry_valid) {
        val = 1;
        val = deposit64(val, 61, 1, ent->t);
        val = deposit64(val, 60, 1, ent->d);
        val = deposit64(val, 59, 1, ent->b);
        val = deposit64(val, 56, 3, ent->ar_type);
        val = deposit64(val, 54, 2, ent->ar_pl1);
        val = deposit64(val, 52, 2, ent->ar_pl2);
        val = deposit64(val, 51, 1, ent->u);
        /* o = bit 50 */
        /* p = bit 49 */
        val = deposit64(val, 1, 31, ent->access_id);
    }

    qemu_put_be64(f, ent->itree.start);
    qemu_put_be64(f, ent->itree.last);
    qemu_put_be64(f, ent->pa);
    qemu_put_be64(f, val);
    return 0;
}

static const VMStateInfo vmstate_tlb_entry = {
    .name = "tlb entry",
    .get = get_tlb,
    .put = put_tlb,
};

static int tlb_pre_load(void *opaque)
{
    CPUHPPAState *env = opaque;

    /*
     * Zap the entire tlb, on-the-side data structures and all.
     * Each tlb entry will have data re-filled by put_tlb.
     */
    memset(env->tlb, 0, sizeof(env->tlb));
    memset(&env->tlb_root, 0, sizeof(env->tlb_root));
    env->tlb_unused = NULL;
    env->tlb_partial = NULL;

    return 0;
}

static int tlb_post_load(void *opaque, int version_id)
{
    CPUHPPAState *env = opaque;
    uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);
    HPPATLBEntry **unused = &env->tlb_unused;
    HPPATLBEntry *partial = NULL;

    /*
     * Re-create the interval tree from the valid entries.
     * Truely invalid entries should have start == end == 0.
     * Otherwise it should be the in-flight tlb_partial entry.
     */
    for (uint32_t i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
        HPPATLBEntry *e = &env->tlb[i];

        if (e->entry_valid) {
            interval_tree_insert(&e->itree, &env->tlb_root);
        } else if (i < btlb_entries) {
            /* btlb not in unused list */
        } else if (partial == NULL && e->itree.start < e->itree.last) {
            partial = e;
        } else {
            *unused = e;
            unused = &e->unused_next;
        }
    }
    env->tlb_partial = partial;
    *unused = NULL;

    return 0;
}

static const VMStateField vmstate_tlb_fields[] = {
    VMSTATE_ARRAY(tlb, CPUHPPAState,
                  ARRAY_SIZE(((CPUHPPAState *)0)->tlb),
                  0, vmstate_tlb_entry, HPPATLBEntry),
    VMSTATE_UINT32(tlb_last, CPUHPPAState),
    VMSTATE_END_OF_LIST()
};

static const VMStateDescription vmstate_tlb = {
    .name = "env/tlb",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = vmstate_tlb_fields,
    .pre_load = tlb_pre_load,
    .post_load = tlb_post_load,
};

static const VMStateField vmstate_env_fields[] = {
    VMSTATE_UINT64_ARRAY(gr, CPUHPPAState, 32),
    VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32),
    VMSTATE_UINT64_ARRAY(sr, CPUHPPAState, 8),
    VMSTATE_UINT64_ARRAY(cr, CPUHPPAState, 32),
    VMSTATE_UINT64_ARRAY(cr_back, CPUHPPAState, 2),
    VMSTATE_UINT64_ARRAY(shadow, CPUHPPAState, 7),

    /* Save the architecture value of the psw, not the internally
       expanded version.  Since this architecture value does not
       exist in memory to be stored, this requires a but of hoop
       jumping.  We want OFFSET=0 so that we effectively pass ENV
       to the helper functions, and we need to fill in the name by
       hand since there's no field of that name.  */
    {
        .name = "psw",
        .version_id = 0,
        .size = sizeof(uint64_t),
        .info = &vmstate_psw,
        .flags = VMS_SINGLE,
        .offset = 0
    },

    VMSTATE_UINT64(iaoq_f, CPUHPPAState),
    VMSTATE_UINT64(iaoq_b, CPUHPPAState),
    VMSTATE_UINT64(iasq_f, CPUHPPAState),
    VMSTATE_UINT64(iasq_b, CPUHPPAState),

    VMSTATE_UINT32(fr0_shadow, CPUHPPAState),
    VMSTATE_END_OF_LIST()
};

static const VMStateDescription *vmstate_env_subsections[] = {
    &vmstate_tlb,
    NULL
};

static const VMStateDescription vmstate_env = {
    .name = "env",
    .version_id = 3,
    .minimum_version_id = 3,
    .fields = vmstate_env_fields,
    .subsections = vmstate_env_subsections,
};

static const VMStateField vmstate_cpu_fields[] = {
    VMSTATE_CPU(),
    VMSTATE_STRUCT(env, HPPACPU, 1, vmstate_env, CPUHPPAState),
    VMSTATE_END_OF_LIST()
};

const VMStateDescription vmstate_hppa_cpu = {
    .name = "cpu",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = vmstate_cpu_fields,
};
