Merge changes from topic 'unaligned-access-optimization' into emu-master-dev
* changes:
target-mips & softmmu: Misaligned Memory Accesses for R6/MSA
tcg: Use softmmu fast path for unaligned accesses
target-mips & softmmu: Revert: PRPL: Misaligned Memory Accesses for R6/MSA
diff --git a/android-qemu2-glue/.clang-format b/android-qemu2-glue/.clang-format
new file mode 100644
index 0000000..6375c66
--- /dev/null
+++ b/android-qemu2-glue/.clang-format
@@ -0,0 +1,4 @@
+BasedOnStyle: Chromium
+IndentWidth: 4
+ContinuationIndentWidth: 8
+AccessModifierOffset: -4
diff --git a/android-qemu2-glue/build/Makefile.qemu2-glue.mk b/android-qemu2-glue/build/Makefile.qemu2-glue.mk
index 842325b..e692c27 100644
--- a/android-qemu2-glue/build/Makefile.qemu2-glue.mk
+++ b/android-qemu2-glue/build/Makefile.qemu2-glue.mk
@@ -32,6 +32,7 @@
base/files/QemuFileStream.cpp \
emulation/charpipe.c \
emulation/CharSerialLine.cpp \
+ emulation/goldfish_sync.cpp \
emulation/serial_line.cpp \
emulation/VmLock.cpp \
telephony/modem_init.c \
diff --git a/android-qemu2-glue/emulation/goldfish_sync.cpp b/android-qemu2-glue/emulation/goldfish_sync.cpp
new file mode 100644
index 0000000..01cc29f
--- /dev/null
+++ b/android-qemu2-glue/emulation/goldfish_sync.cpp
@@ -0,0 +1,56 @@
+/* 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.
+*/
+#include "android-qemu2-glue/emulation/goldfish_sync.h"
+
+// Glue code between the virtual goldfish sync device, and the
+// host-side sync service implementation.
+
+#include "android/base/Log.h"
+#include "android/emulation/GoldfishSyncCommandQueue.h"
+#include "android/emulation/goldfish_sync.h"
+
+extern "C" {
+#include "hw/misc/goldfish_sync.h"
+} // extern "C"
+
+static trigger_wait_fn_t sTriggerWaitFn = nullptr;
+
+// These callbacks are called from the host sync service to operate
+// on the virtual device (.doHostCommand) or register a trigger-waiting
+// callback that will be invoked later from the device
+// (.registerTriggerWait).
+static GoldfishSyncDeviceInterface kSyncDeviceInterface = {
+ .doHostCommand = goldfish_sync_send_command,
+ .registerTriggerWait = [](trigger_wait_fn_t fn) {
+ sTriggerWaitFn = fn;
+ },
+};
+
+// These callbacks are called from the virtual device to send
+// data to the host sync service.
+static const GoldfishSyncServiceOps kSyncServiceOps = {
+ .receive_hostcmd_result = goldfish_sync_receive_hostcmd_result,
+ .trigger_host_wait = [](uint64_t glsync_ptr,
+ uint64_t thread_ptr,
+ uint64_t timeline) {
+ if (sTriggerWaitFn) {
+ sTriggerWaitFn(glsync_ptr, thread_ptr, timeline);
+ }
+ }
+};
+
+bool qemu_android_sync_init(android::VmLock* vmLock) {
+ goldfish_sync_set_service_ops(&kSyncServiceOps);
+ goldfish_sync_set_hw_funcs(&kSyncDeviceInterface);
+ android::GoldfishSyncCommandQueue::initThreading(vmLock);
+ return true;
+}
diff --git a/android-qemu2-glue/emulation/goldfish_sync.h b/android-qemu2-glue/emulation/goldfish_sync.h
new file mode 100644
index 0000000..cd20b9d
--- /dev/null
+++ b/android-qemu2-glue/emulation/goldfish_sync.h
@@ -0,0 +1,17 @@
+/* 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 "android/emulation/VmLock.h"
+
+/* Initialize Goldfish Sync device and service. */
+bool qemu_android_sync_init(android::VmLock* vmLock);
diff --git a/android-qemu2-glue/main.cpp b/android-qemu2-glue/main.cpp
index 6cce02d..3735019 100755
--- a/android-qemu2-glue/main.cpp
+++ b/android-qemu2-glue/main.cpp
@@ -709,6 +709,12 @@
args[n++] = "-cpu";
args[n++] = kTarget.qemuCpu;
+ // Set env var to "on" for Intel PMU if the feature is enabled.
+ // cpu.c will then read that.
+ if (android::featurecontrol::isEnabled(android::featurecontrol::IntelPerformanceMonitoringUnit)) {
+ System::get()->envSet("ANDROID_EMU_FEATURE_IntelPerformanceMonitoringUnit", "on");
+ }
+
#if defined(TARGET_X86_64) || defined(TARGET_I386)
char* accel_status = NULL;
CpuAccelMode accel_mode = ACCEL_AUTO;
diff --git a/android-qemu2-glue/qemu-setup.cpp b/android-qemu2-glue/qemu-setup.cpp
index 6d96824..1130592 100644
--- a/android-qemu2-glue/qemu-setup.cpp
+++ b/android-qemu2-glue/qemu-setup.cpp
@@ -18,8 +18,8 @@
#include "android/base/Log.h"
#include "android/console.h"
#include "android/emulation/AndroidPipe.h"
-#include "android/emulation/GoldfishSyncCommandQueue.h"
#include "android-qemu2-glue/qemu-control-impl.h"
+#include "android-qemu2-glue/emulation/goldfish_sync.h"
#include "android-qemu2-glue/emulation/VmLock.h"
extern "C" {
@@ -44,7 +44,10 @@
CHECK(prevVmLock == nullptr) << "Another VmLock was already installed!";
android::AndroidPipe::initThreading(vmLock);
- android::GoldfishSyncCommandQueue::initThreading(vmLock);
+
+ if (!qemu_android_sync_init(vmLock)) {
+ return false;
+ }
return android_emulation_setup(&consoleAgents);
}
diff --git a/hw/arm/ranchu.c b/hw/arm/ranchu.c
index 4667a1a..8450a9a 100644
--- a/hw/arm/ranchu.c
+++ b/hw/arm/ranchu.c
@@ -38,7 +38,6 @@
#include "qemu/config-file.h"
#include "sysemu/char.h"
#include "monitor/monitor.h"
-#include "hw/misc/android_pipe.h"
#include "android/android.h"
diff --git a/hw/mips/mips_ranchu.c b/hw/mips/mips_ranchu.c
index 420d763..65d85c4 100644
--- a/hw/mips/mips_ranchu.c
+++ b/hw/mips/mips_ranchu.c
@@ -13,7 +13,6 @@
#include "qemu/config-file.h"
#include "sysemu/char.h"
#include "monitor/monitor.h"
-#include "hw/misc/android_pipe.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/intc/goldfish_pic.h"
diff --git a/hw/misc/android_pipe.c b/hw/misc/android_pipe.c
index bdd85d8..6be9b73 100755
--- a/hw/misc/android_pipe.c
+++ b/hw/misc/android_pipe.c
@@ -28,8 +28,6 @@
** should give some thought to if this needs re-writing to take
** advantage of that infrastructure to create the pipes.
*/
-#include "hw/misc/android_pipe.h"
-
#include "android-qemu2-glue/utils/stream.h"
#include "android/emulation/android_pipe_device.h"
#include "hw/hw.h"
diff --git a/hw/misc/goldfish_sync.c b/hw/misc/goldfish_sync.c
index 777e6de..443086b 100644
--- a/hw/misc/goldfish_sync.c
+++ b/hw/misc/goldfish_sync.c
@@ -10,7 +10,7 @@
** GNU General Public License for more details.
*/
-#include "android/emulation/goldfish_sync.h"
+#include "hw/misc/goldfish_sync.h"
#include "android/utils/debug.h"
#include "hw/hw.h"
@@ -20,14 +20,6 @@
#include "qemu/main-loop.h"
#include "trace.h"
-#ifndef max
-#define max(x, y) ((x) < (y) ? y : x)
-#endif
-
-#ifndef min
-#define min(x, y) ((x) > (y) ? y : x)
-#endif
-
#define DEBUG_LOG_ALL_DEVICE_OPS 0
#if DEBUG_LOG_ALL_DEVICE_OPS
@@ -82,6 +74,20 @@
uint64_t timeline);
};
+// Command numbers that can only be sent from the guest to the device.
+#define SYNC_GUEST_CMD_READY 0
+#define SYNC_GUEST_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
+
// The goldfish sync device is represented by the goldfish_sync_state struct.
// Besides the machinery necessary to do I/O with the guest:
// |pending|: a linked list of |goldfish_sync_pending_cmd|'s
@@ -115,6 +121,12 @@
static struct goldfish_sync_state* s_goldfish_sync_dev;
+static const GoldfishSyncServiceOps* service_ops = NULL;
+
+void goldfish_sync_set_service_ops(const GoldfishSyncServiceOps *ops) {
+ service_ops = ops;
+}
+
// Command list operations======================================================
static struct goldfish_sync_pending_cmd*
@@ -187,15 +199,14 @@
// Callbacks and hw_funcs struct================================================
-// goldfish_sync_host_signal does the actual work of setting up
+// goldfish_sync_send_command does the actual work of setting up
// the sync device registers, causing IRQ blip,
// and waiting for + reading back results from the guest
// (if appplicable)
-static void goldfish_sync_host_signal(
- uint32_t cmd,
- uint64_t handle,
- uint32_t time_arg,
- uint64_t hostcmd_handle) {
+void goldfish_sync_send_command(uint32_t cmd,
+ uint64_t handle,
+ uint32_t time_arg,
+ uint64_t hostcmd_handle) {
struct goldfish_sync_state* s;
struct goldfish_sync_pending_cmd* to_send;
@@ -221,31 +232,6 @@
DPRINT("Exit");
}
-// This sets |trigger_fn| as the function to call
-// when guest asks the host to trigger a wait.
-void goldfish_sync_register_trigger_wait_impl(
- trigger_wait_fn_t trigger_fn) {
-
- DPRINT("Enter");
-
- struct goldfish_sync_state* s = s_goldfish_sync_dev;
-
- if (!s->ops) {
- s->ops =
- (struct goldfish_sync_ops*)
- (malloc(sizeof(struct goldfish_sync_ops)));
- }
-
- s->ops->trigger_wait = trigger_fn;
-
- DPRINT("Exit");
-}
-
-static GoldfishSyncDeviceInterface qemu2_goldfish_sync_hw_funcs = {
- .doHostCommand = goldfish_sync_host_signal,
- .registerTriggerWait = goldfish_sync_register_trigger_wait_impl,
-};
-
#define TYPE_GOLDFISH_SYNC "goldfish_sync"
#define GOLDFISH_SYNC(obj) \
OBJECT_CHECK(struct goldfish_sync_state, (obj), TYPE_GOLDFISH_SYNC)
@@ -365,7 +351,7 @@
incoming.handle,
incoming.time_arg,
incoming.hostcmd_handle);
- goldfish_sync_receive_hostcmd_result(
+ service_ops->receive_hostcmd_result(
incoming.cmd,
incoming.handle,
incoming.time_arg,
@@ -373,7 +359,7 @@
break;
// SYNC_REG_BATCH_GUESTCOMMAND write: Used to send
// guest->host commands. Currently, the only guest->host command
- // that matters is CMD_TRIGGER_HOST_WAIT, which is used
+ // that matters is SYNC_GUEST_CMD_TRIGGER_HOST_WAIT, which is used
// to cause a OpenGL client wait on the host GPU/CPU.
case SYNC_REG_BATCH_GUESTCOMMAND:
DPRINT("write SYNC_REG_BATCH_GUESTCOMMAND. obtaining batch cmd vals.");
@@ -392,14 +378,14 @@
guest_incoming.thread_handle,
guest_incoming.guest_timeline_handle);
switch (guest_incoming.host_command) {
- case CMD_TRIGGER_HOST_WAIT:
- DPRINT("exec CMD_TRIGGER_HOST_WAIT");
- s->ops->trigger_wait(guest_incoming.glsync_handle,
- guest_incoming.thread_handle,
- guest_incoming.guest_timeline_handle);
+ case SYNC_GUEST_CMD_TRIGGER_HOST_WAIT:
+ DPRINT("exec SYNC_GUEST_CMD_TRIGGER_HOST_WAIT");
+ service_ops->trigger_host_wait(guest_incoming.glsync_handle,
+ guest_incoming.thread_handle,
+ guest_incoming.guest_timeline_handle);
break;
- case CMD_SYNC_READY:
- DPRINT("exec CMD_SYNC_READY");
+ case SYNC_GUEST_CMD_READY:
+ DPRINT("exec SYNC_GUEST_CMD_READY");
break;
}
break;
@@ -458,8 +444,6 @@
0x2000);
sysbus_init_mmio(sbdev, &s->iomem);
sysbus_init_irq(sbdev, &s->irq);
-
- goldfish_sync_set_hw_funcs(&qemu2_goldfish_sync_hw_funcs);
}
static Property goldfish_sync_properties[] = {
diff --git a/include/hw/misc/android_pipe.h b/include/hw/misc/android_pipe.h
deleted file mode 100644
index 9afabc8..0000000
--- a/include/hw/misc/android_pipe.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2011 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.
-*/
-#ifndef _HW_ANDROID_PIPE_H
-#define _HW_ANDROID_PIPE_H
-
-#include <stdbool.h>
-#include <stdint.h>
-#include "hw/hw.h"
-
-extern bool qemu2_adb_server_init(int port);
-
-#include "android/emulation/android_pipe_device.h"
-#include "android/opengles-pipe.h"
-
-extern void android_zero_pipe_init(void);
-extern void android_pingpong_init(void);
-extern void android_throttle_init(void);
-extern void android_adb_dbg_backend_init(void);
-extern void android_adb_backend_init(void);
-extern void android_sensors_init(void);
-
-#endif /* _HW_ANDROID_PIPE_H */
diff --git a/include/hw/misc/goldfish_sync.h b/include/hw/misc/goldfish_sync.h
new file mode 100644
index 0000000..26d714a
--- /dev/null
+++ b/include/hw/misc/goldfish_sync.h
@@ -0,0 +1,60 @@
+/* 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.
+*/
+
+#ifndef HW_MISC_GOLDFISH_SYNC_H
+#define HW_MISC_GOLDFISH_SYNC_H
+
+#include <stdint.h>
+
+/* A list of commands to send to the guest through the goldfish_sync device
+ * CMD_CREATE_TIMELINE: used to create a new timeline handle.
+ * CMD_CREATE_FENCE: used to create a new sync fence handle.
+ * CMD_INCREMENT_TIMELINE: used to increment a timeline's value.
+ * CMD_DESTROY_TIMELINE: used to destroy a given timeline handle.
+ * and sync thread handle. */
+typedef enum {
+ GOLDFISH_SYNC_CMD_CREATE_TIMELINE = 1,
+ GOLDFISH_SYNC_CMD_CREATE_FENCE = 2,
+ GOLDFISH_SYNC_CMD_INCREMENT_TIMELINE = 3,
+ GOLDFISH_SYNC_CMD_DESTROY_TIMELINE = 4,
+} GoldfishSyncCommand;
+
+/* A set of callbacks that must be implemented by the host-side sync service
+ * and will be called by the virtual device at runtime. */
+typedef struct {
+ /* Called when the guest sends the result of a previous command to the
+ * host. See goldfish_send_send_command(). */
+ void (*receive_hostcmd_result)(uint32_t cmd,
+ uint64_t handle,
+ uint32_t time_arg,
+ uint64_t hostcmd_handle);
+
+ /* Called when the guest wants to trigger a host-side wait for a
+ * specific glsync and thread pointer pair. */
+ void (*trigger_host_wait)(uint64_t glsync_ptr,
+ uint64_t thread_ptr,
+ uint64_t timeline);
+} GoldfishSyncServiceOps;
+
+/* Register the host-side sync service callbacks with the device. This
+ * must be called at emulation setup time before the device runs. */
+void goldfish_sync_set_service_ops(const GoldfishSyncServiceOps *ops);
+
+/* Send a command to the guest through the goldfish_sync device.
+ * The result will be sent asynchronously through the |receive_hostcmd_result|
+ * callback. */
+void goldfish_sync_send_command(uint32_t cmd,
+ uint64_t handle,
+ uint32_t time_arg,
+ uint64_t hostcmd_handle);
+
+#endif /* HW_MISC_GOLDFISH_SYNC_H */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index b76fa4c..44791f2 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -688,7 +688,7 @@
* SSSE3, SSE4.1, SSE4.2
*/
.name = "android64",
- .level = 4,
+ .level = 4, /* may be modified later if KVM is enabled */
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 6,
@@ -706,7 +706,7 @@
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
- .xlevel = 0x8000000A,
+ .xlevel = 0x8000000A, /* may be modified later if KVM is enabled */
.model_id = "Android virtual processor"
},
#endif
@@ -820,7 +820,7 @@
* required by Android and usually comes alongside SSE4.2.
*/
.name = "android32",
- .level = 4,
+ .level = 4, /* may be modified later if KVM is enabled */
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 6,
@@ -829,7 +829,7 @@
PPRO_FEATURES,
.features[FEAT_1_ECX] =
CPUID_EXT_SSE3 | CPUID_EXT_SSSE3,
- .xlevel = 0x80000004,
+ .xlevel = 0x80000004, /* may be modified later if KVM is enabled */
.model_id = "Android 32-bit virtual processor"
},
#endif
@@ -2137,6 +2137,30 @@
goto out;
}
+#ifdef CONFIG_ANDROID
+ char* intel_pmu_enabled =
+ getenv("ANDROID_EMU_FEATURE_IntelPerformanceMonitoringUnit");
+ if (kvm_enabled() &&
+ intel_pmu_enabled &&
+ !strcmp("on", intel_pmu_enabled)) {
+
+ CPUX86State *env = &cpu->env;
+ KVMState *s = kvm_state;
+
+ /* Use the host/KVM CPUID level in order to enable additional features
+ * supported by the host CPU, such as PMU. Cf. host_x86_cpu_initfn().
+ */
+ env->cpuid_level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
+ env->cpuid_xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0,
+ R_EAX);
+ env->cpuid_xlevel2 = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0,
+ R_EAX);
+
+ /* Enable PMU (this has no effect if env->cpuid_level < 0xA) */
+ object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
+ }
+#endif
+
out:
if (error != NULL) {
error_propagate(errp, error);