/* TODO work out licensing  W.A. is responsible for this version */

/*
 * Local APIC virtualization
 *
 * Copyright (C) 2006 Qumranet, Inc.
 * Copyright (C) 2007 Novell
 * Copyright (C) 2007 Intel
 * Copyright 2009 Red Hat, Inc. and/or its affiliates.
 *
 * Authors:
 *   Dor Laor <dor.laor@qumranet.com>
 *   Gregory Haskins <ghaskins@novell.com>
 *   Yaozu (Eddie) Dong <eddie.dong@intel.com>
 *
 * Based on Xen 3.1 code, Copyright (c) 2004, Intel Corporation.
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <utils/util.h>

#include "vmm/debug.h"

#include "vmm/processor/lapic.h"
#include "vmm/processor/apicdef.h"
#include "vmm/processor/msr.h"
#include "vmm/mmio.h"

#define APIC_BUS_CYCLE_NS 1

#define APIC_DEBUG 0
#define apic_debug(lvl,...) do{ if(lvl < APIC_DEBUG){printf(__VA_ARGS__);fflush(stdout);}}while (0)

#define APIC_LVT_NUM            6
/* 14 is the version for Xeon and Pentium 8.4.8*/
#define APIC_VERSION            (0x14UL | ((APIC_LVT_NUM - 1) << 16))
#define LAPIC_MMIO_LENGTH       (1 << 12)
/* followed define is not in apicdef.h */
#define APIC_SHORT_MASK         0xc0000
#define APIC_DEST_NOSHORT       0x0
#define APIC_DEST_MASK          0x800
#define MAX_APIC_VECTOR         256
#define APIC_VECTORS_PER_REG        32

inline static int pic_get_interrupt(vmm_t *vmm)
{
    return vmm->plat_callbacks.get_interrupt();
}

inline static int pic_has_interrupt(vmm_t *vmm)
{
    return vmm->plat_callbacks.has_interrupt();
}

struct vmm_lapic_irq {
    uint32_t vector;
    uint32_t delivery_mode;
    uint32_t dest_mode;
    uint32_t level;
    uint32_t trig_mode;
    uint32_t shorthand;
    uint32_t dest_id;
};

/* Generic bit operations; TODO move these elsewhere */
static inline int fls(int x)
{
    int r = 32;

    if (!x)
        return 0;

    if (!(x & 0xffff0000u)) {
        x <<= 16;
        r -= 16;
    }
    if (!(x & 0xff000000u)) {
        x <<= 8;
        r -= 8;
    }
    if (!(x & 0xf0000000u)) {
        x <<= 4;
        r -= 4;
    }
    if (!(x & 0xc0000000u)) {
        x <<= 2;
        r -= 2;
    }
    if (!(x & 0x80000000u)) {
        x <<= 1;
        r -= 1;
    }
    return r;
}

static uint32_t hweight32(unsigned int w)
{
    uint32_t res = w - ((w >> 1) & 0x55555555);
    res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
    res = (res + (res >> 4)) & 0x0F0F0F0F;
    res = res + (res >> 8);
    return (res + (res >> 16)) & 0x000000FF;
}
/* End generic bit ops */

void vmm_lapic_reset(vmm_vcpu_t *vcpu);

// Returns whether the irq delivery mode is lowest prio
inline static bool vmm_is_dm_lowest_prio(struct vmm_lapic_irq *irq)
{
    return irq->delivery_mode == APIC_DM_LOWEST;
}

// Access register field
static inline void apic_set_reg(vmm_lapic_t *apic, int reg_off, uint32_t val)
{
    *((uint32_t *) (apic->regs + reg_off)) = val;
}

inline uint32_t vmm_apic_get_reg(vmm_lapic_t *apic, int reg_off)
{
    return *((uint32_t *) (apic->regs + reg_off));
}

static inline int apic_test_vector(int vec, void *bitmap)
{
    return ((1UL << (vec & 31)) & ((uint32_t *)bitmap)[vec >> 5]) != 0;
}

