/* Copyright (C) 2011 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program 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 General Public License for more details.
*/

#include "android-qemu1-glue/utils/stream.h"
#include "android/utils/panic.h"
#include "android/utils/stream.h"
#include "android/utils/system.h"

#include "hw/android/goldfish/pipe.h"
#include "hw/android/goldfish/device.h"
#include "hw/android/goldfish/vmem.h"
#include "exec/ram_addr.h"
#include "migration/vmstate.h"

#define  DEBUG 0

/* Set to 1 to debug i/o register reads/writes */
#define DEBUG_REGS  0

#if DEBUG >= 1
#  define D(...)  fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
#else
#  define D(...)  (void)0
#endif

#if DEBUG >= 2
#  define DD(...)  fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
#else
#  define DD(...)  (void)0
#endif

#if DEBUG_REGS >= 1
#  define DR(...)   D(__VA_ARGS__)
#else
#  define DR(...)   (void)0
#endif

#define E(...)  fprintf(stderr, "ERROR:" __VA_ARGS__), fprintf(stderr, "\n")

/* Set to 1 to enable the 'zero' pipe type, useful for debugging */
#define DEBUG_ZERO_PIPE  1

/* Set to 1 to enable the 'pingpong' pipe type, useful for debugging */
#define DEBUG_PINGPONG_PIPE 1

/* Set to 1 to enable the 'throttle' pipe type, useful for debugging */
#define DEBUG_THROTTLE_PIPE 1

#define GOLDFISH_PIPE_SAVE_VERSION  4
#define GOLDFISH_PIPE_SAVE_LEGACY_VERSION  3

/***********************************************************************
 ***********************************************************************
 *****
 *****    P I P E   C O N N E C T I O N S
 *****
 *****/

typedef struct PipeDevice  PipeDevice;

/***********************************************************************
 ***********************************************************************
 *****
 *****    G O L D F I S H   P I P E   D E V I C E
 *****
 *****/

// An HwPipe instance models the virtual hardware view of a given
// Android pipe.
typedef struct HwPipe {
    struct HwPipe* next;
    struct HwPipe* next_waked;
    uint64_t channel;
    unsigned char wakes;
    unsigned char closed;
    void* pipe;
    struct PipeDevice* device;
} HwPipe;

static HwPipe* hwpipe_new0(struct PipeDevice* device) {
    HwPipe* hwp;
    ANEW0(hwp);
    hwp->device = device;
    return hwp;
}

static HwPipe* hwpipe_new(uint64_t channel, struct PipeDevice* device) {
    HwPipe* hwp = hwpipe_new0(device);
    hwp->channel = channel;
    hwp->pipe = android_pipe_guest_open(hwp);
    return hwp;
}

static void hwpipe_free(HwPipe* hwp) {
  android_pipe_guest_close(hwp->pipe);
  free(hwp);
}

static HwPipe** hwpipe_findp_by_channel(HwPipe** list, uint64_t channel) {
    HwPipe** pnode = list;
    for (;;) {
        HwPipe* node = *pnode;
        if (!node) {
            break;
        }
        if (node->channel == channel) {
            break;
        }
        pnode = &node->next;
    }
    return pnode;
}

static HwPipe** hwpipe_findp_signaled(HwPipe** list, HwPipe* pipe) {
    HwPipe** pnode = list;
    for (;;) {
        HwPipe* node = *pnode;
        if (!node || node == pipe) {
            break;
        }
        pnode = &node->next_waked;
    }
    return pnode;
}


static void hwpipe_remove_signaled(HwPipe** list, HwPipe* pipe) {
    HwPipe** pnode = hwpipe_findp_signaled(list, pipe);
    if (*pnode) {
        *pnode = pipe->next_waked;
        pipe->next_waked = NULL;
    }
}

