target-arm queue:

* hw/arm/smmuv3: Check 31st bit to see if CD is valid
  * qemu-options.hx: Fix formatting of -machine memory-backend option
  * hw: aspeed_gpio: Fix memory size
  * hw/arm/nseries: Display hexadecimal value with '0x' prefix
  * Add sve-default-vector-length cpu property
  * docs: Update path that mentions deprecated.rst
  * hw/intc/armv7m_nvic: for v8.1M VECTPENDING hides S exceptions from NS
  * hw/intc/armv7m_nvic: Correct size of ICSR.VECTPENDING
  * hw/intc/armv7m_nvic: ISCR.ISRPENDING is set for non-enabled pending interrupts
  * target/arm: Report M-profile alignment faults correctly to the guest
  * target/arm: Add missing 'return's after calling v7m_exception_taken()
  * target/arm: Enforce that M-profile SP low 2 bits are always zero
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmD/4/kZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3kOeD/9cYRTWNKhQI1lCpq704GxX
 hWkCPVugtXZDahom+Ill2o4cuvmyc4NNgAeCgSTh7WaUIaEjqR1a7c3eusQJN2lX
 +tEUVi7wDYGv1qJI3M8S+Z0bO5qOIVHjkxnxwpiEwNODqt1nMHBBn02k+uJpg7ME
 i9xoZWeSuFkOOSpUSwWvXRxvuEhfWLKI2TPMM+YZ3d4PkLMIP6P5CR2oYnQ6jjYu
 h1sm0JhbIOJmE8ksnsz0BNlW3nLl2eYdxpAdLObP6wB9lKOqjNh3VlkN22GTOrM8
 k4R7JZIU6lkKDYFiIxjQgSRynmesUL42YLCZFWxpEImtvOlD7RJpIFChCQY0MmFp
 ssB1/JtHR5p1652kjgY+y3hz3owlxknjlM5encuce6aBRx/xEIrQqChDk9jeEnSL
 lc8Zkl7Nhzf0gYPlAWa+2dhLuW7F6t9OC+HK4mv/LML2WcoUDQskkGpYBuTpLaCM
 BwdT2SEf78Z4i1qoTpoCbnuQxddNJYZ+P0fsvMa32WtWqEJZM6sXhWg/83aFBg57
 e3mUSH0A+hhjGW/qEarGnp2IJ4wN06BAWD4+jpJaYyDUHU8G7qZclsp8e5117p/1
 wpAH3/fKev5nYgC3I2G3pveuzqGn+vgSJ2alk12KxXibGLcJbEPKAefx4IgKZpcB
 dp1DfBz13Falx5NeSFEuZg==
 =ru4w
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210727' into staging

target-arm queue:
 * hw/arm/smmuv3: Check 31st bit to see if CD is valid
 * qemu-options.hx: Fix formatting of -machine memory-backend option
 * hw: aspeed_gpio: Fix memory size
 * hw/arm/nseries: Display hexadecimal value with '0x' prefix
 * Add sve-default-vector-length cpu property
 * docs: Update path that mentions deprecated.rst
 * hw/intc/armv7m_nvic: for v8.1M VECTPENDING hides S exceptions from NS
 * hw/intc/armv7m_nvic: Correct size of ICSR.VECTPENDING
 * hw/intc/armv7m_nvic: ISCR.ISRPENDING is set for non-enabled pending interrupts
 * target/arm: Report M-profile alignment faults correctly to the guest
 * target/arm: Add missing 'return's after calling v7m_exception_taken()
 * target/arm: Enforce that M-profile SP low 2 bits are always zero