bool vmm_apic_pending_eoi(vmm_vcpu_t *vcpu, int vector)
{
    vmm_lapic_t *apic = vcpu->lapic;

    return apic_test_vector(vector, apic->regs + APIC_ISR) ||
        apic_test_vector(vector, apic->regs + APIC_IRR);
}

static inline void apic_set_vector(int vec, void *bitmap)
{
    ((uint32_t *)bitmap)[vec >> 5] |= 1UL << (vec & 31);
}

static inline void apic_clear_vector(int vec, void *bitmap)
{
    ((uint32_t *)bitmap)[vec >> 5] &= ~(1UL << (vec & 31));
}

inline int vmm_apic_sw_enabled(vmm_lapic_t *apic)
{
    return vmm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED;
}

inline int vmm_apic_hw_enabled(vmm_lapic_t *apic)
{
    return apic->apic_base & MSR_IA32_APICBASE_ENABLE;
}

inline int vmm_apic_enabled(vmm_lapic_t *apic)
{
    return vmm_apic_sw_enabled(apic) && vmm_apic_hw_enabled(apic);
}

#define LVT_MASK    \
    (APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK)

#define LINT_MASK   \
    (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
     APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)

static inline int vmm_apic_id(vmm_lapic_t *apic)
{
    return (vmm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
}

static inline void apic_set_spiv(vmm_lapic_t *apic, uint32_t val)
{
    apic_set_reg(apic, APIC_SPIV, val);
}

static const unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
    LVT_MASK ,      /* part LVTT mask, timer mode mask added at runtime */
    LVT_MASK | APIC_MODE_MASK,  /* LVTTHMR */
    LVT_MASK | APIC_MODE_MASK,  /* LVTPC */
    LINT_MASK, LINT_MASK,   /* LVT0-1 */
    LVT_MASK        /* LVTERR */
};

static inline void vmm_apic_set_id(vmm_lapic_t *apic, uint8_t id)
{
    apic_set_reg(apic, APIC_ID, id << 24);
}

static inline void vmm_apic_set_ldr(vmm_lapic_t *apic, uint32_t id)
{
    apic_set_reg(apic, APIC_LDR, id);
}

static inline int apic_lvt_enabled(vmm_lapic_t *apic, int lvt_type)
{
    return !(vmm_apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED);
}

static inline int apic_lvt_vector(vmm_lapic_t *apic, int lvt_type)
{
    return vmm_apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK;
}

static inline int vmm_vcpu_is_bsp(vmm_vcpu_t *vcpu)
{
    return vcpu->vcpu_id == BOOT_VCPU;
}

static inline int apic_lvt_nmi_mode(uint32_t lvt_val)
{
    return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI;
}

int vmm_apic_compare_prio(vmm_vcpu_t *vcpu1, vmm_vcpu_t *vcpu2)
{
    return vcpu1->lapic->arb_prio - vcpu2->lapic->arb_prio;
}

static void UNUSED dump_vector(const char *name, void *bitmap)
{
    int vec;
    uint32_t *reg = bitmap;
    
    printf("%s = 0x", name);

    for (vec = MAX_APIC_VECTOR - APIC_VECTORS_PER_REG;
            vec >= 0; vec -= APIC_VECTORS_PER_REG) {
        printf("%08x", reg[vec >> 5]);
    }

    printf("\n");
}


static int find_highest_vector(void *bitmap)
{
    int vec;
    uint32_t *reg = bitmap;

    for (vec = MAX_APIC_VECTOR - APIC_VECTORS_PER_REG;
         vec >= 0; vec -= APIC_VECTORS_PER_REG) {
        if (reg[vec >> 5])
            return fls(reg[vec >> 5]) - 1 + vec;
    }

    return -1;
}

static uint8_t UNUSED count_vectors(void *bitmap)
{
    int vec;
    uint32_t *reg = bitmap;
    uint8_t count = 0;

    for (vec = 0; vec < MAX_APIC_VECTOR; vec += APIC_VECTORS_PER_REG) {
        count += hweight32(reg[vec >> 5]);
    }

    return count;
}

static inline int apic_search_irr(vmm_lapic_t *apic)
{
    return find_highest_vector(apic->regs + APIC_IRR);
}

