Build goldfish sync/dma device interfaces
Bug: 171711491
Change-Id: Ifc2d1131c60ee225d62bbac9d26986057c9a34e4
diff --git a/host-common/CMakeLists.txt b/host-common/CMakeLists.txt
index b1c0dd7..fc9f6a7 100644
--- a/host-common/CMakeLists.txt
+++ b/host-common/CMakeLists.txt
@@ -2,6 +2,11 @@
gfxstream-host-common
crash_reporter.cpp
vm_operations.cpp
- feature_control.cpp)
+ feature_control.cpp
+ dma_device.cpp
+ sync_device.cpp)
target_include_directories(
- gfxstream-host-common PUBLIC ../)
+ gfxstream-host-common
+ PRIVATE
+ ${GFXSTREAM_REPO_ROOT}
+ ${GFXSTREAM_REPO_ROOT}/stream-servers)
diff --git a/host-common/FeatureControl.h b/host-common/FeatureControl.h
new file mode 100644
index 0000000..2ebc74c
--- /dev/null
+++ b/host-common/FeatureControl.h
@@ -0,0 +1,92 @@
+// Copyright 2016 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#pragma once
+
+#include "base/export.h"
+#include "Features.h"
+// #include "HWMatching.h"
+
+#include <string>
+#include <vector>
+
+namespace android {
+namespace featurecontrol {
+
+// featurecontrol is used to switch on/off advanced features It loads
+// sdk/emulator/lib/advancedFeatures.ini for default values and
+// .android/advancedFeatures.ini for user overriden values. If on canary
+// update channel, sdk/emulator/lib/advancedFeaturesCanary.ini is used for
+// default values.
+// It is expected to be initialized at the beginning of the emulator.
+// For easier testing, one may also want to pass the override value through
+// command line and call setEnabledOverride. (Command line override not
+// implemented yet)
+//
+// featurecontrol::isEnabled is thread safe, all other methods are not.
+//
+// To add new features, please (1) add it to android/data/advancedFeatures.ini
+// or android/data/advancedFeaturesCanary.ini and (2) add a new line to
+// FeatureControlDef.h, in the following format:
+// FEATURE_CONTROL_ITEM(YOUR_FEATURE_NAME)
+
+void initialize();
+
+bool isEnabled(Feature feature);
+AEMU_EXPORT void setEnabledOverride(Feature feature, bool isEnabled);
+void resetEnabledToDefault(Feature feature);
+
+// Queries whether this feature is tied to the guest.
+bool isGuestFeature(Feature feature);
+
+// returns true if the user has specified it in
+// home directory's user-based advancedFeatures.ini.
+bool isOverridden(Feature feature);
+
+// like setEnabledOverride, except it is a no-op
+// if isOverridden(feature) == true.
+void setIfNotOverriden(Feature feature, bool isEnabled);
+// like setIfNotOverriden, except it is a no-op
+// if the guest did not enable it too.
+void setIfNotOverridenOrGuestDisabled(Feature feature, bool isEnabled);
+
+Feature stringToFeature(const std::string& str);
+
+// For hardware configurations special enough to warrant
+// disabling or enabling features, we use the concept of
+// "feature pattern" which consists of properties of hardware
+// in question and a set of features to force-enable or disable.
+
+// applyCachedServerFeaturePatterns() queries host hardware
+// confiruation, takes current cached patterns, and enables
+// or disables features based on which patterns match the host.
+// If there is no cached patterns, no action is taken.
+void applyCachedServerFeaturePatterns();
+// asyncUpdateServerFeaturePatterns():
+// If the current cached feature patterns don't exist or are over 24 hours old,
+// asyncUpdateServerFeaturePatterns() starts a download of
+// a protobuf containing the latest feature patterns, replacing
+// the current cached ones.
+void asyncUpdateServerFeaturePatterns();
+
+// Queries the current set of features in various ways:
+// - whether the default guest/host/server config has attempted
+// to enable the feature.
+// - whether the user has overriden the feature.
+// - the resulting set of enabled features, which also accounts for
+// programmatic setting of features.
+std::vector<Feature> getEnabledNonOverride();
+std::vector<Feature> getEnabledOverride();
+std::vector<Feature> getDisabledOverride();
+std::vector<Feature> getEnabled();
+
+} // namespace android
+} // namespace featurecontrol
diff --git a/host-common/Features.h b/host-common/Features.h
new file mode 100644
index 0000000..5413ac0
--- /dev/null
+++ b/host-common/Features.h
@@ -0,0 +1,27 @@
+// Copyright 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+namespace android {
+namespace featurecontrol {
+enum Feature {
+#define FEATURE_CONTROL_ITEM(item) item,
+#include "FeatureControlDefHost.h"
+#include "FeatureControlDefGuest.h"
+#undef FEATURE_CONTROL_ITEM
+ Feature_n_items
+};
+}
+}
diff --git a/host-common/GoldfishDma.h b/host-common/GoldfishDma.h
new file mode 100644
index 0000000..0869af2
--- /dev/null
+++ b/host-common/GoldfishDma.h
@@ -0,0 +1,64 @@
+/* Copyright (C) 2016 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+
+#pragma once
+
+#include "base/Stream.h"
+
+#include <inttypes.h>
+
+static const uint32_t kDmaBufSizeMB = 32;
+// GOLDFISH DMA
+//
+// Goldfish DMA is an extension to the pipe device
+// and is designed to facilitate high-speed RAM->RAM
+// transfers from guest to host.
+//
+// See docs/GOLDFISH-VIRTUAL-HARDWARE.txt and
+// docs/ANDROID-QEMU-PIPE.txt
+//
+// for more details.
+// Host / virtual device interface:
+typedef struct {
+// add_buffer():
+// Tell us that there is a physically-contiguous buffer in the guest
+// starting at |guest_paddr|. This should be used upon allocation
+// of the DMA buffer in the ugest.
+void (*add_buffer)(void* pipe, uint64_t guest_paddr, uint64_t sz);
+// remove_buffer():
+// Tell us that we don't care about tracking this buffer anymore.
+// This should usually be used when the DMA buffer has been freed
+// in the ugest.
+void (*remove_buffer)(uint64_t guest_paddr);
+// get_host_addr():
+// Obtain a pointer to guest physical memory that is usable as
+// as host void*.
+void* (*get_host_addr)(uint64_t guest_paddr);
+// invalidate_host_mappings():
+// Sometimes (say, on snapshot save/load) we may need to re-map
+// the guest DMA buffers so to regain access to them.
+// This function tells our map of DMA buffers to remap the buffers
+// next time they are used.
+void (*invalidate_host_mappings)(void);
+// unlock():
+// Unlocks the buffer at |guest_paddr| to signal the guest
+// that we are done writing it.
+void (*unlock)(uint64_t guest_paddr);
+// reset_host_mappings();
+// Not only invalidates the mappings, but also removes them from the record.
+void (*reset_host_mappings)(void);
+// For snapshots.
+void (*save_mappings)(android::base::Stream* stream);
+void (*load_mappings)(android::base::Stream* stream);
+} GoldfishDmaOps;
+
+extern const GoldfishDmaOps android_goldfish_dma_ops;
diff --git a/host-common/dma_device.cpp b/host-common/dma_device.cpp
new file mode 100644
index 0000000..0628882
--- /dev/null
+++ b/host-common/dma_device.cpp
@@ -0,0 +1,21 @@
+
+#include "GoldfishDma.h"
+#include "dma_device.h"
+
+static void* defaultDmaGetHostAddr(uint64_t guest_paddr) { return nullptr; }
+static void defaultDmaUnlock(uint64_t addr) { }
+
+namespace emugl {
+
+emugl_dma_get_host_addr_t g_emugl_dma_get_host_addr = defaultDmaGetHostAddr;
+emugl_dma_unlock_t g_emugl_dma_unlock = defaultDmaUnlock;
+
+void set_emugl_dma_get_host_addr(emugl_dma_get_host_addr_t f) {
+ g_emugl_dma_get_host_addr = f;
+}
+
+void set_emugl_dma_unlock(emugl_dma_unlock_t f) {
+ g_emugl_dma_unlock = f;
+}
+
+} // namespace emugl
diff --git a/host-common/dma_device.h b/host-common/dma_device.h
new file mode 100644
index 0000000..b5731e2
--- /dev/null
+++ b/host-common/dma_device.h
@@ -0,0 +1,39 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#pragma once
+
+#include "render_api_types.h"
+
+#ifdef _MSC_VER
+# ifdef BUILDING_EMUGL_COMMON_SHARED
+# define EMUGL_COMMON_API __declspec(dllexport)
+# else
+# define EMUGL_COMMON_API __declspec(dllimport)
+#endif
+#else
+# define EMUGL_COMMON_API
+#endif
+
+namespace emugl {
+
+EMUGL_COMMON_API extern emugl_dma_get_host_addr_t g_emugl_dma_get_host_addr;
+EMUGL_COMMON_API extern emugl_dma_unlock_t g_emugl_dma_unlock;
+
+EMUGL_COMMON_API void set_emugl_dma_get_host_addr(emugl_dma_get_host_addr_t);
+EMUGL_COMMON_API void set_emugl_dma_unlock(emugl_dma_unlock_t);
+
+} // namespace emugl
diff --git a/host-common/goldfish_sync.h b/host-common/goldfish_sync.h
new file mode 100644
index 0000000..27b7633
--- /dev/null
+++ b/host-common/goldfish_sync.h
@@ -0,0 +1,171 @@
+/* Copyright (C) 2016 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+
+#pragma once
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+// GOLDFISH SYNC DEVICE
+// The Goldfish sync driver is designed to provide a interface
+// between the underlying host's sync device and the kernel's
+// sw_sync.
+// The purpose of the device/driver is to enable lightweight
+// creation and signaling of timelines and fences
+// in order to synchronize the guest with host-side graphics events.
+
+// Each time the interrupt trips, the driver
+// may perform a sw_sync operation.
+
+// The operations are:
+
+// Ready signal - used to mark when irq should lower
+#define CMD_SYNC_READY 0
+
+// Create a new timeline. writes timeline handle
+#define CMD_CREATE_SYNC_TIMELINE 1
+
+// Create a fence object. reads timeline handle and time argument.
+// Writes fence fd to the SYNC_REG_HANDLE register.
+#define CMD_CREATE_SYNC_FENCE 2
+
+// Increments timeline. reads timeline handle and time argument
+#define CMD_SYNC_TIMELINE_INC 3
+
+// Destroys a timeline. reads timeline handle
+#define CMD_DESTROY_SYNC_TIMELINE 4
+
+// Starts a wait on the host with
+// the given glsync object and sync thread handle.
+#define CMD_TRIGGER_HOST_WAIT 5
+
+// The register layout is:
+
+#define SYNC_REG_BATCH_COMMAND 0x00 // host->guest batch commands
+#define SYNC_REG_BATCH_GUESTCOMMAND 0x04 // guest->host batch commands
+#define SYNC_REG_BATCH_COMMAND_ADDR 0x08 // communicate physical address of host->guest batch commands
+#define SYNC_REG_BATCH_COMMAND_ADDR_HIGH 0x0c // 64-bit part
+#define SYNC_REG_BATCH_GUESTCOMMAND_ADDR 0x10 // communicate physical address of guest->host commands
+#define SYNC_REG_BATCH_GUESTCOMMAND_ADDR_HIGH 0x14 // 64-bit part
+#define SYNC_REG_INIT 0x18 // to signal that the device has been detected by the kernel
+
+#define GUEST_TRIGGERED(cmd) (cmd == CMD_SYNC_READY || \
+ cmd == CMD_TRIGGER_HOST_WAIT)
+
+typedef void (*trigger_wait_fn_t)(uint64_t, uint64_t, uint64_t);
+
+// The commands below operate on Android sync "timelines" and
+// "fences". The basic concept is as follows.
+// - Timeline and fences work together as a state to determine
+// which events have completed. The timeline abstraction
+// is used to represent a monotonic ordering of events,
+// while fences represent levels of progress along
+// timelines. By having different threads wait on fences
+// until their associated timelines make the required progress,
+// we can synchronize multiple threads within a process
+// and with binder, across processes.
+// - What follows is an abstract definition of that concept
+// that does not match implementation exactly, but is
+// sufficient for our purposes:
+// - A timeline is a represnted by a single uint32_t, known as
+// its "value". Over time, the value may increase.
+// timeline : value
+// - Let "timeline-id" be a uint64_t that uniquely identifies each
+// timeline.
+// A fence is an immutable map from timeline-id's to values:
+// fence : map(timeline-id -> value). We will refer to the
+// "timeline-id-values" of a fence to be the set of all pairs
+// (timeline-id, value) that comprise the mapping.
+// - Let "fence-id" be an int that uniquely identifies each fence.
+// This is also known as a "fence fd".
+// The important state is represented by a pair of maps:
+// (T = map(timeline-id -> timeline), F = map(fence-id -> fence)).
+// This state may change over time, with timelines and fences
+// being added or removed.
+// For any state, we care primarily about the "signaled" status
+// of the fences within.
+// - Each fence in the map from fence-id's to fences is
+// signaled if:
+// - For all timeline-id-values = (timeline-id, value)
+// of that fence, T[timeline-id] >= value.
+// Or, timeline-id does not exist in T's keys.
+// - Otherwise, it is considered "unsignaled."
+// The functions below operate with the above abstraction in mind.
+// They all mutate a particular collection of fences and timelines.
+// We can think of them as implicitly taking a state (T, F)
+// as input and returning a new one (T', F') that is possibly updated,
+// according to the changes described. The new collection then
+// serves as the true abstract state for all further operations.
+
+// |goldfish_sync_create_timeline| creates a new timeline
+// with value 0. The timeline id is returned.
+uint64_t goldfish_sync_create_timeline();
+
+// |goldfish_sync_create_fence| creates a fence
+// that has a single timeline-id-value pair as its map.
+// The first two arguments comprise the pair.
+// Returns a unique identifier for the fence.
+// Note that this implementation only allows the creation of
+// fences associated with a single timeline-id-value pair.
+int goldfish_sync_create_fence(uint64_t timeline, uint32_t pt);
+
+// |goldfish_sync_timeline_inc| advances the value component
+// of a given timeline by |howmuch|; that is, if
+// (t, v) is the timeline-id and value of a timeline before this call,
+// (t, v + |howmuch|) is the value after.
+// Thus, this may end up changing some fence objects to signaled state.
+void goldfish_sync_timeline_inc(uint64_t timeline, uint32_t howmuch);
+
+// |goldfish_sync_destroy_timeline| removes the key |timeline|
+// from the global timeline map.
+// Any fence objects whose only timeline-id-value (t, v) is such that
+// t == |timeline| would be considered signaled.
+// If there are any other timeline-id-values, the fence may still be
+// unsignaled. We would need the other timelines referenced by this fence
+// to have reached the target value of this fence, fence[timeline].
+void goldfish_sync_destroy_timeline(uint64_t timeline);
+
+// Registering callbacks for goldfish sync ops
+// Currently, only trigger_wait is supported.
+void goldfish_sync_register_trigger_wait(trigger_wait_fn_t trigger_fn);
+
+// If the virtual device doesn't actually exist (e.g., when
+// using QEMU1), query that using this function:
+bool goldfish_sync_device_exists();
+
+// Function types for sending commands to the virtual device.
+typedef void (*queue_device_command_t)
+ (uint32_t cmd, uint64_t handle, uint32_t time_arg,
+ uint64_t hostcmd_handle);
+
+typedef struct GoldfishSyncDeviceInterface {
+ // Callback for all communications with virtual device
+ queue_device_command_t doHostCommand;
+
+ // Callbacks to register other callbacks for triggering
+ // OpenGL waits from the guest
+ void (*registerTriggerWait)(trigger_wait_fn_t);
+} GoldfishSyncDeviceInterface;
+
+// The virtual device will call |goldfish_sync_set_hw_funcs|
+// to connect up to the AndroidEmu part.
+extern void
+goldfish_sync_set_hw_funcs(GoldfishSyncDeviceInterface* hw_funcs);
+
+// The virtual device calls this |goldfish_sync_receive_hostcmd_result|
+// when it receives a reply for host->guest commands that support
+// that protocol.
+extern void
+goldfish_sync_receive_hostcmd_result(uint32_t cmd,
+ uint64_t handle,
+ uint32_t time_arg,
+ uint64_t hostcmd_handle);
diff --git a/host-common/sync_device.cpp b/host-common/sync_device.cpp
new file mode 100644
index 0000000..8aeadaf
--- /dev/null
+++ b/host-common/sync_device.cpp
@@ -0,0 +1,80 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "sync_device.h"
+
+static uint64_t defaultCreateTimeline() { return 0; }
+
+static int defaultCreateFence(uint64_t timeline, uint32_t pt) {
+ (void)timeline;
+ (void)pt;
+ return -1;
+}
+
+static void defaultTimelineInc(uint64_t timeline, uint32_t howmuch) {
+ (void)timeline;
+ (void)howmuch;
+ return;
+}
+
+static void defaultDestroyTimeline(uint64_t timeline) {
+ (void)timeline;
+ return;
+}
+
+static void defaultRegisterTriggerWait(emugl_sync_trigger_wait_t f) {
+ (void)f;
+ return;
+}
+
+static bool defaultDeviceExists() {
+ return false;
+}
+
+namespace emugl {
+
+emugl_sync_create_timeline_t emugl_sync_create_timeline = defaultCreateTimeline;
+emugl_sync_create_fence_t emugl_sync_create_fence = defaultCreateFence;
+emugl_sync_timeline_inc_t emugl_sync_timeline_inc = defaultTimelineInc;
+emugl_sync_destroy_timeline_t emugl_sync_destroy_timeline = defaultDestroyTimeline;
+emugl_sync_register_trigger_wait_t emugl_sync_register_trigger_wait = defaultRegisterTriggerWait;
+emugl_sync_device_exists_t emugl_sync_device_exists = defaultDeviceExists;
+
+void set_emugl_sync_create_timeline(emugl_sync_create_timeline_t f) {
+ emugl_sync_create_timeline = f;
+}
+
+void set_emugl_sync_create_fence(emugl_sync_create_fence_t f) {
+ emugl_sync_create_fence = f;
+}
+
+void set_emugl_sync_timeline_inc(emugl_sync_timeline_inc_t f) {
+ emugl_sync_timeline_inc = f;
+}
+
+void set_emugl_sync_destroy_timeline(emugl_sync_destroy_timeline_t f) {
+ emugl_sync_destroy_timeline = f;
+}
+
+void set_emugl_sync_register_trigger_wait(emugl_sync_register_trigger_wait_t f) {
+ emugl_sync_register_trigger_wait = f;
+}
+
+void set_emugl_sync_device_exists(emugl_sync_device_exists_t f) {
+ emugl_sync_device_exists = f;
+}
+
+} // namespace emugl
diff --git a/host-common/sync_device.h b/host-common/sync_device.h
new file mode 100644
index 0000000..f8bc825
--- /dev/null
+++ b/host-common/sync_device.h
@@ -0,0 +1,47 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#pragma once
+
+#include "render_api_types.h"
+
+#ifdef _MSC_VER
+# ifdef BUILDING_EMUGL_COMMON_SHARED
+# define EMUGL_COMMON_API __declspec(dllexport)
+# else
+# define EMUGL_COMMON_API __declspec(dllimport)
+#endif
+#else
+# define EMUGL_COMMON_API
+#endif
+
+namespace emugl {
+
+EMUGL_COMMON_API extern emugl_sync_create_timeline_t emugl_sync_create_timeline;
+EMUGL_COMMON_API extern emugl_sync_create_fence_t emugl_sync_create_fence;
+EMUGL_COMMON_API extern emugl_sync_timeline_inc_t emugl_sync_timeline_inc;
+EMUGL_COMMON_API extern emugl_sync_destroy_timeline_t emugl_sync_destroy_timeline;
+EMUGL_COMMON_API extern emugl_sync_register_trigger_wait_t emugl_sync_register_trigger_wait;
+EMUGL_COMMON_API extern emugl_sync_device_exists_t emugl_sync_device_exists;
+
+EMUGL_COMMON_API void set_emugl_sync_create_timeline(emugl_sync_create_timeline_t);
+EMUGL_COMMON_API void set_emugl_sync_create_fence(emugl_sync_create_fence_t);
+EMUGL_COMMON_API void set_emugl_sync_timeline_inc(emugl_sync_timeline_inc_t);
+EMUGL_COMMON_API void set_emugl_sync_destroy_timeline(emugl_sync_destroy_timeline_t);
+EMUGL_COMMON_API void set_emugl_sync_register_trigger_wait(emugl_sync_register_trigger_wait_t trigger_fn);
+EMUGL_COMMON_API void set_emugl_sync_device_exists(emugl_sync_device_exists_t);
+
+} // namespace emugl
diff --git a/stream-servers/render_api_types.h b/stream-servers/render_api_types.h
index aefe4b3..7291a86 100644
--- a/stream-servers/render_api_types.h
+++ b/stream-servers/render_api_types.h
@@ -15,9 +15,9 @@
// Interface between android-emu non-base libraries and emugl
-#include "android/emulation/GoldfishDma.h"
-#include "android/emulation/goldfish_sync.h"
-#include "android/featurecontrol/FeatureControl.h"
+#include "host-common/GoldfishDma.h"
+#include "host-common/goldfish_sync.h"
+#include "host-common/FeatureControl.h"
// Crash reporter
typedef void (*emugl_crash_reporter_t)(const char* format, ...);