aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-08-24 14:54:17 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-08-24 14:54:17 +0100
commitdf82aa7fe10e46b675678977999d49bd586538f8 (patch)
tree97bd0faa4d30c6d221294835c851efb6adc86078 /target
parent07d914cb9489f7acbd91ed675355674c8a5545b0 (diff)
parent43f4e3d4fa2f9dba6bd68452a3380864ad9453c1 (diff)
Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2020-08-24.for-upstream' into staging
For upstream. # gpg: Signature made Mon 24 Aug 2020 10:53:42 BST # gpg: using RSA key AC44FEDC14F7F1EBEDBF415129C596780F6BCA83 # gpg: Good signature from "Edgar E. Iglesias (Xilinx key) <edgar.iglesias@xilinx.com>" [unknown] # gpg: aka "Edgar E. Iglesias <edgar.iglesias@gmail.com>" [full] # Primary key fingerprint: AC44 FEDC 14F7 F1EB EDBF 4151 29C5 9678 0F6B CA83 * remotes/edgar/tags/edgar/xilinx-next-2020-08-24.for-upstream: microblaze: petalogix-s3adsp1800: Add device-tree source microblaze: petalogix-ml605: Add device-tree source target/microblaze: mbar: Trap sleeps from user-space configure: microblaze: Enable mttcg target/microblaze: swx: Use atomic_cmpxchg target/microblaze: mbar: Add support for data-access barriers target/microblaze: mbar: Move LOG_DIS to before sleep target/microblaze: mbar: Transfer dc->rd to mbar_imm Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/microblaze/translate.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index f6ff2591c3..a96cb21d96 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -1075,14 +1075,16 @@ static void dec_store(DisasContext *dc)
swx_skip = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, addr, swx_skip);
- /* Compare the value loaded at lwx with current contents of
- the reserved location.
- FIXME: This only works for system emulation where we can expect
- this compare and the following write to be atomic. For user
- emulation we need to add atomicity between threads. */
+ /*
+ * Compare the value loaded at lwx with current contents of
+ * the reserved location.
+ */
tval = tcg_temp_new_i32();
- tcg_gen_qemu_ld_i32(tval, addr, cpu_mmu_index(&dc->cpu->env, false),
- MO_TEUL);
+
+ tcg_gen_atomic_cmpxchg_i32(tval, addr, env_res_val,
+ cpu_R[dc->rd], mem_index,
+ mop);
+
tcg_gen_brcond_i32(TCG_COND_NE, env_res_val, tval, swx_skip);
write_carryi(dc, 0);
tcg_temp_free_i32(tval);
@@ -1108,7 +1110,10 @@ static void dec_store(DisasContext *dc)
break;
}
}
- tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr, mem_index, mop);
+
+ if (!ex) {
+ tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr, mem_index, mop);
+ }
/* Verify alignment if needed. */
if (dc->cpu->cfg.unaligned_exceptions && size > 1) {
@@ -1229,13 +1234,27 @@ static void dec_br(DisasContext *dc)
/* Memory barrier. */
mbar = (dc->ir >> 16) & 31;
if (mbar == 2 && dc->imm == 4) {
+ uint16_t mbar_imm = dc->rd;
+
+ LOG_DIS("mbar %d\n", mbar_imm);
+
+ /* Data access memory barrier. */
+ if ((mbar_imm & 2) == 0) {
+ tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
+ }
+
/* mbar IMM & 16 decodes to sleep. */
- if (dc->rd & 16) {
+ if (mbar_imm & 16) {
TCGv_i32 tmp_hlt = tcg_const_i32(EXCP_HLT);
TCGv_i32 tmp_1 = tcg_const_i32(1);
LOG_DIS("sleep\n");
+ if (trap_userspace(dc, true)) {
+ /* Sleep is a privileged instruction. */
+ return;
+ }
+
t_sync_flags(dc);
tcg_gen_st_i32(tmp_1, cpu_env,
-offsetof(MicroBlazeCPU, env)
@@ -1246,7 +1265,6 @@ static void dec_br(DisasContext *dc)
tcg_temp_free_i32(tmp_1);
return;
}
- LOG_DIS("mbar %d\n", dc->rd);
/* Break the TB. */
dc->cpustate_changed = 1;
return;