/*
 * ACPI implementation
 *
 * Copyright (c) 2006 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2 as published by the Free Software Foundation.
 *
 * 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/>
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */
#include "sysemu/sysemu.h"
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/acpi/acpi.h"
#include "qemu/config-file.h"
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
#include "qapi-visit.h"
#include "qapi-event.h"

struct acpi_table_header {
    uint16_t _length;         /* our length, not actual part of the hdr */
                              /* allows easier parsing for fw_cfg clients */
    char sig[4];              /* ACPI signature (4 ASCII characters) */
    uint32_t length;          /* Length of table, in bytes, including header */
    uint8_t revision;         /* ACPI Specification minor version # */
    uint8_t checksum;         /* To make sum of entire table == 0 */
    char oem_id[6];           /* OEM identification */
    char oem_table_id[8];     /* OEM table identification */
    uint32_t oem_revision;    /* OEM revision number */
    char asl_compiler_id[4];  /* ASL compiler vendor ID */
    uint32_t asl_compiler_revision; /* ASL compiler revision number */
} QEMU_PACKED;

#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t)  /* size of the extra prefix */

static const char unsigned dfl_hdr[ACPI_TABLE_HDR_SIZE - ACPI_TABLE_PFX_SIZE] =
    "QEMU\0\0\0\0\1\0"       /* sig (4), len(4), revno (1), csum (1) */
    "QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */
    "QEMU\1\0\0\0"           /* ASL compiler ID (4), version (4) */
    ;

char unsigned *acpi_tables;
size_t acpi_tables_len;

static QemuOptsList qemu_acpi_opts = {
    .name = "acpi",
    .implied_opt_name = "data",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_acpi_opts.head),
    .desc = { { 0 } } /* validated with OptsVisitor */
};

static void acpi_register_config(void)
{
    qemu_add_opts(&qemu_acpi_opts);
}

machine_init(acpi_register_config);

static int acpi_checksum(const uint8_t *data, int len)
{
    int sum, i;
    sum = 0;
    for (i = 0; i < len; i++) {
        sum += data[i];
    }
    return (-sum) & 0xff;
}


/* Install a copy of the ACPI table specified in @blob.
 *
 * If @has_header is set, @blob starts with the System Description Table Header
 * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field
 * is optionally overwritten from @hdrs.
 *
 * It is valid to call this function with
 * (@blob == NULL && bloblen == 0 && !has_header).
 *
 * @hdrs->file and @hdrs->data are ignored.
 *
 * SIZE_MAX is considered "infinity" in this function.
 *
 * The number of tables that can be installed is not limited, but the 16-bit
 * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX.
 */