static void hwpipe_save(HwPipe* pipe, Stream* file) {
    /* Now save other common data */
    stream_put_be64(file, pipe->channel);
    stream_put_byte(file, (int)pipe->wakes);
    stream_put_byte(file, (int)pipe->closed);

    android_pipe_guest_save(pipe->pipe, file);
}

static HwPipe* hwpipe_load(PipeDevice* dev, Stream* file, int version_id) {
    HwPipe* pipe = hwpipe_new0(dev);

    char force_close = 0;
    if (version_id == GOLDFISH_PIPE_SAVE_LEGACY_VERSION) {
      pipe->pipe = android_pipe_guest_load_legacy(file, pipe, &pipe->channel,
                                                  &pipe->wakes, &pipe->closed,
                                                  &force_close);
    } else {
        pipe->channel = stream_get_be64(file);
        pipe->wakes = stream_get_byte(file);
        pipe->closed = stream_get_byte(file);
        pipe->pipe = android_pipe_guest_load(file, pipe, &force_close);
    }

    // SUBTLE: android_pipe_guest_load() may return NULL if the pipe state
    // could not be saved. In this case |force_close| will be set though, so
    // always check it first.
    if (force_close) {
        pipe->closed = 1;
    } else if (!pipe->pipe) {
        hwpipe_free(pipe);
        return NULL;
    }

    return pipe;
}

struct PipeDevice {
    struct goldfish_device dev;

    /* the list of all pipes */
    HwPipe*  pipes;

    /* the list of signalled pipes */
    HwPipe*  signaled_pipes;

    /* i/o registers */
    uint64_t  address;
    uint32_t  size;
    uint32_t  status;
    uint64_t  channel;
    uint32_t  wakes;
    uint64_t  params_addr;
};

/* Update this version number if the device's interface changes. */
#define PIPE_DEVICE_VERSION  1

typedef enum { USE_VA, USE_PA } PipeDeviceMode;

/* ============ Backward Compatibility support ============
 *
 * By default, assume old device behavior which
 * uses guest virtual addresses for read/write operations.
 * New driver will change the device mode to operate with
 * guest physical addresses by reading the version register.
 */
static PipeDeviceMode deviceMode = USE_VA;

/* Map the guest buffer into host memory.
 *
 * @xaddr    - Guest VA or PA depending on the driver version.
 * @size     - Size of the mapping
 * @is_write - Is it a read or write?
 *
 * @Return - Return a host pointer which should be unmapped later via
 * cpu_physical_memory_unmap(), or NULL if mapping failed
 * (likely because the paddr doesn't actually point at RAM).
 * Note that for RAM the "mapping" process doesn't actually involve a
 * data copy.
 */
static void *map_guest_buffer(target_ulong xaddr, size_t size, int is_write)
{
    CPUOldState* env = cpu_single_env;
    target_ulong page = xaddr & TARGET_PAGE_MASK;
    hwaddr l = size;
    hwaddr phys = xaddr;
    void *ptr;

    if (unlikely(deviceMode == USE_VA)) {
        phys = safe_get_phys_page_debug(ENV_GET_CPU(env), page);
#ifdef TARGET_X86_64
        phys = phys & TARGET_PTE_MASK;
#endif
    }

    ptr = cpu_physical_memory_map(phys, &l, is_write);
    if (!ptr) {
        /* Can't happen for RAM */
        return NULL;
    }
    if (l != size) {
        /* This will only happen if the address pointed at non-RAM,
         * or if the size means the buffer end is beyond the end of
         * the RAM block.
         */
        cpu_physical_memory_unmap(ptr, l, 0, 0);
        return NULL;
    }

    if (unlikely(deviceMode == USE_VA)) {
        ptr += xaddr - page;
    }

    return ptr;
}

static void close_all_pipes(void* opaque) {
    struct PipeDevice* dev = opaque;
    HwPipe* pipe = dev->pipes;
    while(pipe) {
        HwPipe* old_pipe = pipe;
        pipe = pipe->next;
        hwpipe_remove_signaled(&dev->signaled_pipes, old_pipe);
        hwpipe_free(old_pipe);
    }
}

