| // Copyright 2019 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_MEDIA_LIB_INTERNAL_BUFFER_INTERNAL_BUFFER_H_ |
| #define SRC_MEDIA_LIB_INTERNAL_BUFFER_INTERNAL_BUFFER_H_ |
| |
| #include <fuchsia/sysmem/cpp/fidl.h> |
| #include <lib/fit/function.h> |
| #include <threads.h> |
| #include <zircon/types.h> |
| |
| // Helper class to allocate a physically contiguous buffer. Allocated via sysmem in |
| // fuchsia::sysmem::HeapType::SYSTEM_RAM or fuchsia::sysmem::HeapType::AMLOGIC_SECURE memory, |
| // depending on whether is_secure. |
| class InternalBuffer { |
| public: |
| using ErrorHandler = fit::callback<void(zx_status_t status)>; |
| // |name| is borrowed during the call - not retained. Copied into ZX_PROP_NAME of the allocated |
| // vmo. |
| // |
| // |sysmem| is borrowed during the call - not retained. |
| // |
| // |bti| is borrowed during the call - not retained. |
| // |
| // |size| of the requested buffer. This must be % ZX_PAGE_SIZE == 0. |
| // |
| // |is_secure| is whether to allocate secure buffers or non-secure buffers. All buffers are |
| // allocated via sysmem and are physically contiguous. |
| // |
| // |is_writable| the buffer must be writable, else read-only. |
| // |
| // |is_mapping_needed| if a mapping to the allocated buffer is needed. This must be false if |
| // is_secure. |
| static fit::result<InternalBuffer, zx_status_t> Create(const char* name, |
| fuchsia::sysmem::AllocatorSyncPtr* sysmem, |
| const zx::unowned_bti& bti, size_t size, |
| bool is_secure, bool is_writable, |
| bool is_mapping_needed); |
| |
| // Same as above, but alignment is the byte multiple to align the buffer to. |
| static fit::result<InternalBuffer, zx_status_t> CreateAligned( |
| const char* name, fuchsia::sysmem::AllocatorSyncPtr* sysmem, const zx::unowned_bti& bti, |
| size_t size, size_t alignment, bool is_secure, bool is_writable, bool is_mapping_needed); |
| |
| ~InternalBuffer(); |
| |
| // move-only; delete copy just for clarity |
| InternalBuffer(InternalBuffer&& other); |
| InternalBuffer& operator=(InternalBuffer&& other); |
| InternalBuffer(const InternalBuffer& other) = delete; |
| InternalBuffer& operator=(const InternalBuffer& other) = delete; |
| |
| // This will assert in debug if !is_mapping_needed. |
| uint8_t* virt_base(); |
| |
| zx_paddr_t phys_base(); |
| |
| size_t size(); |
| |
| const zx::vmo& vmo(); |
| |
| // If is_secure, ignored. If !is_secure, flushes cache, or panics if the flush doesn't work. |
| // |
| // offset - start of range to flush |
| // length - length of range to flush |
| void CacheFlush(size_t offset, size_t length); |
| void CacheFlushInvalidate(size_t offset, size_t length); |
| |
| private: |
| InternalBuffer(size_t size, bool is_secure, bool is_writable, bool is_mapping_needed); |
| |
| InternalBuffer(size_t size); |
| zx_status_t Init(const char* name, fuchsia::sysmem::AllocatorSyncPtr* sysmem, size_t alignment, |
| const zx::unowned_bti& bti); |
| void DeInit(); |
| void CacheFlushPossibleInvalidate(size_t offset, size_t length, bool invalidate); |
| |
| size_t size_{}; |
| bool is_secure_{}; |
| bool is_writable_{}; |
| bool is_mapping_needed_{}; |
| uint8_t* virt_base_{}; |
| // Include size for alignment. |
| size_t real_size_{}; |
| uint8_t* real_virt_base_{}; |
| uintptr_t alignment_offset_{}; |
| zx::pmt pin_; |
| zx_paddr_t phys_base_{}; |
| fidl::InterfaceHandle<fuchsia::sysmem::BufferCollection> buffer_collection_; |
| zx::vmo vmo_; |
| bool is_moved_out_ = false; |
| }; |
| |
| #endif // SRC_MEDIA_LIB_INTERNAL_BUFFER_INTERNAL_BUFFER_H_ |