// 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;

    dprintf(INFO, "HPET: detected at %#" PRIx64 " ticks per ms %" PRIu64 " num timers %hhu\n",
            hpet_desc.address, _hpet_ticks_per_ms, num_timers);

    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)
        ;
}
