mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-target-arm-20230824' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * hw/gpio/nrf51: implement DETECT signal * accel/kvm: Specify default IPA size for arm64 * ptw: refactor, fix some FEAT_RME bugs * target/arm: Adjust PAR_EL1.SH for Device and Normal-NC memory types * target/arm/helper: Implement CNTHCTL_EL2.CNT[VP]MASK * Fix SME ST1Q * Fix 64-bit SSRA # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmTnIoUZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3vufEACPJcwyFvSBHDv4VQ6tbgOU # zwjpUMv4RMKhCOjuxBlJ2DICwOcGNuKer0tc6wkH2T5Ebhoego1osYbRZZoawAJf # ntg+Ndrx1QH9ORuGqYccLXtHnP741KiKggDHM05BJqB7rqtuH+N4fEn7Cdsw/DNg # XuCYD5QrxMYvkSOD1l8W0aqp81ucYPgkFqLufypgxrXUiRZ1RBAmPF47BFFdnM8f # NmrmT1LTF5jr70ySRB+ukK6BAGDc0CUfs6R6nYRwUjRPmSG2rrtUDGo+nOQGDqJo # PHWmt7rdZQG2w7HVyE/yc3h/CQ3NciwWKbCkRlaoujxHx/B6DRynSeO3NXsP8ELu # Gizoi3ltwHDQVIGQA19P5phZKHZf7x3MXmK4fDBGB9znvoSFTcjJqkdaN/ARXXO3 # e1vnK1MqnPI8Z1nGdeVIAUIrqhtLHnrrM7jf1tI/e4sjpl3prHq2PvQkakXu8clr # H8bPZ9zZzyrrSbl4NhpaFTsUiYVxeLoJsNKAmG8dHb+9YsFGXTvEBhtR9eUxnbaV # XyZ3jEdeW7/ngQ4C6XMD2ZDiKVdx2xJ2Pp5npvljldjmtGUvwQabKo+fPDt2fKjM # BwjhHA50I633k4fYIwm8YOb70I4oxoL9Lr6PkKriWPMTI5r7+dtwgigREVwnCn+Y # RsiByKMkDO2TcoQjvBZlCA== # =3MJ8 # -----END PGP SIGNATURE----- # gpg: Signature made Thu 24 Aug 2023 05:27:33 EDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20230824' of https://git.linaro.org/people/pmaydell/qemu-arm: (35 commits) target/arm: Fix 64-bit SSRA target/arm: Fix SME ST1Q target/arm/helper: Implement CNTHCTL_EL2.CNT[VP]MASK target/arm/helper: Check SCR_EL3.{NSE, NS} encoding for AT instructions target/arm: Pass security space rather than flag for AT instructions target/arm: Skip granule protection checks for AT instructions target/arm/helper: Fix tlbmask and tlbbits for TLBI VAE2* target/arm/ptw: Load stage-2 tables from realm physical space target/arm: Adjust PAR_EL1.SH for Device and Normal-NC memory types target/arm/ptw: Report stage 2 fault level for stage 2 faults on stage 1 ptw target/arm/ptw: Check for block descriptors at invalid levels target/arm/ptw: Set attributes correctly for MMU disabled data accesses target/arm/ptw: Drop S1Translate::out_secure target/arm/ptw: Remove S1Translate::in_secure target/arm/ptw: Remove last uses of ptw->in_secure target/arm/ptw: Only fold in NSTable bit effects in Secure state target/arm: Pass an ARMSecuritySpace to arm_is_el2_enabled_secstate() target/arm/ptw: Pass an ARMSecuritySpace to arm_hcr_el2_eff_secstate() target/arm/ptw: Pass ARMSecurityState to regime_translation_disabled() target/arm/ptw: Pass ptw into get_phys_addr_pmsa*() and get_phys_addr_disabled() ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
+11
-8
@@ -1454,15 +1454,13 @@ static void *kvm_dirty_ring_reaper_thread(void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int kvm_dirty_ring_reaper_init(KVMState *s)
|
||||
static void kvm_dirty_ring_reaper_init(KVMState *s)
|
||||
{
|
||||
struct KVMDirtyRingReaper *r = &s->reaper;
|
||||
|
||||
qemu_thread_create(&r->reaper_thr, "kvm-reaper",
|
||||
kvm_dirty_ring_reaper_thread,
|
||||
s, QEMU_THREAD_JOINABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_dirty_ring_init(KVMState *s)
|
||||
@@ -2458,7 +2456,7 @@ static int kvm_init(MachineState *ms)
|
||||
KVMState *s;
|
||||
const KVMCapabilityInfo *missing_cap;
|
||||
int ret;
|
||||
int type = 0;
|
||||
int type;
|
||||
uint64_t dirty_log_manual_caps;
|
||||
|
||||
qemu_mutex_init(&kml_slots_lock);
|
||||
@@ -2523,6 +2521,13 @@ static int kvm_init(MachineState *ms)
|
||||
type = mc->kvm_type(ms, kvm_type);
|
||||
} else if (mc->kvm_type) {
|
||||
type = mc->kvm_type(ms, NULL);
|
||||
} else {
|
||||
type = kvm_arch_get_default_type(ms);
|
||||
}
|
||||
|
||||
if (type < 0) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -2737,10 +2742,7 @@ static int kvm_init(MachineState *ms)
|
||||
}
|
||||
|
||||
if (s->kvm_dirty_ring_size) {
|
||||
ret = kvm_dirty_ring_reaper_init(s);
|
||||
if (ret) {
|
||||
goto err;
|
||||
}
|
||||
kvm_dirty_ring_reaper_init(s);
|
||||
}
|
||||
|
||||
if (kvm_check_extension(kvm_state, KVM_CAP_BINARY_STATS_FD)) {
|
||||
@@ -2758,6 +2760,7 @@ err:
|
||||
if (s->fd != -1) {
|
||||
close(s->fd);
|
||||
}
|
||||
g_free(s->as);
|
||||
g_free(s->memory_listener.slots);
|
||||
|
||||
return ret;
|
||||
|
||||
+1
-1
@@ -2913,7 +2913,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
|
||||
"require an IPA range (%d bits) larger than "
|
||||
"the one supported by the host (%d bits)",
|
||||
requested_pa_size, max_vm_pa_size);
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* We return the requested PA log size, unless KVM only supports
|
||||
|
||||
+13
-1
@@ -78,6 +78,7 @@ static void update_state(NRF51GPIOState *s)
|
||||
int pull;
|
||||
size_t i;
|
||||
bool connected_out, dir, connected_in, out, in, input;
|
||||
bool assert_detect = false;
|
||||
|
||||
for (i = 0; i < NRF51_GPIO_PINS; i++) {
|
||||
pull = pull_value(s->cnf[i]);
|
||||
@@ -99,7 +100,15 @@ static void update_state(NRF51GPIOState *s)
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"GPIO pin %zu short circuited\n", i);
|
||||
}
|
||||
if (!connected_in) {
|
||||
if (connected_in) {
|
||||
uint32_t detect_config = extract32(s->cnf[i], 16, 2);
|
||||
if ((detect_config == 2) && (in == 1)) {
|
||||
assert_detect = true;
|
||||
}
|
||||
if ((detect_config == 3) && (in == 0)) {
|
||||
assert_detect = true;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Floating input: the output stimulates IN if connected,
|
||||
* otherwise pull-up/pull-down resistors put a value on both
|
||||
@@ -116,6 +125,8 @@ static void update_state(NRF51GPIOState *s)
|
||||
}
|
||||
update_output_irq(s, i, connected_out, out);
|
||||
}
|
||||
|
||||
qemu_set_irq(s->detect, assert_detect);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -291,6 +302,7 @@ static void nrf51_gpio_init(Object *obj)
|
||||
|
||||
qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
|
||||
qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
|
||||
qdev_init_gpio_out_named(DEVICE(s), &s->detect, "detect", 1);
|
||||
}
|
||||
|
||||
static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "qemu/datadir.h"
|
||||
#include "qapi/error.h"
|
||||
#include "elf.h"
|
||||
#include "kvm_mips.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "hw/intc/loongson_liointc.h"
|
||||
#include "hw/mips/mips.h"
|
||||
@@ -612,7 +611,6 @@ static void loongson3v_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->max_cpus = LOONGSON_MAX_VCPUS;
|
||||
mc->default_ram_id = "loongson3.highram";
|
||||
mc->default_ram_size = 1600 * MiB;
|
||||
mc->kvm_type = mips_kvm_type;
|
||||
mc->minimum_page_bits = 14;
|
||||
mc->default_nic = "virtio-net-pci";
|
||||
}
|
||||
|
||||
+1
-1
@@ -3105,7 +3105,7 @@ static int spapr_kvm_type(MachineState *machine, const char *vm_type)
|
||||
}
|
||||
|
||||
error_report("Unknown kvm-type specified '%s'", vm_type);
|
||||
exit(1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -64,6 +64,7 @@ struct NRF51GPIOState {
|
||||
uint32_t old_out_connected;
|
||||
|
||||
qemu_irq output[NRF51_GPIO_PINS];
|
||||
qemu_irq detect;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -369,6 +369,8 @@ int kvm_arch_get_registers(CPUState *cpu);
|
||||
|
||||
int kvm_arch_put_registers(CPUState *cpu, int level);
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms);
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s);
|
||||
|
||||
int kvm_arch_init_vcpu(CPUState *cpu);
|
||||
|
||||
+37
-15
@@ -365,6 +365,15 @@ void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
|
||||
process_command_cb = pc_cb;
|
||||
}
|
||||
|
||||
static void qtest_install_gpio_out_intercept(DeviceState *dev, const char *name, int n)
|
||||
{
|
||||
qemu_irq *disconnected = g_new0(qemu_irq, 1);
|
||||
qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
|
||||
disconnected, n);
|
||||
|
||||
*disconnected = qdev_intercept_gpio_out(dev, icpt, name, n);
|
||||
}
|
||||
|
||||
static void qtest_process_command(CharBackend *chr, gchar **words)
|
||||
{
|
||||
const gchar *command;
|
||||
@@ -388,8 +397,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
||||
|| strcmp(words[0], "irq_intercept_in") == 0) {
|
||||
DeviceState *dev;
|
||||
NamedGPIOList *ngl;
|
||||
bool is_named;
|
||||
bool is_outbound;
|
||||
bool interception_succeeded = false;
|
||||
|
||||
g_assert(words[1]);
|
||||
is_named = words[2] != NULL;
|
||||
is_outbound = words[0][14] == 'o';
|
||||
dev = DEVICE(object_resolve_path(words[1], NULL));
|
||||
if (!dev) {
|
||||
qtest_send_prefix(chr);
|
||||
@@ -397,6 +411,12 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_named && !is_outbound) {
|
||||
qtest_send_prefix(chr);
|
||||
qtest_send(chr, "FAIL Interception of named in-GPIOs not yet supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (irq_intercept_dev) {
|
||||
qtest_send_prefix(chr);
|
||||
if (irq_intercept_dev != dev) {
|
||||
@@ -408,28 +428,30 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
||||
}
|
||||
|
||||
QLIST_FOREACH(ngl, &dev->gpios, node) {
|
||||
/* We don't support intercept of named GPIOs yet */
|
||||
if (ngl->name) {
|
||||
continue;
|
||||
}
|
||||
if (words[0][14] == 'o') {
|
||||
int i;
|
||||
for (i = 0; i < ngl->num_out; ++i) {
|
||||
qemu_irq *disconnected = g_new0(qemu_irq, 1);
|
||||
qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
|
||||
disconnected, i);
|
||||
|
||||
*disconnected = qdev_intercept_gpio_out(dev, icpt,
|
||||
ngl->name, i);
|
||||
/* We don't support inbound interception of named GPIOs yet */
|
||||
if (is_outbound) {
|
||||
/* NULL is valid and matchable, for "unnamed GPIO" */
|
||||
if (g_strcmp0(ngl->name, words[2]) == 0) {
|
||||
int i;
|
||||
for (i = 0; i < ngl->num_out; ++i) {
|
||||
qtest_install_gpio_out_intercept(dev, ngl->name, i);
|
||||
}
|
||||
interception_succeeded = true;
|
||||
}
|
||||
} else {
|
||||
qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
|
||||
ngl->num_in);
|
||||
interception_succeeded = true;
|
||||
}
|
||||
}
|
||||
irq_intercept_dev = dev;
|
||||
|
||||
qtest_send_prefix(chr);
|
||||
qtest_send(chr, "OK\n");
|
||||
if (interception_succeeded) {
|
||||
irq_intercept_dev = dev;
|
||||
qtest_send(chr, "OK\n");
|
||||
} else {
|
||||
qtest_send(chr, "FAIL No intercepts installed\n");
|
||||
}
|
||||
} else if (strcmp(words[0], "set_irq_in") == 0) {
|
||||
DeviceState *dev;
|
||||
qemu_irq irq;
|
||||
|
||||
@@ -2169,6 +2169,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
set_feature(env, ARM_FEATURE_VBAR);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (tcg_enabled() && cpu_isar_feature(aa64_rme, cpu)) {
|
||||
arm_register_el_change_hook(cpu, >_rme_post_el_change, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
register_cp_regs_for_features(cpu);
|
||||
arm_cpu_register_gdb_regs_for_features(cpu);
|
||||
|
||||
|
||||
+13
-6
@@ -1115,6 +1115,7 @@ struct ArchCPU {
|
||||
};
|
||||
|
||||
unsigned int gt_cntfrq_period_ns(ARMCPU *cpu);
|
||||
void gt_rme_post_el_change(ARMCPU *cpu, void *opaque);
|
||||
|
||||
void arm_cpu_post_init(Object *obj);
|
||||
|
||||
@@ -1743,6 +1744,9 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
|
||||
#define HSTR_TTEE (1 << 16)
|
||||
#define HSTR_TJDBX (1 << 17)
|
||||
|
||||
#define CNTHCTL_CNTVMASK (1 << 18)
|
||||
#define CNTHCTL_CNTPMASK (1 << 19)
|
||||
|
||||
/* Return the current FPSCR value. */
|
||||
uint32_t vfp_get_fpscr(CPUARMState *env);
|
||||
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
|
||||
@@ -2504,17 +2508,19 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
|
||||
/*
|
||||
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
|
||||
* This corresponds to the pseudocode EL2Enabled()
|
||||
* This corresponds to the pseudocode EL2Enabled().
|
||||
*/
|
||||
static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
|
||||
static inline bool arm_is_el2_enabled_secstate(CPUARMState *env,
|
||||
ARMSecuritySpace space)
|
||||
{
|
||||
assert(space != ARMSS_Root);
|
||||
return arm_feature(env, ARM_FEATURE_EL2)
|
||||
&& (!secure || (env->cp15.scr_el3 & SCR_EEL2));
|
||||
&& (space != ARMSS_Secure || (env->cp15.scr_el3 & SCR_EEL2));
|
||||
}
|
||||
|
||||
static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
{
|
||||
return arm_is_el2_enabled_secstate(env, arm_is_secure_below_el3(env));
|
||||
return arm_is_el2_enabled_secstate(env, arm_security_space_below_el3(env));
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -2538,7 +2544,8 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
|
||||
static inline bool arm_is_el2_enabled_secstate(CPUARMState *env,
|
||||
ARMSecuritySpace space)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -2555,7 +2562,7 @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
|
||||
* "for all purposes other than a direct read or write access of HCR_EL2."
|
||||
* Not included here is HCR_RW.
|
||||
*/
|
||||
uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure);
|
||||
uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space);
|
||||
uint64_t arm_hcr_el2_eff(CPUARMState *env);
|
||||
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
|
||||
|
||||
|
||||
+156
-51
@@ -2608,6 +2608,39 @@ static uint64_t gt_get_countervalue(CPUARMState *env)
|
||||
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / gt_cntfrq_period_ns(cpu);
|
||||
}
|
||||
|
||||
static void gt_update_irq(ARMCPU *cpu, int timeridx)
|
||||
{
|
||||
CPUARMState *env = &cpu->env;
|
||||
uint64_t cnthctl = env->cp15.cnthctl_el2;
|
||||
ARMSecuritySpace ss = arm_security_space(env);
|
||||
/* ISTATUS && !IMASK */
|
||||
int irqstate = (env->cp15.c14_timer[timeridx].ctl & 6) == 4;
|
||||
|
||||
/*
|
||||
* If bit CNTHCTL_EL2.CNT[VP]MASK is set, it overrides IMASK.
|
||||
* It is RES0 in Secure and NonSecure state.
|
||||
*/
|
||||
if ((ss == ARMSS_Root || ss == ARMSS_Realm) &&
|
||||
((timeridx == GTIMER_VIRT && (cnthctl & CNTHCTL_CNTVMASK)) ||
|
||||
(timeridx == GTIMER_PHYS && (cnthctl & CNTHCTL_CNTPMASK)))) {
|
||||
irqstate = 0;
|
||||
}
|
||||
|
||||
qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
|
||||
trace_arm_gt_update_irq(timeridx, irqstate);
|
||||
}
|
||||
|
||||
void gt_rme_post_el_change(ARMCPU *cpu, void *ignored)
|
||||
{
|
||||
/*
|
||||
* Changing security state between Root and Secure/NonSecure, which may
|
||||
* happen when switching EL, can change the effective value of CNTHCTL_EL2
|
||||
* mask bits. Update the IRQ state accordingly.
|
||||
*/
|
||||
gt_update_irq(cpu, GTIMER_VIRT);
|
||||
gt_update_irq(cpu, GTIMER_PHYS);
|
||||
}
|
||||
|
||||
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
|
||||
{
|
||||
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
|
||||
@@ -2623,13 +2656,9 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
|
||||
/* Note that this must be unsigned 64 bit arithmetic: */
|
||||
int istatus = count - offset >= gt->cval;
|
||||
uint64_t nexttick;
|
||||
int irqstate;
|
||||
|
||||
gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
|
||||
|
||||
irqstate = (istatus && !(gt->ctl & 2));
|
||||
qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
|
||||
|
||||
if (istatus) {
|
||||
/* Next transition is when count rolls back over to zero */
|
||||
nexttick = UINT64_MAX;
|
||||
@@ -2648,14 +2677,14 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
|
||||
} else {
|
||||
timer_mod(cpu->gt_timer[timeridx], nexttick);
|
||||
}
|
||||
trace_arm_gt_recalc(timeridx, irqstate, nexttick);
|
||||
trace_arm_gt_recalc(timeridx, nexttick);
|
||||
} else {
|
||||
/* Timer disabled: ISTATUS and timer output always clear */
|
||||
gt->ctl &= ~4;
|
||||
qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
|
||||
timer_del(cpu->gt_timer[timeridx]);
|
||||
trace_arm_gt_recalc_disabled(timeridx);
|
||||
}
|
||||
gt_update_irq(cpu, timeridx);
|
||||
}
|
||||
|
||||
static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
@@ -2759,10 +2788,8 @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
* IMASK toggled: don't need to recalculate,
|
||||
* just set the interrupt line based on ISTATUS
|
||||
*/
|
||||
int irqstate = (oldval & 4) && !(value & 2);
|
||||
|
||||
trace_arm_gt_imask_toggle(timeridx, irqstate);
|
||||
qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
|
||||
trace_arm_gt_imask_toggle(timeridx);
|
||||
gt_update_irq(cpu, timeridx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2888,6 +2915,21 @@ static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
gt_ctl_write(env, ri, GTIMER_VIRT, value);
|
||||
}
|
||||
|
||||
static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
ARMCPU *cpu = env_archcpu(env);
|
||||
uint32_t oldval = env->cp15.cnthctl_el2;
|
||||
|
||||
raw_write(env, ri, value);
|
||||
|
||||
if ((oldval ^ value) & CNTHCTL_CNTVMASK) {
|
||||
gt_update_irq(cpu, GTIMER_VIRT);
|
||||
} else if ((oldval ^ value) & CNTHCTL_CNTPMASK) {
|
||||
gt_update_irq(cpu, GTIMER_PHYS);
|
||||
}
|
||||
}
|
||||
|
||||
static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
@@ -3342,9 +3384,22 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCG
|
||||
static int par_el1_shareability(GetPhysAddrResult *res)
|
||||
{
|
||||
/*
|
||||
* The PAR_EL1.SH field must be 0b10 for Device or Normal-NC
|
||||
* memory -- see pseudocode PAREncodeShareability().
|
||||
*/
|
||||
if (((res->cacheattrs.attrs & 0xf0) == 0) ||
|
||||
res->cacheattrs.attrs == 0x44 || res->cacheattrs.attrs == 0x40) {
|
||||
return 2;
|
||||
}
|
||||
return res->cacheattrs.shareability;
|
||||
}
|
||||
|
||||
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
bool is_secure)
|
||||
ARMSecuritySpace ss)
|
||||
{
|
||||
bool ret;
|
||||
uint64_t par64;
|
||||
@@ -3352,8 +3407,12 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
||||
ARMMMUFaultInfo fi = {};
|
||||
GetPhysAddrResult res = {};
|
||||
|
||||
ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
|
||||
is_secure, &res, &fi);
|
||||
/*
|
||||
* I_MXTJT: Granule protection checks are not performed on the final address
|
||||
* of a successful translation.
|
||||
*/
|
||||
ret = get_phys_addr_with_space_nogpc(env, value, access_type, mmu_idx, ss,
|
||||
&res, &fi);
|
||||
|
||||
/*
|
||||
* ATS operations only do S1 or S1+S2 translations, so we never
|
||||
@@ -3470,7 +3529,7 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
||||
par64 |= (1 << 9); /* NS */
|
||||
}
|
||||
par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
|
||||
par64 |= res.cacheattrs.shareability << 7; /* SH */
|
||||
par64 |= par_el1_shareability(&res) << 7; /* SH */
|
||||
} else {
|
||||
uint32_t fsr = arm_fi_to_lfsc(&fi);
|
||||
|
||||
@@ -3518,7 +3577,7 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
uint64_t par64;
|
||||
ARMMMUIdx mmu_idx;
|
||||
int el = arm_current_el(env);
|
||||
bool secure = arm_is_secure_below_el3(env);
|
||||
ARMSecuritySpace ss = arm_security_space(env);
|
||||
|
||||
switch (ri->opc2 & 6) {
|
||||
case 0:
|
||||
@@ -3526,10 +3585,9 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
switch (el) {
|
||||
case 3:
|
||||
mmu_idx = ARMMMUIdx_E3;
|
||||
secure = true;
|
||||
break;
|
||||
case 2:
|
||||
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
|
||||
g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
|
||||
/* fall through */
|
||||
case 1:
|
||||
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
|
||||
@@ -3547,10 +3605,9 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
switch (el) {
|
||||
case 3:
|
||||
mmu_idx = ARMMMUIdx_E10_0;
|
||||
secure = true;
|
||||
break;
|
||||
case 2:
|
||||
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
|
||||
g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */
|
||||
mmu_idx = ARMMMUIdx_Stage1_E0;
|
||||
break;
|
||||
case 1:
|
||||
@@ -3563,18 +3620,18 @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
|
||||
case 4:
|
||||
/* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */
|
||||
mmu_idx = ARMMMUIdx_E10_1;
|
||||
secure = false;
|
||||
ss = ARMSS_NonSecure;
|
||||
break;
|
||||
case 6:
|
||||
/* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */
|
||||
mmu_idx = ARMMMUIdx_E10_0;
|
||||
secure = false;
|
||||
ss = ARMSS_NonSecure;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
par64 = do_ats_write(env, value, access_type, mmu_idx, secure);
|
||||
par64 = do_ats_write(env, value, access_type, mmu_idx, ss);
|
||||
|
||||
A32_BANKED_CURRENT_REG_SET(env, par, par64);
|
||||
#else
|
||||
@@ -3591,7 +3648,8 @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t par64;
|
||||
|
||||
/* There is no SecureEL2 for AArch32. */
|
||||
par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2, false);
|
||||
par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2,
|
||||
ARMSS_NonSecure);
|
||||
|
||||
A32_BANKED_CURRENT_REG_SET(env, par, par64);
|
||||
#else
|
||||
@@ -3600,6 +3658,22 @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
#endif /* CONFIG_TCG */
|
||||
}
|
||||
|
||||
static CPAccessResult at_e012_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
bool isread)
|
||||
{
|
||||
/*
|
||||
* R_NYXTL: instruction is UNDEFINED if it applies to an Exception level
|
||||
* lower than EL3 and the combination SCR_EL3.{NSE,NS} is reserved. This can
|
||||
* only happen when executing at EL3 because that combination also causes an
|
||||
* illegal exception return. We don't need to check FEAT_RME either, because
|
||||
* scr_write() ensures that the NSE bit is not set otherwise.
|
||||
*/
|
||||
if ((env->cp15.scr_el3 & (SCR_NSE | SCR_NS)) == SCR_NSE) {
|
||||
return CP_ACCESS_TRAP;
|
||||
}
|
||||
return CP_ACCESS_OK;
|
||||
}
|
||||
|
||||
static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
bool isread)
|
||||
{
|
||||
@@ -3607,7 +3681,7 @@ static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
!(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) {
|
||||
return CP_ACCESS_TRAP;
|
||||
}
|
||||
return CP_ACCESS_OK;
|
||||
return at_e012_access(env, ri, isread);
|
||||
}
|
||||
|
||||
static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
@@ -3616,7 +3690,6 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
#ifdef CONFIG_TCG
|
||||
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
|
||||
ARMMMUIdx mmu_idx;
|
||||
int secure = arm_is_secure_below_el3(env);
|
||||
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||
bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE);
|
||||
|
||||
@@ -3636,7 +3709,6 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
break;
|
||||
case 6: /* AT S1E3R, AT S1E3W */
|
||||
mmu_idx = ARMMMUIdx_E3;
|
||||
secure = true;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
@@ -3656,7 +3728,7 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
}
|
||||
|
||||
env->cp15.par_el[1] = do_ats_write(env, value, access_type,
|
||||
mmu_idx, secure);
|
||||
mmu_idx, arm_security_space(env));
|
||||
#else
|
||||
/* Handled by hardware accelerator. */
|
||||
g_assert_not_reached();
|
||||
@@ -4650,6 +4722,21 @@ static int vae1_tlbmask(CPUARMState *env)
|
||||
return mask;
|
||||
}
|
||||
|
||||
static int vae2_tlbmask(CPUARMState *env)
|
||||
{
|
||||
uint64_t hcr = arm_hcr_el2_eff(env);
|
||||
uint16_t mask;
|
||||
|
||||
if (hcr & HCR_E2H) {
|
||||
mask = ARMMMUIdxBit_E20_2 |
|
||||
ARMMMUIdxBit_E20_2_PAN |
|
||||
ARMMMUIdxBit_E20_0;
|
||||
} else {
|
||||
mask = ARMMMUIdxBit_E2;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
/* Return 56 if TBI is enabled, 64 otherwise. */
|
||||
static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
|
||||
uint64_t addr)
|
||||
@@ -4676,6 +4763,25 @@ static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
|
||||
return tlbbits_for_regime(env, mmu_idx, addr);
|
||||
}
|
||||
|
||||
static int vae2_tlbbits(CPUARMState *env, uint64_t addr)
|
||||
{
|
||||
uint64_t hcr = arm_hcr_el2_eff(env);
|
||||
ARMMMUIdx mmu_idx;
|
||||
|
||||
/*
|
||||
* Only the regime of the mmu_idx below is significant.
|
||||
* Regime EL2&0 has two ranges with separate TBI configuration, while EL2
|
||||
* only has one.
|
||||
*/
|
||||
if (hcr & HCR_E2H) {
|
||||
mmu_idx = ARMMMUIdx_E20_2;
|
||||
} else {
|
||||
mmu_idx = ARMMMUIdx_E2;
|
||||
}
|
||||
|
||||
return tlbbits_for_regime(env, mmu_idx, addr);
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
@@ -4768,10 +4874,11 @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
* flush-last-level-only.
|
||||
*/
|
||||
CPUState *cs = env_cpu(env);
|
||||
int mask = e2_tlbmask(env);
|
||||
int mask = vae2_tlbmask(env);
|
||||
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
||||
int bits = vae2_tlbbits(env, pageaddr);
|
||||
|
||||
tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
|
||||
tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
@@ -4825,11 +4932,11 @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
int mask = vae2_tlbmask(env);
|
||||
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
||||
int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
|
||||
int bits = vae2_tlbbits(env, pageaddr);
|
||||
|
||||
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
|
||||
ARMMMUIdxBit_E2, bits);
|
||||
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
@@ -5001,11 +5108,6 @@ static void tlbi_aa64_rvae1is_write(CPUARMState *env,
|
||||
do_rvae_write(env, value, vae1_tlbmask(env), true);
|
||||
}
|
||||
|
||||
static int vae2_tlbmask(CPUARMState *env)
|
||||
{
|
||||
return ARMMMUIdxBit_E2;
|
||||
}
|
||||
|
||||
static void tlbi_aa64_rvae2_write(CPUARMState *env,
|
||||
const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
@@ -5461,38 +5563,38 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E1R,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E1W,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E0R,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E0W,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
|
||||
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
|
||||
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
|
||||
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
|
||||
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
/* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */
|
||||
{ .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
|
||||
@@ -5772,11 +5874,13 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
* Bits that are not included here:
|
||||
* RW (read from SCR_EL3.RW as needed)
|
||||
*/
|
||||
uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure)
|
||||
uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space)
|
||||
{
|
||||
uint64_t ret = env->cp15.hcr_el2;
|
||||
|
||||
if (!arm_is_el2_enabled_secstate(env, secure)) {
|
||||
assert(space != ARMSS_Root);
|
||||
|
||||
if (!arm_is_el2_enabled_secstate(env, space)) {
|
||||
/*
|
||||
* "This register has no effect if EL2 is not enabled in the
|
||||
* current Security state". This is ARMv8.4-SecEL2 speak for
|
||||
@@ -5840,7 +5944,7 @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
|
||||
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||
return 0;
|
||||
}
|
||||
return arm_hcr_el2_eff_secstate(env, arm_is_secure_below_el3(env));
|
||||
return arm_hcr_el2_eff_secstate(env, arm_security_space_below_el3(env));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6141,7 +6245,8 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
|
||||
* reset values as IMPDEF. We choose to reset to 3 to comply with
|
||||
* both ARMv7 and ARMv8.
|
||||
*/
|
||||
.access = PL2_RW, .resetvalue = 3,
|
||||
.access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 3,
|
||||
.writefn = gt_cnthctl_write, .raw_writefn = raw_write,
|
||||
.fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) },
|
||||
{ .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
|
||||
@@ -8033,12 +8138,12 @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E1RP,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
{ .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
|
||||
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
|
||||
.fgt = FGT_ATS1E1WP,
|
||||
.writefn = ats_write64 },
|
||||
.accessfn = at_e012_access, .writefn = ats_write64 },
|
||||
};
|
||||
|
||||
static const ARMCPRegInfo ats1cp_reginfo[] = {
|
||||
|
||||
+14
-11
@@ -1190,12 +1190,11 @@ typedef struct GetPhysAddrResult {
|
||||
} GetPhysAddrResult;
|
||||
|
||||
/**
|
||||
* get_phys_addr_with_secure: get the physical address for a virtual address
|
||||
* get_phys_addr: get the physical address for a virtual address
|
||||
* @env: CPUARMState
|
||||
* @address: virtual address to get physical address for
|
||||
* @access_type: 0 for read, 1 for write, 2 for execute
|
||||
* @mmu_idx: MMU index indicating required translation regime
|
||||
* @is_secure: security state for the access
|
||||
* @result: set on translation success.
|
||||
* @fi: set to fault info if the translation fails
|
||||
*
|
||||
@@ -1212,26 +1211,30 @@ typedef struct GetPhysAddrResult {
|
||||
* * for PSMAv5 based systems we don't bother to return a full FSR format
|
||||
* value.
|
||||
*/
|
||||
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type,
|
||||
ARMMMUIdx mmu_idx, bool is_secure,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
__attribute__((nonnull));
|
||||
|
||||
/**
|
||||
* get_phys_addr: get the physical address for a virtual address
|
||||
* get_phys_addr_with_space_nogpc: get the physical address for a virtual
|
||||
* address
|
||||
* @env: CPUARMState
|
||||
* @address: virtual address to get physical address for
|
||||
* @access_type: 0 for read, 1 for write, 2 for execute
|
||||
* @mmu_idx: MMU index indicating required translation regime
|
||||
* @space: security space for the access
|
||||
* @result: set on translation success.
|
||||
* @fi: set to fault info if the translation fails
|
||||
*
|
||||
* Similarly, but use the security regime of @mmu_idx.
|
||||
* Similar to get_phys_addr, but use the given security space and don't perform
|
||||
* a Granule Protection Check on the resulting address.
|
||||
*/
|
||||
bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
|
||||
bool get_phys_addr_with_space_nogpc(CPUARMState *env, target_ulong address,
|
||||
MMUAccessType access_type,
|
||||
ARMMMUIdx mmu_idx, ARMSecuritySpace space,
|
||||
GetPhysAddrResult *result,
|
||||
ARMMMUFaultInfo *fi)
|
||||
__attribute__((nonnull));
|
||||
|
||||
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
|
||||
|
||||
@@ -247,6 +247,13 @@ int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
|
||||
return ret > 0 ? ret : 40;
|
||||
}
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
bool fixed_ipa;
|
||||
int size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa);
|
||||
return fixed_ipa ? 0 : size;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
+143
-88
File diff suppressed because it is too large
Load Diff
@@ -379,7 +379,7 @@ static inline void HNAME##_host(void *za, intptr_t off, void *host) \
|
||||
{ \
|
||||
uint64_t *ptr = za + off; \
|
||||
HOST(host, ptr[BE]); \
|
||||
HOST(host + 1, ptr[!BE]); \
|
||||
HOST(host + 8, ptr[!BE]); \
|
||||
} \
|
||||
static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
|
||||
{ \
|
||||
|
||||
@@ -3053,7 +3053,7 @@ void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_ssra64_i64,
|
||||
.fniv = gen_ssra_vec,
|
||||
.fno = gen_helper_gvec_ssra_b,
|
||||
.fno = gen_helper_gvec_ssra_d,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.opt_opc = vecop_list,
|
||||
.load_dest = true,
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# See docs/devel/tracing.rst for syntax documentation.
|
||||
|
||||
# helper.c
|
||||
arm_gt_recalc(int timer, int irqstate, uint64_t nexttick) "gt recalc: timer %d irqstate %d next tick 0x%" PRIx64
|
||||
arm_gt_recalc_disabled(int timer) "gt recalc: timer %d irqstate 0 timer disabled"
|
||||
arm_gt_recalc(int timer, uint64_t nexttick) "gt recalc: timer %d next tick 0x%" PRIx64
|
||||
arm_gt_recalc_disabled(int timer) "gt recalc: timer %d timer disabled"
|
||||
arm_gt_cval_write(int timer, uint64_t value) "gt_cval_write: timer %d value 0x%" PRIx64
|
||||
arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%" PRIx64
|
||||
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
|
||||
arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
|
||||
arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle"
|
||||
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
|
||||
arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
|
||||
|
||||
# kvm.c
|
||||
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
|
||||
|
||||
@@ -2556,6 +2556,11 @@ static void register_smram_listener(Notifier *n, void *unused)
|
||||
&smram_address_space, 1, "kvm-smram");
|
||||
}
|
||||
|
||||
int kvm_arch_get_default_type(MachineState *ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
uint64_t identity_base = 0xfffbc000;
|
||||
|
||||
+2
-1
@@ -1266,7 +1266,7 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
|
||||
abort();
|
||||
}
|
||||
|
||||
int mips_kvm_type(MachineState *machine, const char *vm_type)
|
||||
int kvm_arch_get_default_type(MachineState *machine)
|
||||
{
|
||||
#if defined(KVM_CAP_MIPS_VZ)
|
||||
int r;
|
||||
@@ -1278,6 +1278,7 @@ int mips_kvm_type(MachineState *machine, const char *vm_type)
|
||||
}
|
||||
#endif
|
||||
|
||||
error_report("KVM_VM_MIPS_VZ type is not available");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,4 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu);
|
||||
int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level);
|
||||
int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level);
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
int mips_kvm_type(MachineState *machine, const char *vm_type);
|
||||
#else
|
||||
static inline int mips_kvm_type(MachineState *machine, const char *vm_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KVM_MIPS_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user