address space device direct handle API
bug: 140112486
Change-Id: Ia5f4e36be6c539237d7a677b01e802a39070b73c
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
index e8170db..b52473f 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.h
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -121,4 +121,40 @@
GoldfishAddressSpaceBlockProvider m_provider;
};
+// Convenience functions that run address space driver api without wrapping in
+// a class. Useful for when a client wants to manage the driver handle directly
+// (e.g., mmaping() more than one region associated with a single handle will
+// require different lifetime expectations versus GoldfishAddressSpaceBlock).
+
+// We also expose the ping info struct that is shared between host and guest.
+struct goldfish_address_space_ping {
+ uint64_t offset;
+ uint64_t size;
+ uint64_t metadata;
+ uint32_t version;
+ uint32_t wait_fd;
+ uint32_t wait_flags;
+ uint32_t direction;
+};
+
+address_space_handle_t goldfish_address_space_open();
+void goldfish_address_space_close(address_space_handle_t);
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset);
+bool goldfish_address_space_free(
+ address_space_handle_t, uint64_t offset);
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t, uint64_t offset, uint64_t size);
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t, uint64_t offset);
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0);
+void goldfish_address_space_unmap(void* ptr, uint64_t size);
+
+bool goldfish_address_space_ping(address_space_handle_t, struct goldfish_address_space_ping*);
+
#endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_android.impl b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
index e5a84a7..a4ebac2 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_android.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
@@ -41,16 +41,6 @@
__u64 phys_addr;
};
-struct goldfish_address_space_ping {
- __u64 offset;
- __u64 size;
- __u64 metadata;
- __u32 version;
- __u32 wait_fd;
- __u32 wait_flags;
- __u32 direction;
-};
-
struct goldfish_address_space_claim_shared {
__u64 offset;
__u64 size;
@@ -414,3 +404,99 @@
block->replace(NULL);
}
+
+address_space_handle_t goldfish_address_space_open() {
+ return ::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR);
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+ ::close(handle);
+}
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t handle,
+ size_t size, uint64_t* phys_addr, uint64_t* offset) {
+
+ struct goldfish_address_space_allocate_block request;
+ ::memset(&request, 0, sizeof(request));
+ request.size = size;
+
+ long res = ioctl_allocate(handle, &request);
+
+ if (res) return false;
+
+ *phys_addr = request.phys_addr;
+ *offset = request.offset;
+ return true;
+}
+
+bool goldfish_address_space_free(
+ address_space_handle_t handle, uint64_t offset) {
+
+ long res = ioctl_deallocate(handle, offset);
+
+ if (res) {
+ ALOGE("ioctl_deallocate failed, res=%ld", res);
+ ::abort();
+ }
+
+ return true;
+}
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+ struct goldfish_address_space_claim_shared request;
+ request.offset = offset;
+ request.size = size;
+ long res = ioctl_claim_shared(handle, &request);
+
+ if (res) return false;
+
+ return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t handle, uint64_t offset) {
+ long res = ioctl_unclaim_shared(handle, offset);
+ if (res) {
+ ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
+ ::abort();
+ }
+
+ return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t handle,
+ uint64_t offset, uint64_t size,
+ uint64_t pgoff) {
+
+ void* res = ::mmap64(0, size, PROT_WRITE, MAP_SHARED, handle, offset);
+
+ if (res == MAP_FAILED) {
+ ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
+ return nullptr;
+ }
+
+ return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+void goldfish_address_space_unmap(void* ptr, uint64_t size) {
+ void* pagePtr = (void*)(((uintptr_t)ptr) & ~(PAGE_SIZE - 1));
+ ::munmap(pagePtr, size);
+}
+
+bool goldfish_address_space_ping(
+ address_space_handle_t handle,
+ struct goldfish_address_space_ping* ping) {
+ long res = ioctl_ping(handle, ping);
+
+ if (res) {
+ ALOGE("%s: ping failed: errno: %d\n", __func__, errno);
+ return false;
+ }
+
+ return true;
+}
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
index e1e07f2..c44b10d 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
@@ -214,3 +214,60 @@
void GoldfishAddressSpaceHostMemoryAllocator::hostFree(GoldfishAddressSpaceBlock *block)
{
}
+
+// TODO: Implement address_space_handle_t interface
+address_space_handle_t goldfish_address_space_open() {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t,
+ size_t, uint64_t*, uint64_t*) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+bool goldfish_address_space_free(
+ address_space_handle_t, uint64_t) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t, uint64_t, uint64_t) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t, uint64_t) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t,
+ uint64_t, uint64_t,
+ uint64_t) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+void goldfish_address_space_unmap(void*, uint64_t) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
+
+bool goldfish_address_space_ping(
+ address_space_handle_t handle,
+ struct goldfish_address_space_ping* ping) {
+ ALOGE("%s: not implemented!\n", __func__);
+ abort();
+}
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_host.impl b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
index d2001dd..d5567ad 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_host.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
@@ -23,6 +23,7 @@
#include <log/log.h>
#endif
+#include <errno.h>
#include "goldfish_address_space.h"
namespace {
@@ -287,3 +288,82 @@
block->replace(NULL);
}
+address_space_handle_t goldfish_address_space_open() {
+ return HostAddressSpaceDevice::get()->open();
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+ HostAddressSpaceDevice::get()->close(handle);
+}
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t handle,
+ size_t size, uint64_t* phys_addr, uint64_t* offset) {
+
+ *offset =
+ HostAddressSpaceDevice::get()->allocBlock(
+ handle, size, phys_addr);
+
+ return true;
+}
+
+bool goldfish_address_space_free(
+ address_space_handle_t handle, uint64_t offset) {
+ HostAddressSpaceDevice::get()->freeBlock(handle, offset);
+ return true;
+}
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+ int claimRes = HostAddressSpaceDevice::get()->claimShared(
+ handle, offset, size);
+
+ if (claimRes) {
+ ALOGE("%s: failed to claim shared region. Error: %d\n", __func__, claimRes);
+ return false;
+ }
+
+ return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t handle, uint64_t offset) {
+ HostAddressSpaceDevice::get()->unclaimShared(handle, offset);
+ return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t handle,
+ uint64_t offset, uint64_t size,
+ uint64_t pgoff) {
+
+ (void)size;
+
+ void* res = HostAddressSpaceDevice::get()->
+ getHostAddr(
+ HostAddressSpaceDevice::get()->offsetToPhysAddr(offset));
+
+ if (!res) {
+ ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
+ return nullptr;
+ }
+
+ return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+// same address space
+void goldfish_address_space_unmap(void*, uint64_t) { }
+
+bool goldfish_address_space_ping(
+ address_space_handle_t handle,
+ struct goldfish_address_space_ping* ping) {
+
+ AddressSpaceDevicePingInfo* asHostPingInfo =
+ reinterpret_cast<AddressSpaceDevicePingInfo*>(ping);
+
+ HostAddressSpaceDevice::get()->ping(handle, asHostPingInfo);
+
+ return true;
+}