blob: aa659e128d546d3857eb2a6d1ce4bc52ef740351 [file] [log] [blame]
Roman Kiryanov79632592019-06-03 12:31:49 -07001// Copyright (C) 2019 The Android Open Source Project
2// Copyright (C) 2019 Google Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#include <memory>
17#include <fcntl.h>
Roman Kiryanov79632592019-06-03 12:31:49 -070018#include <lib/zx/channel.h>
19#include <lib/zx/vmo.h>
David Revemanecd9e532019-06-07 09:10:06 -040020#include <log/log.h>
Roman Kiryanov79632592019-06-03 12:31:49 -070021#include <stdlib.h>
22#include <sys/stat.h>
23#include <sys/types.h>
24#include <unistd.h>
25#include <zircon/process.h>
26#include <zircon/syscalls.h>
27#include <zircon/syscalls/object.h>
28
29#include "goldfish_address_space.h"
John Bauman8153a442019-10-16 15:41:17 -070030#include "services/service_connector.h"
Roman Kiryanov79632592019-06-03 12:31:49 -070031
Lingfeng Yang37193ee2019-10-15 08:04:36 -070032GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(uint64_t subdevice) {
33
34 if (subdevice != SUBDEVICE_TYPE_NO_SUBDEVICE_ID) {
35 ALOGE("%s: Tried to use a nontrivial subdevice when support has not been added\n", __func__);
36 abort();
37 }
38
John Bauman8153a442019-10-16 15:41:17 -070039 zx::channel channel(GetConnectToServiceFunction()(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME));
40 if (!channel) {
41 ALOGE("%s: failed to get service handle for " GOLDFISH_ADDRESS_SPACE_DEVICE_NAME,
42 __FUNCTION__);
Roman Kiryanov79632592019-06-03 12:31:49 -070043 return;
44 }
45 m_device.Bind(std::move(channel));
46}
47
48GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
49{
50}
51
52bool GoldfishAddressSpaceBlockProvider::is_opened() const
53{
54 return m_device.is_bound();
55}
56
57// void GoldfishAddressSpaceBlockProvider::close() - not implemented
Roman Kiryanov754c3eb2019-10-10 14:09:23 -070058// address_space_handle_t GoldfishAddressSpaceBlockProvider::release() - not imeplemented
Roman Kiryanov79632592019-06-03 12:31:49 -070059
60GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock()
61 : m_device(NULL)
62 , m_vmo(ZX_HANDLE_INVALID)
63 , m_mmaped_ptr(NULL)
64 , m_phys_addr(0)
65 , m_host_addr(0)
66 , m_offset(0)
67 , m_size(0) {}
68
69GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock()
70{
71 destroy();
72}
73
74GoldfishAddressSpaceBlock &GoldfishAddressSpaceBlock::operator=(const GoldfishAddressSpaceBlock &rhs)
75{
76 m_vmo = rhs.m_vmo;
77 m_mmaped_ptr = rhs.m_mmaped_ptr;
78 m_phys_addr = rhs.m_phys_addr;
79 m_host_addr = rhs.m_host_addr;
80 m_offset = rhs.m_offset;
81 m_size = rhs.m_size;
82 m_device = rhs.m_device;
83
84 return *this;
85}
86
87bool GoldfishAddressSpaceBlock::allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size)
88{
89 ALOGD("%s: Ask for block of size 0x%llx\n", __func__,
90 (unsigned long long)size);
91
92 destroy();
93
94 if (!provider->is_opened()) {
95 return false;
96 }
97
Yilong Lib373b392019-10-17 15:30:14 -070098 fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr* device = &provider->m_device;
Roman Kiryanov79632592019-06-03 12:31:49 -070099
100 int32_t res = ZX_OK;
101 zx::vmo vmo;
102 zx_status_t status = (*device)->AllocateBlock(size, &res, &m_phys_addr, &vmo);
103 if (status != ZX_OK || res != ZX_OK) {
104 ALOGE("%s: allocate block failed: %d:%d", __func__, status, res);
105 return false;
106 }
107
108 m_offset = 0;
109 m_size = size;
110 m_vmo = vmo.release();
111
112 ALOGD("%s: allocate returned offset 0x%llx size 0x%llx\n", __func__,
113 (unsigned long long)m_offset,
114 (unsigned long long)m_size);
115
116 m_device = device;
117 return true;
118}
119
Lingfeng Yang8d04bdd2019-10-19 10:59:53 -0700120bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
121{
122 ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
123 (unsigned long long)offset,
124 (unsigned long long)offset + size);
125 ALOGE("%s: FATAL: claimShared not supported!\n");
126 abort();
127}
128
Roman Kiryanov79632592019-06-03 12:31:49 -0700129uint64_t GoldfishAddressSpaceBlock::physAddr() const
130{
131 return m_phys_addr;
132}
133
134uint64_t GoldfishAddressSpaceBlock::hostAddr() const
135{
136 return m_host_addr;
137}
138
139void *GoldfishAddressSpaceBlock::mmap(uint64_t host_addr)
140{
141 if (m_size == 0) {
142 ALOGE("%s: called with zero size\n", __func__);
143 return NULL;
144 }
145 if (m_mmaped_ptr) {
146 ALOGE("'mmap' called for an already mmaped address block");
147 ::abort();
148 }
149
150 zx_vaddr_t ptr = 0;
151 zx_status_t status = zx_vmar_map(zx_vmar_root_self(),
152 ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
153 0, m_vmo,
154 m_offset,
155 m_size,
156 &ptr);
157 if (status != ZX_OK) {
158 ALOGE("%s: host memory map failed with size 0x%llx "
159 "off 0x%llx status %d\n",
160 __func__,
161 (unsigned long long)m_size,
162 (unsigned long long)m_offset, status);
163 return NULL;
164 } else {
165 m_mmaped_ptr = (void*)ptr;
166 m_host_addr = host_addr;
167 return guestPtr();
168 }
169}
170
171void *GoldfishAddressSpaceBlock::guestPtr() const
172{
173 return reinterpret_cast<char *>(m_mmaped_ptr) + (m_host_addr & (PAGE_SIZE - 1));
174}
175
176void GoldfishAddressSpaceBlock::destroy()
177{
178 if (m_mmaped_ptr && m_size) {
179 zx_vmar_unmap(zx_vmar_root_self(),
180 (zx_vaddr_t)m_mmaped_ptr,
181 m_size);
182 m_mmaped_ptr = NULL;
183 }
184
185 if (m_size) {
186 zx_handle_close(m_vmo);
187 m_vmo = ZX_HANDLE_INVALID;
188 int32_t res = ZX_OK;
189 zx_status_t status = (*m_device)->DeallocateBlock(m_phys_addr, &res);
190 if (status != ZX_OK || res != ZX_OK) {
191 ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
192 }
193 m_device = NULL;
194 m_phys_addr = 0;
195 m_host_addr = 0;
196 m_offset = 0;
197 m_size = 0;
198 }
199}
200
201GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
Yilong Liced3b8a2019-10-17 11:47:05 -0700202 : m_provider(GoldfishAddressSpaceBlockProvider::SUBDEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID)
Roman Kiryanov79632592019-06-03 12:31:49 -0700203{
204}
205
David Revemanecd9e532019-06-07 09:10:06 -0400206long GoldfishAddressSpaceHostMemoryAllocator::hostMalloc(GoldfishAddressSpaceBlock *block, size_t size)
Roman Kiryanov79632592019-06-03 12:31:49 -0700207{
208 return 0;
209}
210
David Revemanecd9e532019-06-07 09:10:06 -0400211void GoldfishAddressSpaceHostMemoryAllocator::hostFree(GoldfishAddressSpaceBlock *block)
Roman Kiryanov79632592019-06-03 12:31:49 -0700212{
213}
Lingfeng Yang6000a8e2019-10-19 11:56:56 -0700214
215// TODO: Implement address_space_handle_t interface
216address_space_handle_t goldfish_address_space_open() {
217 ALOGE("%s: not implemented!\n", __func__);
218 abort();
219}
220
221void goldfish_address_space_close(address_space_handle_t handle) {
222 ALOGE("%s: not implemented!\n", __func__);
223 abort();
224}
225
226bool goldfish_address_space_allocate(
227 address_space_handle_t,
228 size_t, uint64_t*, uint64_t*) {
229 ALOGE("%s: not implemented!\n", __func__);
230 abort();
231}
232
233bool goldfish_address_space_free(
234 address_space_handle_t, uint64_t) {
235 ALOGE("%s: not implemented!\n", __func__);
236 abort();
237}
238
239bool goldfish_address_space_claim_shared(
240 address_space_handle_t, uint64_t, uint64_t) {
241 ALOGE("%s: not implemented!\n", __func__);
242 abort();
243}
244
245bool goldfish_address_space_unclaim_shared(
246 address_space_handle_t, uint64_t) {
247 ALOGE("%s: not implemented!\n", __func__);
248 abort();
249}
250
251// pgoff is the offset into the page to return in the result
252void* goldfish_address_space_map(
253 address_space_handle_t,
254 uint64_t, uint64_t,
255 uint64_t) {
256 ALOGE("%s: not implemented!\n", __func__);
257 abort();
258}
259
260void goldfish_address_space_unmap(void*, uint64_t) {
261 ALOGE("%s: not implemented!\n", __func__);
262 abort();
263}
264
265bool goldfish_address_space_ping(
266 address_space_handle_t handle,
267 struct goldfish_address_space_ping* ping) {
268 ALOGE("%s: not implemented!\n", __func__);
269 abort();
270}