static void reset_pipe_device(void* opaque) {
    PipeDevice* dev = opaque;
    dev->pipes = NULL;
    dev->signaled_pipes = NULL;
    goldfish_device_set_irq(&dev->dev, 0, 0);
}

static void
pipeDevice_doCommand( PipeDevice* dev, uint32_t command )
{
    HwPipe** lookup = hwpipe_findp_by_channel(&dev->pipes, dev->channel);
    HwPipe*  pipe = *lookup;

    /* Check that we're referring a known pipe channel */
    if (command != PIPE_CMD_OPEN && pipe == NULL) {
        dev->status = PIPE_ERROR_INVAL;
        return;
    }

    /* If the pipe is closed by the host, return an error */
    if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
        dev->status = PIPE_ERROR_IO;
        return;
    }

    switch (command) {
    case PIPE_CMD_OPEN:
        DD("%s: CMD_OPEN channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        if (pipe != NULL) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        pipe = hwpipe_new(dev->channel, dev);
        pipe->next = dev->pipes;
        dev->pipes = pipe;
        dev->status = 0;
        break;

    case PIPE_CMD_CLOSE:
        DD("%s: CMD_CLOSE channel=0x%llx", __FUNCTION__, (unsigned long long)dev->channel);
        /* Remove from device's lists */
        *lookup = pipe->next;
        pipe->next = NULL;
        hwpipe_remove_signaled(&dev->signaled_pipes, pipe);
        hwpipe_free(pipe);
        break;

    case PIPE_CMD_POLL:
      dev->status = android_pipe_guest_poll(pipe->pipe);
      DD("%s: CMD_POLL > status=%d", __FUNCTION__, dev->status);
      break;

    case PIPE_CMD_READ_BUFFER: {
        /* Map guest buffer identified by dev->address
         * (guest PA or VA depending on the driver version)
         * into host memory.
         */
        AndroidPipeBuffer  buffer;
        buffer.data = map_guest_buffer(dev->address, dev->size, 1);
        if (!buffer.data) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        buffer.size = dev->size;
        dev->status = android_pipe_guest_recv(pipe->pipe, &buffer, 1);
        DD("%s: CMD_READ_BUFFER channel=0x%llx address=0x%llx size=%d > status=%d",
           __FUNCTION__, (unsigned long long)dev->channel, (unsigned long long)dev->address,
           dev->size, dev->status);
        cpu_physical_memory_unmap(buffer.data, dev->size, 1, dev->size);
        break;
    }

    case PIPE_CMD_WRITE_BUFFER: {
        /* Map guest buffer identified by dev->address
         * (guest PA or VA depending on the driver version)
         * into host memory.
         */
        AndroidPipeBuffer  buffer;
        buffer.data = map_guest_buffer(dev->address, dev->size, 0);
        if (!buffer.data) {
            dev->status = PIPE_ERROR_INVAL;
            break;
        }
        buffer.size = dev->size;
        dev->status = android_pipe_guest_send(pipe->pipe, &buffer, 1);
        DD("%s: CMD_WRITE_BUFFER channel=0x%llx address=0x%llx size=%d > status=%d",
           __FUNCTION__, (unsigned long long)dev->channel,
           (unsigned long long)dev->address,
           dev->size, dev->status);
        cpu_physical_memory_unmap(buffer.data, dev->size, 0, dev->size);
        break;
    }

    case PIPE_CMD_WAKE_ON_READ:
        DD("%s: CMD_WAKE_ON_READ channel=0x%llx", __FUNCTION__,
           (unsigned long long)dev->channel);
        if ((pipe->wakes & PIPE_WAKE_READ) == 0) {
            pipe->wakes |= PIPE_WAKE_READ;
            android_pipe_guest_wake_on(pipe->pipe, pipe->wakes);
        }
        dev->status = 0;
        break;

    case PIPE_CMD_WAKE_ON_WRITE:
        DD("%s: CMD_WAKE_ON_WRITE channel=0x%llx", __FUNCTION__,
           (unsigned long long)dev->channel);
        if ((pipe->wakes & PIPE_WAKE_WRITE) == 0) {
            pipe->wakes |= PIPE_WAKE_WRITE;
            android_pipe_guest_wake_on(pipe->pipe, pipe->wakes);
        }
        dev->status = 0;
        break;

    default:
        D("%s: command=%d (0x%x)\n", __FUNCTION__, command, command);
    }
}

