// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014 Travis Geiselbrecht
//
// 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 "vm_priv.h"
#include <assert.h>
#include <err.h>
#include <inttypes.h>
#include <kernel/mutex.h>
#include <kernel/thread_lock.h>
#include <lib/console.h>
#include <lib/ktrace.h>
#include <object/diagnostics.h>
#include <string.h>
#include <trace.h>
#include <vm/fault.h>
#include <vm/pmm.h>
#include <vm/vm.h>
#include <vm/vm_address_region.h>
#include <vm/vm_aspace.h>
#include <zircon/types.h>

#define LOCAL_TRACE MAX(VM_GLOBAL_TRACE, 0)
#define TRACE_PAGE_FAULT 0

// This file mostly contains C wrappers around the underlying C++ objects, conforming to
// the older api.

static inline void vmm_context_switch(VmAspace* oldspace, VmAspace* newaspace) {
    DEBUG_ASSERT(thread_lock_held());

    ArchVmAspace::ContextSwitch(oldspace ? &oldspace->arch_aspace() : nullptr,
                                newaspace ? &newaspace->arch_aspace() : nullptr);
}

void vmm_context_switch(vmm_aspace_t* oldspace, vmm_aspace_t* newaspace) {
    vmm_context_switch(reinterpret_cast<VmAspace*>(oldspace), reinterpret_cast<VmAspace*>(newaspace));
}

zx_status_t vmm_page_fault_handler(vaddr_t addr, uint flags) {

    // hardware fault, mark it as such
    flags |= VMM_PF_FLAG_HW_FAULT;

#if TRACE_PAGE_FAULT || LOCAL_TRACE
    thread_t* current_thread = get_current_thread();
    TRACEF("thread %s va %#" PRIxPTR ", flags 0x%x\n", current_thread->name, addr, flags);
#endif

    ktrace(TAG_PAGE_FAULT, (uint32_t)(addr >> 32), (uint32_t)addr, flags, arch_curr_cpu_num());

    // get the address space object this pointer is in
    VmAspace* aspace = VmAspace::vaddr_to_aspace(addr);
    if (!aspace)
        return ZX_ERR_NOT_FOUND;

    // page fault it
    zx_status_t status = aspace->PageFault(addr, flags);

    // If it's a user fault, dump info about process memory usage.
    // If it's a kernel fault, the kernel could possibly already
    // hold locks on VMOs, Aspaces, etc, so we can't safely do
    // this.
    if ((status == ZX_ERR_NOT_FOUND) && (flags & VMM_PF_FLAG_USER)) {
        printf("PageFault: %zu free pages\n", pmm_count_free_pages());
        DumpProcessMemoryUsage("PageFault: MemoryUsed: ", 8 * 256);
    }

    ktrace(TAG_PAGE_FAULT_EXIT, (uint32_t)(addr >> 32), (uint32_t)addr, flags, arch_curr_cpu_num());

    return status;
}

void vmm_set_active_aspace(vmm_aspace_t* aspace) {
    LTRACEF("aspace %p\n", aspace);

    thread_t* t = get_current_thread();
    DEBUG_ASSERT(t);

    if (aspace == t->aspace)
        return;

    // grab the thread lock and switch to the new address space
    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
    vmm_aspace_t* old = t->aspace;
    t->aspace = aspace;
    vmm_context_switch(old, t->aspace);
}

vmm_aspace_t* vmm_get_kernel_aspace(void) {
    return reinterpret_cast<vmm_aspace_t*>(VmAspace::kernel_aspace());
}

