// Copyright 2018 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 LIB_MMIO_MMIO_H_
#define LIB_MMIO_MMIO_H_

#include <ddk/debug.h>
#include <ddk/mmio-buffer.h>
#include <fbl/macros.h>
#include <hw/arch_ops.h>
#include <lib/zx/bti.h>
#include <lib/zx/resource.h>
#include <lib/zx/vmo.h>
#include <optional>
#include <string.h>
#include <utility>
#include <zircon/assert.h>
#include <zircon/process.h>

namespace ddk {

// Usage Notes:
//
// ddk::MmioBuffer is a c++ wrapper around the mmio_buffer_t object. It provides
// capabilities to map an MMIO region provided by a VMO, and accessors to read and
// write the MMIO region. Destroying it will result in the MMIO region being
// unmapped. All read/write operations are bounds checked.
//
// ddk::MmioView provides a slice view of an mmio region. It provides the same
// accessors provided by MmioBuffer, but does not manage the buffer's mapping.
// It must not outlive the ddk::MmioBuffer it is spawned from.
//
// ddk::MmioPinnedBuffer is a c++ wrapper around the mmio_pinned_buffer_t object.
// It is generated by calling |Pin()| on a MmioBuffer or MmioView and provides
// access to the physical address space for the region. Performing pinning on MmioView
// will only pin the pages associated with the MmioView, and not the entire
// MmioBuffer. Destorying MmioPInnedBuffer will unpin the memory.
//
// Consider using this in conjuntion with hwreg::RegisterBase for increased safety
// and improved ergonomics.
//
////////////////////////////////////////////////////////////////////////////////
// Example: An mmio region provided by the Platform Device protocol.
//
// pdev_mmio_t pdev_mmio;
// GetMmio(index, &pdev_mmio);
//
// std::optional<ddk::MmioBuffer> mmio;
// zx_status_t status;
//
// status = ddk::MmioBuffer::Create(pdev_mmio.offset, pdev_mmio.size,
//                                  zx::vmo(pdev_mmio.vmo),
//                                  ZX_CACHE_POLICY_UNCACHED_DEVICE, mmio);
// if (status != ZX_OK) return status;
//
// auto value = mmio->Read<uint32_t>(kRegOffset);
// value |= kRegFlag;
// mmio->Write(value, kRegOffset);
//
////////////////////////////////////////////////////////////////////////////////
// Example: An mmio region created from a physical region.
//
// std::optional<ddk::MmioBuffer> mmio;
// zx_status_t status;
//
// Please do not use get_root_resource() in new code. See ZX-1467.
// zx::unowned_resource resource(get_root_resource());
// status = ddk::MmioBuffer::Create(T931_USBPHY21_BASE, T931_USBPHY21_LENGTH,
//                                  *resource, ZX_CACHE_POLICY_UNCACHED_DEVICE,
//                                  &mmio);
// if (status != ZX_OK) return status;
//
// mmio->SetBits(kRegFlag, kRegOffset);
//
////////////////////////////////////////////////////////////////////////////////
// Example: An mmio region which is pinned in order to perform dma. Using views
// to increase safetey.
//
// std::optional<ddk::MmioBuffer> mmio;
// status = ddk::MmioBuffer::Create(pdev_mmio.offset, pdev_mmio.size,
//                                  zx::vmo(pdev_mmio.vmo),
//                                  ZX_CACHE_POLICY_UNCACHED_DEVICE, &mmio);
// if (status != ZX_OK) return status;
//
// ddk::MmioView dma_region = mmio->View(kDmaRegionOffset, kDmaRegionSize);
// ddk::MmioView dma_ctrl = mmio->View(kDmaCtrlRegOffset, kDmaCtrlRegSize);
//
// std::optional<ddk::MmioPinnedBuffer> dma_pinned_region;
// status = dma_region->Pin(&bti_, &dma_pinned_region);
// if (status != ZX_OK) return status;
//
// dma_ctrl->Write<uint64_t>(dma_pinnedRegion->get_paddr(), kPaddrOffset);
// <...>
//

// MmioPinnedBuffer is wrapper around mmio_pinned_buffer_t.
class MmioPinnedBuffer {

public:
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(MmioPinnedBuffer);

    explicit MmioPinnedBuffer(mmio_pinned_buffer_t pinned)
        : pinned_(pinned) {
        ZX_ASSERT(pinned_.paddr != 0);
    }

    ~MmioPinnedBuffer() {
        mmio_buffer_unpin(&pinned_);
    }

    MmioPinnedBuffer(MmioPinnedBuffer&& other) {
        transfer(std::move(other));
    }