static inline int apic_find_highest_irr(vmm_lapic_t *apic)
{
    int result;

    if (!apic->irr_pending)
        return -1;

    result = apic_search_irr(apic);
    assert(result == -1 || result >= 16);

    return result;
}

static inline void apic_set_irr(int vec, vmm_lapic_t *apic)
{
    if (vec != 0x30) {
        apic_debug(5, "!settting irr 0x%x\n", vec);
    }

    apic->irr_pending = true;
    apic_set_vector(vec, apic->regs + APIC_IRR);
}

static inline void apic_clear_irr(int vec, vmm_lapic_t *apic)
{
    apic_clear_vector(vec, apic->regs + APIC_IRR);
    
    vec = apic_search_irr(apic);
    apic->irr_pending = (vec != -1);
}

static inline void apic_set_isr(int vec, vmm_lapic_t *apic)
{
    if (apic_test_vector(vec, apic->regs + APIC_ISR)) {
        return;
    }
    apic_set_vector(vec, apic->regs + APIC_ISR);

    ++apic->isr_count;
    /*
     * ISR (in service register) bit is set when injecting an interrupt.
     * The highest vector is injected. Thus the latest bit set matches
     * the highest bit in ISR.
     */
}

static inline int apic_find_highest_isr(vmm_lapic_t *apic)
{
    int result;

    /*
     * Note that isr_count is always 1, and highest_isr_cache
     * is always -1, with APIC virtualization enabled.
     */
    if (!apic->isr_count)
        return -1;
    if (apic->highest_isr_cache != -1)
        return apic->highest_isr_cache;

    result = find_highest_vector(apic->regs + APIC_ISR);
    assert(result == -1 || result >= 16);

    return result;
}

static inline void apic_clear_isr(int vec, vmm_lapic_t *apic)
{
    if (!apic_test_vector(vec, apic->regs + APIC_ISR)) {
        return;
    }
    apic_clear_vector(vec, apic->regs + APIC_ISR);

    --apic->isr_count;
    apic->highest_isr_cache = -1;
}

int vmm_lapic_find_highest_irr(vmm_vcpu_t *vcpu)
{
    int highest_irr;
    
    highest_irr = apic_find_highest_irr(vcpu->lapic);

    return highest_irr;
}

static int __apic_accept_irq(vmm_vcpu_t *vcpu, int delivery_mode,
                 int vector, int level, int trig_mode,
                 unsigned long *dest_map);

int vmm_apic_set_irq(vmm_vcpu_t *vcpu, struct vmm_lapic_irq *irq,
        unsigned long *dest_map)
{
    return __apic_accept_irq(vcpu, irq->delivery_mode, irq->vector,
            irq->level, irq->trig_mode, dest_map);
}

void vmm_apic_update_tmr(vmm_vcpu_t *vcpu, uint32_t *tmr)
{
    vmm_lapic_t *apic = vcpu->lapic;
    int i;

    for (i = 0; i < 8; i++)
        apic_set_reg(apic, APIC_TMR + 0x10 * i, tmr[i]);
}

static void apic_update_ppr(vmm_vcpu_t *vcpu)
{
    uint32_t tpr, isrv, ppr, old_ppr;
    int isr;
    vmm_lapic_t *apic = vcpu->lapic;

    old_ppr = vmm_apic_get_reg(apic, APIC_PROCPRI);
    tpr = vmm_apic_get_reg(apic, APIC_TASKPRI);
    isr = apic_find_highest_isr(apic);
    isrv = (isr != -1) ? isr : 0;

    if ((tpr & 0xf0) >= (isrv & 0xf0))
        ppr = tpr & 0xff;
    else
        ppr = isrv & 0xf0;

    apic_debug(6, "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x\n",
           apic, ppr, isr, isrv);

    if (old_ppr != ppr) {
        apic_set_reg(apic, APIC_PROCPRI, ppr);
        if (ppr < old_ppr) {
            /* Might have unmasked some pending interrupts */
            vmm_vcpu_accept_interrupt(vcpu);
        }
    }
}

