// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "dev.h"

#include <hw/inout.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <fdio/debug.h>

#include "errors.h"

#define MXDEBUG 0

/* EC commands */
#define EC_CMD_QUERY 0x84

/* EC status register bits */
#define EC_SC_SCI_EVT (1 << 5)
#define EC_SC_IBF (1 << 1)
#define EC_SC_OBF (1 << 0)

/* Thread shutdown signals */
#define EC_THREAD_SHUTDOWN ZX_USER_SIGNAL_0
#define EC_THREAD_SHUTDOWN_DONE ZX_USER_SIGNAL_1

typedef struct acpi_ec_device {
    zx_device_t* mxdev;

    ACPI_HANDLE acpi_handle;

    // PIO addresses for EC device
    uint16_t cmd_port;
    uint16_t data_port;

    // GPE for EC events
    ACPI_HANDLE gpe_block;
    UINT32 gpe;

    // thread for processing System Control Interrupts
    thrd_t sci_thread;
    zx_handle_t pending_sci_evt;

    bool gpe_setup : 1;
    bool thread_setup : 1;
} acpi_ec_device_t;

static ACPI_STATUS get_ec_handle(ACPI_HANDLE, UINT32, void*, void**);
static ACPI_STATUS get_ec_gpe_info(ACPI_HANDLE, ACPI_HANDLE*, UINT32*);
static ACPI_STATUS get_ec_ports(ACPI_HANDLE, uint16_t*, uint16_t*);

static int acpi_ec_thread(void* arg) {
    acpi_ec_device_t* dev = arg;

    while (1) {
        uint32_t pending;
        zx_status_t zx_status = zx_object_wait_one(dev->pending_sci_evt,
                                                   ZX_EVENT_SIGNALED | EC_THREAD_SHUTDOWN,
                                                   ZX_TIME_INFINITE,
                                                   &pending);
        if (zx_status != ZX_OK) {
            printf("acpi-ec: thread wait failed: %d\n", zx_status);
            break;
        }

        if (pending & EC_THREAD_SHUTDOWN) {
            zx_object_signal(dev->pending_sci_evt, 0, EC_THREAD_SHUTDOWN_DONE);
            break;
        }

        zx_object_signal(dev->pending_sci_evt, ZX_EVENT_SIGNALED, 0);

        UINT32 global_lock;
        while (AcpiAcquireGlobalLock(0xFFFF, &global_lock) != AE_OK)
            ;

        uint8_t status;
        do {
            status = inp(dev->cmd_port);
            /* Read the status out of the command/status port */
            if (!(status & EC_SC_SCI_EVT)) {
                break;
            }

            /* Query EC command */
            outp(dev->cmd_port, EC_CMD_QUERY);

            /* Wait for EC to read the command */
            while (!((status = inp(dev->cmd_port)) & EC_SC_IBF))
                ;

            /* Wait for EC to respond */
            while (!((status = inp(dev->cmd_port)) & EC_SC_OBF))
                ;

            while ((status = inp(dev->cmd_port)) & EC_SC_OBF) {
                /* Read until the output buffer is empty */
                uint8_t event_code = inp(dev->data_port);
                char method[5] = {0};
                snprintf(method, sizeof(method), "_Q%02x", event_code);
                xprintf("acpi-ec: Invoking method %s\n", method);
                AcpiEvaluateObject(dev->acpi_handle, method, NULL, NULL);
                xprintf("acpi-ec: Invoked method %s\n", method);
            }
        } while (status & EC_SC_SCI_EVT);

        AcpiReleaseGlobalLock(global_lock);
    }

    xprintf("acpi-ec: thread terminated\n");
    return 0;
}

static uint32_t raw_ec_event_gpe_handler(ACPI_HANDLE gpe_dev, uint32_t gpe_num, void* ctx) {
    acpi_ec_device_t* dev = ctx;
    zx_object_signal(dev->pending_sci_evt, 0, ZX_EVENT_SIGNALED);
    return ACPI_REENABLE_GPE;
}

