// 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 Dump();

  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_