    MmioPinnedBuffer& operator=(MmioPinnedBuffer&& other) {
        transfer(std::move(other));
        return *this;
    }

    void reset() {
        memset(&pinned_, 0, sizeof(pinned_));
    }

    zx_paddr_t get_paddr() const {
        return pinned_.paddr;
    }

private:
    void transfer(MmioPinnedBuffer&& other) {
        pinned_ = other.pinned_;
        other.reset();
    }
    mmio_pinned_buffer_t pinned_;
};

// Forward declaration.
class MmioView;

// MmioBuffer is wrapper around mmio_block_t.
class MmioBuffer {

public:
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(MmioBuffer);

    explicit MmioBuffer(mmio_buffer_t mmio)
        : mmio_(mmio), ptr_(reinterpret_cast<uintptr_t>(mmio.vaddr)) {
        ZX_ASSERT(mmio_.vaddr != nullptr);
    }

    virtual ~MmioBuffer() {
        mmio_buffer_release(&mmio_);
    }

    MmioBuffer(MmioBuffer&& other) {
        transfer(std::move(other));
    }

    MmioBuffer& operator=(MmioBuffer&& other) {
        transfer(std::move(other));
        return *this;
    }

    static zx_status_t Create(zx_off_t offset, size_t size, zx::vmo vmo, uint32_t cache_policy,
                              std::optional<MmioBuffer>* mmio_buffer) {
        mmio_buffer_t mmio;
        zx_status_t status = mmio_buffer_init(&mmio, offset, size, vmo.release(), cache_policy);
        if (status == ZX_OK) {
            *mmio_buffer = MmioBuffer(mmio);
        }
        return status;
    }

    static zx_status_t Create(zx_paddr_t base, size_t size, const zx::resource& resource,
                              uint32_t cache_policy, std::optional<MmioBuffer>* mmio_buffer) {
        mmio_buffer_t mmio;
        zx_status_t status = mmio_buffer_init_physical(&mmio, base, size, resource.get(),
                                                       cache_policy);
        if (status == ZX_OK) {
            *mmio_buffer = MmioBuffer(mmio);
        }
        return status;
    }

    void reset() {
        memset(&mmio_, 0, sizeof(mmio_));
    }

    void Info() const {
        zxlogf(INFO, "vaddr = %p\n", mmio_.vaddr);
        zxlogf(INFO, "size = %lu\n", mmio_.size);
    }

    void* get() const {
        return mmio_.vaddr;
    }
    zx_off_t get_offset() const {
        return mmio_.offset;
    }
    size_t get_size() const {
        return mmio_.size;
    }
    zx::unowned_vmo get_vmo() const {
        return zx::unowned_vmo(mmio_.vmo);
    }

    zx_status_t Pin(const zx::bti& bti, std::optional<MmioPinnedBuffer>* pinned_buffer) {
        mmio_pinned_buffer_t pinned;
        zx_status_t status = mmio_buffer_pin(&mmio_, bti.get(), &pinned);
        if (status == ZX_OK) {
            *pinned_buffer = MmioPinnedBuffer(pinned);
        }
        return status;
    }

    // Provides a slice view into the mmio.
    // The returned slice object must not outlive this object.
    MmioView View(zx_off_t off) const;
    MmioView View(zx_off_t off, size_t size) const;

    uint32_t Read32(zx_off_t offs) const {
        return Read<uint32_t>(offs);
    }

    uint32_t ReadMasked32(uint32_t mask, zx_off_t offs) const {
        return ReadMasked<uint32_t>(mask, offs);
    }

    void Write32(uint32_t val, zx_off_t offs) const {
        Write<uint32_t>(val, offs);
    }

    void ModifyBits32(uint32_t bits, uint32_t mask, zx_off_t offs) const {
        ModifyBits<uint32_t>(bits, mask, offs);
    }

    void ModifyBits32(uint32_t val, uint32_t start, uint32_t width, zx_off_t offs) const {
        ModifyBits<uint32_t>(val, start, width, offs);
    }

    void SetBits32(uint32_t bits, zx_off_t offs) const {
        SetBits<uint32_t>(bits, offs);
    }

    void ClearBits32(uint32_t bits, zx_off_t offs) const {
        ClearBits<uint32_t>(bits, offs);
    }

    void CopyFrom32(const MmioBuffer& source, zx_off_t source_offs,
                    zx_off_t dest_offs, size_t count) const {
        CopyFrom<uint32_t>(source, source_offs, dest_offs, count);
    }

