1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <ddk/debug.h>
6#include <ddktl/device.h>
7#include <lib/zx/vmar.h>
8
9#include "vmo_helper.h"
10
11namespace audio {
12namespace gauss {
13
14zx_status_t VmoHelperBase::AllocateVmo(zx_handle_t bti, size_t buffer_size) {
15    return io_buffer_init(&buffer_, bti, buffer_size, IO_BUFFER_RW | IO_BUFFER_CONTIG);
16}
17
18zx_status_t VmoHelper<true>::AllocateVmo(zx_handle_t bti, size_t buffer_size) {
19    zx_status_t status = VmoHelperBase::AllocateVmo(bti, buffer_size);
20    if (status != ZX_OK) {
21        return status;
22    }
23
24    ring_buffer_virt_ = reinterpret_cast<uintptr_t>(io_buffer_virt(&buffer_));
25    return status;
26}
27
28zx_status_t VmoHelperBase::GetVmoRange(zx_paddr_t* start_address) {
29    *start_address = io_buffer_phys(&buffer_);
30    return ZX_OK;
31}
32
33zx_status_t VmoHelperBase::Duplicate(uint32_t rights, zx::vmo* handle) {
34    zx_handle_t copy;
35    zx_status_t status = zx_handle_duplicate(buffer_.vmo_handle, rights, &copy);
36    if (status != ZX_OK) {
37        return status;
38    }
39    handle->reset(copy);
40    return ZX_OK;
41}
42
43void VmoHelperBase::DestroyVmo() {
44    io_buffer_release(&buffer_);
45}
46
47template <bool DEBUG>
48zx_status_t VmoHelper<DEBUG>::AllocateVmo(zx_handle_t bti, size_t buffer_size) {
49    return VmoHelperBase::AllocateVmo(bti, buffer_size);
50}
51
52template <bool DEBUG>
53void VmoHelper<DEBUG>::printoffsetinvmo(uint32_t offset) {}
54
55void VmoHelper<true>::printoffsetinvmo(uint32_t offset) {
56    io_buffer_cache_flush_invalidate(&buffer_, 0, buffer_.size);
57
58    zxlogf(DEBUG1, "Current position: 0x%04x. data: ", offset);
59
60    // Print some offsets to probe the data.
61    static const uint32_t offsets[] = {0, 0x1000, 0x2000, 0x3000,
62                                       0x4000, 0x5000, 0x6000, 0x7000};
63
64    for (const auto& offset : offsets) {
65        zxlogf(DEBUG1, " 0x%04x: 0x%08lx,", offset,
66               *(reinterpret_cast<uintptr_t*>(offset +
67                                              ring_buffer_virt_)));
68    }
69
70    // print the last frame of data:
71    zxlogf(DEBUG1, "offset is at: 0x%x\n", offset);
72
73    if (offset > 32) {
74        uint8_t* frame_start = reinterpret_cast<uint8_t*>(
75            static_cast<uintptr_t>(offset) - 32 + ring_buffer_virt_);
76        for (int i = 0; i < 32; i++) {
77            zxlogf(DEBUG1, "%d: 0x%x, ", i, (frame_start[i] & 0xff));
78        }
79    }
80
81    zxlogf(DEBUG1, "\n");
82}
83
84template <bool DEBUG>
85void VmoHelper<DEBUG>::DestroyVmo() {
86    VmoHelperBase::DestroyVmo();
87}
88
89void VmoHelper<true>::DestroyVmo() {
90    VmoHelperBase::DestroyVmo();
91    ring_buffer_virt_ = 0;
92}
93
94template class VmoHelper<false>;
95}
96}
97