Add support for arm{,64} cuttlefish phone platforms
Only 'aosp_cf_arm_phone-userdebug' can boot up successfully because
swiftshader does not support arm64.
Bug: 118442619
Test: lunch aosp_cf_arm_phone-userdebug && make -j128 dist
Test: lunch aosp_cf_arm64_phone-userdebug && make -j128 dist
Change-Id: I68f39bbe2bd7d6f0dac4ab8bce888dc9ca4babad
diff --git a/Android.bp b/Android.bp
index a901fe1..d9cbf16 100644
--- a/Android.bp
+++ b/Android.bp
@@ -59,19 +59,6 @@
vendor: true,
}
-// ARM code should not touch the VSoC window on an x86 CPU.
-cc_defaults {
- name: "cuttlefish_native_isa",
- target: {
- android_arm: {
- enabled: false,
- },
- android_arm64: {
- enabled: false,
- },
- },
-}
-
cc_defaults {
name: "cuttlefish_guest_only",
defaults: ["cuttlefish_base"],
@@ -137,7 +124,7 @@
],
},
},
- defaults: ["cuttlefish_host_and_guest", "cuttlefish_native_isa"],
+ defaults: ["cuttlefish_host_and_guest"],
}
cc_test_host {
diff --git a/Android.mk b/Android.mk
index c38d99b..fa659d7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -11,7 +11,7 @@
# 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.
-ifneq ($(filter vsoc_x86 vsoc_x86_64, $(TARGET_DEVICE)),)
+ifneq ($(filter vsoc_arm vsoc_arm64 vsoc_x86 vsoc_x86_64, $(TARGET_DEVICE)),)
LOCAL_PATH:= $(call my-dir)
include $(call first-makefiles-under,$(LOCAL_PATH))
endif
diff --git a/common/frontend/socket_forward_proxy/Android.bp b/common/frontend/socket_forward_proxy/Android.bp
index 81ba9c4..74ef53a 100644
--- a/common/frontend/socket_forward_proxy/Android.bp
+++ b/common/frontend/socket_forward_proxy/Android.bp
@@ -41,5 +41,5 @@
],
},
},
- defaults: ["cuttlefish_host_and_guest", "cuttlefish_native_isa"]
+ defaults: ["cuttlefish_host_and_guest"]
}
diff --git a/common/frontend/socket_vsock_proxy/Android.bp b/common/frontend/socket_vsock_proxy/Android.bp
index 2cebe17..a0bc46f 100644
--- a/common/frontend/socket_vsock_proxy/Android.bp
+++ b/common/frontend/socket_vsock_proxy/Android.bp
@@ -39,5 +39,5 @@
],
},
},
- defaults: ["cuttlefish_host_and_guest", "cuttlefish_native_isa"]
+ defaults: ["cuttlefish_host_and_guest"]
}
diff --git a/common/vsoc/shm/lock.h b/common/vsoc/shm/lock.h
index cc86add..2049ba8 100644
--- a/common/vsoc/shm/lock.h
+++ b/common/vsoc/shm/lock.h
@@ -23,7 +23,13 @@
// types that can be referenced below.
// For _mm_pause()
+#if defined(__SSE2__)
#include <x86intrin.h>
+#define _pause() _mm_pause()
+#elif defined(__arm__) || defined(__aarch64__)
+#include <arm_acle.h>
+#define _pause() __yield()
+#endif
#include <atomic>
#include <cstdint>
@@ -62,7 +68,7 @@
if (lock_.compare_exchange_strong(expected, Sides::OurSide)) {
return;
}
- _mm_pause();
+ _pause();
}
}
diff --git a/host/libs/vm_manager/cf_qemu.sh b/host/libs/vm_manager/cf_qemu.sh
index f3e2384..8cfff78 100755
--- a/host/libs/vm_manager/cf_qemu.sh
+++ b/host/libs/vm_manager/cf_qemu.sh
@@ -16,6 +16,33 @@
# limitations under the License.
#
+print_command() {
+ binary=$1; shift
+ binary_args=("$@")
+ printf %s "${binary}"
+ for i in "${binary_args[@]}"; do
+ case "$i" in
+ -*) printf "\\%s %s " $'\n' "$i" ;;
+ *) printf "%s " "$i" ;;
+ esac
+ done
+ echo
+}
+
+exec_run() {
+ binary=$1; shift
+ binary_args=("$@")
+ print_command "${binary}" "${binary_args[@]}"
+ exec "${binary}" "${binary_args[@]}"
+}
+
+run() {
+ binary=$1; shift
+ binary_args=("$@")
+ print_command "${binary}" "${binary_args[@]}"
+ "${binary}" "${binary_args[@]}"
+}
+
default_instance_number() {
if [[ "${USER::5}" == "vsoc-" ]]; then
echo "${USER: -2}"
@@ -30,15 +57,33 @@
default_mobile_tap_name="cvd-mtap-${CUTTLEFISH_INSTANCE}"
default_wifi_tap_name="cvd-wtap-${CUTTLEFISH_INSTANCE}"
+qemu_binary=${qemu_binary=/usr/bin/qemu-system-x86_64}
+dtc_binary=${dtc_binary:-dtc}
+
if [[ -z "${ivshmem_vector_count}" ]]; then
echo "The required ivshmem_vector_count environment variable is not set" >&2
exit 1
fi
+if [[ "${qemu_binary##*/}" = "qemu-system-aarch64" ]]; then
+ # On ARM, the early console can be PCI, and ISA is not supported
+ kernel_console_serial="pci-serial,addr=0xb"
+ machine="virt,gic_version=2"
+ cpu=cortex-a53
+else
+ # On x86, the early console must be ISA, not PCI, so we start to get kernel
+ # messages as soon as possible. ISA devices do not have 'addr' assignments.
+ kernel_console_serial="isa-serial"
+ machine="pc-i440fx-2.8,accel=kvm"
+ cpu=host
+fi
+
+# Put anything here that might affect the machine configuration generated by
+# QEMU. Anything which connects statefully to another service (like a socket)
+# should be added in another section below.
args=(
- -enable-kvm
-name "guest=${instance_name:-${default_instance_name}},debug-threads=on"
- -machine "pc-i440fx-2.8,accel=kvm,usb=off,dump-guest-core=off"
+ -machine "${machine},usb=off,dump-guest-core=off"
-m "${memory_mb:-2048}"
-realtime mlock=off
-smp "${cpus:-2},sockets=${cpus:-2},cores=1,threads=1"
@@ -46,8 +91,6 @@
-display none
-no-user-config
-nodefaults
- -chardev "socket,id=charmonitor,path=${monitor_path:-${default_dir}/qemu_monitor.sock},nowait"
- -mon "chardev=charmonitor,id=monitor,mode=control"
-rtc "base=utc"
-no-shutdown
-boot "strict=on"
@@ -68,19 +111,83 @@
-device "virtio-net-pci,netdev=hostnet0,id=net0,addr=0x2"
-netdev "tap,id=hostnet1,ifname=${mobile_tap_name:-${default_mobile_tap_name}},script=no,downscript=no"
-device "virtio-net-pci,netdev=hostnet1,id=net1,addr=0x3"
+ -device "virtio-balloon-pci,id=balloon0,addr=0x9"
+ -object "rng-random,id=objrng0,filename=/dev/urandom"
+ -device "virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=1024,period=2000,addr=0xa"
+ -cpu "${cpu}"
+ -msg "timestamp=on"
+)
+
+if [[ -n "${dtb_path}" ]]; then
+ if [[ "${qemu_binary##*/}" = "qemu-system-aarch64" ]]; then
+ # Decompile the dt fragment to include in our machine FDT
+ dtsi_path="${default_dir}/android.dtsi"
+ dtc_args=(
+ -I dtb
+ "${dtb_path}"
+ -O dts
+ -o "${dtsi_path}"
+ )
+ run "${dtc_binary}" "${dtc_args[@]}"
+
+ # Remove duplicate version definition from the dtsi
+ sed_binary=sed
+ sed_args=(
+ -i "/^\/dts-v1\/;$/d"
+ ${dtsi_path}
+ )
+ run "${sed_binary}" "${sed_args[@]}"
+
+ # Dump the machine FDT blob
+ dts_path="${default_dir}/cuttlefish.dts"
+ dtb_path="${default_dir}/cuttlefish.dtb"
+ dtb_args=(-machine "dumpdtb=${dtb_path}")
+ run "${qemu_binary}" "${args[@]}" "${dtb_args[@]}"
+
+ # Decompile the FDT blob
+ dtc_args=(
+ -I dtb
+ ${dtb_path}
+ -O dts
+ -o ${dts_path}
+ )
+ run "${dtc_binary}" "${dtc_args[@]}"
+
+ # Concatenate the dts and dtsi sources
+ echo "cat ${dtsi_path} >>${dts_path}"
+ echo
+ cat ${dtsi_path} >>${dts_path}
+
+ # Compile the patched machine FDT
+ dtc_args=(
+ -i "${dts_path%/*}"
+ -I dts
+ "${dts_path}"
+ -O dtb
+ -o "${dtb_path}"
+ )
+ run "${dtc_binary}" "${dtc_args[@]}"
+ fi
+
+ args+=(-dtb "${dtb_path}")
+fi
+
+# The services providing these sockets don't expect multiple connections,
+# so we must not have them in 'args' when we dump the machine FDT. It's
+# OK to add them now, after the dumping and patching has completed.
+# The (maybe patched) DTB can also be provided now.
+
+args+=(
+ -chardev "socket,id=charmonitor,path=${monitor_path:-${default_dir}/qemu_monitor.sock},nowait"
+ -mon "chardev=charmonitor,id=monitor,mode=control"
-chardev "socket,id=charserial0,path=${kernel_log_socket_name:-${default_dir}/kernel-log}"
- -device "isa-serial,chardev=charserial0,id=serial0"
+ -device "${kernel_console_serial},chardev=charserial0,id=serial0"
-chardev "socket,id=charserial1,path=${console_path:-${default_dir}/console},server,nowait"
-device "pci-serial,chardev=charserial1,id=serial1,addr=0xc"
-chardev "file,id=charchannel0,path=${logcat_path:-${default_dir}/logcat},append=on"
-device "virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=cf-logcat"
- -device "virtio-balloon-pci,id=balloon0,addr=0x9"
- -object "rng-random,id=objrng0,filename=/dev/urandom"
- -device "virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=1024,period=2000,addr=0xa"
-chardev "socket,path=${ivshmem_qemu_socket_path:-${default_dir}/ivshmem_socket_qemu},id=ivsocket"
-device "ivshmem-doorbell,chardev=ivsocket,vectors=${ivshmem_vector_count},addr=0xd"
- -cpu host
- -msg "timestamp=on"
)
if [[ -n "${gdb_flag}" ]]; then
@@ -102,14 +209,4 @@
args+=(-device "vhost-vsock-pci,guest-cid=${vsock_guest_cid}")
fi
-printf %s "exec ${qemu_binary=/usr/bin/qemu-system-x86_64}"
-for i in "${args[@]}"; do
- case "$i" in
- -*) printf "\\%s %s " $'\n' "$i" ;;
- *) printf "%s " "$i" ;;
- esac
-done
-echo
-
-exec "${qemu_binary=/usr/bin/qemu-system-x86_64}" \
- "${args[@]}"
+exec_run "${qemu_binary}" "${args[@]}"