// 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 <debug.h>
#include <err.h>
#include <platform.h>
#include <string.h>

#include <arch/ops.h>
#include <arch/user_copy.h>
#include <kernel/cmdline.h>
#include <vm/vm_aspace.h>
#include <lib/ktrace.h>
#include <lk/init.h>
#include <zircon/thread_annotations.h>
#include <object/thread_dispatcher.h>

#define ktrace_timestamp() current_ticks();
#define ktrace_ticks_per_ms() (ticks_per_second() / 1000)

static void ktrace_name_etc(uint32_t tag, uint32_t id, uint32_t arg, const char* name, bool always);

// Generated struct that has the syscall index and name.
static struct ktrace_syscall_info {
    uint32_t id;
    uint32_t nargs;
    const char* name;
} kt_syscall_info [] = {
    #include <zircon/syscall-ktrace-info.inc>
    {0, 0, nullptr}
};

void ktrace_report_syscalls(ktrace_syscall_info* call) {
    size_t ix = 0;
    while (call[ix].name) {
        ktrace_name_etc(TAG_SYSCALL_NAME, call[ix].id, 0, call[ix].name, true);
        ++ix;
    }
}

static uint32_t probe_number = 1;

extern ktrace_probe_info_t* const __start_ktrace_probe[];
extern ktrace_probe_info_t* const __stop_ktrace_probe[];

static fbl::Mutex probe_list_lock;
static ktrace_probe_info_t* probe_list TA_GUARDED(probe_list_lock);

static ktrace_probe_info_t* ktrace_find_probe(const char* name) TA_REQ(probe_list_lock) {
    ktrace_probe_info_t* probe;
    for (probe = probe_list; probe != nullptr; probe = probe->next) {
        if (!strcmp(name, probe->name)) {
            return probe;
        }
    }
    return nullptr;
}

static void ktrace_add_probe(ktrace_probe_info_t* probe) TA_REQ(probe_list_lock) {
    if (probe->num == 0) {
        probe->num = probe_number++;
    }
    probe->next = probe_list;
    probe_list = probe;
    ktrace_name_etc(TAG_PROBE_NAME, probe->num, 0, probe->name, true);
}

static void ktrace_report_probes(void) {
    fbl::AutoLock lock(&probe_list_lock);
    ktrace_probe_info_t *probe;
    for (probe = probe_list; probe != nullptr; probe = probe->next) {
        ktrace_name_etc(TAG_PROBE_NAME, probe->num, 0, probe->name, true);
    }
}

typedef struct ktrace_state {
    // where the next record will be written
    int offset;

    // mask of groups we allow, 0 == tracing disabled
    int grpmask;

    // total size of the trace buffer
    uint32_t bufsize;

    // offset where tracing was stopped, 0 if tracing active
    uint32_t marker;

    // raw trace buffer
    uint8_t* buffer;
} ktrace_state_t;

static ktrace_state_t KTRACE_STATE;

int ktrace_read_user(void* ptr, uint32_t off, uint32_t len) {
    ktrace_state_t* ks = &KTRACE_STATE;

    // Buffer size is limited by the marker if set,
    // otherwise limited by offset (last written point).
    // Offset can end up pointing past the end, so clip
    // it to the actual buffer size to be safe.
    uint32_t max;
    if (ks->marker) {
        max = ks->marker;
    } else {
        max = ks->offset;
        if (max > ks->bufsize) {
            max = ks->bufsize;
        }
    }

    // null read is a query for trace buffer size
    if (ptr == nullptr) {
        return max;
    }

    // constrain read to available buffer
    if (off >= max) {
        return 0;
    }
    if (len > (max - off)) {
        len = max - off;
    }

    if (arch_copy_to_user(ptr, ks->buffer + off, len) != ZX_OK) {
        return ZX_ERR_INVALID_ARGS;
    }
    return len;
}

zx_status_t ktrace_control(uint32_t action, uint32_t options, void* ptr) {
    ktrace_state_t* ks = &KTRACE_STATE;
    switch (action) {
    case KTRACE_ACTION_START:
        options = KTRACE_GRP_TO_MASK(options);
        ks->marker = 0;
        atomic_store(&ks->grpmask, options ? options : KTRACE_GRP_TO_MASK(KTRACE_GRP_ALL));
        ktrace_report_live_processes();
        ktrace_report_live_threads();
        break;
    case KTRACE_ACTION_STOP: {
        atomic_store(&ks->grpmask, 0);
        uint32_t n = ks->offset;
        if (n > ks->bufsize) {
            ks->marker = ks->bufsize;
        } else {
            ks->marker = n;
        }
        break;
    }
    case KTRACE_ACTION_REWIND:
        // roll back to just after the metadata
        atomic_store(&ks->offset, KTRACE_RECSIZE * 2);
        ktrace_report_syscalls(kt_syscall_info);
        ktrace_report_probes();
        break;
    case KTRACE_ACTION_NEW_PROBE: {
        fbl::AutoLock lock(&probe_list_lock);
        ktrace_probe_info_t* probe;
        if ((probe = ktrace_find_probe((const char*) ptr)) != nullptr) {
            return probe->num;
        }
        probe = (ktrace_probe_info_t*) calloc(sizeof(*probe) + ZX_MAX_NAME_LEN, 1);
        if (probe == nullptr) {
            return ZX_ERR_NO_MEMORY;
        }
        probe->name = (const char*) (probe + 1);
        memcpy(probe + 1, ptr, ZX_MAX_NAME_LEN);
        ktrace_add_probe(probe);
        return probe->num;
    }
    default:
        return ZX_ERR_INVALID_ARGS;
    }
    return ZX_OK;
}

