aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-10-06 17:00:42 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-10-06 17:00:42 +0100
commit5121d81e387bba17496f5908d43fd623a946c645 (patch)
tree970a97ab62d9cb35de8308e010ce395ab6783309 /hw/intc
parenta26a98dfb9d448d7234d931ae3720feddf6f0651 (diff)
parent04829ce334bece78d4fa1d0fdbc8bc27dae9b242 (diff)
downloadqemu-5121d81e387bba17496f5908d43fd623a946c645.zip
qemu-5121d81e387bba17496f5908d43fd623a946c645.tar.gz
qemu-5121d81e387bba17496f5908d43fd623a946c645.tar.bz2
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20171006' into staging
target-arm: * v8M: more preparatory work * nvic: reset properly rather than leaving the nvic in a weird state * xlnx-zynqmp: Mark the "xlnx, zynqmp" device with user_creatable = false * sd: fix out-of-bounds check for multi block reads * arm: Fix SMC reporting to EL2 when QEMU provides PSCI # gpg: Signature made Fri 06 Oct 2017 16:58:15 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20171006: nvic: Add missing code for writing SHCSR.HARDFAULTPENDED bit target/arm: Factor out "get mmuidx for specified security state" target/arm: Fix calculation of secure mm_idx values target/arm: Implement security attribute lookups for memory accesses nvic: Implement Security Attribution Unit registers target/arm: Add v8M support to exception entry code target/arm: Add support for restoring v8M additional state context target/arm: Update excret sanity checks for v8M target/arm: Add new-in-v8M SFSR and SFAR target/arm: Don't warn about exception return with PC low bit set for v8M target/arm: Warn about restoring to unaligned stack target/arm: Check for xPSR mismatch usage faults earlier for v8M target/arm: Restore SPSEL to correct CONTROL register on exception return target/arm: Restore security state on exception return target/arm: Prepare for CONTROL.SPSEL being nonzero in Handler mode target/arm: Don't switch to target stack early in v7M exception return nvic: Clear the vector arrays and prigroup on reset hw/arm/xlnx-zynqmp: Mark the "xlnx, zynqmp" device with user_creatable = false hw/sd: fix out-of-bounds check for multi block reads arm: Fix SMC reporting to EL2 when QEMU provides PSCI Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/armv7m_nvic.c158
1 files changed, 157 insertions, 1 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index d90d8d0..22d5e6e 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -616,7 +616,7 @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
vec->active = 1;
vec->pending = 0;
- env->v7m.exception = s->vectpending;
+ write_v7m_exception(env, s->vectpending);
nvic_irq_update(s);
@@ -1017,6 +1017,76 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
goto bad_offset;
}
return cpu->env.pmsav8.mair1[attrs.secure];
+ case 0xdd0: /* SAU_CTRL */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ return cpu->env.sau.ctrl;
+ case 0xdd4: /* SAU_TYPE */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ return cpu->sau_sregion;
+ case 0xdd8: /* SAU_RNR */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ return cpu->env.sau.rnr;
+ case 0xddc: /* SAU_RBAR */
+ {
+ int region = cpu->env.sau.rnr;
+
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ if (region >= cpu->sau_sregion) {
+ return 0;
+ }
+ return cpu->env.sau.rbar[region];
+ }
+ case 0xde0: /* SAU_RLAR */
+ {
+ int region = cpu->env.sau.rnr;
+
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ if (region >= cpu->sau_sregion) {
+ return 0;
+ }
+ return cpu->env.sau.rlar[region];
+ }
+ case 0xde4: /* SFSR */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ return cpu->env.v7m.sfsr;
+ case 0xde8: /* SFAR */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return 0;
+ }
+ return cpu->env.v7m.sfar;
default:
bad_offset:
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
@@ -1160,6 +1230,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =
(value & (1 << 18)) != 0;
+ s->sec_vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;
/* SecureFault not banked, but RAZ/WI to NS */
s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0;
s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0;
@@ -1368,6 +1439,86 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
* only affect cacheability, and we don't implement caching.
*/
break;
+ case 0xdd0: /* SAU_CTRL */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return;
+ }
+ cpu->env.sau.ctrl = value & 3;
+ case 0xdd4: /* SAU_TYPE */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ break;
+ case 0xdd8: /* SAU_RNR */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return;
+ }
+ if (value >= cpu->sau_sregion) {
+ qemu_log_mask(LOG_GUEST_ERROR, "SAU region out of range %"
+ PRIu32 "/%" PRIu32 "\n",
+ value, cpu->sau_sregion);
+ } else {
+ cpu->env.sau.rnr = value;
+ }
+ break;
+ case 0xddc: /* SAU_RBAR */
+ {
+ int region = cpu->env.sau.rnr;
+
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return;
+ }
+ if (region >= cpu->sau_sregion) {
+ return;
+ }
+ cpu->env.sau.rbar[region] = value & ~0x1f;
+ tlb_flush(CPU(cpu));
+ break;
+ }
+ case 0xde0: /* SAU_RLAR */
+ {
+ int region = cpu->env.sau.rnr;
+
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return;
+ }
+ if (region >= cpu->sau_sregion) {
+ return;
+ }
+ cpu->env.sau.rlar[region] = value & ~0x1c;
+ tlb_flush(CPU(cpu));
+ break;
+ }
+ case 0xde4: /* SFSR */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return;
+ }
+ cpu->env.v7m.sfsr &= ~value; /* W1C */
+ break;
+ case 0xde8: /* SFAR */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (!attrs.secure) {
+ return;
+ }
+ cpu->env.v7m.sfsr = value;
+ break;
case 0xf00: /* Software Triggered Interrupt Register */
{
int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
@@ -1782,6 +1933,11 @@ static void armv7m_nvic_reset(DeviceState *dev)
int resetprio;
NVICState *s = NVIC(dev);
+ memset(s->vectors, 0, sizeof(s->vectors));
+ memset(s->sec_vectors, 0, sizeof(s->sec_vectors));
+ s->prigroup[M_REG_NS] = 0;
+ s->prigroup[M_REG_S] = 0;
+
s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
/* MEM, BUS, and USAGE are enabled through
* the System Handler Control register