static void pipe_dev_write(void *opaque, hwaddr offset, uint32_t value)
{
    PipeDevice *s = (PipeDevice *)opaque;

    switch (offset) {
    case PIPE_REG_COMMAND:
        DR("%s: command=%d (0x%x)", __FUNCTION__, value, value);
        pipeDevice_doCommand(s, value);
        break;

    case PIPE_REG_SIZE:
        DR("%s: size=%d (0x%x)", __FUNCTION__, value, value);
        s->size = value;
        break;

    case PIPE_REG_ADDRESS:
        DR("%s: address=%d (0x%x)", __FUNCTION__, value, value);
        uint64_set_low(&s->address, value);
        break;

    case PIPE_REG_ADDRESS_HIGH:
        DR("%s: address_high=%d (0x%x)", __FUNCTION__, value, value);
        uint64_set_high(&s->address, value);
        break;

    case PIPE_REG_CHANNEL:
        DR("%s: channel=%d (0x%x)", __FUNCTION__, value, value);
        uint64_set_low(&s->channel, value);
        break;

    case PIPE_REG_CHANNEL_HIGH:
        DR("%s: channel_high=%d (0x%x)", __FUNCTION__, value, value);
        uint64_set_high(&s->channel, value);
        break;

    case PIPE_REG_PARAMS_ADDR_HIGH:
        s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL << 32) ) |
                          ((uint64_t)value << 32);
        break;

    case PIPE_REG_PARAMS_ADDR_LOW:
        s->params_addr = (s->params_addr & ~(0xFFFFFFFFULL) ) | value;
        break;

    case PIPE_REG_ACCESS_PARAMS:
    {
        struct access_params aps;
        struct access_params_64 aps64;
        uint32_t cmd;

        /* Don't touch aps.result if anything wrong */
        if (s->params_addr == 0)
            break;

        if (goldfish_guest_is_64bit()) {
            cpu_physical_memory_read(s->params_addr, (void*)&aps64,
                                     sizeof(aps64));
        } else {
            cpu_physical_memory_read(s->params_addr, (void*)&aps,
                                     sizeof(aps));
        }
        /* sync pipe device state from batch buffer */
        if (goldfish_guest_is_64bit()) {
            s->channel = aps64.channel;
            s->size = aps64.size;
            s->address = aps64.address;
            cmd = aps64.cmd;
        } else {
            s->channel = aps.channel;
            s->size = aps.size;
            s->address = aps.address;
            cmd = aps.cmd;
        }
        if ((cmd != PIPE_CMD_READ_BUFFER) && (cmd != PIPE_CMD_WRITE_BUFFER))
            break;

        pipeDevice_doCommand(s, cmd);
        if (goldfish_guest_is_64bit()) {
            aps64.result = s->status;
            cpu_physical_memory_write(s->params_addr, (void*)&aps64,
                                      sizeof(aps64));
        } else {
            aps.result = s->status;
            cpu_physical_memory_write(s->params_addr, (void*)&aps,
                                      sizeof(aps));
        }
    }
    break;

    default:
        D("%s: offset=%lld (0x%llx) value=%lld (0x%llx)\n", __FUNCTION__,
          (long long)offset, (long long)offset, (long long)value,
          (long long)value);
        break;
    }
}

