// 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/auto_lock.h>
#include <kernel/mutex.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);
    }

    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
    AutoThreadLock lock;
    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);
