// 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 <object/resource_dispatcher.h>

#include <fbl/alloc_checker.h>
#include <inttypes.h>
#include <kernel/auto_lock.h>
#include <kernel/range_check.h>
#include <lib/counters.h>
#include <pretty/sizes.h>
#include <string.h>
#include <trace.h>
#include <vm/vm.h>
#include <zircon/rights.h>
#include <zircon/syscalls/resource.h>

#define LOCAL_TRACE 0

KCOUNTER(root_resource_created, "resource.root.created")
KCOUNTER(hypervisor_resource_created, "resource.hypervisor.created")
KCOUNTER(vmex_resource_created, "resource.vmex.created")
KCOUNTER(mmio_resource_created, "resource.mmio.created")
KCOUNTER(irq_resource_created, "resource.irq.created")
KCOUNTER(ioport_resource_created, "resource.ioport.created")
KCOUNTER(smc_resource_created, "resource.smc.created")
KCOUNTER(dispatcher_resource_create_count, "dispatcher.resource.create")
KCOUNTER(dispatcher_resource_destroy_count, "dispatcher.resource.destroy")

// Storage for static members of ResourceDispatcher
RegionAllocator ResourceDispatcher::static_rallocs_[ZX_RSRC_KIND_COUNT];
ResourceDispatcher::ResourceList ResourceDispatcher::static_resource_list_;
RegionAllocator::RegionPool::RefPtr ResourceDispatcher::region_pool_;
const char* kLogTag = "Resources:";

zx_status_t ResourceDispatcher::Create(KernelHandle<ResourceDispatcher>* handle,
                                       zx_rights_t* rights,
                                       uint32_t kind,
                                       uint64_t base,
                                       size_t size,
                                       uint32_t flags,
                                       const char name[ZX_MAX_NAME_LEN],
                                       RegionAllocator rallocs[ZX_RSRC_KIND_COUNT],
                                       ResourceList* resource_list) {
    Guard<Mutex> guard{ResourcesLock::Get()};
    if (kind >= ZX_RSRC_KIND_COUNT || (flags & ZX_RSRC_FLAGS_MASK) != flags) {
        return ZX_ERR_INVALID_ARGS;
    }

    // The first thing we need to do for any resource is ensure that it has not
    // been exclusively reserved. If GetRegion succeeds and we have a region
    // uptr then in the case of an exclusive resource we'll move it into the
    // class instance. Otherwise, the resource is shared and we'll release it
    // back to the allocator since we only used it to verify it existed in the
    // allocator.
    //
    // TODO: Hypervisor resources should be represented in some other capability
    // object because they represent a binary permission rather than anything
    // more finely grained. It will work properly here because the base/size of a
    // hypervisor resource is never checked, but it's a workaround until a
    // proper capability exists for it.
    zx_status_t status;
    RegionAllocator::Region::UPtr region_uptr = nullptr;
    switch (kind) {
    case ZX_RSRC_KIND_ROOT:
    case ZX_RSRC_KIND_HYPERVISOR:
    case ZX_RSRC_KIND_VMEX:
        // It does not make sense for an abstract resource type to have a base/size tuple
        if (base || size) {
            return ZX_ERR_INVALID_ARGS;
        }
        break;
    default:
        status = rallocs[kind].GetRegion({.base = base, .size = size}, region_uptr);
        if (status != ZX_OK) {
            LTRACEF("%s couldn't pull the resource out of the ralloc %d\n", kLogTag, status);
            return status;
        }
    }

    // If the allocation is exclusive then a check needs to be made to ensure
    // that no shared allocation already exists and/or overlaps. Shared
    // resources don't need to do so because grabbing the exclusive region above
    // (temporarily) ensures they are valid allocations. If this check fails
    // then the region above will be released back to the pool anyway.
    if (flags & ZX_RSRC_FLAG_EXCLUSIVE) {
        auto callback = [&](const ResourceDispatcher& rsrc) {
            LTRACEF("%s walking resources, found [%u, %#lx, %zu]\n", kLogTag, rsrc.get_kind(),
                    rsrc.get_base(), rsrc.get_size());
            if (kind != rsrc.get_kind()) {
                return ZX_OK;
            }

            if (Intersects(base, size, rsrc.get_base(), rsrc.get_size())) {
                LTRACEF("%s [%#lx, %zu] intersects with [%#lx, %zu] found in list!\n", kLogTag,
                        base, size, rsrc.get_base(), rsrc.get_size());
                return ZX_ERR_NOT_FOUND;
            }

            return ZX_OK;
        };
        LTRACEF("%s scanning resource list for [%u, %#lx, %zu]\n", kLogTag, kind, base, size);
        zx_status_t status = ResourceDispatcher::ForEachResourceLocked(callback, resource_list);
        if (status != ZX_OK) {
            return status;
        }
    }

    // We've passed the first hurdle, so it's time to construct the dispatcher
    // itself. The constructor will handle adding itself to the shared list if
    // necessary.
    fbl::AllocChecker ac;
    KernelHandle new_handle(fbl::AdoptRef(new (&ac) ResourceDispatcher(kind, base, size, flags,
                                                                       ktl::move(region_uptr),
                                                                       rallocs, resource_list)));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    if (name != nullptr) {
        new_handle.dispatcher()->set_name(name, ZX_MAX_NAME_LEN);
    }

    *rights = default_rights();
    *handle = ktl::move(new_handle);

    LTRACEF("%s [%u, %#lx, %zu] resource created.\n", kLogTag, kind, base, size);
    return ZX_OK;
}

