// 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 <inttypes.h>
#include <lib/counters.h>
#include <string.h>
#include <trace.h>
#include <zircon/rights.h>
#include <zircon/syscalls/resource.h>

#include <fbl/alloc_checker.h>
#include <kernel/auto_lock.h>
#include <kernel/range_check.h>
#include <pretty/sizes.h>
#include <vm/vm.h>

#define LOCAL_TRACE 0

KCOUNTER(root_resource_created, "resource.root.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(system_resource_created, "resource.system.created")
KCOUNTER(dispatcher_resource_create_count, "dispatcher.resource.create")
KCOUNTER(dispatcher_resource_destroy_count, "dispatcher.resource.destroy")

// Storage for static members of ResourceDispatcher
ResourceDispatcher::ResourceStorage ResourceDispatcher::static_storage_;
RegionAllocator::RegionPool::RefPtr ResourceDispatcher::region_pool_;
const char* kLogTag = "Resources:";

// The Create() method here only validates exclusive allocations because
// the kernel is permitted to create shared resources without restriction.
// Validation of parent handles is handled at the syscall boundary in the
// implementation for |zx_resource_create|.
zx_status_t ResourceDispatcher::Create(KernelHandle<ResourceDispatcher>* handle,
                                       zx_rights_t* rights, zx_rsrc_kind_t kind, uint64_t base,
                                       size_t size, uint32_t flags,
                                       const char name[ZX_MAX_NAME_LEN], ResourceStorage* storage) {
  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.

  // Use the local static bookkeeping for system resources unless mocks are passed in.
  if (storage == nullptr) {
    storage = &static_storage_;
  }

  zx_status_t status;
  RegionAllocator::Region::UPtr region_uptr = nullptr;
  switch (kind) {
    case ZX_RSRC_KIND_ROOT:
      // 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:
      // If we have not assigned a region pool to our allocator yet, then we are not
      // yet initialized and should return ZX_ERR_BAD_STATE.
      if (!storage->rallocs[kind].HasRegionPool()) {
        return ZX_ERR_BAD_STATE;
      }

      status = storage->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, storage);
    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), storage)));
  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;
}

// The CreateRootRanged() method here does not validate exclusive allocations because
// it represents a ranged resource with all valid regions.
// Validation of regions is handled at the syscall boundary in the
// implementation for |zx_resource_create|.
zx_status_t ResourceDispatcher::CreateRangedRoot(KernelHandle<ResourceDispatcher>* handle,
                                                 zx_rights_t* rights, zx_rsrc_kind_t kind,
                                                 const char name[ZX_MAX_NAME_LEN],
                                                 ResourceStorage* storage) {
  Guard<Mutex> guard{ResourcesLock::Get()};
  if (kind >= ZX_RSRC_KIND_COUNT) {
    return ZX_ERR_INVALID_ARGS;
  }

  // Use the local static bookkeeping for system resources unless mocks are passed in.
  if (storage == nullptr) {
    storage = &static_storage_;
  }

  // Abstract resource types have no size. Ranged resource types are given infinite size to
  // indicate that they represent all valid ranges.
  switch (kind) {
    // TODO(smpham): remove this when root resource is removed.
    case ZX_RSRC_KIND_ROOT:
      // The Create() method should be used for making these resource kinds.
      return ZX_ERR_WRONG_TYPE;
    default:
      // If we have not assigned a region pool to our allocator yet, then we are not
      // yet initialized and should return ZX_ERR_BAD_STATE.
      if (!storage->rallocs[kind].HasRegionPool()) {
        return ZX_ERR_BAD_STATE;
      }
  }

  // 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, 0, 0, 0, nullptr, storage)));
  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] ranged root resource created.\n", kLogTag, kind);
  return ZX_OK;
}

ResourceDispatcher::ResourceDispatcher(zx_rsrc_kind_t kind, uint64_t base, uint64_t size,
                                       uint32_t flags, RegionAllocator::Region::UPtr&& region,
                                       ResourceStorage* storage)
    : kind_(kind),
      base_(base),
      size_(size),
      flags_(flags),
      resource_list_(&storage->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_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;
    case ZX_RSRC_KIND_SYSTEM:
      kcounter_add(system_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(zx_rsrc_kind_t kind, uint64_t base, size_t size,
                                                    ResourceStorage* storage) {
  DEBUG_ASSERT(kind < ZX_RSRC_KIND_COUNT);
  DEBUG_ASSERT(size > 0);

  // Static methods need to check for mocks manually.
  if (storage == nullptr) {
    storage = &static_storage_;
  }

  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 = storage->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 = storage->rallocs[kind].AddRegion({.base = base, .size = size});
  LTRACEF("%s added [%#lx, %zu] to kind %u in allocator %p: %d\n", kLogTag, base, size, kind,
          &storage->rallocs[kind], 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() {
  zx_rsrc_kind_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");
        printf("\t%8lu", r.get_koid());
        pad_field(kFlagLen);  // Root has no flags
        printf("\t%.*s", kNameLen, name);
        printf("\n");
        break;
      case ZX_RSRC_KIND_IRQ:
        printf("%.*s", kTypeLen, "irq");
        printf("\t%8lu", r.get_koid());
        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%.*zu", kPrettyLen, r.get_size());
        printf("\n");
        break;
      case ZX_RSRC_KIND_IOPORT:
        printf("%.*s", kTypeLen, "io");
        printf("\t%8lu", r.get_koid());
        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%8lu", r.get_koid());
        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%8lu", r.get_koid());
        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_SYSTEM:
        printf("%.*s", kTypeLen, "system");
        printf("\t%8lu", r.get_koid());
        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%8s\t%4s\t%31s\t%16s\t%16s\t%8s\n\n", "type", "koid", "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)