    template <typename T>
    T Read(zx_off_t offs) const {
        ZX_DEBUG_ASSERT(offs + sizeof(T) <= mmio_.size);
        ZX_DEBUG_ASSERT(ptr_);
        return *reinterpret_cast<volatile T*>(ptr_ + offs);
    }

    template <typename T>
    T ReadMasked(T mask, zx_off_t offs) const {
        return (Read<T>(offs) & mask);
    }

    template <typename T>
    void CopyFrom(const MmioBuffer& source, zx_off_t source_offs,
                  zx_off_t dest_offs, size_t count) const {
        for (size_t i = 0; i < count; i++) {
            T val = source.Read<T>(source_offs);
            Write<T>(val, dest_offs);
            source_offs = source_offs + sizeof(T);
            dest_offs = dest_offs + sizeof(T);
        }
    }

    template <typename T>
    void Write(T val, zx_off_t offs) const {
        ZX_DEBUG_ASSERT(offs + sizeof(T) <= mmio_.size);
        ZX_DEBUG_ASSERT(ptr_);
        *reinterpret_cast<volatile T*>(ptr_ + offs) = val;
        hw_mb();
    }

    template <typename T>
    void ModifyBits(T bits, T mask, zx_off_t offs) const {
        T val = Read<T>(offs);
        Write<T>(static_cast<T>((val & ~mask) | (bits & mask)), offs);
    }

    template <typename T>
    void SetBits(T bits, zx_off_t offs) const {
        ModifyBits<T>(bits, bits, offs);
    }

    template <typename T>
    void ClearBits(T bits, zx_off_t offs) const {
        ModifyBits<T>(0, bits, offs);
    }

    template <typename T>
    T GetBits(size_t shift, size_t count, zx_off_t offs) const {
        T mask = static_cast<T>(((static_cast<T>(1) << count) - 1) << shift);
        T val = Read<T>(offs);
        return static_cast<T>((val & mask) >> shift);
    }

    template <typename T>
    T GetBit(size_t shift, zx_off_t offs) const {
        return GetBits<T>(shift, 1, offs);
    }

    template <typename T>
    void ModifyBits(T bits, size_t shift, size_t count, zx_off_t offs) const {
        T mask = static_cast<T>(((static_cast<T>(1) << count) - 1) << shift);
        T val = Read<T>(offs);
        Write<T>(static_cast<T>((val & ~mask) | ((bits << shift) & mask)), offs);
    }

    template <typename T>
    void ModifyBit(bool val, size_t shift, zx_off_t offs) const {
        ModifyBits<T>(val, shift, 1, offs);
    }

    template <typename T>
    void SetBit(size_t shift, zx_off_t offs) const {
        ModifyBit<T>(true, shift, offs);
    }

    template <typename T>
    void ClearBit(size_t shift, zx_off_t offs) const {
        ModifyBit<T>(false, shift, offs);
    }

protected:
    mmio_buffer_t mmio_;

private:
    void transfer(MmioBuffer&& other) {
        mmio_ = other.mmio_;
        ptr_ = other.ptr_;
        other.reset();
    }

    uintptr_t ptr_;
};

// A sliced view that of an mmio which does not unmap on close. Must not outlive
// mmio buffer it is created from.
class MmioView : public MmioBuffer {
public:
    MmioView(const mmio_buffer_t& mmio, zx_off_t offset)
        : MmioBuffer(mmio_buffer_t{
                .vaddr = static_cast<uint8_t*>(mmio.vaddr) + offset,
                .offset = mmio.offset + offset,
                .size = mmio.size - offset,
                .vmo = mmio.vmo,
            }) {
        ZX_ASSERT(offset < mmio.size);
    }

    MmioView(const mmio_buffer_t& mmio, zx_off_t offset, size_t size)
        : MmioBuffer(mmio_buffer_t{
                .vaddr = static_cast<uint8_t*>(mmio.vaddr) + offset,
                .offset = mmio.offset + offset,
                .size = size,
                .vmo = mmio.vmo,
            }) {
        ZX_ASSERT(size + offset <= mmio.size);
    }

    MmioView(const MmioView& mmio)
        : MmioBuffer(mmio.mmio_) {}

    virtual ~MmioView() override {
        // Prevent unmap operation from occurring.
        mmio_.vmo = ZX_HANDLE_INVALID;
    }
};

// These can't be defined inside the class because they need MmioView
// to be completely defined first.

inline MmioView MmioBuffer::View(zx_off_t off) const {
    return MmioView(mmio_, off);
}

inline MmioView MmioBuffer::View(zx_off_t off, size_t size) const {
    return MmioView(mmio_, off, size);
}

} //namespace ddk

#endif  // LIB_MMIO_MMIO_H_
