/**
 * Copyright (C) Arm Limited 2010-2016. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */

static void marshal_frame(int cpu, int buftype)
{
    int frame;
    bool write_cpu;

    if (!per_cpu(gator_buffer, cpu)[buftype])
        return;

    switch (buftype) {
    case SUMMARY_BUF:
        write_cpu = false;
        frame = FRAME_SUMMARY;
        break;
    case BACKTRACE_BUF:
        write_cpu = true;
        frame = FRAME_BACKTRACE;
        break;
    case NAME_BUF:
        write_cpu = true;
        frame = FRAME_NAME;
        break;
    case COUNTER_BUF:
        write_cpu = false;
        frame = FRAME_COUNTER;
        break;
    case BLOCK_COUNTER_BUF:
        write_cpu = true;
        frame = FRAME_BLOCK_COUNTER;
        break;
    case ANNOTATE_BUF:
        write_cpu = false;
        frame = FRAME_ANNOTATE;
        break;
    case SCHED_TRACE_BUF:
        write_cpu = true;
        frame = FRAME_SCHED_TRACE;
        break;
    case IDLE_BUF:
        write_cpu = false;
        frame = FRAME_IDLE;
        break;
    case ACTIVITY_BUF:
        write_cpu = false;
        frame = FRAME_ACTIVITY;
        break;
    default:
        write_cpu = false;
        frame = -1;
        break;
    }

    /* add response type */
    if (gator_response_type > 0)
        gator_buffer_write_packed_int(cpu, buftype, gator_response_type);

    /* leave space for 4-byte unpacked length */
    per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];

    /* add frame type and core number */
    gator_buffer_write_packed_int(cpu, buftype, frame);
    if (write_cpu)
        gator_buffer_write_packed_int(cpu, buftype, cpu);
}

static int buffer_bytes_available(int cpu, int buftype)
{
    int remaining, filled;

    filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_read, cpu)[buftype];
    if (filled < 0)
        filled += gator_buffer_size[buftype];

    remaining = gator_buffer_size[buftype] - filled;

    if (per_cpu(buffer_space_available, cpu)[buftype])
        /* Give some extra room; also allows space to insert the overflow error packet */
        remaining -= 200;
    else
        /* Hysteresis, prevents multiple overflow messages */
        remaining -= 2000;

    return remaining;
}

static bool buffer_check_space(int cpu, int buftype, int bytes)
{
    int remaining = buffer_bytes_available(cpu, buftype);

    if (remaining < bytes)
        per_cpu(buffer_space_available, cpu)[buftype] = false;
    else
        per_cpu(buffer_space_available, cpu)[buftype] = true;

    return per_cpu(buffer_space_available, cpu)[buftype];
}

static int contiguous_space_available(int cpu, int buftype)
{
    int remaining = buffer_bytes_available(cpu, buftype);
    int contiguous = gator_buffer_size[buftype] - per_cpu(gator_buffer_write, cpu)[buftype];

    if (remaining < contiguous)
        return remaining;
    return contiguous;
}

static void gator_commit_buffer(int cpu, int buftype, u64 time)
{
    int type_length, commit, length, byte;
    unsigned long flags;

    if (!per_cpu(gator_buffer, cpu)[buftype])
        return;

    /* post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload */
    local_irq_save(flags);
    type_length = gator_response_type ? 1 : 0;
    commit = per_cpu(gator_buffer_commit, cpu)[buftype];
    length = per_cpu(gator_buffer_write, cpu)[buftype] - commit;
    if (length < 0)
        length += gator_buffer_size[buftype];
    length = length - type_length - sizeof(s32);

    if (length <= FRAME_HEADER_SIZE) {
        /* Nothing to write, only the frame header is present */
        local_irq_restore(flags);
        return;
    }

    for (byte = 0; byte < sizeof(s32); byte++)
        per_cpu(gator_buffer, cpu)[buftype][(commit + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF;

    per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype];

    if (gator_live_rate > 0) {
        while (time > per_cpu(gator_buffer_commit_time, cpu))
            per_cpu(gator_buffer_commit_time, cpu) += gator_live_rate;
    }

    marshal_frame(cpu, buftype);
    local_irq_restore(flags);

    /* had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater */
    if (per_cpu(in_scheduler_context, cpu)) {
#ifndef CONFIG_PREEMPT_RT_FULL
        /* mod_timer can not be used in interrupt context in RT-Preempt full */
        mod_timer(&gator_buffer_wake_up_timer, jiffies + 1);
#endif
    } else {
        up(&gator_buffer_wake_sem);
    }
}

static void buffer_check(int cpu, int buftype, u64 time)
{
    int filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_commit, cpu)[buftype];

    if (filled < 0)
        filled += gator_buffer_size[buftype];
    if (filled >= ((gator_buffer_size[buftype] * 3) / 4))
        gator_commit_buffer(cpu, buftype, time);
}