static void apic_set_tpr(vmm_vcpu_t *vcpu, uint32_t tpr)
{
    apic_set_reg(vcpu->lapic, APIC_TASKPRI, tpr);
    apic_debug(3, "vcpu %d lapic TPR set to %d\n", vcpu->vcpu_id, tpr);
    apic_update_ppr(vcpu);
}

int vmm_apic_match_physical_addr(vmm_lapic_t *apic, uint16_t dest)
{
    return dest == 0xff || vmm_apic_id(apic) == dest;
}

int vmm_apic_match_logical_addr(vmm_lapic_t *apic, uint8_t mda)
{
    int result = 0;
    uint32_t logical_id;

    logical_id = GET_APIC_LOGICAL_ID(vmm_apic_get_reg(apic, APIC_LDR));

    switch (vmm_apic_get_reg(apic, APIC_DFR)) {
    case APIC_DFR_FLAT:
        if (logical_id & mda)
            result = 1;
        break;
    case APIC_DFR_CLUSTER:
        if (((logical_id >> 4) == (mda >> 0x4))
            && (logical_id & mda & 0xf))
            result = 1;
        break;
    default:
        apic_debug(1, "Bad DFR: %08x\n", vmm_apic_get_reg(apic, APIC_DFR));
        break;
    }

    return result;
}

int vmm_apic_match_dest(vmm_vcpu_t *vcpu, vmm_lapic_t *source,
               int short_hand, int dest, int dest_mode)
{
    int result = 0;
    vmm_lapic_t *target = vcpu->lapic;

    assert(target);
    switch (short_hand) {
    case APIC_DEST_NOSHORT:
        if (dest_mode == 0)
            /* Physical mode. */
            result = vmm_apic_match_physical_addr(target, dest);
        else
            /* Logical mode. */
            result = vmm_apic_match_logical_addr(target, dest);
        break;
    case APIC_DEST_SELF:
        result = (target == source);
        break;
    case APIC_DEST_ALLINC:
        result = 1;
        break;
    case APIC_DEST_ALLBUT:
        result = (target != source);
        break;
    default:
        apic_debug(2, "apic: Bad dest shorthand value %x\n",
               short_hand);
        break;
    }

    apic_debug(4, "target %p, source %p, dest 0x%x, "
           "dest_mode 0x%x, short_hand 0x%x",
           target, source, dest, dest_mode, short_hand);
    if (result) {
        apic_debug(4, " MATCH\n");
    } else {
        apic_debug(4, "\n");
    }

    return result;
}

int vmm_irq_delivery_to_apic(vmm_vcpu_t *src_vcpu, struct vmm_lapic_irq *irq, unsigned long *dest_map)
{
    int i, r = -1;
    vmm_lapic_t *src = src_vcpu->lapic;
    vmm_t *vmm = src_vcpu->vmm;
    
    vmm_vcpu_t *lowest = NULL;

    if (irq->shorthand == APIC_DEST_SELF) {
        return vmm_apic_set_irq(src_vcpu, irq, dest_map);
    }
    
    for (i = 0; i < vmm->num_vcpus; i++) {
        vmm_vcpu_t *dest_vcpu = &vmm->vcpus[i];

        if (!vmm_apic_hw_enabled(dest_vcpu->lapic)) {
            continue;
        }
    
        if (!vmm_apic_match_dest(dest_vcpu, src, irq->shorthand,
                        irq->dest_id, irq->dest_mode)) {
            continue;
        }

        if (!vmm_is_dm_lowest_prio(irq)) {
            // Normal delivery
            if (r < 0) {
                r = 0;
            }
            r += vmm_apic_set_irq(dest_vcpu, irq, dest_map);
        } else if (vmm_apic_enabled(dest_vcpu->lapic)) {
            // Pick vcpu with lowest priority to deliver to
            if (!lowest) {
                lowest = dest_vcpu;
            } else if (vmm_apic_compare_prio(dest_vcpu, lowest) < 0) {
                lowest = dest_vcpu;
            }
        }
    }
    
    if (lowest) {
        r = vmm_apic_set_irq(lowest, irq, dest_map);
    }

    return r;
}

/*
 * Add a pending IRQ into lapic.
 * Return 1 if successfully added and 0 if discarded.
 */
