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 
11 namespace audio {
12 namespace gauss {
13 
AllocateVmo(zx_handle_t bti,size_t buffer_size)14 zx_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 
AllocateVmo(zx_handle_t bti,size_t buffer_size)18 zx_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 
GetVmoRange(zx_paddr_t * start_address)28 zx_status_t VmoHelperBase::GetVmoRange(zx_paddr_t* start_address) {
29     *start_address = io_buffer_phys(&buffer_);
30     return ZX_OK;
31 }
32 
Duplicate(uint32_t rights,zx::vmo * handle)33 zx_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 
DestroyVmo()43 void VmoHelperBase::DestroyVmo() {
44     io_buffer_release(&buffer_);
45 }
46 
47 template <bool DEBUG>
AllocateVmo(zx_handle_t bti,size_t buffer_size)48 zx_status_t VmoHelper<DEBUG>::AllocateVmo(zx_handle_t bti, size_t buffer_size) {
49     return VmoHelperBase::AllocateVmo(bti, buffer_size);
50 }
51 
52 template <bool DEBUG>
printoffsetinvmo(uint32_t offset)53 void VmoHelper<DEBUG>::printoffsetinvmo(uint32_t offset) {}
54 
printoffsetinvmo(uint32_t offset)55 void 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 
84 template <bool DEBUG>
DestroyVmo()85 void VmoHelper<DEBUG>::DestroyVmo() {
86     VmoHelperBase::DestroyVmo();
87 }
88 
DestroyVmo()89 void VmoHelper<true>::DestroyVmo() {
90     VmoHelperBase::DestroyVmo();
91     ring_buffer_virt_ = 0;
92 }
93 
94 template class VmoHelper<false>;
95 }
96 }
97