// Copyright 2017 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_PINNED_MEMORY_TOKEN_DISPATCHER_H_
#define ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_PINNED_MEMORY_TOKEN_DISPATCHER_H_

#include <sys/types.h>
#include <zircon/rights.h>
#include <zircon/types.h>

#include <dev/iommu.h>
#include <fbl/array.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/ref_ptr.h>
#include <object/dispatcher.h>
#include <object/handle.h>
#include <vm/pinned_vm_object.h>

class BusTransactionInitiatorDispatcher;
class VmObject;

// The tag for the list type used by the containing BTI to hold a list of all
// its PMTs, including those which are quarantined.
struct PmtListTag {};

// The tag for the list type used by the containing BTI to hold a list of all
// its quarantined PMTs.
struct PmtQuarantineListTag {};

class PinnedMemoryTokenDispatcher final
    : public SoloDispatcher<PinnedMemoryTokenDispatcher, ZX_DEFAULT_PMT_RIGHTS>,
      public fbl::ContainableBaseClasses<
          fbl::TaggedDoublyLinkedListable<PinnedMemoryTokenDispatcher*, PmtListTag>,
          fbl::TaggedDoublyLinkedListable<fbl::RefPtr<PinnedMemoryTokenDispatcher>, PmtQuarantineListTag>
      > {
 public:
  ~PinnedMemoryTokenDispatcher();

  zx_obj_type_t get_type() const final { return ZX_OBJ_TYPE_PMT; }
  void on_zero_handles() final;

  // Unpin this PMT. If this is not done before on_zero_handles() runs, then it will get moved to
  // the quarantine.
  void Unpin();

  // |mapped_addrs_count| must be either
  // 1) If |compress_results|, |pinned_vmo_.size()|/|bti_.minimum_contiguity()|, rounded up, in
  // which case each returned address represents a run of |bti_.minimum_contiguity()| bytes (with
  // the exception of the last which may be short)
  // 2) If |contiguous|, 1, in which case the returned address is the start of the
  // contiguous memory.
  // 3) Otherwise, |pinned_vmo_.size()|/|PAGE_SIZE|, in which case each returned address
  // represents a single page.
  //
  // Returns ZX_ERR_INVALID_ARGS if |mapped_addrs_count| is not exactly the value described above.
  zx_status_t EncodeAddrs(bool compress_results, bool contiguous, dev_vaddr_t* mapped_addrs,
                          size_t mapped_addrs_count);

  // Returns the number of bytes pinned by the PMT.
  uint64_t size() const { return pinned_vmo_.size(); }

 protected:
  friend BusTransactionInitiatorDispatcher;
  // Set the permissions of |pinned_vmo|'s pinned range to |perms| on
  // behalf of |bti|. |perms| should be flags suitable for the Iommu::Map()
  // interface.  Must be created under the BTI dispatcher's lock.
  static zx_status_t Create(fbl::RefPtr<BusTransactionInitiatorDispatcher> bti,
                            PinnedVmObject pinned_vmo, uint32_t perms,
                            KernelHandle<PinnedMemoryTokenDispatcher>* handle, zx_rights_t* rights);

 private:
  PinnedMemoryTokenDispatcher(fbl::RefPtr<BusTransactionInitiatorDispatcher> bti,
                              PinnedVmObject pinned_vmo, fbl::Array<dev_vaddr_t> mapped_addrs);
  DISALLOW_COPY_ASSIGN_AND_MOVE(PinnedMemoryTokenDispatcher);

  zx_status_t MapIntoIommu(uint32_t perms);
  zx_status_t UnmapFromIommuLocked() TA_REQ(get_lock());

  void InvalidateMappedAddrsLocked() TA_REQ(get_lock());

  PinnedVmObject pinned_vmo_;

  // Set to true by Unpin()
  bool explicitly_unpinned_ TA_GUARDED(get_lock()) = false;

  const fbl::RefPtr<BusTransactionInitiatorDispatcher> bti_;
  const fbl::Array<dev_vaddr_t> mapped_addrs_ TA_GUARDED(get_lock());

  // Set to true during Create() once we are fully initialized. Do not call
  // any |bti_| locking methods if this is false, since that indicates we're
  // being called from Create() and already have the |bti_| lock.
  bool initialized_ = false;
};

#endif  // ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_PINNED_MEMORY_TOKEN_DISPATCHER_H_