static int __apic_accept_irq(vmm_vcpu_t *vcpu, int delivery_mode,
                 int vector, int level, int trig_mode,
                 unsigned long *dest_map)
{
    int result = 0;
    vmm_lapic_t *apic = vcpu->lapic;

    switch (delivery_mode) {
    case APIC_DM_LOWEST:
        apic->arb_prio++;
    case APIC_DM_FIXED:
        /* FIXME add logic for vcpu on reset */
        if (!vmm_apic_enabled(apic)) {
            break;
        }
        apic_debug(4, "####fixed ipi 0x%x to vcpu %d\n", vector, vcpu->vcpu_id);

        result = 1;
        apic_set_irr(vector, apic);
        vmm_vcpu_accept_interrupt(vcpu);
        break;

    case APIC_DM_NMI:
    case APIC_DM_REMRD:
        result = 1;
        vmm_vcpu_accept_interrupt(vcpu);
        break;

    case APIC_DM_SMI:
        apic_debug(2, "Ignoring guest SMI\n");
        break;

    case APIC_DM_INIT:
        apic_debug(2, "Got init ipi on vcpu %d\n", vcpu->vcpu_id);
        if (!trig_mode || level) {
            if (apic->state == LAPIC_STATE_RUN) {
                /* Already running, ignore inits */
                break;
            }
            result = 1;
            vmm_lapic_reset(vcpu);
            apic->arb_prio = vmm_apic_id(apic);
            apic->state = LAPIC_STATE_WAITSIPI;
        } else {
            apic_debug(2, "Ignoring de-assert INIT to vcpu %d\n",
                   vcpu->vcpu_id);
        }
        break;

    case APIC_DM_STARTUP:
        if (apic->state != LAPIC_STATE_WAITSIPI) {
            apic_debug(1, "Received SIPI while processor was not in wait for SIPI state\n");
        } else {
            apic_debug(2, "SIPI to vcpu %d vector 0x%02x\n",
                   vcpu->vcpu_id, vector);
            result = 1;
            apic->sipi_vector = vector;
            apic->state = LAPIC_STATE_RUN;

            /* Start the VCPU thread. */
            vmm_start_ap_vcpu(vcpu, vector);
        }
        break;
    
    case APIC_DM_EXTINT:
        /* extints are handled by vmm_apic_consume_extints */
        printf("extint should not come to this function. vcpu %d\n", vcpu->vcpu_id);
        assert(0);
        break;
    
    default:
        printf("TODO: unsupported lapic ipi delivery mode %x", delivery_mode);
        assert(0);
        break;
    }
    return result;
}

static int apic_set_eoi(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic = vcpu->lapic;
    int vector = apic_find_highest_isr(apic);

    /*
     * Not every write EOI will has corresponding ISR,
     * one example is when Kernel check timer on setup_IO_APIC
     */
    if (vector == -1)
        return vector;

    apic_clear_isr(vector, apic);
    apic_update_ppr(vcpu);

    /* If another interrupt is pending, raise it */
    vmm_vcpu_accept_interrupt(vcpu);

    return vector;
}

static void apic_send_ipi(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic = vcpu->lapic;
    uint32_t icr_low = vmm_apic_get_reg(apic, APIC_ICR);
    uint32_t icr_high = vmm_apic_get_reg(apic, APIC_ICR2);
    struct vmm_lapic_irq irq;

    irq.vector = icr_low & APIC_VECTOR_MASK;
    irq.delivery_mode = icr_low & APIC_MODE_MASK;
    irq.dest_mode = icr_low & APIC_DEST_MASK;
    irq.level = icr_low & APIC_INT_ASSERT;
    irq.trig_mode = icr_low & APIC_INT_LEVELTRIG;
    irq.shorthand = icr_low & APIC_SHORT_MASK;
    irq.dest_id = GET_APIC_DEST_FIELD(icr_high);

    apic_debug(3, "icr_high 0x%x, icr_low 0x%x, "
           "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
           "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
           icr_high, icr_low, irq.shorthand, irq.dest_id,
           irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode,
           irq.vector);

    vmm_irq_delivery_to_apic(vcpu, &irq, NULL);
}

