1363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross/*
2363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * Copyright (C) 2013 The Android Open Source Project
3363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross *
4363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * Licensed under the Apache License, Version 2.0 (the "License");
5363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * you may not use this file except in compliance with the License.
6363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * You may obtain a copy of the License at
7363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross *
8363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross *      http://www.apache.org/licenses/LICENSE-2.0
9363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross *
10363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * Unless required by applicable law or agreed to in writing, software
11363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * distributed under the License is distributed on an "AS IS" BASIS,
12363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * See the License for the specific language governing permissions and
14363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross * limitations under the License.
15363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross */
16363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
17363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <fcntl.h>
18f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh#include <memory>
19363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <sys/mman.h>
20363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <sys/stat.h>
21363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <sys/types.h>
22363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
23363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <linux/ion_test.h>
24363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
25363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <gtest/gtest.h>
26363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
27363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include <ion/ion.h>
28363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
29363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#include "ion_test_fixture.h"
30363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
31363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross#define ALIGN(x,y) (((x) + ((y) - 1)) & ~((y) - 1))
32363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
33363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossclass Device : public IonAllHeapsTest {
34363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross public:
35363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    virtual void SetUp();
36363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    virtual void TearDown();
37363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    int m_deviceFd;
38363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void readDMA(int fd, void *buf, size_t size);
39363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void writeDMA(int fd, void *buf, size_t size);
40363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void readKernel(int fd, void *buf, size_t size);
41363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void writeKernel(int fd, void *buf, size_t size);
42363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void blowCache();
43363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void dirtyCache(void *ptr, size_t size);
44363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross};
45363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
46363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::SetUp()
47363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
48363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    IonAllHeapsTest::SetUp();
491ba4e981dbb75985b320c2d97c7c2567b9ebcf51Jeff Vander Stoep    m_deviceFd = open("/dev/ion-test", O_RDONLY);
50363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_GE(m_deviceFd, 0);
51363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
52363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
53363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::TearDown()
54363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
55363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, close(m_deviceFd));
56363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    IonAllHeapsTest::TearDown();
57363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
58363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
59363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::readDMA(int fd, void *buf, size_t size)
60363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
61363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
62363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    struct ion_test_rw_data ion_test_rw_data = {
63363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .ptr = (uint64_t)buf,
64363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .offset = 0,
65363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .size = size,
66363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .write = 0,
67363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    };
68363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
69363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_DMA_MAPPING, &ion_test_rw_data));
70363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
71363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
72363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
73363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::writeDMA(int fd, void *buf, size_t size)
74363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
75363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
76363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    struct ion_test_rw_data ion_test_rw_data = {
77363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .ptr = (uint64_t)buf,
78363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .offset = 0,
79363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .size = size,
80363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .write = 1,
81363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    };
82363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
83363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_DMA_MAPPING, &ion_test_rw_data));
84363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
85363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
86363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
87363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::readKernel(int fd, void *buf, size_t size)
88363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
89363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
90363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    struct ion_test_rw_data ion_test_rw_data = {
91363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .ptr = (uint64_t)buf,
92363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .offset = 0,
93363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .size = size,
94363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .write = 0,
95363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    };
96363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
97363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_KERNEL_MAPPING, &ion_test_rw_data));
98363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
99363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
100363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
101363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::writeKernel(int fd, void *buf, size_t size)
102363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
103363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
104363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    struct ion_test_rw_data ion_test_rw_data = {
105363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .ptr = (uint64_t)buf,
106363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .offset = 0,
107363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .size = size,
108363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            .write = 1,
109363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    };
110363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
111363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_KERNEL_MAPPING, &ion_test_rw_data));
112363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
113363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
114363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
115363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::blowCache()
116363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
117363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    const size_t bigger_than_cache = 8*1024*1024;
118363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void *buf1 = malloc(bigger_than_cache);
119363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    void *buf2 = malloc(bigger_than_cache);
120363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    memset(buf1, 0xaa, bigger_than_cache);
121363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    memcpy(buf2, buf1, bigger_than_cache);
122363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    free(buf1);
123363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    free(buf2);
124363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
125363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
126363441b120aa7ff4ec7c639bac099e775c2ace69Colin Crossvoid Device::dirtyCache(void *ptr, size_t size)
127363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
128363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    /* try to dirty cache lines */
129363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (size_t i = size-1; i > 0; i--) {
130363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((volatile char *)ptr)[i];
131363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)ptr)[i] = i;
132363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
133363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
134363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
135363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, KernelReadCached)
136363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
137f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
138f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
139363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
140363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
141363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
142363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
143363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED;
144363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
145363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
146363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
147363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
148363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
149363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
150363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
151363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
152363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
153363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ((char *)ptr)[i] = i;
154363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
155363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char*)buf)[4096] = 0x12;
156363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readKernel(map_fd, buf, 4096);
157363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(((char*)buf)[4096], 0x12);
158363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
159363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
160363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)buf)[i]);
161363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
162363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
163363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
164363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
165363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
166363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
167363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, KernelWriteCached)
168363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
169f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
170f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
171363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
172363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (int i = 0; i < 4096; i++)
173363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)buf)[i] = i;
174363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
175363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
176363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
177363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
178363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED;
179363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
180363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
181363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
182363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
183363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
184363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
185363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
186363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
187363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
188363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
189363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        writeKernel(map_fd, buf, 4096);
190363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
191363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
192363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
193363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
194363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
195363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
196363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
197363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
198363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
199363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, DMAReadCached)
200363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
201f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
202f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
203363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
204363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
205363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
206363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
207363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED;
208363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
209363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
210363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
211363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
212363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
213363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
214363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
215363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
216363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
217363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ((char *)ptr)[i] = i;
218363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
219363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readDMA(map_fd, buf, 4096);
220363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
221363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
222363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)buf)[i]);
223363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
224363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
225363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
226363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
227363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
228363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
229363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, DMAWriteCached)
230363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
231f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
232f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
233363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
234363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (int i = 0; i < 4096; i++)
235363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)buf)[i] = i;
236363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
237363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
238363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
239363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
240363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED;
241363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
242363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
243363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
244363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
245363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
246363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
247363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
248363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
249363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
250363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
251363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        writeDMA(map_fd, buf, 4096);
252363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
253363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
254363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
255363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
256363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
257363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
258363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
259363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
260363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
261363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, KernelReadCachedNeedsSync)
262363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
263f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
264f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
265363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
266363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
267363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
268363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
269363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
270363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
271363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
272363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
273363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
274363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
275363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
276363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
277363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
278363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
279363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ((char *)ptr)[i] = i;
280363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
281363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char*)buf)[4096] = 0x12;
282363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readKernel(map_fd, buf, 4096);
283363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(((char*)buf)[4096], 0x12);
284363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
285363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
286363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)buf)[i]);
287363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
288363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
289363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
290363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
291363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
292363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
293363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, KernelWriteCachedNeedsSync)
294363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
295f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
296f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
297363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
298363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (int i = 0; i < 4096; i++)
299363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)buf)[i] = i;
300363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
301363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
302363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
303363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
304363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
305363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
306363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
307363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
308363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
309363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
310363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
311363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
312363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
313363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
314363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
315363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        writeKernel(map_fd, buf, 4096);
316363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
317363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
318363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
319363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
320363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
321363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
322363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
323363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
324363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
325363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, DMAReadCachedNeedsSync)
326363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
327f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
328f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
329363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
330363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
331363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
332363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
333363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
334363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
335363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
336363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
337363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
338363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
339363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
340363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
341363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
342363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
343363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ((char *)ptr)[i] = i;
344363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
345363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ion_sync_fd(m_ionFd, map_fd);
346363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
347363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readDMA(map_fd, buf, 4096);
348363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
349363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
350363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)buf)[i]);
351363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
352363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
353363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
354363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
355363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
356363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
357363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, DMAWriteCachedNeedsSync)
358363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
359f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
360f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
361363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
362363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (int i = 0; i < 4096; i++)
363363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)buf)[i] = i;
364363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
365363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
366363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
367363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
368363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
369363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
370363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
371363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
372363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
373363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
374363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
375363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
376363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
377363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
378363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
379363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        writeDMA(map_fd, buf, 4096);
380363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
381363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ion_sync_fd(m_ionFd, map_fd);
382363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
383363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
384363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
385363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
386363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
387363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
388363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
389363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
390363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, KernelRead)
391363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
392f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
393f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
394363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
395363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
396363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
397363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
398363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = 0;
399363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
400363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
401363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
402363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
403363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
404363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
405363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
406363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
407363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
408363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ((char *)ptr)[i] = i;
409363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
410363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char*)buf)[4096] = 0x12;
411363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readKernel(map_fd, buf, 4096);
412363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(((char*)buf)[4096], 0x12);
413363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
414363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
415363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)buf)[i]);
416363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
417363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
418363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
419363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
420363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
421363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
422363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, KernelWrite)
423363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
424f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
425f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
426363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
427363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (int i = 0; i < 4096; i++)
428363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)buf)[i] = i;
429363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
430363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
431363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
432363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
433363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = 0;
434363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
435363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
436363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
437363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
438363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
439363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
440363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
441363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
442363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
443363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
444363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        writeKernel(map_fd, buf, 4096);
445363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
446363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
447363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
448363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
449363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
450363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
451363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
452363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
453363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
454363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, DMARead)
455363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
456f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
457f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
458363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
459363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
460363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
461363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
462363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = 0;
463363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
464363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
465363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
466363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
467363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
468363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
469363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
470363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
471363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
472363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ((char *)ptr)[i] = i;
473363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
474363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readDMA(map_fd, buf, 4096);
475363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
476363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
477363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)buf)[i]);
478363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
479363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
480363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
481363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
482363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
483363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
484363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, DMAWrite)
485363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
486f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto alloc_ptr = std::make_unique<char[]>(8192 + 1024);
487f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = (void *)(ALIGN((unsigned long)alloc_ptr.get(), 4096) + 1024);
488363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
489363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (int i = 0; i < 4096; i++)
490363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ((char *)buf)[i] = i;
491363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
492363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
493363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
494363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
495363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = 0;
496363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
497363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
498363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
499363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
500363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
501363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
502363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
503363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
504363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
505363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
506363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        writeDMA(map_fd, buf, 4096);
507363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
508363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 0; i < 4096; i++)
509363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
510363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
511363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
512363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
513363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
514363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
515363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
516363441b120aa7ff4ec7c639bac099e775c2ace69Colin CrossTEST_F(Device, IsCached)
517363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross{
518f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    auto buf_ptr = std::make_unique<char[]>(4096);
519f60cbb7245bddab013f9afc09fa8284091d74785Chih-Hung Hsieh    void *buf = buf_ptr.get();
520363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
521363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    for (unsigned int heapMask : m_allHeaps) {
522363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
523363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        int map_fd = -1;
524363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
525363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
526363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
527363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_GE(map_fd, 0);
528363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
529363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        void *ptr;
530363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
531363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_TRUE(ptr != NULL);
532363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
533363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        dirtyCache(ptr, 4096);
534363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
535363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        readDMA(map_fd, buf, 4096);
536363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
537363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        bool same = true;
538363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        for (int i = 4096-16; i >= 0; i -= 16)
539363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross            if (((char *)buf)[i] != i)
540363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross                same = false;
541363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_FALSE(same);
542363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross
543363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, munmap(ptr, 4096));
544363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross        ASSERT_EQ(0, close(map_fd));
545363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross    }
546363441b120aa7ff4ec7c639bac099e775c2ace69Colin Cross}
547