static int cmd_vmm(int argc, const cmd_args* argv, uint32_t flags) {
    if (argc < 2) {
    notenoughargs:
        printf("not enough arguments\n");
    usage:
        printf("usage:\n");
        printf("%s aspaces\n", argv[0].str);
        printf("%s kaspace\n", argv[0].str);
        printf("%s alloc <size> <align_pow2>\n", argv[0].str);
        printf("%s alloc_physical <paddr> <size> <align_pow2>\n", argv[0].str);
        printf("%s alloc_contig <size> <align_pow2>\n", argv[0].str);
        printf("%s free_region <address>\n", argv[0].str);
        printf("%s create_aspace\n", argv[0].str);
        printf("%s create_test_aspace\n", argv[0].str);
        printf("%s free_aspace <address>\n", argv[0].str);
        printf("%s set_test_aspace <address>\n", argv[0].str);
        return ZX_ERR_INTERNAL;
    }

    static fbl::RefPtr<VmAspace> test_aspace;
    if (!test_aspace)
        test_aspace = fbl::WrapRefPtr(VmAspace::kernel_aspace());

    if (!strcmp(argv[1].str, "aspaces")) {
        DumpAllAspaces(true);
    } else if (!strcmp(argv[1].str, "kaspace")) {
        VmAspace::kernel_aspace()->Dump(true);
    } else if (!strcmp(argv[1].str, "alloc")) {
        if (argc < 3)
            goto notenoughargs;

        void* ptr = (void*)0x99;
        uint8_t align = (argc >= 4) ? (uint8_t)argv[3].u : 0u;
        zx_status_t err = test_aspace->Alloc("alloc test", argv[2].u, &ptr, align, 0, 0);
        printf("VmAspace::Alloc returns %d, ptr %p\n", err, ptr);
    } else if (!strcmp(argv[1].str, "alloc_physical")) {
        if (argc < 4)
            goto notenoughargs;

        void* ptr = (void*)0x99;
        uint8_t align = (argc >= 5) ? (uint8_t)argv[4].u : 0u;
        zx_status_t err = test_aspace->AllocPhysical("physical test", argv[3].u, &ptr, align, argv[2].u,
                                                     0, ARCH_MMU_FLAG_UNCACHED_DEVICE | ARCH_MMU_FLAG_PERM_READ |
                                                            ARCH_MMU_FLAG_PERM_WRITE);
        printf("VmAspace::AllocPhysical returns %d, ptr %p\n", err, ptr);
    } else if (!strcmp(argv[1].str, "alloc_contig")) {
        if (argc < 3)
            goto notenoughargs;

        void* ptr = (void*)0x99;
        uint8_t align = (argc >= 4) ? (uint8_t)argv[3].u : 0u;
        zx_status_t err = test_aspace->AllocContiguous("contig test", argv[2].u, &ptr, align, 0,
                                                       ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE);
        printf("VmAspace::AllocContiguous returns %d, ptr %p\n", err, ptr);
    } else if (!strcmp(argv[1].str, "free_region")) {
        if (argc < 2)
            goto notenoughargs;

        zx_status_t err = test_aspace->FreeRegion(reinterpret_cast<vaddr_t>(argv[2].u));
        printf("VmAspace::FreeRegion returns %d\n", err);
    } else if (!strcmp(argv[1].str, "create_aspace")) {
        fbl::RefPtr<VmAspace> aspace = VmAspace::Create(0, "test");
        printf("VmAspace::Create aspace %p\n", aspace.get());
    } else if (!strcmp(argv[1].str, "create_test_aspace")) {
        fbl::RefPtr<VmAspace> aspace = VmAspace::Create(0, "test");
        printf("VmAspace::Create aspace %p\n", aspace.get());

        test_aspace = aspace;
        get_current_thread()->aspace = reinterpret_cast<vmm_aspace_t*>(aspace.get());
        thread_sleep(1); // XXX hack to force it to reschedule and thus load the aspace
    } else if (!strcmp(argv[1].str, "free_aspace")) {
        if (argc < 2)
            goto notenoughargs;

        fbl::RefPtr<VmAspace> aspace = fbl::WrapRefPtr((VmAspace*)(void*)argv[2].u);
        if (test_aspace == aspace)
            test_aspace = nullptr;

        if (get_current_thread()->aspace == reinterpret_cast<vmm_aspace_t*>(aspace.get())) {
            get_current_thread()->aspace = nullptr;
            thread_sleep(1); // hack
        }

        zx_status_t err = aspace->Destroy();
        printf("VmAspace::Destroy() returns %d\n", err);
    } else if (!strcmp(argv[1].str, "set_test_aspace")) {
        if (argc < 2)
            goto notenoughargs;

        test_aspace = fbl::WrapRefPtr((VmAspace*)(void*)argv[2].u);
        get_current_thread()->aspace = reinterpret_cast<vmm_aspace_t*>(test_aspace.get());
        thread_sleep(1); // XXX hack to force it to reschedule and thus load the aspace
    } else {
        printf("unknown command\n");
        goto usage;
    }

    return ZX_OK;
}

STATIC_COMMAND_START
#if LK_DEBUGLEVEL > 0
STATIC_COMMAND("vmm", "virtual memory manager", &cmd_vmm)
#endif
STATIC_COMMAND_END(vmm);