static uint32_t __apic_read(vmm_lapic_t *apic, unsigned int offset)
{
    uint32_t val = 0;

    if (offset >= LAPIC_MMIO_LENGTH)
        return 0;

    switch (offset) {
    case APIC_ID:
        val = vmm_apic_id(apic) << 24;
        break;
    case APIC_ARBPRI:
        apic_debug(2, "Access APIC ARBPRI register which is for P6\n");
        break;

    case APIC_TMCCT:    /* Timer CCR */
        break;
    case APIC_PROCPRI:
        val = vmm_apic_get_reg(apic, offset);
        break;
    default:
        val = vmm_apic_get_reg(apic, offset);
        break;
    }

    return val;
}

static void apic_manage_nmi_watchdog(vmm_lapic_t *apic, uint32_t lvt0_val)
{
    int nmi_wd_enabled = apic_lvt_nmi_mode(vmm_apic_get_reg(apic, APIC_LVT0));

    if (apic_lvt_nmi_mode(lvt0_val)) {
        if (!nmi_wd_enabled) {
            apic_debug(4, "Receive NMI setting on APIC_LVT0 \n");
        }
    }
}

static int apic_reg_write(vmm_vcpu_t *vcpu, uint32_t reg, uint32_t val)
{
    vmm_lapic_t *apic = vcpu->lapic;
    int ret = 0;

    switch (reg) {
    case APIC_ID:       /* Local APIC ID */
        vmm_apic_set_id(apic, val >> 24);
        break;

    case APIC_TASKPRI:
        apic_set_tpr(vcpu, val & 0xff);
        break;

    case APIC_EOI:
        apic_set_eoi(vcpu);
        break;

    case APIC_LDR:
        vmm_apic_set_ldr(apic, val & APIC_LDR_MASK);
        break;

    case APIC_DFR:
        apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
        break;

    case APIC_SPIV: {
        uint32_t mask = 0x3ff;
        if (vmm_apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI)
            mask |= APIC_SPIV_DIRECTED_EOI;
        apic_set_spiv(apic, val & mask);
        if (!(val & APIC_SPIV_APIC_ENABLED)) {
            int i;
            uint32_t lvt_val;

            for (i = 0; i < APIC_LVT_NUM; i++) {
                lvt_val = vmm_apic_get_reg(apic,
                               APIC_LVTT + 0x10 * i);
                apic_set_reg(apic, APIC_LVTT + 0x10 * i,
                         lvt_val | APIC_LVT_MASKED);
            }
        //    atomic_set(&apic->lapic_timer.pending, 0);

        }
        break;
    }
    case APIC_ICR:
        /* No delay here, so we always clear the pending bit */
        apic_set_reg(apic, APIC_ICR, val & ~(1 << 12));
        apic_send_ipi(vcpu);
        break;

    case APIC_ICR2:
        val &= 0xff000000;
        apic_set_reg(apic, APIC_ICR2, val);
        break;

    case APIC_LVT0:
        apic_manage_nmi_watchdog(apic, val);
    case APIC_LVTTHMR:
    case APIC_LVTPC:
    case APIC_LVT1:
    case APIC_LVTERR:
        /* TODO: Check vector */
        if (!vmm_apic_sw_enabled(apic))
            val |= APIC_LVT_MASKED;

        val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
        apic_set_reg(apic, reg, val);

        break;

    case APIC_LVTT:
        apic_set_reg(apic, APIC_LVTT, val);
        break;

    case APIC_TMICT:
        apic_set_reg(apic, APIC_TMICT, val);
        break;

    case APIC_TDCR:
        apic_set_reg(apic, APIC_TDCR, val);
        break;
    
    default:
        ret = 1;
        break;
    }
    if (ret)
        apic_debug(2, "Local APIC Write to read-only register %x\n", reg);
    return ret;
}

void vmm_apic_mmio_write(vmm_vcpu_t *vcpu, void *cookie, uint32_t offset,
        int len, const uint32_t data)
{
    (void)cookie;

    /*
     * APIC register must be aligned on 128-bits boundary.
     * 32/64/128 bits registers must be accessed thru 32 bits.
     * Refer SDM 8.4.1
     */
    if (len != 4 || (offset & 0xf)) {
        apic_debug(1, "apic write: bad size=%d %x\n", len, offset);
        return;
    }

    /* too common printing */
    if (offset != APIC_EOI)
        apic_debug(6, "lapic mmio write at %s: offset 0x%x with length 0x%x, and value is "
               "0x%x\n", __func__, offset, len, data);

    apic_reg_write(vcpu, offset & 0xff0, data);
}

static int apic_reg_read(vmm_lapic_t *apic, uint32_t offset, int len,
        void *data)
{
    unsigned char alignment = offset & 0xf;
    uint32_t result;
    /* this bitmask has a bit cleared for each reserved register */
    static const uint64_t rmask = 0x43ff01ffffffe70cULL;

    if ((alignment + len) > 4) {
        apic_debug(2, "APIC READ: alignment error %x %d\n",
               offset, len);
        return 1;
    }

    if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) {
        apic_debug(2, "APIC_READ: read reserved register %x\n",
               offset);
        return 1;
    }

    result = __apic_read(apic, offset & ~0xf);

    switch (len) {
    case 1:
    case 2:
    case 4:
        memcpy(data, (char *)&result + alignment, len);
        break;
    default:
        apic_debug(2, "Local APIC read with len = %x, "
               "should be 1,2, or 4 instead\n", len);
        break;
    }
    return 0;
}

void vmm_apic_mmio_read(vmm_vcpu_t *vcpu, void *cookie, uint32_t offset,
        int len, uint32_t *data)
{
    vmm_lapic_t *apic = vcpu->lapic;
    (void)cookie;

    apic_reg_read(apic, offset, len, data);

    apic_debug(6, "lapic mmio read on vcpu %d, reg %08x = %08x\n", vcpu->vcpu_id, offset, *data);

    return;
}

void vmm_free_lapic(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic = vcpu->lapic;

    if (!apic)
        return;

    if (apic->regs) {
        free(apic->regs);
    }

    free(apic);
}

void vmm_lapic_set_base_msr(vmm_vcpu_t *vcpu, uint32_t value)
{
    apic_debug(2, "IA32_APIC_BASE MSR set to %08x on vcpu %d\n", value, vcpu->vcpu_id);

    if (!(value & MSR_IA32_APICBASE_ENABLE)) {
        printf("Warning! Local apic has been disabled by MSR on vcpu %d. "
               "This will probably not work!\n", vcpu->vcpu_id);
    }

    vcpu->lapic->apic_base = value;
}

uint32_t vmm_lapic_get_base_msr(vmm_vcpu_t *vcpu)
{
    uint32_t value = vcpu->lapic->apic_base;

    if (vmm_vcpu_is_bsp(vcpu)) {
        value |= MSR_IA32_APICBASE_BSP;
    } else {
        value &= ~MSR_IA32_APICBASE_BSP;
    }

    apic_debug(2, "Read from IA32_APIC_BASE MSR returns %08x on vcpu %d\n", value, vcpu->vcpu_id);

    return value;   
}

void vmm_lapic_reset(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic;
    int i;

    apic_debug(4, "%s\n", __func__);

    assert(vcpu);
    apic = vcpu->lapic;
    assert(apic != NULL);

    /* Stop the timer in case it's a reset to an active apic */

    vmm_apic_set_id(apic, vcpu->vcpu_id); /* In agreement with ACPI code */
    apic_set_reg(apic, APIC_LVR, APIC_VERSION);

    for (i = 0; i < APIC_LVT_NUM; i++)
        apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);

    apic_set_reg(apic, APIC_DFR, 0xffffffffU);
    apic_set_spiv(apic, 0xff);
    apic_set_reg(apic, APIC_TASKPRI, 0);
    vmm_apic_set_ldr(apic, 0);
    apic_set_reg(apic, APIC_ESR, 0);
    apic_set_reg(apic, APIC_ICR, 0);
    apic_set_reg(apic, APIC_ICR2, 0);
    apic_set_reg(apic, APIC_TDCR, 0);
    apic_set_reg(apic, APIC_TMICT, 0);
    for (i = 0; i < 8; i++) {
        apic_set_reg(apic, APIC_IRR + 0x10 * i, 0);
        apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
        apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
    }
    apic->irr_pending = 0;
    apic->isr_count = 0;
    apic->highest_isr_cache = -1;
    apic_update_ppr(vcpu);

    vcpu->lapic->arb_prio = 0;

    apic_debug(4, "%s: vcpu=%p, id=%d, base_msr="
           "0x%016x\n", __func__,
           vcpu, vmm_apic_id(apic),
           apic->apic_base);

    if (vcpu->vcpu_id == BOOT_VCPU) {
        /* Bootstrap boot vcpu lapic in virtual wire mode */
        apic_set_reg(apic, APIC_LVT0,
             SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
        apic_set_reg(apic, APIC_SPIV, APIC_SPIV_APIC_ENABLED);

        assert(vmm_apic_sw_enabled(apic));
    } else {
        apic_set_reg(apic, APIC_SPIV, 0);
    }
}