/* I/O read */
static uint32_t pipe_dev_read(void *opaque, hwaddr offset)
{
    PipeDevice *dev = (PipeDevice *)opaque;

    switch (offset) {
    case PIPE_REG_STATUS:
        DR("%s: REG_STATUS status=%d (0x%x)", __FUNCTION__, dev->status, dev->status);
        return dev->status;

    case PIPE_REG_CHANNEL:
        if (dev->signaled_pipes != NULL) {
            HwPipe* pipe = dev->signaled_pipes;
            DR("%s: channel=0x%llx wakes=%d", __FUNCTION__,
               (unsigned long long)pipe->channel, pipe->wakes);
            dev->wakes = pipe->wakes;
            pipe->wakes = 0;
            dev->signaled_pipes = pipe->next_waked;
            pipe->next_waked = NULL;
            if (dev->signaled_pipes == NULL) {
                goldfish_device_set_irq(&dev->dev, 0, 0);
                DD("%s: lowering IRQ", __FUNCTION__);
            }
            return (uint32_t)(pipe->channel & 0xFFFFFFFFUL);
        }
        DR("%s: no signaled channels", __FUNCTION__);
        return 0;

    case PIPE_REG_CHANNEL_HIGH:
        if (dev->signaled_pipes != NULL) {
            HwPipe* pipe = dev->signaled_pipes;
            DR("%s: channel_high=0x%llx wakes=%d", __FUNCTION__,
               (unsigned long long)pipe->channel, pipe->wakes);
            return (uint32_t)(pipe->channel >> 32);
        }
        DR("%s: no signaled channels", __FUNCTION__);
        return 0;

    case PIPE_REG_WAKES:
        DR("%s: wakes %d", __FUNCTION__, dev->wakes);
        return dev->wakes;

    case PIPE_REG_PARAMS_ADDR_HIGH:
        return (uint32_t)(dev->params_addr >> 32);

    case PIPE_REG_PARAMS_ADDR_LOW:
        return (uint32_t)(dev->params_addr & 0xFFFFFFFFUL);

    case PIPE_REG_VERSION:
        deviceMode = USE_PA;
        // PIPE_REG_VERSION is issued on probe, which means that
        // we should clean up all existing stale pipes.
        // This helps keep the right state on rebooting.
        close_all_pipes(dev);
        reset_pipe_device(dev);
        return PIPE_DEVICE_VERSION;

    default:
        D("%s: offset=%lld (0x%llx)\n", __FUNCTION__, (long long)offset,
          (long long)offset);
    }
    return 0;
}

static CPUReadMemoryFunc *pipe_dev_readfn[] = {
   pipe_dev_read,
   pipe_dev_read,
   pipe_dev_read
};

static CPUWriteMemoryFunc *pipe_dev_writefn[] = {
   pipe_dev_write,
   pipe_dev_write,
   pipe_dev_write
};

static void
goldfish_pipe_save( QEMUFile* file, void* opaque )
{
    PipeDevice* dev = opaque;

    Stream* stream = stream_from_qemufile(file);

    stream_put_be64(stream, dev->address);
    stream_put_be32(stream, dev->size);
    stream_put_be32(stream, dev->status);
    stream_put_be64(stream, dev->channel);
    stream_put_be32(stream, dev->wakes);
    stream_put_be64(stream, dev->params_addr);

    /* Count the number of pipe connections */
    HwPipe* pipe;
    int count = 0;
    for (pipe = dev->pipes; pipe; pipe = pipe->next) {
        count++;
    }
    stream_put_be32(stream, count);

    /* Now save each pipe one after the other */
    for (pipe = dev->pipes; pipe; pipe = pipe->next) {
        hwpipe_save(pipe, stream);
    }
    stream_free(stream);
}

static void goldfish_pipe_wake(void* hwpipe, unsigned flags);  // forward
static void goldfish_pipe_close(void* hwpipe);                 // forward