static void acpi_table_install(const char unsigned *blob, size_t bloblen,
                               bool has_header,
                               const struct AcpiTableOptions *hdrs,
                               Error **errp)
{
    size_t body_start;
    const char unsigned *hdr_src;
    size_t body_size, acpi_payload_size;
    struct acpi_table_header *ext_hdr;
    unsigned changed_fields;

    /* Calculate where the ACPI table body starts within the blob, plus where
     * to copy the ACPI table header from.
     */
    if (has_header) {
        /*   _length             | ACPI header in blob | blob body
         *   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^
         *   ACPI_TABLE_PFX_SIZE     sizeof dfl_hdr      body_size
         *                           == body_start
         *
         *                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         *                           acpi_payload_size == bloblen
         */
        body_start = sizeof dfl_hdr;

        if (bloblen < body_start) {
            error_setg(errp, "ACPI table claiming to have header is too "
                       "short, available: %zu, expected: %zu", bloblen,
                       body_start);
            return;
        }
        hdr_src = blob;
    } else {
        /*   _length             | ACPI header in template | blob body
         *   ^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^
         *   ACPI_TABLE_PFX_SIZE       sizeof dfl_hdr        body_size
         *                                                   == bloblen
         *
         *                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         *                                  acpi_payload_size
         */
        body_start = 0;
        hdr_src = dfl_hdr;
    }
    body_size = bloblen - body_start;
    acpi_payload_size = sizeof dfl_hdr + body_size;

    if (acpi_payload_size > UINT16_MAX) {
        error_setg(errp, "ACPI table too big, requested: %zu, max: %u",
                   acpi_payload_size, (unsigned)UINT16_MAX);
        return;
    }

    /* We won't fail from here on. Initialize / extend the globals. */
    if (acpi_tables == NULL) {
        acpi_tables_len = sizeof(uint16_t);
        acpi_tables = g_malloc0(acpi_tables_len);
    }

    acpi_tables = g_realloc(acpi_tables, acpi_tables_len +
                                         ACPI_TABLE_PFX_SIZE +
                                         sizeof dfl_hdr + body_size);

    ext_hdr = (struct acpi_table_header *)(acpi_tables + acpi_tables_len);
    acpi_tables_len += ACPI_TABLE_PFX_SIZE;

    memcpy(acpi_tables + acpi_tables_len, hdr_src, sizeof dfl_hdr);
    acpi_tables_len += sizeof dfl_hdr;

    if (blob != NULL) {
        memcpy(acpi_tables + acpi_tables_len, blob + body_start, body_size);
        acpi_tables_len += body_size;
    }

    /* increase number of tables */
    stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u);

    /* Update the header fields. The strings need not be NUL-terminated. */
    changed_fields = 0;
    ext_hdr->_length = cpu_to_le16(acpi_payload_size);

    if (hdrs->has_sig) {
        strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig);
        ++changed_fields;
    }

    if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) {
        fprintf(stderr,
                "warning: ACPI table has wrong length, header says "
                "%" PRIu32 ", actual size %zu bytes\n",
                le32_to_cpu(ext_hdr->length), acpi_payload_size);
    }
    ext_hdr->length = cpu_to_le32(acpi_payload_size);

    if (hdrs->has_rev) {
        ext_hdr->revision = hdrs->rev;
        ++changed_fields;
    }

    ext_hdr->checksum = 0;

    if (hdrs->has_oem_id) {
        strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id);
        ++changed_fields;
    }
    if (hdrs->has_oem_table_id) {
        strncpy(ext_hdr->oem_table_id, hdrs->oem_table_id,
                sizeof ext_hdr->oem_table_id);
        ++changed_fields;
    }
    if (hdrs->has_oem_rev) {
        ext_hdr->oem_revision = cpu_to_le32(hdrs->oem_rev);
        ++changed_fields;
    }
    if (hdrs->has_asl_compiler_id) {
        strncpy(ext_hdr->asl_compiler_id, hdrs->asl_compiler_id,
                sizeof ext_hdr->asl_compiler_id);
        ++changed_fields;
    }
    if (hdrs->has_asl_compiler_rev) {
        ext_hdr->asl_compiler_revision = cpu_to_le32(hdrs->asl_compiler_rev);
        ++changed_fields;
    }

    if (!has_header && changed_fields == 0) {
        fprintf(stderr, "warning: ACPI table: no headers are specified\n");
    }

    /* recalculate checksum */
    ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr +
                                      ACPI_TABLE_PFX_SIZE, acpi_payload_size);
}

void acpi_table_add(const QemuOpts *opts, Error **errp)
{
    AcpiTableOptions *hdrs = NULL;
    Error *err = NULL;
    char **pathnames = NULL;
    char **cur;
    size_t bloblen = 0;
    char unsigned *blob = NULL;

    {
        OptsVisitor *ov;

        ov = opts_visitor_new(opts);
        visit_type_AcpiTableOptions(opts_get_visitor(ov), &hdrs, NULL, &err);
        opts_visitor_cleanup(ov);
    }

    if (err) {
        goto out;
    }
    if (hdrs->has_file == hdrs->has_data) {
        error_setg(&err, "'-acpitable' requires one of 'data' or 'file'");
        goto out;
    }

    pathnames = g_strsplit(hdrs->has_file ? hdrs->file : hdrs->data, ":", 0);
    if (pathnames == NULL || pathnames[0] == NULL) {
        error_setg(&err, "'-acpitable' requires at least one pathname");
        goto out;
    }

    /* now read in the data files, reallocating buffer as needed */
    for (cur = pathnames; *cur; ++cur) {
        int fd = open(*cur, O_RDONLY | O_BINARY);

        if (fd < 0) {
            error_setg(&err, "can't open file %s: %s", *cur, strerror(errno));
            goto out;
        }

        for (;;) {
            char unsigned data[8192];
            ssize_t r;

            r = read(fd, data, sizeof data);
            if (r == 0) {
                break;
            } else if (r > 0) {
                blob = g_realloc(blob, bloblen + r);
                memcpy(blob + bloblen, data, r);
                bloblen += r;
            } else if (errno != EINTR) {
                error_setg(&err, "can't read file %s: %s",
                           *cur, strerror(errno));
                close(fd);
                goto out;
            }
        }

        close(fd);
    }

    acpi_table_install(blob, bloblen, hdrs->has_file, hdrs, &err);

out:
    g_free(blob);
    g_strfreev(pathnames);

    if (hdrs != NULL) {
        QapiDeallocVisitor *dv;

        dv = qapi_dealloc_visitor_new();
        visit_type_AcpiTableOptions(qapi_dealloc_get_visitor(dv), &hdrs, NULL,
                                    NULL);
        qapi_dealloc_visitor_cleanup(dv);
    }

    error_propagate(errp, err);
}

static bool acpi_table_builtin = false;

