blob: c110c48ec2db565b91e60d90ca02960c61f7f43d [file]
// 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_DRIVER_MMIO_CPP_MMIO_H_
#define LIB_DRIVER_MMIO_CPP_MMIO_H_
#include <lib/driver/mmio/cpp/mmio-buffer.h>
#include <lib/driver/mmio/cpp/mmio-pinned-buffer.h>
#include <lib/driver/mmio/cpp/mmio-view.h>
// Usage Notes:
//
// fdf::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.
//
// fdf::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 fdf::MmioBuffer it is spawned from.
//
// fdf::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. Destroying MmioPInnedBuffer will unpin the memory.
//
// Consider using this in conjunction 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<fdf::MmioBuffer> mmio;
// zx_status_t status;
//
// status = fdf::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<fdf::MmioBuffer> mmio;
// zx_status_t status;
//
// zx::unowned_resource resource(get_mmio_resource());
// status = fdf::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<fdf::MmioBuffer> mmio;
// status = fdf::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;
//
// fdf::MmioView dma_region = mmio->View(kDmaRegionOffset, kDmaRegionSize);
// fdf::MmioView dma_ctrl = mmio->View(kDmaCtrlRegOffset, kDmaCtrlRegSize);
//
// std::optional<fdf::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);
// <...>
//
#endif // LIB_DRIVER_MMIO_CPP_MMIO_H_