ResourceDispatcher::ResourceDispatcher(uint32_t kind,
                                       uint64_t base,
                                       uint64_t size,
                                       uint32_t flags,
                                       RegionAllocator::Region::UPtr&& region,
                                       RegionAllocator rallocs[ZX_RSRC_KIND_COUNT],
                                       ResourceList* resource_list)
    : kind_(kind), base_(base), size_(size), flags_(flags),
      resource_list_(resource_list) {

    kcounter_add(dispatcher_resource_create_count, 1);

    if (flags_ & ZX_RSRC_FLAG_EXCLUSIVE) {
        exclusive_region_ = ktl::move(region);
    }

    switch (kind_) {
    case ZX_RSRC_KIND_ROOT:
        kcounter_add(root_resource_created, 1);
        break;
    case ZX_RSRC_KIND_HYPERVISOR:
        kcounter_add(hypervisor_resource_created, 1);
        break;
    case ZX_RSRC_KIND_VMEX:
        kcounter_add(vmex_resource_created, 1);
        break;
    case ZX_RSRC_KIND_MMIO:
        kcounter_add(mmio_resource_created, 1);
        break;
    case ZX_RSRC_KIND_IRQ:
        kcounter_add(irq_resource_created, 1);
        break;
    case ZX_RSRC_KIND_IOPORT:
        kcounter_add(ioport_resource_created, 1);
        break;
    case ZX_RSRC_KIND_SMC:
        kcounter_add(smc_resource_created, 1);
        break;
    }
    resource_list_->push_back(this);
}

ResourceDispatcher::~ResourceDispatcher() {
    kcounter_add(dispatcher_resource_destroy_count, 1);

    // exclusive allocations will be released when the uptr goes out of scope,
    // shared need to be removed from |all_shared_list_|
    Guard<Mutex> guard{ResourcesLock::Get()};
    char name[ZX_MAX_NAME_LEN];
    get_name(name);
    resource_list_->erase(*this);
}

zx_status_t ResourceDispatcher::InitializeAllocator(uint32_t kind,
                                                    uint64_t base,
                                                    size_t size,
                                                    RegionAllocator rallocs[ZX_RSRC_KIND_COUNT]) {
    DEBUG_ASSERT(kind < ZX_RSRC_KIND_COUNT);
    DEBUG_ASSERT(size > 0);

    Guard<Mutex> guard{ResourcesLock::Get()};
    zx_status_t status;

    // This method should only be called for resource kinds with bookkeeping.
    if (kind >= ZX_RSRC_KIND_COUNT) {
        return ZX_ERR_INVALID_ARGS;
    }

    // Create the initial region pool if necessary. Its storage is allocated in this cpp file
    if (region_pool_ == nullptr) {
        region_pool_ = RegionAllocator::RegionPool::Create(kMaxRegionPoolSize);
    }

    // Failure to allocate this early in boot is a critical error
    DEBUG_ASSERT(region_pool_);

    status = rallocs[kind].SetRegionPool(region_pool_);
    if (status != ZX_OK) {
        return status;
    }

    // Add the initial address space specified by the platform to the region allocator.
    // This will be used for verifying both shared and exclusive allocations of address
    // space.
    status = rallocs[kind].AddRegion({.base = base, .size = size});
    LTRACEF("%s added [%#lx, %zu] to kind %u in allocator %p: %d\n",
            kLogTag, base, size, kind, rallocs, status);
    return status;
}

