blob: 944c73c99775d41e2eac39f8129f66b687e44522 [file] [log] [blame]
// Copyright 2022 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 SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_ACPI_MEMORY_REGION_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_ACPI_MEMORY_REGION_H_
#include <lib/ddk/driver.h>
#include <lib/stdcompat/span.h>
#include <lib/zx/result.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>
#include <cstddef>
#include <cstdint>
namespace i915 {
// A subset of an ACPI custom Operation Region mapped into this process.
class AcpiMemoryRegion {
public:
// Creates a memory region of `region_size` bytes starting at `region_base`.
//
// The `region_base` and `region_size` should refer to memory that is entirely
// contained within a memory region in the system's ACPI (Advanced
// Configuration and Power Interface) tables that is marked as NVS (saved
// during the Non-Volatile Sleep state)
static zx::result<AcpiMemoryRegion> Create(zx_device_t* parent, zx_paddr_t region_base,
size_t region_size);
// Creates an empty memory region without any backing VMO.
constexpr AcpiMemoryRegion() = default;
// Creates a representation of an already-mapped memory region.
//
// This constructor is exposed for testing convenience. Production usage
// should prefer Create(), which handles mapping physical memory.
//
// If `region_vmo` is a valid VMO, the newly created instance keeps the VMO
// alive throughout its life, and unmaps the pages that contain `region_data`
// upon destruction.
//
// If `region_vmo` is not a valid VMO, the caller must ensure that the memory
// backing `region_data` stays alive while the newly created instance exists.
//
// `region_data` must not be empty.
explicit AcpiMemoryRegion(zx::vmo region_vmo, cpp20::span<uint8_t> region_data);
// Copying is not allowed.
AcpiMemoryRegion(const AcpiMemoryRegion&) = delete;
AcpiMemoryRegion& operator=(const AcpiMemoryRegion&) = delete;
// Moving is allowed so AcpiMemoryRegion can be used as a return type.
AcpiMemoryRegion(AcpiMemoryRegion&& rhs) noexcept;
AcpiMemoryRegion& operator=(AcpiMemoryRegion&& rhs) noexcept;
~AcpiMemoryRegion();
bool is_empty() const { return region_data_.empty(); }
// The mapped memory. Empty iff this is an empty memory region.
cpp20::span<uint8_t> data() { return region_data_; }
cpp20::span<const uint8_t> data() const { return region_data_; }
zx::unowned_vmo vmo_for_testing() const { return region_vmo_.borrow(); }
private:
cpp20::span<uint8_t> region_data_;
// Holds onto the VMO backing `region_data_`.
//
// The VMO may be invalid if `region_data_` is empty, or if the
// AcpiMemoryRegion instance is created without a backing VMO.
zx::vmo region_vmo_;
};
} // namespace i915
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_ACPI_MEMORY_REGION_H_