# gpg: Signature made Tue 27 Jul 2021 11:46:17 BST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20210727:
  hw: aspeed_gpio: Fix memory size
  hw/arm/nseries: Display hexadecimal value with '0x' prefix
  target/arm: Add sve-default-vector-length cpu property
  target/arm: Export aarch64_sve_zcr_get_valid_len
  target/arm: Correctly bound length in sve_zcr_get_valid_len
  docs: Update path that mentions deprecated.rst
  hw/intc/armv7m_nvic: for v8.1M VECTPENDING hides S exceptions from NS
  hw/intc/armv7m_nvic: Correct size of ICSR.VECTPENDING
  hw/intc/armv7m_nvic: ISCR.ISRPENDING is set for non-enabled pending interrupts
  target/arm: Report M-profile alignment faults correctly to the guest
  target/arm: Add missing 'return's after calling v7m_exception_taken()
  target/arm: Enforce that M-profile SP low 2 bits are always zero
  qemu-options.hx: Fix formatting of -machine memory-backend option
  hw/arm/smmuv3: Check 31st bit to see if CD is valid

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-07-27 15:32:00 +01:00
commit 9ae1246a9b
17 changed files with 183 additions and 43 deletions

View File

@ -3439,7 +3439,7 @@ F: contrib/gitdm/*
Incompatible changes Incompatible changes
R: libvir-list@redhat.com R: libvir-list@redhat.com
F: docs/system/deprecated.rst F: docs/about/deprecated.rst
Build System Build System
------------ ------------

2
configure vendored
View File

@ -5230,7 +5230,7 @@ fi
if test -n "${deprecated_features}"; then if test -n "${deprecated_features}"; then
echo "Warning, deprecated features enabled." echo "Warning, deprecated features enabled."
echo "Please see docs/system/deprecated.rst" echo "Please see docs/about/deprecated.rst"
echo " features: ${deprecated_features}" echo " features: ${deprecated_features}"
fi fi

View File

@ -376,3 +376,18 @@ verbose command lines. However, the recommended way to select vector
lengths is to explicitly enable each desired length. Therefore only lengths is to explicitly enable each desired length. Therefore only
example's (1), (4), and (6) exhibit recommended uses of the properties. example's (1), (4), and (6) exhibit recommended uses of the properties.
SVE User-mode Default Vector Length Property
--------------------------------------------
For qemu-aarch64, the cpu property ``sve-default-vector-length=N`` is
defined to mirror the Linux kernel parameter file
``/proc/sys/abi/sve_default_vector_length``. The default length, ``N``,
is in units of bytes and must be between 16 and 8192.
If not specified, the default vector length is 64.
If the default length is larger than the maximum vector length enabled,
the actual vector length will be reduced. Note that the maximum vector
length supported by QEMU is 256.
If this property is set to ``-1`` then the default vector length
is set to the maximum possible length.

View File

@ -692,7 +692,7 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
default: default:
bad_cmd: bad_cmd:
qemu_log_mask(LOG_GUEST_ERROR, qemu_log_mask(LOG_GUEST_ERROR,
"%s: unknown command %02x\n", __func__, s->cmd); "%s: unknown command 0x%02x\n", __func__, s->cmd);
break; break;
} }

View File

@ -570,7 +570,7 @@ static inline int pa_range(STE *ste)
/* CD fields */ /* CD fields */
#define CD_VALID(x) extract32((x)->word[0], 30, 1) #define CD_VALID(x) extract32((x)->word[0], 31, 1)
#define CD_ASID(x) extract32((x)->word[1], 16, 16) #define CD_ASID(x) extract32((x)->word[1], 16, 16)
#define CD_TTB(x, sel) \ #define CD_TTB(x, sel) \
({ \ ({ \

View File

@ -207,7 +207,6 @@
#define GPIO_1_8V_MEM_SIZE 0x9D8 #define GPIO_1_8V_MEM_SIZE 0x9D8
#define GPIO_1_8V_REG_ARRAY_SIZE ((GPIO_1_8V_MEM_SIZE - \ #define GPIO_1_8V_REG_ARRAY_SIZE ((GPIO_1_8V_MEM_SIZE - \
GPIO_1_8V_REG_OFFSET) >> 2) GPIO_1_8V_REG_OFFSET) >> 2)
#define GPIO_MAX_MEM_SIZE MAX(GPIO_3_6V_MEM_SIZE, GPIO_1_8V_MEM_SIZE)
static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio) static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
{ {
@ -849,7 +848,7 @@ static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
} }
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s, memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
TYPE_ASPEED_GPIO, GPIO_MAX_MEM_SIZE); TYPE_ASPEED_GPIO, 0x800);
sysbus_init_mmio(sbd, &s->iomem); sysbus_init_mmio(sbd, &s->iomem);
} }

