// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_MAPPING_H_
#define GPU_MAPPING_H_

#include "magma_util/macros.h"
#include "platform_bus_mapper.h"
#include <cstdint>
#include <memory>
#include <vector>

class MsdArmBuffer;
class MsdArmConnection;

// A buffer may be mapped into a connection at multiple virtual addresses. The
// connection owns the GpuMapping, so |owner_| is always valid. The buffer
// deletes all the mappings it owns before it's destroyed, so that's why
// |buffer_| is always valid.
class GpuMapping {
public:
    class Owner {
    public:
        virtual bool RemoveMapping(uint64_t address) = 0;
        virtual bool UpdateCommittedMemory(GpuMapping* mapping) = 0;
    };

    GpuMapping(uint64_t addr, uint64_t page_offset, uint64_t size, uint64_t flags, Owner* owner,
               std::shared_ptr<MsdArmBuffer> buffer);

    ~GpuMapping();

    uint64_t gpu_va() const { return addr_; }
    uint64_t page_offset() const { return page_offset_; }
    uint64_t size() const { return size_; }
    uint64_t flags() const { return flags_; }

    uint64_t pinned_page_count() const { return pinned_page_count_; }
    void shrink_pinned_pages(uint64_t pages_removed,
                             std::unique_ptr<magma::PlatformBusMapper::BusMapping> bus_mapping)
    {
        DASSERT(pinned_page_count_ >= pages_removed);
        pinned_page_count_ -= pages_removed;
        if (bus_mapping) {
            DASSERT(pinned_page_count_ == bus_mapping->page_count());
            if (magma::kDebug) {
                // Check that the physical addresses of pages haven't changed
                // (e.g. due to being mapped to a new place with the iommu).
                for (auto& mapping : bus_mappings_) {
                    for (uint32_t i = 0; i < mapping->page_count(); i++) {
                        if (mapping->page_offset() + i < bus_mapping->page_offset())
                            continue;
                        uint64_t new_offset =
                            mapping->page_offset() + i - bus_mapping->page_offset();
                        if (new_offset >= bus_mapping->page_count())
                            continue;
                        DASSERT(bus_mapping->Get()[new_offset] == mapping->Get()[i]);
                    }
                }
            }

            bus_mappings_.clear();
            bus_mappings_.push_back(std::move(bus_mapping));
        }
    }
    void grow_pinned_pages(std::unique_ptr<magma::PlatformBusMapper::BusMapping> bus_mapping)
    {
        pinned_page_count_ += bus_mapping->page_count();
        bus_mappings_.push_back(std::move(bus_mapping));
    }

    std::weak_ptr<MsdArmBuffer> buffer() const;
    void Remove() { owner_->RemoveMapping(addr_); }
    bool UpdateCommittedMemory() { return owner_->UpdateCommittedMemory(this); }

private:
    friend class TestConnection;
    const uint64_t addr_;
    const uint64_t page_offset_;
    const uint64_t size_;
    const uint64_t flags_;
    Owner* const owner_;
    uint64_t pinned_page_count_ = 0;
    std::weak_ptr<MsdArmBuffer> buffer_;
    std::vector<std::unique_ptr<magma::PlatformBusMapper::BusMapping>> bus_mappings_;
};

#endif // GPU_MAPPING_H_