static ACPI_STATUS get_ec_handle(
    ACPI_HANDLE object,
    UINT32 nesting_level,
    void* context,
    void** ret) {

    *(ACPI_HANDLE*)context = object;
    return AE_OK;
}

static ACPI_STATUS get_ec_gpe_info(
    ACPI_HANDLE ec_handle, ACPI_HANDLE* gpe_block, UINT32* gpe) {
    ACPI_BUFFER buffer = {
        .Length = ACPI_ALLOCATE_BUFFER,
        .Pointer = NULL,
    };
    ACPI_STATUS status = AcpiEvaluateObject(
        ec_handle, (char*)"_GPE", NULL, &buffer);
    if (status != AE_OK) {
        return status;
    }

    /* According to section 12.11 of ACPI v6.1, a _GPE object on this device
     * evaluates to either an integer specifying bit in the GPEx_STS blocks
     * to use, or a package specifying which GPE block and which bit inside
     * that block to use. */
    ACPI_OBJECT* gpe_obj = buffer.Pointer;
    if (gpe_obj->Type == ACPI_TYPE_INTEGER) {
        *gpe_block = NULL;
        *gpe = gpe_obj->Integer.Value;
    } else if (gpe_obj->Type == ACPI_TYPE_PACKAGE) {
        if (gpe_obj->Package.Count != 2) {
            goto bailout;
        }
        ACPI_OBJECT* block_obj = &gpe_obj->Package.Elements[0];
        ACPI_OBJECT* gpe_num_obj = &gpe_obj->Package.Elements[1];
        if (block_obj->Type != ACPI_TYPE_LOCAL_REFERENCE) {
            goto bailout;
        }
        if (gpe_num_obj->Type != ACPI_TYPE_INTEGER) {
            goto bailout;
        }
        *gpe_block = block_obj->Reference.Handle;
        *gpe = gpe_num_obj->Integer.Value;
    } else {
        goto bailout;
    }
    ACPI_FREE(buffer.Pointer);
    return AE_OK;

bailout:
    xprintf("Failed to intepret EC GPE number");
    ACPI_FREE(buffer.Pointer);
    return AE_BAD_DATA;
}

struct ec_ports_callback_ctx {
    uint16_t* data_port;
    uint16_t* cmd_port;
    unsigned int resource_num;
};

static ACPI_STATUS get_ec_ports_callback(
    ACPI_RESOURCE* Resource, void* Context) {
    struct ec_ports_callback_ctx* ctx = Context;

    if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG) {
        return AE_OK;
    }

    /* The spec says there will be at most 3 resources */
    if (ctx->resource_num >= 3) {
        return AE_BAD_DATA;
    }
    /* The third resource only exists on HW-Reduced platforms, which we don't
     * support at the moment. */
    if (ctx->resource_num == 2) {
        xprintf("RESOURCE TYPE %d\n", Resource->Type);
        return AE_NOT_IMPLEMENTED;
    }

    /* The two resources we're expecting are both address regions.  First the
     * data one, then the command one.  We assume they're single IO ports. */
    if (Resource->Type != ACPI_RESOURCE_TYPE_IO) {
        return AE_SUPPORT;
    }
    if (Resource->Data.Io.Maximum != Resource->Data.Io.Minimum) {
        return AE_SUPPORT;
    }

    uint16_t port = Resource->Data.Io.Minimum;
    if (ctx->resource_num == 0) {
        *ctx->data_port = port;
    } else {
        *ctx->cmd_port = port;
    }

    ctx->resource_num++;
    return AE_OK;
}

static ACPI_STATUS get_ec_ports(
    ACPI_HANDLE ec_handle, uint16_t* data_port, uint16_t* cmd_port) {
    struct ec_ports_callback_ctx ctx = {
        .data_port = data_port,
        .cmd_port = cmd_port,
        .resource_num = 0,
    };

    return AcpiWalkResources(ec_handle, (char*)"_CRS", get_ec_ports_callback, &ctx);
}

