summary refs log tree commit diff stats
path: root/hw/misc/aspeed_sdmc.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-05-11 14:34:27 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-05-11 14:34:27 +0100
commitde2f658b6bb422ec0e0fa94a49e476018602eeea (patch)
treefdf6331408573ce7e328e44524f9edc9d7ee7214 /hw/misc/aspeed_sdmc.c
parentc88f1ffc19e38008a1c33ae039482a860aa7418c (diff)
parent7e17d50ebd359ee5fa3d65d7fdc0fe0336d60694 (diff)
downloadfocaccia-qemu-de2f658b6bb422ec0e0fa94a49e476018602eeea.tar.gz
focaccia-qemu-de2f658b6bb422ec0e0fa94a49e476018602eeea.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200511' into staging
target-arm queue:
 aspeed: Add boot stub for smp booting
 target/arm: Drop access_el3_aa32ns_aa64any()
 aspeed: Support AST2600A1 silicon revision
 aspeed: sdmc: Implement AST2600 locking behaviour
 nrf51: Tracing cleanups
 target/arm: Improve handling of SVE loads and stores
 target/arm: Don't show TCG-only CPUs in KVM-only QEMU builds
 hw/arm/musicpal: Map the UART devices unconditionally
 target/arm: Fix tcg_gen_gvec_dup_imm vs DUP (indexed)
 target/arm: Use tcg_gen_gvec_5_ptr for sve FMLA/FCMLA

# gpg: Signature made Mon 11 May 2020 14:33:14 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-20200511: (34 commits)
  target/arm: Fix tcg_gen_gvec_dup_imm vs DUP (indexed)
  target/arm: Use tcg_gen_gvec_5_ptr for sve FMLA/FCMLA
  hw/arm/musicpal: Map the UART devices unconditionally
  target/arm: Restrict TCG cpus to TCG accel
  target/arm/cpu: Restrict v8M IDAU interface to Aarch32 CPUs
  target/arm/cpu: Use ARRAY_SIZE() to iterate over ARMCPUInfo[]
  target/arm: Make set_feature() available for other files
  target/arm/kvm: Inline set_feature() calls
  target/arm: Remove sve_memopidx
  target/arm: Reuse sve_probe_page for gather loads
  target/arm: Reuse sve_probe_page for scatter stores
  target/arm: Reuse sve_probe_page for gather first-fault loads
  target/arm: Use SVEContLdSt for contiguous stores
  target/arm: Update contiguous first-fault and no-fault loads
  target/arm: Use SVEContLdSt for multi-register contiguous loads
  target/arm: Handle watchpoints in sve_ld1_r
  target/arm: Use SVEContLdSt in sve_ld1_r
  target/arm: Adjust interface of sve_ld1_host_fn
  target/arm: Add sve infrastructure for page lookup
  target/arm: Drop manual handling of set/clear_helper_retaddr
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/misc/aspeed_sdmc.c')
-rw-r--r--hw/misc/aspeed_sdmc.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 7b466bf19a..14db9cfc1f 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -23,7 +23,12 @@
 
 /* Protection Key Register */
 #define R_PROT            (0x00 / 4)
+#define   PROT_UNLOCKED      0x01
+#define   PROT_HARDLOCKED    0x10  /* AST2600 */
+#define   PROT_SOFTLOCKED    0x00
+
 #define   PROT_KEY_UNLOCK     0xFC600309
+#define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */
 
 /* Configuration Register */
 #define R_CONF            (0x04 / 4)
@@ -130,16 +135,6 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
         return;
     }
 
-    if (addr == R_PROT) {
-        s->regs[addr] = (data == PROT_KEY_UNLOCK) ? 1 : 0;
-        return;
-    }
-
-    if (!s->regs[R_PROT]) {
-        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
-        return;
-    }
-
     asc->write(s, addr, data);
 }
 
@@ -320,6 +315,16 @@ static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
 static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg,
                                    uint32_t data)
 {
+    if (reg == R_PROT) {
+        s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
+        return;
+    }
+
+    if (!s->regs[R_PROT]) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
+        return;
+    }
+
     switch (reg) {
     case R_CONF:
         data = aspeed_2400_sdmc_compute_conf(s, data);
@@ -368,6 +373,16 @@ static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
 static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg,
                                    uint32_t data)
 {
+    if (reg == R_PROT) {
+        s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
+        return;
+    }
+
+    if (!s->regs[R_PROT]) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
+        return;
+    }
+
     switch (reg) {
     case R_CONF:
         data = aspeed_2500_sdmc_compute_conf(s, data);
@@ -424,7 +439,27 @@ static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
 static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
                                    uint32_t data)
 {
+    if (s->regs[R_PROT] == PROT_HARDLOCKED) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n",
+                __func__);
+        return;
+    }
+
+    if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
+        return;
+    }
+
     switch (reg) {
+    case R_PROT:
+        if (data == PROT_KEY_UNLOCK)  {
+            data = PROT_UNLOCKED;
+        } else if (data == PROT_KEY_HARDLOCK) {
+            data = PROT_HARDLOCKED;
+        } else {
+            data = PROT_SOFTLOCKED;
+        }
+        break;
     case R_CONF:
         data = aspeed_2600_sdmc_compute_conf(s, data);
         break;