Skip to content

Instantly share code, notes, and snippets.

@KhaosT
Created November 30, 2020 04:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KhaosT/ffc2d04f6137aa4ce4cc0897415f76e9 to your computer and use it in GitHub Desktop.
Save KhaosT/ffc2d04f6137aa4ce4cc0897415f76e9 to your computer and use it in GitHub Desktop.
From 947aea7a1330d293e0612ea9bff55e5951c5e867 Mon Sep 17 00:00:00 2001
From: Khaos Tian <khaos.tian@gmail.com>
Date: Sun, 29 Nov 2020 20:34:45 -0800
Subject: [PATCH] Support host
---
target/arm/cpu64.c | 21 ++++++++++++
target/arm/hvf/hvf.c | 74 ++++++++++++++++++++++++++++++++++++++++
target/arm/hvf/hvf_arm.h | 41 ++++++++++++++++++++++
3 files changed, 136 insertions(+)
create mode 100644 target/arm/hvf/hvf_arm.h
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 649213082f..526b9eecc0 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -25,6 +25,9 @@
#if !defined(CONFIG_USER_ONLY)
#include "hw/loader.h"
#endif
+#ifdef CONFIG_HVF
+#include "hvf/hvf_arm.h"
+#endif
#include "sysemu/kvm.h"
#include "kvm_arm.h"
#include "qapi/visitor.h"
@@ -734,6 +737,20 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "max", .initfn = aarch64_max_initfn },
};
+#ifdef CONFIG_HVF
+static void arm_hvf_host_initfn(Object *obj)
+{
+ ARMCPU *cpu = ARM_CPU(obj);
+ hvf_arm_set_cpu_features_from_host(cpu);
+}
+
+static const ARMCPUInfo host_arm_cpu_type_info = {
+ .name = "host",
+ .initfn = arm_hvf_host_initfn,
+};
+
+#endif
+
static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
@@ -843,6 +860,10 @@ static void aarch64_cpu_register_types(void)
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
aarch64_cpu_register(&aarch64_cpus[i]);
}
+
+#ifdef CONFIG_HVF
+ aarch64_cpu_register(&host_arm_cpu_type_info);
+#endif
}
type_init(aarch64_cpu_register_types)
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 8fe10966d2..fefa25bb9a 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -26,6 +26,7 @@
#include "sysemu/cpus.h"
#include "target/arm/cpu.h"
#include "target/arm/internals.h"
+#include "hvf_arm.h"
#define HVF_DEBUG 0
#define DPRINTF(...) \
@@ -294,6 +295,17 @@ static uint64_t hvf_get_reg(CPUState *cpu, int rt)
return val;
}
+static uint64_t hvf_get_feature_reg(hv_vcpu_config_t config, hv_feature_reg_t reg)
+{
+ uint64_t val = 0;
+ hv_return_t r;
+
+ r = hv_vcpu_config_get_feature_reg(config, reg, &val);
+ assert_hvf_ok(r);
+
+ return val;
+}
+
void hvf_arch_vcpu_destroy(CPUState *cpu)
{
}
@@ -318,6 +330,68 @@ int hvf_arch_init_vcpu(CPUState *cpu)
return 0;
}
+void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
+{
+ cpu->dtb_compatible = "arm,apple";
+
+ hv_vcpu_config_t cfg = hv_vcpu_config_create();
+
+ uint64_t data_cache[8] = { 0 };
+ hv_vcpu_config_get_ccsidr_el1_sys_reg_values(
+ cfg,
+ HV_CACHE_TYPE_DATA,
+ (uint64_t *)&data_cache
+ );
+
+ for (int i = 0; i < 8; i++) {
+ if (data_cache[i] != 0) {
+ cpu->ccsidr[i*2] = data_cache[i];
+ } else {
+ break;
+ }
+ }
+
+ uint64_t instruction_cache[8] = { 0 };
+ hv_vcpu_config_get_ccsidr_el1_sys_reg_values(
+ cfg,
+ HV_CACHE_TYPE_INSTRUCTION,
+ (uint64_t *)&instruction_cache
+ );
+
+ for (int i = 0; i < 8; i++) {
+ if (instruction_cache[i] != 0) {
+ cpu->ccsidr[i*2+1] = instruction_cache[i];
+ } else {
+ break;
+ }
+ }
+
+ cpu->reset_sctlr = 0x00c50838;
+
+ cpu->isar.id_aa64pfr0 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64PFR0_EL1);
+ cpu->isar.id_aa64pfr1 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64PFR1_EL1);
+ cpu->isar.id_aa64dfr0 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64DFR0_EL1);
+ cpu->isar.id_aa64dfr1 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64DFR1_EL1);
+ cpu->isar.id_aa64isar0 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64ISAR0_EL1);
+ cpu->isar.id_aa64isar1 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64ISAR1_EL1);
+ cpu->isar.id_aa64mmfr0 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64MMFR0_EL1);
+ cpu->isar.id_aa64mmfr1 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64MMFR1_EL1);
+ cpu->isar.id_aa64mmfr2 = hvf_get_feature_reg(cfg, HV_FEATURE_REG_ID_AA64MMFR2_EL1);
+
+ cpu->ctr = hvf_get_feature_reg(cfg, HV_FEATURE_REG_CTR_EL0);
+ cpu->clidr = hvf_get_feature_reg(cfg, HV_FEATURE_REG_CLIDR_EL1);
+ cpu->dcz_blocksize = hvf_get_feature_reg(cfg, HV_FEATURE_REG_DCZID_EL0);
+
+ set_feature(&cpu->env, ARM_FEATURE_V8);
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
+}
+
void hvf_kick_vcpu_thread(CPUState *cpu)
{
if (cpu->hvf->sleeping) {
diff --git a/target/arm/hvf/hvf_arm.h b/target/arm/hvf/hvf_arm.h
new file mode 100644
index 0000000000..e892153a73
--- /dev/null
+++ b/target/arm/hvf/hvf_arm.h
@@ -0,0 +1,41 @@
+/*
+ * QEMU HVF support -- ARM specific functions.
+ *
+ * Copyright (c) 2020 Tian Zhang
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_HVF_ARM_H
+#define QEMU_HVF_ARM_H
+
+#include "sysemu/hvf.h"
+#include "exec/memory.h"
+#include "qemu/error-report.h"
+
+#ifdef CONFIG_HVF
+
+/**
+ * hvf_arm_set_cpu_features_from_host:
+ * @cpu: ARMCPU to set the features for
+ *
+ * Set up the ARMCPU struct fields up to match the information probed
+ * from the host CPU.
+ */
+void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu);
+
+#else
+
+/*
+ * These functions should never actually be called without HVF support.
+ */
+static inline void hvf_arm_set_cpu_features_from_host(ARMCPU *cpu)
+{
+ g_assert_not_reached();
+}
+
+#endif
+
+#endif
--
2.27.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment