// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <platform/pc/hpet.h>

#include <bits.h>
#include <err.h>
#include <fbl/algorithm.h>
#include <kernel/auto_lock.h>
#include <kernel/spinlock.h>
#include <lk/init.h>
#include <vm/vm_aspace.h>
#include <zircon/types.h>

struct hpet_timer_registers {
    volatile uint64_t conf_caps;
    volatile uint64_t comparator_value;
    volatile uint64_t fsb_int_route;
    uint8_t _reserved[8];
} __PACKED;

struct hpet_registers {
    volatile uint64_t general_caps;
    uint8_t _reserved0[8];
    volatile uint64_t general_config;
    uint8_t _reserved1[8];
    volatile uint64_t general_int_status;
    uint8_t _reserved2[0xf0 - 0x28];
    volatile uint64_t main_counter_value;
    uint8_t _reserved3[8];
    struct hpet_timer_registers timers[];
} __PACKED;

static spin_lock_t lock = SPIN_LOCK_INITIAL_VALUE;

static struct acpi_hpet_descriptor hpet_desc;
static bool hpet_present = false;
static struct hpet_registers* hpet_regs;
uint64_t _hpet_ticks_per_ms;
static uint64_t tick_period_in_fs;
static uint8_t num_timers;

/* Minimum number of ticks ahead a oneshot timer needs to be.  Targetted
 * to be 100ns */
static uint64_t min_ticks_ahead;

#define MAX_PERIOD_IN_FS 0x05F5E100ULL

/* Bit masks for the general_config register */
#define GEN_CONF_EN 1

/* Bit masks for the per-time conf_caps register */
#define TIMER_CONF_LEVEL_TRIGGERED (1ULL << 1)
#define TIMER_CONF_INT_EN (1ULL << 2)
#define TIMER_CONF_PERIODIC (1ULL << 3)
#define TIMER_CAP_PERIODIC(reg) BIT_SET(reg, 4)
#define TIMER_CAP_64BIT(reg) BIT_SET(reg, 5)
#define TIMER_CONF_PERIODIC_SET_COUNT (1ULL << 6)
#define TIMER_CONF_IRQ(n) ((uint64_t)((n) & (0x1f)) << 9)
#define TIMER_CAP_IRQS(reg) static_cast<uint32_t>(BITS_SHIFT(reg, 63, 32))

static void hpet_init(uint level) {
    zx_status_t status = platform_find_hpet(&hpet_desc);
    if (status != ZX_OK) {
        return;
    }

    if (hpet_desc.port_io) {
        return;
    }

    zx_status_t res = VmAspace::kernel_aspace()->AllocPhysical(
        "hpet",
        PAGE_SIZE,                  /* size */
        (void**)&hpet_regs,         /* returned virtual address */
        PAGE_SIZE_SHIFT,            /* alignment log2 */
        (paddr_t)hpet_desc.address, /* physical address */
        0,                          /* vmm flags */
        ARCH_MMU_FLAG_UNCACHED_DEVICE | ARCH_MMU_FLAG_PERM_READ |
            ARCH_MMU_FLAG_PERM_WRITE);
    if (res != ZX_OK) {
        return;
    }

    bool has_64bit_count = BIT_SET(hpet_regs->general_caps, 13);
    tick_period_in_fs = hpet_regs->general_caps >> 32;
    if (tick_period_in_fs == 0 || tick_period_in_fs > MAX_PERIOD_IN_FS) {
        goto fail;
    }

    /* We only support HPETs that are 64-bit and have at least two timers */
    num_timers = static_cast<uint8_t>(BITS_SHIFT(hpet_regs->general_caps, 12, 8) + 1);
    if (!has_64bit_count || num_timers < 2) {
        goto fail;
    }

    /* Make sure all timers have interrupts disabled */
    for (uint8_t i = 0; i < num_timers; ++i) {
        hpet_regs->timers[i].conf_caps &= ~TIMER_CONF_INT_EN;
    }

    _hpet_ticks_per_ms = 1000000000000ULL / tick_period_in_fs;
    min_ticks_ahead = 100000000ULL / tick_period_in_fs;
    hpet_present = true;
    return;

fail:
    VmAspace::kernel_aspace()->FreeRegion(reinterpret_cast<vaddr_t>(hpet_regs));
    hpet_regs = nullptr;
    num_timers = 0;
}
/* Begin running after ACPI tables are up */
LK_INIT_HOOK(hpet, hpet_init, LK_INIT_LEVEL_VM + 2);

zx_status_t hpet_timer_disable(uint n) {
    if (unlikely(n >= num_timers)) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    AutoSpinLockNoIrqSave guard(&lock);
    hpet_regs->timers[n].conf_caps &= ~TIMER_CONF_INT_EN;

    return ZX_OK;
}

uint64_t hpet_get_value(void) {
    uint64_t v = hpet_regs->main_counter_value;
    uint64_t v2 = hpet_regs->main_counter_value;
    /* Even though the specification says it should not be necessary to read
     * multiple times, we have observed that QEMU converts the 64-bit
     * memory access in to two 32-bit accesses, resulting in bad reads. QEMU
     * reads the low 32-bits first, so the result is a large jump when it
     * wraps 32 bits.  To work around this, we return the lesser of two reads.
     */
    return fbl::min(v, v2);
}

zx_status_t hpet_set_value(uint64_t v) {
    AutoSpinLockNoIrqSave guard(&lock);

    if (hpet_regs->general_config & GEN_CONF_EN) {
        return ZX_ERR_BAD_STATE;
    }

    hpet_regs->main_counter_value = v;
    return ZX_OK;
}

zx_status_t hpet_timer_configure_irq(uint n, uint irq) {
    if (unlikely(n >= num_timers)) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    AutoSpinLockNoIrqSave guard(&lock);

    uint32_t irq_bitmap = TIMER_CAP_IRQS(hpet_regs->timers[n].conf_caps);
    if (irq >= 32 || !BIT_SET(irq_bitmap, irq)) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint64_t conf = hpet_regs->timers[n].conf_caps;
    conf &= ~TIMER_CONF_IRQ(~0ULL);
    conf |= TIMER_CONF_IRQ(irq);
    hpet_regs->timers[n].conf_caps = conf;

    return ZX_OK;
}

zx_status_t hpet_timer_set_oneshot(uint n, uint64_t deadline) {
    if (unlikely(n >= num_timers)) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    AutoSpinLockNoIrqSave guard(&lock);

    uint64_t difference = deadline - hpet_get_value();
    if (unlikely(difference > (1ULL >> 63))) {
        /* Either this is a very long timer, or we wrapped around */
        return ZX_ERR_INVALID_ARGS;
    }
    if (unlikely(difference < min_ticks_ahead)) {
        return ZX_ERR_INVALID_ARGS;
    }

    hpet_regs->timers[n].conf_caps &= ~(TIMER_CONF_PERIODIC |
                                        TIMER_CONF_PERIODIC_SET_COUNT);
    hpet_regs->timers[n].comparator_value = deadline;
    hpet_regs->timers[n].conf_caps |= TIMER_CONF_INT_EN;

    return ZX_OK;
}

zx_status_t hpet_timer_set_periodic(uint n, uint64_t period) {
    if (unlikely(n >= num_timers)) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    AutoSpinLockNoIrqSave guard(&lock);

    if (!TIMER_CAP_PERIODIC(hpet_regs->timers[n].conf_caps)) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    /* It's unsafe to set a periodic timer while the hpet is running or the
     * main counter value is not 0. */
    if ((hpet_regs->general_config & GEN_CONF_EN) ||
        hpet_regs->main_counter_value != 0ULL) {
        return ZX_ERR_BAD_STATE;
    }

    hpet_regs->timers[n].conf_caps |= TIMER_CONF_PERIODIC |
                                      TIMER_CONF_PERIODIC_SET_COUNT;
    hpet_regs->timers[n].comparator_value = period;
    hpet_regs->timers[n].conf_caps |= TIMER_CONF_INT_EN;

    return ZX_OK;
}

bool hpet_is_present(void) {
    return hpet_present;
}

void hpet_enable(void) {
    DEBUG_ASSERT(hpet_is_present());

    AutoSpinLockNoIrqSave guard(&lock);
    hpet_regs->general_config |= GEN_CONF_EN;
}

void hpet_disable(void) {
    DEBUG_ASSERT(hpet_is_present());

    AutoSpinLockNoIrqSave guard(&lock);
    hpet_regs->general_config &= ~GEN_CONF_EN;
}

/* Blocks for the requested number of milliseconds.
 * For use in calibration */
void hpet_wait_ms(uint16_t ms) {
    uint64_t init_timer_value = hpet_regs->main_counter_value;
    uint64_t target = (uint64_t)ms * _hpet_ticks_per_ms;
    while (hpet_regs->main_counter_value - init_timer_value <= target)
        ;
}
