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

#pragma once

#include <assert.h>
#include <kernel/mutex.h>
#include <kernel/vm.h>
#include <lib/user_copy/user_ptr.h>
#include <list.h>
#include <zircon/thread_annotations.h>
#include <fbl/array.h>
#include <fbl/canary.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <stdint.h>
#include <vm/pmm.h>
#include <vm/vm_object.h>
#include <vm/vm_page_list.h>

// the main VM object type, holding a list of pages
class VmObjectPaged final : public VmObject {
public:
    static status_t Create(uint32_t pmm_alloc_flags, uint64_t size, fbl::RefPtr<VmObject>* vmo);

    static status_t CreateFromROData(const void* data, size_t size, fbl::RefPtr<VmObject>* vmo);

    status_t Resize(uint64_t size) override;
    status_t ResizeLocked(uint64_t size) override TA_REQ(lock_);
    uint64_t size() const override
        // TODO: Figure out whether it's safe to lock here without causing
        // any deadlocks.
        TA_NO_THREAD_SAFETY_ANALYSIS { return size_; }
    bool is_paged() const override { return true; }

    size_t AllocatedPagesInRange(uint64_t offset, uint64_t len) const override;

    status_t CommitRange(uint64_t offset, uint64_t len, uint64_t* committed) override;
    status_t CommitRangeContiguous(uint64_t offset, uint64_t len, uint64_t* committed,
                                   uint8_t alignment_log2) override;
    status_t DecommitRange(uint64_t offset, uint64_t len, uint64_t* decommitted) override;

    status_t Pin(uint64_t offset, uint64_t len) override;
    void Unpin(uint64_t offset, uint64_t len) override;

    status_t Read(void* ptr, uint64_t offset, size_t len, size_t* bytes_read) override;
    status_t Write(const void* ptr, uint64_t offset, size_t len, size_t* bytes_written) override;
    status_t Lookup(uint64_t offset, uint64_t len, uint pf_flags,
                    vmo_lookup_fn_t lookup_fn, void* context) override;

    status_t ReadUser(user_ptr<void> ptr, uint64_t offset, size_t len,
                      size_t* bytes_read) override;
    status_t WriteUser(user_ptr<const void> ptr, uint64_t offset, size_t len,
                       size_t* bytes_written) override;

    status_t LookupUser(uint64_t offset, uint64_t len, user_ptr<paddr_t> buffer,
                        size_t buffer_size) override;

    void Dump(uint depth, bool verbose) override;

    status_t InvalidateCache(const uint64_t offset, const uint64_t len) override;
    status_t CleanCache(const uint64_t offset, const uint64_t len) override;
    status_t CleanInvalidateCache(const uint64_t offset, const uint64_t len) override;
    status_t SyncCache(const uint64_t offset, const uint64_t len) override;

    status_t GetPageLocked(uint64_t offset, uint pf_flags, list_node* free_list,
                           vm_page_t**, paddr_t*) override
        // Calls a Locked method of the parent, which confuses analysis.
        TA_NO_THREAD_SAFETY_ANALYSIS;

    status_t CloneCOW(uint64_t offset, uint64_t size, bool copy_name,
                      fbl::RefPtr<VmObject>* clone_vmo) override
        // Calls a Locked method of the child, which confuses analysis.
        TA_NO_THREAD_SAFETY_ANALYSIS;

    void RangeChangeUpdateFromParentLocked(uint64_t offset, uint64_t len) override
        // Called under the parent's lock, which confuses analysis.
        TA_NO_THREAD_SAFETY_ANALYSIS;

private:
    // private constructor (use Create())
    explicit VmObjectPaged(uint32_t pmm_alloc_flags, fbl::RefPtr<VmObject> parent);

    // private destructor, only called from refptr
    ~VmObjectPaged() override;
    friend fbl::RefPtr<VmObjectPaged>;

    DISALLOW_COPY_ASSIGN_AND_MOVE(VmObjectPaged);

    // perform a cache maintenance operation against the vmo.
    enum class CacheOpType { Invalidate,
                             Clean,
                             CleanInvalidate,
                             Sync };
    status_t CacheOp(const uint64_t offset, const uint64_t len, const CacheOpType type);

    // add a page to the object
    status_t AddPage(vm_page_t* p, uint64_t offset);
    status_t AddPageLocked(vm_page_t* p, uint64_t offset) TA_REQ(lock_);

    // internal page list routine
    void AddPageToArray(size_t index, vm_page_t* p);

    status_t PinLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);
    void UnpinLocked(uint64_t offset, uint64_t len) TA_REQ(lock_);

    // internal check if any pages in a range are pinned
    bool AnyPagesPinnedLocked(uint64_t offset, size_t len) TA_REQ(lock_);

    // internal read/write routine that takes a templated copy function to help share some code
    template <typename T>
    status_t ReadWriteInternal(uint64_t offset, size_t len, size_t* bytes_copied, bool write,
                               T copyfunc);

    // set our offset within our parent
    status_t SetParentOffsetLocked(uint64_t o) TA_REQ(lock_);

    // maximum size of a VMO is one page less than the full 64bit range
    static const uint64_t MAX_SIZE = ROUNDDOWN(UINT64_MAX, PAGE_SIZE);

    // members
    uint64_t size_ TA_GUARDED(lock_) = 0;
    uint64_t parent_offset_ TA_GUARDED(lock_) = 0;
    uint32_t pmm_alloc_flags_ TA_GUARDED(lock_) = PMM_ALLOC_FLAG_ANY;

    // a tree of pages
    VmPageList page_list_ TA_GUARDED(lock_);
};