int vmm_create_lapic(vmm_vcpu_t *vcpu, int enabled)
{
    vmm_lapic_t *apic;

    assert(vcpu != NULL);
    apic_debug(2, "apic_init %d\n", vcpu->vcpu_id);

    apic = malloc(sizeof(*apic));
    if (!apic)
        goto nomem;

    vcpu->lapic = apic;

    apic->regs = malloc(sizeof(struct local_apic_regs)); // TODO this is a page; allocate a page
    if (!apic->regs) {
        printf("malloc apic regs error for vcpu %x\n",
               vcpu->vcpu_id);
        goto nomem_free_apic;
    }

    if (enabled) {
        vmm_lapic_set_base_msr(vcpu, APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE);
    } else {
        vmm_lapic_set_base_msr(vcpu, APIC_DEFAULT_PHYS_BASE);
    }

    /* mainly init registers */
    vmm_lapic_reset(vcpu);

    return 0;
nomem_free_apic:
    free(apic);
nomem:
    return -1;
}

/* Return 1 if this vcpu should accept a PIC interrupt */
int vmm_apic_accept_pic_intr(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic = vcpu->lapic;
    uint32_t lvt0 = vmm_apic_get_reg(apic, APIC_LVT0);

    return ((lvt0 & APIC_LVT_MASKED) == 0 &&
        GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT &&
        vmm_apic_sw_enabled(vcpu->lapic));
}

/* Service an interrupt */
int vmm_apic_get_interrupt(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic = vcpu->lapic;
    int vector = vmm_apic_has_interrupt(vcpu);
    
    if (vector == 1) {
        return pic_get_interrupt(vcpu->vmm);
    } else if (vector == -1) {
        return -1;
    }

    apic_set_isr(vector, apic);
    apic_update_ppr(vcpu);
    apic_clear_irr(vector, apic);
    return vector;
}

/* Return which vector is next up for servicing */
int vmm_apic_has_interrupt(vmm_vcpu_t *vcpu)
{
    vmm_lapic_t *apic = vcpu->lapic;
    int highest_irr;

    if (vmm_apic_accept_pic_intr(vcpu) && pic_has_interrupt(vcpu->vmm)) {
        return 1;
    }

    highest_irr = apic_find_highest_irr(apic);
    if ((highest_irr == -1) ||
        ((highest_irr & 0xF0) <= vmm_apic_get_reg(apic, APIC_PROCPRI))) {
        return -1;
    }

    return highest_irr;
}

#if 0
int vmm_apic_local_deliver(vmm_vcpu_t *vcpu, int lvt_type)
{
    vmm_lapic_t *apic = vcpu->lapic;
    uint32_t reg = vmm_apic_get_reg(apic, lvt_type);
    int vector, mode, trig_mode;

    if (!(reg & APIC_LVT_MASKED)) {
        vector = reg & APIC_VECTOR_MASK;
        mode = reg & APIC_MODE_MASK;
        trig_mode = reg & APIC_LVT_LEVEL_TRIGGER;
        return __apic_accept_irq(vcpu, mode, vector, 1, trig_mode, NULL);
    }
    return 0;
}
#endif

