// 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

#ifndef ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_RESOURCE_DISPATCHER_H_
#define ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_RESOURCE_DISPATCHER_H_

#include <lib/zircon-internal/thread_annotations.h>
#include <sys/types.h>
#include <zircon/compiler.h>
#include <zircon/rights.h>
#include <zircon/syscalls/resource.h>
#include <zircon/types.h>

#include <array>

#include <fbl/intrusive_double_list.h>
#include <fbl/name.h>
#include <kernel/lockdep.h>
#include <kernel/mutex.h>
#include <object/dispatcher.h>
#include <object/handle.h>
#include <region-alloc/region-alloc.h>

class ResourceRecord;

class ResourceDispatcher final
    : public SoloDispatcher<ResourceDispatcher, ZX_DEFAULT_RESOURCE_RIGHTS>,
      public fbl::DoublyLinkedListable<ResourceDispatcher*> {
 public:
  static constexpr size_t kMaxRegionPoolSize = 64 << 10;

  using ResourceList = fbl::DoublyLinkedList<ResourceDispatcher*>;
  using RefPtr = fbl::RefPtr<ResourceDispatcher>;

  struct ResourceStorage {
    ResourceList resource_list;
    ktl::array<RegionAllocator, ZX_RSRC_KIND_COUNT> rallocs;
  };

  // Creates ResourceDispatcher object representing access rights to a
  // given region of address space from a particular address space allocator, or a root resource
  // granted full access permissions. Only one instance of the root resource is created at boot.
  static zx_status_t 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* = nullptr);
  // Creates ResourceDispatcher object representing access rights to all
  // regions of address space for a ranged resource.
  static zx_status_t CreateRangedRoot(KernelHandle<ResourceDispatcher>* handle, zx_rights_t* rights,
                                      zx_rsrc_kind_t kind, const char name[ZX_MAX_NAME_LEN],
                                      ResourceStorage* storage = nullptr);
  // Initializes the static mmembers used for bookkeeping and storage.
  static zx_status_t InitializeAllocator(zx_rsrc_kind_t kind, uint64_t base, size_t size,
                                         ResourceStorage* = nullptr);
  static void DumpResources();
  static void DumpAllocators();

  template <typename T>
  static zx_status_t ForEachResource(T func, ResourceStorage* storage = nullptr)
      TA_EXCL(ResourcesLock::Get()) {
    Guard<Mutex> guard{ResourcesLock::Get()};
    return ForEachResourceLocked(func, (storage != nullptr) ? storage : &static_storage_);
  }

  bool IsRangedRoot(zx_rsrc_kind_t kind) const {
    switch (kind_) {
      case ZX_RSRC_KIND_ROOT:
        return false;
    }
    return (kind_ == kind && base_ == 0 && size_ == 0);
  }

  zx_obj_type_t get_type() const final { return ZX_OBJ_TYPE_RESOURCE; }

  // Returns a null-terminated name, or the empty string if set_name() has not
  // been called.
  void get_name(char (&out_name)[ZX_MAX_NAME_LEN]) const final {
    name_.get(ZX_MAX_NAME_LEN, out_name);
  }

  // Sets the name of the object. May truncate internally. |size| is the size
  // of the buffer pointed to by |name|.
  zx_status_t set_name(const char* name, size_t size) final { return name_.set(name, size); }

  uint64_t get_base() const { return base_; }
  size_t get_size() const { return size_; }
  uint32_t get_kind() const { return kind_; }
  uint32_t get_flags() const { return flags_; }
  ~ResourceDispatcher();

 private:
  ResourceDispatcher(zx_rsrc_kind_t kind, uint64_t base, size_t size, uint32_t flags,
                     RegionAllocator::Region::UPtr&& region, ResourceStorage* storage);

  template <typename T>
  static zx_status_t ForEachResourceLocked(T callback, ResourceStorage* storage)
      TA_REQ(ResourcesLock::Get()) {
    for (const auto& resource : storage->resource_list) {
      zx_status_t status = callback(resource);
      if (status != ZX_OK) {
        return status;
      }
    }
    return ZX_OK;
  }

  const zx_rsrc_kind_t kind_;
  const uint64_t base_;
  const size_t size_;
  const uint32_t flags_;
  ResourceList* resource_list_;
  fbl::Name<ZX_MAX_NAME_LEN> name_;
  RegionAllocator::Region::UPtr exclusive_region_;

  // Static tracking data structures for physical address space allocations.
  // Exclusive allocations are pulled out of the RegionAllocators, and all
  // allocations are added to |static_resource_list_|. Shared allocations will
  // check that no exclusive reservation exists, but then release the region
  // back to the allocator. Likewise, exclusive allocations will check to
  // ensure that the region has not already been allocated as a shared region
  // by checking the static resource list.
  DECLARE_SINGLETON_MUTEX(ResourcesLock);
  static RegionAllocator::RegionPool::RefPtr region_pool_;
  // A single global list is used for all resources so that root and hypervisor resources can
  // still be tracked, and filtering can be done via client tools/commands when displaying
  // the list is concerned.
  static ResourceStorage static_storage_ TA_GUARDED(ResourcesLock::Get());
};

#endif  // ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_RESOURCE_DISPATCHER_H_