static int
goldfish_pipe_load( QEMUFile* file, void* opaque, int version_id )
{
    PipeDevice* dev = opaque;

    if ((version_id != GOLDFISH_PIPE_SAVE_VERSION) &&
        (version_id != GOLDFISH_PIPE_SAVE_LEGACY_VERSION)) {
        return -EINVAL;
    }

    Stream* stream = stream_from_qemufile(file);

    dev->address = stream_get_be64(stream);
    dev->size    = stream_get_be32(stream);
    dev->status  = stream_get_be32(stream);
    dev->channel = stream_get_be64(stream);

    dev->wakes = stream_get_be32(stream);
    dev->params_addr = stream_get_be64(stream);

    /* Count the number of pipe connections */
    HwPipe* pipe;
    int count = stream_get_be32(stream);

    /* Load all pipe connections */
    for (; count > 0; count--) {
        pipe = hwpipe_load(dev, stream, version_id);
        if (pipe == NULL) {
            stream_free(stream);
            return -EIO;
        }
        pipe->next = dev->pipes;
        dev->pipes = pipe;
    }

    /* Now we need to wake/close all relevant pipes */
    for (pipe = dev->pipes; pipe; pipe = pipe->next) {
        if (pipe->wakes != 0) {
          goldfish_pipe_wake(pipe, pipe->wakes);
        }
        if (pipe->closed != 0) {
          goldfish_pipe_close(pipe);
        }
    }

    stream_free(stream);
    return 0;
}

static void goldfish_pipe_reset(void* hwpipe, void* internal_pipe) {
    HwPipe*  pipe = hwpipe;
    pipe->pipe = internal_pipe;
}

static void goldfish_pipe_wake(void* hwpipe, unsigned flags) {
    HwPipe*  pipe = hwpipe;
    HwPipe** lookup;
    PipeDevice*  dev = pipe->device;

    DD("%s: channel=0x%llx flags=%d", __FUNCTION__,
       (unsigned long long)pipe->channel, flags);

    /* If not already there, add to the list of signaled pipes */
    lookup = hwpipe_findp_signaled(&dev->signaled_pipes, pipe);
    if (!*lookup) {
        pipe->next_waked = dev->signaled_pipes;
        dev->signaled_pipes = pipe;
    }
    pipe->wakes |= (unsigned)flags;

    /* Raise IRQ to indicate there are items on our list ! */
    goldfish_device_set_irq(&dev->dev, 0, 1);
    DD("%s: raising IRQ", __FUNCTION__);
}

static void goldfish_pipe_close(void* hwpipe) {
    HwPipe* pipe = hwpipe;

    D("%s: channel=0x%llx (closed=%d)", __FUNCTION__,
      (unsigned long long)pipe->channel, pipe->closed);

    pipe->closed = 1;
    goldfish_pipe_wake(hwpipe, PIPE_WAKE_CLOSED);
}

static const AndroidPipeHwFuncs goldfish_pipe_hw_funcs = {
    .resetPipe = goldfish_pipe_reset,
    .closeFromHost = goldfish_pipe_close,
    .signalWake = goldfish_pipe_wake,
};

/* initialize the trace device */
void pipe_dev_init(bool newDeviceNaming)
{
    PipeDevice *s;

    s = (PipeDevice *) g_malloc0(sizeof(*s));

    s->dev.name = newDeviceNaming ? "goldfish_pipe" : "qemu_pipe";
    s->dev.id = -1;
    s->dev.base = 0;       // will be allocated dynamically
    s->dev.size = 0x2000;
    s->dev.irq = 0;
    s->dev.irq_count = 1;

    goldfish_device_add(&s->dev, pipe_dev_readfn, pipe_dev_writefn, s);

    register_savevm(NULL,
                    "goldfish_pipe",
                    0,
                    GOLDFISH_PIPE_SAVE_VERSION,
                    goldfish_pipe_save,
                    goldfish_pipe_load,
                    s);

    android_pipe_set_hw_funcs(&goldfish_pipe_hw_funcs);
}