void acpi_table_add_builtin(const QemuOpts *opts, Error **errp)
{
    acpi_table_builtin = true;
    acpi_table_add(opts, errp);
}

unsigned acpi_table_len(void *current)
{
    struct acpi_table_header *hdr = current - sizeof(hdr->_length);
    return hdr->_length;
}

static
void *acpi_table_hdr(void *h)
{
    struct acpi_table_header *hdr = h;
    return &hdr->sig;
}

uint8_t *acpi_table_first(void)
{
    if (acpi_table_builtin || !acpi_tables) {
        return NULL;
    }
    return acpi_table_hdr(acpi_tables + ACPI_TABLE_PFX_SIZE);
}

uint8_t *acpi_table_next(uint8_t *current)
{
    uint8_t *next = current + acpi_table_len(current);

    if (next - acpi_tables >= acpi_tables_len) {
        return NULL;
    } else {
        return acpi_table_hdr(next);
    }
}

static void acpi_notify_wakeup(Notifier *notifier, void *data)
{
    ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup);
    WakeupReason *reason = data;

    switch (*reason) {
    case QEMU_WAKEUP_REASON_RTC:
        ar->pm1.evt.sts |=
            (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS);
        break;
    case QEMU_WAKEUP_REASON_PMTIMER:
        ar->pm1.evt.sts |=
            (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS);
        break;
    case QEMU_WAKEUP_REASON_OTHER:
        /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
           Pretend that resume was caused by power button */
        ar->pm1.evt.sts |=
            (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
        break;
    default:
        break;
    }
}

/* ACPI PM1a EVT */
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
{
    /* Compare ns-clock, not PM timer ticks, because
       acpi_pm_tmr_update function uses ns for setting the timer. */
    int64_t d = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    if (d >= muldiv64(ar->tmr.overflow_time,
                      get_ticks_per_sec(), PM_TIMER_FREQUENCY)) {
        ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
    }
    return ar->pm1.evt.sts;
}

static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val)
{
    uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar);
    if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) {
        /* if TMRSTS is reset, then compute the new overflow time */
        acpi_pm_tmr_calc_overflow_time(ar);
    }
    ar->pm1.evt.sts &= ~val;
}

static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val)
{
    ar->pm1.evt.en = val;
    qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC,
                              val & ACPI_BITMASK_RT_CLOCK_ENABLE);
    qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER,
                              val & ACPI_BITMASK_TIMER_ENABLE);
}

void acpi_pm1_evt_power_down(ACPIREGS *ar)
{
    if (ar->pm1.evt.en & ACPI_BITMASK_POWER_BUTTON_ENABLE) {
        ar->pm1.evt.sts |= ACPI_BITMASK_POWER_BUTTON_STATUS;
        ar->tmr.update_sci(ar);
    }
}

void acpi_pm1_evt_reset(ACPIREGS *ar)
{
    ar->pm1.evt.sts = 0;
    ar->pm1.evt.en = 0;
    qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, 0);
    qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, 0);
}

static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width)
{
    ACPIREGS *ar = opaque;
    switch (addr) {
    case 0:
        return acpi_pm1_evt_get_sts(ar);
    case 2:
        return ar->pm1.evt.en;
    default:
        return 0;
    }
}

static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned width)
{
    ACPIREGS *ar = opaque;
    switch (addr) {
    case 0:
        acpi_pm1_evt_write_sts(ar, val);
        ar->pm1.evt.update_sci(ar);
        break;
    case 2:
        acpi_pm1_evt_write_en(ar, val);
        ar->pm1.evt.update_sci(ar);
        break;
    }
}

static const MemoryRegionOps acpi_pm_evt_ops = {
    .read = acpi_pm_evt_read,
    .write = acpi_pm_evt_write,
    .valid.min_access_size = 2,
    .valid.max_access_size = 2,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                       MemoryRegion *parent)
{
    ar->pm1.evt.update_sci = update_sci;
    memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent),
                          &acpi_pm_evt_ops, ar, "acpi-evt", 4);
    memory_region_add_subregion(parent, 0, &ar->pm1.evt.io);
}

/* ACPI PM_TMR */
void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
{
    int64_t expire_time;

    /* schedule a timer interruption if needed */
    if (enable) {
        expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(),
                               PM_TIMER_FREQUENCY);
        timer_mod(ar->tmr.timer, expire_time);
    } else {
        timer_del(ar->tmr.timer);
    }
}

void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar)
{
    int64_t d = acpi_pm_tmr_get_clock();
    ar->tmr.overflow_time = (d + 0x800000LL) & ~0x7fffffLL;
}

static uint32_t acpi_pm_tmr_get(ACPIREGS *ar)
{
    uint32_t d = acpi_pm_tmr_get_clock();
    return d & 0xffffff;
}