static void acpi_ec_release(void* ctx) {
    acpi_ec_device_t* dev = ctx;

    if (dev->pending_sci_evt != ZX_HANDLE_INVALID) {
        if (dev->thread_setup) {
            /* Shutdown the EC thread */
            zx_object_signal(dev->pending_sci_evt, 0, EC_THREAD_SHUTDOWN);
            zx_object_wait_one(dev->pending_sci_evt, EC_THREAD_SHUTDOWN_DONE, ZX_TIME_INFINITE, NULL);
            thrd_join(dev->sci_thread, NULL);
        }

        zx_handle_close(dev->pending_sci_evt);
    }

    if (dev->gpe_setup) {
        AcpiDisableGpe(dev->gpe_block, dev->gpe);
        AcpiRemoveGpeHandler(dev->gpe_block, dev->gpe, raw_ec_event_gpe_handler);
    }

    free(dev);
}

static zx_protocol_device_t acpi_ec_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .release = acpi_ec_release,
};

zx_status_t ec_init(zx_device_t* parent, ACPI_HANDLE acpi_handle) {
    xprintf("acpi-ec: init\n");

    acpi_ec_device_t* dev = calloc(1, sizeof(acpi_ec_device_t));
    if (!dev) {
        return ZX_ERR_NO_MEMORY;
    }
    dev->acpi_handle = acpi_handle;

    zx_status_t err = zx_event_create(0, &dev->pending_sci_evt);
    if (err != ZX_OK) {
        xprintf("acpi-ec: Failed to create event: %d\n", err);
        acpi_ec_release(dev);
        return err;
    }

    ACPI_STATUS status = get_ec_gpe_info(acpi_handle, &dev->gpe_block, &dev->gpe);
    if (status != AE_OK) {
        xprintf("acpi-ec: Failed to decode GPE info: %d\n", status);
        goto acpi_error;
    }

    status = get_ec_ports(
        acpi_handle, &dev->data_port, &dev->cmd_port);
    if (status != AE_OK) {
        xprintf("acpi-ec: Failed to decode comm info: %d\n", status);
        goto acpi_error;
    }

    /* Setup GPE handling */
    status = AcpiInstallGpeHandler(
        dev->gpe_block, dev->gpe, ACPI_GPE_EDGE_TRIGGERED,
        raw_ec_event_gpe_handler, dev);
    if (status != AE_OK) {
        xprintf("acpi-ec: Failed to install GPE %d: %x\n", dev->gpe, status);
        goto acpi_error;
    }
    status = AcpiEnableGpe(dev->gpe_block, dev->gpe);
    if (status != AE_OK) {
        xprintf("acpi-ec: Failed to enable GPE %d: %x\n", dev->gpe, status);
        AcpiRemoveGpeHandler(dev->gpe_block, dev->gpe, raw_ec_event_gpe_handler);
        goto acpi_error;
    }
    dev->gpe_setup = true;

    int ret = thrd_create_with_name(&dev->sci_thread, acpi_ec_thread, dev, "acpi-ec-sci");
    if (ret != thrd_success) {
        xprintf("acpi-ec: Failed to create thread\n");
        acpi_ec_release(dev);
        return ZX_ERR_INTERNAL;
    }
    dev->thread_setup = true;

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "acpi-ec",
        .ctx = dev,
        .ops = &acpi_ec_device_proto,
        .proto_id = ZX_PROTOCOL_MISC,
    };

    status = device_add(parent, &args, &dev->mxdev);
    if (status != ZX_OK) {
        xprintf("acpi-ec: could not add device! err=%d\n", status);
        acpi_ec_release(dev);
        return status;
    }

    printf("acpi-ec: initialized\n");
    return ZX_OK;

acpi_error:
    acpi_ec_release(dev);
    return acpi_to_zx_status(status);
}
