// Copyright 2017 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

#ifdef __x86_64__ // entire file

#include <inttypes.h>

#include "lib/mtrace.h"
#include "trace.h"

#include <arch/user_copy.h>
#include <object/process_dispatcher.h>
#include <object/vm_object_dispatcher.h>

#include <lib/zircon-internal/mtrace.h>

#include "arch/x86/perf_mon.h"
using zx_arch_pmu_properties_t = zx_x86_pmu_properties_t;
using zx_arch_pmu_config_t = zx_x86_pmu_config_t;
using zx_arch_pmu_buffer_t = zx_x86_pmu_buffer_t;

#define LOCAL_TRACE 0

zx_status_t mtrace_cpuperf_control(uint32_t action, uint32_t options,
                                   user_inout_ptr<void> arg, size_t size) {
    LTRACEF("action %u, options 0x%x, arg %p, size 0x%zx\n",
            action, options, arg.get(), size);

    switch (action) {
    case MTRACE_CPUPERF_GET_PROPERTIES: {
        zx_arch_pmu_properties_t props;
        if (size != sizeof(props))
            return ZX_ERR_INVALID_ARGS;
        if (options != 0)
            return ZX_ERR_INVALID_ARGS;
        auto status = arch_perfmon_get_properties(&props);
        if (status != ZX_OK)
            return status;
        status = arg.reinterpret<zx_arch_pmu_properties_t>().copy_to_user(props);
        if (status != ZX_OK)
            return status;
        return ZX_OK;
    }

    case MTRACE_CPUPERF_INIT:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_init();

    case MTRACE_CPUPERF_ASSIGN_BUFFER: {
        zx_arch_pmu_buffer_t buffer;
        if (size != sizeof(buffer))
            return ZX_ERR_INVALID_ARGS;
        zx_status_t status = arg.reinterpret<zx_arch_pmu_buffer_t>().copy_from_user(&buffer);
        if (status != ZX_OK)
            return status;

        // TODO(dje): Later need to rework to assign buffers to things
        // like threads.
        uint32_t cpu = MTRACE_CPUPERF_OPTIONS_CPU(options);
        if ((options & ~MTRACE_CPUPERF_OPTIONS_CPU_MASK) != 0)
            return ZX_ERR_INVALID_ARGS;

        // lookup the VMO dispatcher from handle
        // TODO(dje): Passing in a vmo from userspace, even from a device
        // driver we control, to which we will write from kernel space, feels
        // dodgey. Perhaps we should allocate the vmo here, but that put more
        // of this driver in kernel space. Revisit.
        auto up = ProcessDispatcher::GetCurrent();
        fbl::RefPtr<VmObjectDispatcher> vmo;
        zx_rights_t vmo_rights;
        zx_rights_t needed_rights =
            ZX_RIGHT_MAP | ZX_RIGHT_READ | ZX_RIGHT_WRITE;
        status = up->GetDispatcherWithRights(buffer.vmo, needed_rights,
                                             &vmo, &vmo_rights);
        if (status != ZX_OK)
            return status;

        return arch_perfmon_assign_buffer(cpu, ktl::move(vmo->vmo()));
    }

    case MTRACE_CPUPERF_STAGE_CONFIG: {
        zx_arch_pmu_config_t config;
        if (size != sizeof(config))
            return ZX_ERR_INVALID_ARGS;
        zx_status_t status = arg.reinterpret<zx_arch_pmu_config_t>().copy_from_user(&config);
        if (status != ZX_OK)
            return status;
        if (options != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_stage_config(&config);
    }

    case MTRACE_CPUPERF_START:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_start();

    case MTRACE_CPUPERF_STOP:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_stop();

    case MTRACE_CPUPERF_FINI:
        if (options != 0 || size != 0)
            return ZX_ERR_INVALID_ARGS;
        return arch_perfmon_fini();

    default:
        return ZX_ERR_INVALID_ARGS;
    }
}

#endif