View File

@ -127,15 +127,14 @@ static bool nvic_isrpending(NVICState *s)
{ {
int irq; int irq;
/* We can shortcut if the highest priority pending interrupt /*
* happens to be external or if there is nothing pending. * We can shortcut if the highest priority pending interrupt
* happens to be external; if not we need to check the whole
* vectors[] array.
*/ */
if (s->vectpending > NVIC_FIRST_IRQ) { if (s->vectpending > NVIC_FIRST_IRQ) {
return true; return true;
} }
if (s->vectpending == 0) {
return false;
}
for (irq = NVIC_FIRST_IRQ; irq < s->num_irq; irq++) { for (irq = NVIC_FIRST_IRQ; irq < s->num_irq; irq++) {
if (s->vectors[irq].pending) { if (s->vectors[irq].pending) {
@ -805,6 +804,16 @@ void armv7m_nvic_acknowledge_irq(void *opaque)
nvic_irq_update(s); nvic_irq_update(s);
} }
static bool vectpending_targets_secure(NVICState *s)
{
/* Return true if s->vectpending targets Secure state */
if (s->vectpending_is_s_banked) {
return true;
}
return !exc_is_banked(s->vectpending) &&
exc_targets_secure(s, s->vectpending);
}
void armv7m_nvic_get_pending_irq_info(void *opaque, void armv7m_nvic_get_pending_irq_info(void *opaque,
int *pirq, bool *ptargets_secure) int *pirq, bool *ptargets_secure)
{ {
@ -814,12 +823,7 @@ void armv7m_nvic_get_pending_irq_info(void *opaque,
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
if (s->vectpending_is_s_banked) { targets_secure = vectpending_targets_secure(s);
targets_secure = true;
} else {
targets_secure = !exc_is_banked(pending) &&
exc_targets_secure(s, pending);
}
trace_nvic_get_pending_irq_info(pending, targets_secure); trace_nvic_get_pending_irq_info(pending, targets_secure);
@ -1040,7 +1044,19 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
/* VECTACTIVE */ /* VECTACTIVE */
val = cpu->env.v7m.exception; val = cpu->env.v7m.exception;
/* VECTPENDING */ /* VECTPENDING */
val |= (s->vectpending & 0xff) << 12; if (s->vectpending) {
/*
* From v8.1M VECTPENDING must read as 1 if accessed as
* NonSecure and the highest priority pending and enabled
* exception targets Secure.
*/
int vp = s->vectpending;
if (!attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_V8_1M) &&
vectpending_targets_secure(s)) {
vp = 1;
}
val |= (vp & 0x1ff) << 12;
}
/* ISRPENDING - set if any external IRQ is pending */ /* ISRPENDING - set if any external IRQ is pending */
if (nvic_isrpending(s)) { if (nvic_isrpending(s)) {
val |= (1 << 22); val |= (1 << 22);

View File

@ -104,19 +104,23 @@ SRST
For example: For example:
:: ::
-object memory-backend-file,id=pc.ram,size=512M,mem-path=/hugetlbfs,prealloc=on,share=on -object memory-backend-file,id=pc.ram,size=512M,mem-path=/hugetlbfs,prealloc=on,share=on
-machine memory-backend=pc.ram -machine memory-backend=pc.ram
-m 512M -m 512M
Migration compatibility note: Migration compatibility note:
a) as backend id one shall use value of 'default-ram-id', advertised by
* as backend id one shall use value of 'default-ram-id', advertised by
machine type (available via ``query-machines`` QMP command), if migration machine type (available via ``query-machines`` QMP command), if migration
to/from old QEMU (<5.0) is expected. to/from old QEMU (<5.0) is expected.
b) for machine types 4.0 and older, user shall * for machine types 4.0 and older, user shall
use ``x-use-canonical-path-for-ramblock-id=off`` backend option use ``x-use-canonical-path-for-ramblock-id=off`` backend option
if migration to/from old QEMU (<5.0) is expected. if migration to/from old QEMU (<5.0) is expected.
For example: For example:
:: ::
-object memory-backend-ram,id=pc.ram,size=512M,x-use-canonical-path-for-ramblock-id=off -object memory-backend-ram,id=pc.ram,size=512M,x-use-canonical-path-for-ramblock-id=off
-machine memory-backend=pc.ram -machine memory-backend=pc.ram
-m 512M -m 512M

View File

@ -201,7 +201,8 @@ static void arm_cpu_reset(DeviceState *dev)
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3); env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
/* with reasonable vector length */ /* with reasonable vector length */
if (cpu_isar_feature(aa64_sve, cpu)) { if (cpu_isar_feature(aa64_sve, cpu)) {
env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3); env->vfp.zcr_el[1] =
aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
} }
/* /*
* Enable TBI0 but not TBI1. * Enable TBI0 but not TBI1.
@ -1051,7 +1052,16 @@ static void arm_cpu_initfn(Object *obj)
QLIST_INIT(&cpu->pre_el_change_hooks); QLIST_INIT(&cpu->pre_el_change_hooks);
QLIST_INIT(&cpu->el_change_hooks); QLIST_INIT(&cpu->el_change_hooks);
#ifndef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
# ifdef TARGET_AARCH64
/*
* The linux kernel defaults to 512-bit vectors, when sve is supported.
* See documentation for /proc/sys/abi/sve_default_vector_length, and
* our corresponding sve-default-vector-length cpu property.
*/
cpu->sve_default_vq = 4;
# endif
#else
/* Our inbound IRQ and FIQ lines */ /* Our inbound IRQ and FIQ lines */
if (kvm_enabled()) { if (kvm_enabled()) {
/* VIRQ and VFIQ are unused with KVM but we add them to maintain /* VIRQ and VFIQ are unused with KVM but we add them to maintain

View File

@ -1006,6 +1006,11 @@ struct ARMCPU {
/* Used to set the maximum vector length the cpu will support. */ /* Used to set the maximum vector length the cpu will support. */
uint32_t sve_max_vq; uint32_t sve_max_vq;
#ifdef CONFIG_USER_ONLY
/* Used to set the default vector length at process start. */
uint32_t sve_default_vq;
#endif
/* /*
* In sve_vq_map each set bit is a supported vector length of * In sve_vq_map each set bit is a supported vector length of
* (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector

View File

@ -559,6 +559,59 @@ static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
cpu->isar.id_aa64pfr0 = t; cpu->isar.id_aa64pfr0 = t;
} }
#ifdef CONFIG_USER_ONLY
/* Mirror linux /proc/sys/abi/sve_default_vector_length. */
static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
int32_t default_len, default_vq, remainder;
if (!visit_type_int32(v, name, &default_len, errp)) {
return;
}
/* Undocumented, but the kernel allows -1 to indicate "maximum". */
if (default_len == -1) {
cpu->sve_default_vq = ARM_MAX_VQ;
return;
}
default_vq = default_len / 16;
remainder = default_len % 16;
/*
* Note that the 512 max comes from include/uapi/asm/sve_context.h
* and is the maximum architectural width of ZCR_ELx.LEN.
*/
if (remainder || default_vq < 1 || default_vq > 512) {
error_setg(errp, "cannot set sve-default-vector-length");
if (remainder) {
error_append_hint(errp, "Vector length not a multiple of 16\n");
} else if (default_vq < 1) {
error_append_hint(errp, "Vector length smaller than 16\n");
} else {
error_append_hint(errp, "Vector length larger than %d\n",
512 * 16);
}
return;
}
cpu->sve_default_vq = default_vq;
}
static void cpu_arm_get_sve_default_vec_len(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
ARMCPU *cpu = ARM_CPU(obj);
int32_t value = cpu->sve_default_vq * 16;
visit_type_int32(v, name, &value, errp);
}
#endif
void aarch64_add_sve_properties(Object *obj) void aarch64_add_sve_properties(Object *obj)
{ {
uint32_t vq; uint32_t vq;
@ -571,6 +624,13 @@ void aarch64_add_sve_properties(Object *obj)
object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
cpu_arm_set_sve_vq, NULL, NULL); cpu_arm_set_sve_vq, NULL, NULL);
} }
#ifdef CONFIG_USER_ONLY
/* Mirror linux /proc/sys/abi/sve_default_vector_length. */
object_property_add(obj, "sve-default-vector-length", "int32",
cpu_arm_get_sve_default_vec_len,
cpu_arm_set_sve_default_vec_len, NULL, NULL);
#endif
} }
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)