// Size specifiers for the debug output
constexpr int kTypeLen = 10;
constexpr int kFlagLen = 6;
constexpr int kNameLen = ZX_MAX_NAME_LEN - 1;
constexpr int kNumLen = 16;
constexpr int kPrettyLen = 8;

// Utility function to format the flags into a user-readable string.
static constexpr void flags_to_string(uint32_t flags, char str[kFlagLen]) {
    str[0] = ' ';
    str[1] = ' ';
    str[2] = ' ';
    str[3] = (flags & ZX_RSRC_FLAG_EXCLUSIVE) ? ' ' : 's';
    str[4] = (flags & ZX_RSRC_FLAG_EXCLUSIVE) ? 'x' : ' ';
    str[5] = '\0';
}

static void pad_field(int width) {
    printf("\t%.*s", width, "                        ");
}

void ResourceDispatcher::Dump() {
    uint32_t kind;
    auto callback = [&](const ResourceDispatcher& r) -> zx_status_t {
        char name[ZX_MAX_NAME_LEN];
        char flag_str[kFlagLen];
        char pretty_size[kPrettyLen];

        // exit early so we can print the list in a grouped format
        // without adding overhead to the list management.
        if (r.get_kind() != kind) {
            return ZX_OK;
        }

        // A safety check to make sure we don't need to worry about snprintf edge cases
        r.get_name(name);
        flags_to_string(r.get_flags(), flag_str);

        // IRQs are allocated one at a time, so range display doesn't make much sense.
        switch (r.get_kind()) {
        case ZX_RSRC_KIND_ROOT:
            printf("%.*s", kTypeLen, "root");
            pad_field(kFlagLen); // Root has no flags
            printf("\t%.*s", kNameLen, name);
            printf("\n");
            break;
        case ZX_RSRC_KIND_HYPERVISOR:
            printf("%.*s", kTypeLen, "hypervisor");
            printf("\t%.*s", kFlagLen, flag_str);
            printf("\t%.*s", kNameLen, name);
            printf("\n");
            break;
        case ZX_RSRC_KIND_IRQ:
            printf("%.*s", kTypeLen, "irq");
            printf("\t%.*s", kFlagLen, flag_str);
            printf("\t%.*s", kNameLen, name);
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base());
            printf("\n");
            break;
        case ZX_RSRC_KIND_IOPORT:
            printf("%.*s", kTypeLen, "io");
            printf("\t%.*s", kFlagLen, flag_str);
            printf("\t%.*s", kNameLen, name);
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base());
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base() + r.get_size());
            printf("\t%.*s", kPrettyLen,
                   format_size(pretty_size, sizeof(pretty_size), r.get_size()));
            printf("\n");
            break;
        case ZX_RSRC_KIND_MMIO:
            printf("%.*s", kTypeLen, "mmio");
            printf("\t%.*s", kFlagLen, flag_str);
            printf("\t%.*s", kNameLen, name);
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base());
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base() + r.get_size());
            printf("\t%.*s", kPrettyLen,
                   format_size(pretty_size, sizeof(pretty_size), r.get_size()));
            printf("\n");
            break;
        case ZX_RSRC_KIND_SMC:
            printf("%.*s", kTypeLen, "smc");
            printf("\t%.*s", kFlagLen, flag_str);
            printf("\t%.*s", kNameLen, name);
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base());
            printf("\t%#.*" PRIxPTR, kNumLen, r.get_base() + r.get_size());
            printf("\t%.*s", kPrettyLen,
                   format_size(pretty_size, sizeof(pretty_size), r.get_size()));
            printf("\n");
            break;
        }

        return ZX_OK;
    };

    printf("%10s\t%4s\t%31s\t%16s\t%16s\t%8s\n\n", "type", "flags", "name", "start", "end", "size");
    for (kind = 0; kind < ZX_RSRC_KIND_COUNT; kind++) {
        ResourceDispatcher::ForEachResource(callback);
    }
}

#include <lib/console.h>

static int cmd_resources(int argc, const cmd_args* argv, uint32_t flags) {
    ResourceDispatcher::Dump();
    return true;
}

STATIC_COMMAND_START
STATIC_COMMAND("resource", "Inspect physical address space resource allocations", &cmd_resources)
STATIC_COMMAND_END(resources)
