// 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/cpp/sizes.h>
#include <vm/vm.h>

using pretty::FormattedBytes;

#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];

    // 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, FormattedBytes(r.get_size()).str());
        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, FormattedBytes(r.get_size()).str());
        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, FormattedBytes(r.get_size()).str());
        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, FormattedBytes(r.get_size()).str());
        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)