View File

@ -84,6 +84,10 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
if (n < 16) { if (n < 16) {
/* Core integer register. */ /* Core integer register. */
if (n == 13 && arm_feature(env, ARM_FEATURE_M)) {
/* M profile SP low bits are always 0 */
tmp &= ~3;
}
env->regs[n] = tmp; env->regs[n] = tmp;
return 4; return 4;
} }

View File

@ -6457,11 +6457,13 @@ int sve_exception_el(CPUARMState *env, int el)
return 0; return 0;
} }
static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len) uint32_t aarch64_sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len)
{ {
uint32_t end_len; uint32_t end_len;
end_len = start_len &= 0xf; start_len = MIN(start_len, ARM_MAX_VQ - 1);
end_len = start_len;
if (!test_bit(start_len, cpu->sve_vq_map)) { if (!test_bit(start_len, cpu->sve_vq_map)) {
end_len = find_last_bit(cpu->sve_vq_map, start_len); end_len = find_last_bit(cpu->sve_vq_map, start_len);
assert(end_len < start_len); assert(end_len < start_len);
@ -6487,7 +6489,7 @@ uint32_t sve_zcr_len_for_el(CPUARMState *env, int el)
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]); zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
} }
return sve_zcr_get_valid_len(cpu, zcr_len); return aarch64_sve_zcr_get_valid_len(cpu, zcr_len);
} }
static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri, static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,