int trace_not_ready = 0;

void ktrace_init(unsigned level) {
    ktrace_state_t* ks = &KTRACE_STATE;

    uint32_t mb = cmdline_get_uint32("ktrace.bufsize", KTRACE_DEFAULT_BUFSIZE);
    uint32_t grpmask = cmdline_get_uint32("ktrace.grpmask", KTRACE_DEFAULT_GRPMASK);

    if (mb == 0) {
        dprintf(INFO, "ktrace: disabled\n");
        return;
    }

    mb *= (1024*1024);

    zx_status_t status;
    VmAspace* aspace = VmAspace::kernel_aspace();
    if ((status = aspace->Alloc("ktrace", mb, (void**)&ks->buffer, 0, VmAspace::VMM_FLAG_COMMIT,
                                ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE)) < 0) {
        dprintf(INFO, "ktrace: cannot alloc buffer %d\n", status);
        return;
    }

    // The last packet written can overhang the end of the buffer,
    // so we reduce the reported size by the max size of a record
    ks->bufsize = mb - 256;

    dprintf(INFO, "ktrace: buffer at %p (%u bytes)\n", ks->buffer, mb);

    // register all static probes
    {
        fbl::AutoLock lock(&probe_list_lock);
        for (auto probe = __start_ktrace_probe;
             probe != __stop_ktrace_probe;
             ++probe) {
            ktrace_add_probe(*probe);
        }
    }

    // write metadata to the first two event slots
    uint64_t n = ktrace_ticks_per_ms();
    ktrace_rec_32b_t* rec = (ktrace_rec_32b_t*) ks->buffer;
    rec[0].tag = TAG_VERSION;
    rec[0].a = KTRACE_VERSION;
    rec[1].tag = TAG_TICKS_PER_MS;
    rec[1].a = (uint32_t)n;
    rec[1].b = (uint32_t)(n >> 32);

    // enable tracing
    atomic_store(&ks->offset, KTRACE_RECSIZE * 2);
    ktrace_report_syscalls(kt_syscall_info);
    ktrace_report_probes();
    atomic_store(&ks->grpmask, KTRACE_GRP_TO_MASK(grpmask));

    // report names of existing threads
    ktrace_report_live_threads();

    // Report an event for "tracing is all set up now".  This also
    // serves to ensure that there will be at least one static probe
    // entry so that the __{start,stop}_ktrace_probe symbols above
    // will be defined by the linker.
    ktrace_probe0("ktrace_ready");
}

void ktrace_tiny(uint32_t tag, uint32_t arg) {
    ktrace_state_t* ks = &KTRACE_STATE;
    if (tag & atomic_load(&ks->grpmask)) {
        tag = (tag & 0xFFFFFFF0) | 2;
        int off;
        if ((off = atomic_add(&ks->offset, KTRACE_HDRSIZE)) >= (int)ks->bufsize) {
            // if we arrive at the end, stop
            atomic_store(&ks->grpmask, 0);
        } else {
            ktrace_header_t* hdr = (ktrace_header_t*) (ks->buffer + off);
            hdr->ts = ktrace_timestamp();
            hdr->tag = tag;
            hdr->tid = arg;
        }
    }
}

void* ktrace_open(uint32_t tag) {
    ktrace_state_t* ks = &KTRACE_STATE;
    if (!(tag & atomic_load(&ks->grpmask))) {
        return nullptr;
    }

    int off;
    if ((off = atomic_add(&ks->offset, KTRACE_LEN(tag))) >= (int)ks->bufsize) {
        // if we arrive at the end, stop
        atomic_store(&ks->grpmask, 0);
        return nullptr;
    }

    ktrace_header_t* hdr = (ktrace_header_t*) (ks->buffer + off);
    hdr->ts = ktrace_timestamp();
    hdr->tag = tag;
    hdr->tid = (uint32_t)get_current_thread()->user_tid;
    return hdr + 1;
}

static void ktrace_name_etc(uint32_t tag, uint32_t id, uint32_t arg, const char* name, bool always) {
    ktrace_state_t* ks = &KTRACE_STATE;
    if ((tag & atomic_load(&ks->grpmask)) || always) {
        uint32_t len = static_cast<uint32_t>(strnlen(name, ZX_MAX_NAME_LEN - 1));

        // set size to: sizeof(hdr) + len + 1, round up to multiple of 8
        tag = (tag & 0xFFFFFFF0) | ((KTRACE_NAMESIZE + len + 1 + 7) >> 3);

        int off;
        if ((off = atomic_add(&ks->offset, KTRACE_LEN(tag))) >= (int)ks->bufsize) {
            // if we arrive at the end, stop
            atomic_store(&ks->grpmask, 0);
        } else {
            ktrace_rec_name_t* rec = (ktrace_rec_name_t*) (ks->buffer + off);
            rec->tag = tag;
            rec->id = id;
            rec->arg = arg;
            memcpy(rec->name, name, len);
            rec->name[len] = 0;
        }
    }
}

void ktrace_name(uint32_t tag, uint32_t id, uint32_t arg, const char* name) {
    ktrace_name_etc(tag, id, arg, name, false);
}

LK_INIT_HOOK(ktrace, ktrace_init, LK_INIT_LEVEL_USER);