static void acpi_pm_tmr_timer(void *opaque)
{
    ACPIREGS *ar = opaque;
    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER);
    ar->tmr.update_sci(ar);
}

static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width)
{
    return acpi_pm_tmr_get(opaque);
}

static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned width)
{
    /* nothing */
}

static const MemoryRegionOps acpi_pm_tmr_ops = {
    .read = acpi_pm_tmr_read,
    .write = acpi_pm_tmr_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                      MemoryRegion *parent)
{
    ar->tmr.update_sci = update_sci;
    ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar);
    memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
                          &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
    memory_region_add_subregion(parent, 8, &ar->tmr.io);
}

void acpi_pm_tmr_reset(ACPIREGS *ar)
{
    ar->tmr.overflow_time = 0;
    timer_del(ar->tmr.timer);
}

/* ACPI PM1aCNT */
static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val)
{
    ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);

    if (val & ACPI_BITMASK_SLEEP_ENABLE) {
        /* change suspend type */
        uint16_t sus_typ = (val >> 10) & 7;
        switch(sus_typ) {
        case 0: /* soft power off */
            qemu_system_shutdown_request();
            break;
        case 1:
            qemu_system_suspend_request();
            break;
        default:
            if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */
                qapi_event_send_suspend_disk(&error_abort);
                qemu_system_shutdown_request();
            }
            break;
        }
    }
}

void acpi_pm1_cnt_update(ACPIREGS *ar,
                         bool sci_enable, bool sci_disable)
{
    /* ACPI specs 3.0, 4.7.2.5 */
    if (sci_enable) {
        ar->pm1.cnt.cnt |= ACPI_BITMASK_SCI_ENABLE;
    } else if (sci_disable) {
        ar->pm1.cnt.cnt &= ~ACPI_BITMASK_SCI_ENABLE;
    }
}

static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width)
{
    ACPIREGS *ar = opaque;
    return ar->pm1.cnt.cnt;
}

static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned width)
{
    acpi_pm1_cnt_write(opaque, val);
}

static const MemoryRegionOps acpi_pm_cnt_ops = {
    .read = acpi_pm_cnt_read,
    .write = acpi_pm_cnt_write,
    .valid.min_access_size = 2,
    .valid.max_access_size = 2,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, uint8_t s4_val)
{
    ar->pm1.cnt.s4_val = s4_val;
    ar->wakeup.notify = acpi_notify_wakeup;
    qemu_register_wakeup_notifier(&ar->wakeup);
    memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent),
                          &acpi_pm_cnt_ops, ar, "acpi-cnt", 2);
    memory_region_add_subregion(parent, 4, &ar->pm1.cnt.io);
}

void acpi_pm1_cnt_reset(ACPIREGS *ar)
{
    ar->pm1.cnt.cnt = 0;
}

/* ACPI GPE */
void acpi_gpe_init(ACPIREGS *ar, uint8_t len)
{
    ar->gpe.len = len;
    ar->gpe.sts = g_malloc0(len / 2);
    ar->gpe.en = g_malloc0(len / 2);
}

void acpi_gpe_reset(ACPIREGS *ar)
{
    memset(ar->gpe.sts, 0, ar->gpe.len / 2);
    memset(ar->gpe.en, 0, ar->gpe.len / 2);
}

static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr)
{
    uint8_t *cur = NULL;

    if (addr < ar->gpe.len / 2) {
        cur = ar->gpe.sts + addr;
    } else if (addr < ar->gpe.len) {
        cur = ar->gpe.en + addr - ar->gpe.len / 2;
    } else {
        abort();
    }

    return cur;
}

void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
{
    uint8_t *cur;

    cur = acpi_gpe_ioport_get_ptr(ar, addr);
    if (addr < ar->gpe.len / 2) {
        /* GPE_STS */
        *cur = (*cur) & ~val;
    } else if (addr < ar->gpe.len) {
        /* GPE_EN */
        *cur = val;
    } else {
        abort();
    }
}

uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
{
    uint8_t *cur;
    uint32_t val;

    cur = acpi_gpe_ioport_get_ptr(ar, addr);
    val = 0;
    if (cur != NULL) {
        val = *cur;
    }

    return val;
}

void acpi_update_sci(ACPIREGS *regs, qemu_irq irq)
{
    int sci_level, pm1a_sts;

    pm1a_sts = acpi_pm1_evt_get_sts(regs);

    sci_level = ((pm1a_sts &
                  regs->pm1.evt.en & ACPI_BITMASK_PM1_COMMON_ENABLED) != 0) ||
                ((regs->gpe.sts[0] & regs->gpe.en[0]) != 0);

    qemu_set_irq(irq, sci_level);

    /* schedule a timer interruption if needed */
    acpi_pm_tmr_update(regs,
                       (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
}