View File

@ -177,6 +177,16 @@ void arm_translate_init(void);
void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb); void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
#endif /* CONFIG_TCG */ #endif /* CONFIG_TCG */
/**
* aarch64_sve_zcr_get_valid_len:
* @cpu: cpu context
* @start_len: maximum len to consider
*
* Return the maximum supported sve vector length <= @start_len.
* Note that both @start_len and the return value are in units
* of ZCR_ELx.LEN, so the vector bit length is (x + 1) * 128.
*/
uint32_t aarch64_sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len);
enum arm_fprounding { enum arm_fprounding {
FPROUNDING_TIEEVEN, FPROUNDING_TIEEVEN,

View File

@ -1554,6 +1554,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
"stackframe: NSACR prevents clearing FPU registers\n"); "stackframe: NSACR prevents clearing FPU registers\n");
v7m_exception_taken(cpu, excret, true, false); v7m_exception_taken(cpu, excret, true, false);
return;
} else if (!cpacr_pass) { } else if (!cpacr_pass) {
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
exc_secure); exc_secure);
@ -1561,6 +1562,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
"stackframe: CPACR prevents clearing FPU registers\n"); "stackframe: CPACR prevents clearing FPU registers\n");
v7m_exception_taken(cpu, excret, true, false); v7m_exception_taken(cpu, excret, true, false);
return;
} }
} }
/* Clear s0..s15, FPSCR and VPR */ /* Clear s0..s15, FPSCR and VPR */
@ -2246,6 +2248,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK; env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
break; break;
case EXCP_UNALIGNED: case EXCP_UNALIGNED:
/* Unaligned faults reported by M-profile aware code */
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK; env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
break; break;
@ -2318,6 +2321,13 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
} }
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
break; break;
case 0x1: /* Alignment fault reported by generic code */
qemu_log_mask(CPU_LOG_INT,
"...really UsageFault with UFSR.UNALIGNED\n");
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
env->v7m.secure);
break;
default: default:
/* /*
* All other FSR values are either MPU faults or "can't happen * All other FSR values are either MPU faults or "can't happen
@ -2563,13 +2573,13 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
if (!env->v7m.secure) { if (!env->v7m.secure) {
return; return;
} }
env->v7m.other_ss_msp = val; env->v7m.other_ss_msp = val & ~3;
return; return;
case 0x89: /* PSP_NS */ case 0x89: /* PSP_NS */
if (!env->v7m.secure) { if (!env->v7m.secure) {
return; return;
} }
env->v7m.other_ss_psp = val; env->v7m.other_ss_psp = val & ~3;
return; return;
case 0x8a: /* MSPLIM_NS */ case 0x8a: /* MSPLIM_NS */
if (!env->v7m.secure) { if (!env->v7m.secure) {
@ -2638,6 +2648,8 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
limit = is_psp ? env->v7m.psplim[false] : env->v7m.msplim[false]; limit = is_psp ? env->v7m.psplim[false] : env->v7m.msplim[false];
val &= ~0x3;
if (val < limit) { if (val < limit) {
raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC()); raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
} }
@ -2660,16 +2672,16 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
break; break;
case 8: /* MSP */ case 8: /* MSP */
if (v7m_using_psp(env)) { if (v7m_using_psp(env)) {
env->v7m.other_sp = val; env->v7m.other_sp = val & ~3;
} else { } else {
env->regs[13] = val; env->regs[13] = val & ~3;
} }
break; break;
case 9: /* PSP */ case 9: /* PSP */
if (v7m_using_psp(env)) { if (v7m_using_psp(env)) {
env->regs[13] = val; env->regs[13] = val & ~3;
} else { } else {
env->v7m.other_sp = val; env->v7m.other_sp = val & ~3;
} }
break; break;
case 10: /* MSPLIM */ case 10: /* MSPLIM */

View File

@ -291,6 +291,9 @@ void store_reg(DisasContext *s, int reg, TCGv_i32 var)
*/ */
tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3); tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
s->base.is_jmp = DISAS_JUMP; s->base.is_jmp = DISAS_JUMP;
} else if (reg == 13 && arm_dc_feature(s, ARM_FEATURE_M)) {
/* For M-profile SP bits [1:0] are always zero */
tcg_gen_andi_i32(var, var, ~3);
} }
tcg_gen_mov_i32(cpu_R[reg], var); tcg_gen_mov_i32(cpu_R[reg], var);
tcg_temp_free_i32(var); tcg_temp_free_i32(var);

View File

@ -4110,7 +4110,7 @@ static const X86CPUDefinition builtin_x86_defs[] = {
* none", but this is just for compatibility while libvirt isn't * none", but this is just for compatibility while libvirt isn't
* adapted to resolve CPU model versions before creating VMs. * adapted to resolve CPU model versions before creating VMs.
* See "Runnability guarantee of CPU models" at * See "Runnability guarantee of CPU models" at
* docs/system/deprecated.rst. * docs/about/deprecated.rst.
*/ */
X86CPUVersion default_cpu_version = 1; X86CPUVersion default_cpu_version = 1;