All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Dovgalyuk <pavel.dovgalyuk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: pavel.dovgalyuk@ispras.ru, mrolnik@gmail.com, philmd@linaro.org,
	richard.henderson@linaro.org
Subject: [PATCH 2/4] target/avr: implement small RAM/large RAM feature
Date: Sat, 19 Nov 2022 08:55:59 +0300	[thread overview]
Message-ID: <166883735975.1540909.16334439765982123298.stgit@pasha-ThinkPad-X280> (raw)
In-Reply-To: <166883734868.1540909.6779276759642478650.stgit@pasha-ThinkPad-X280>

translate.c functions use RAMPZ for RAM access. This register
is also used for ROM reads. However, in MCUs with 64k RAM support
RAMPZ is used for ROM only. Therefore when RAMPZ is set,
addressing the RAM becomes incorrect in the emulator.
This patch adds LARGE RAM feature which can be used in xmega controllers,
that could be added later. For the currently supported MCUs this
feature is disabled and RAMPZ is not used for RAM access.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
---
 target/avr/cpu.h       |    2 ++
 target/avr/translate.c |   63 ++++++++++++++++++++++++++++++------------------
 2 files changed, 41 insertions(+), 24 deletions(-)

diff --git a/target/avr/cpu.h b/target/avr/cpu.h
index 96419c0c2b..cfdc0ecb70 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -106,6 +106,8 @@ typedef enum AVRFeature {
     AVR_FEATURE_RAMPX,
     AVR_FEATURE_RAMPY,
     AVR_FEATURE_RAMPZ,
+
+    AVR_FEATURE_LARGE_RAM,
 } AVRFeature;
 
 typedef struct CPUArchState {
diff --git a/target/avr/translate.c b/target/avr/translate.c
index c9a0a39c2d..e4900d630f 100644
--- a/target/avr/translate.c
+++ b/target/avr/translate.c
@@ -1542,13 +1542,17 @@ static bool trans_BRBS(DisasContext *ctx, arg_BRBS *a)
  *  M assumed to be in 0x000000ff format
  *  L assumed to be in 0x000000ff format
  */
-static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+static void gen_set_addr_short(TCGv addr, TCGv M, TCGv L)
 {
-
     tcg_gen_andi_tl(L, addr, 0x000000ff);
 
     tcg_gen_andi_tl(M, addr, 0x0000ff00);
     tcg_gen_shri_tl(M, M, 8);
+}
+
+static void gen_set_addr(TCGv addr, TCGv H, TCGv M, TCGv L)
+{
+    gen_set_addr_short(addr, M, L);
 
     tcg_gen_andi_tl(H, addr, 0x00ff0000);
 }
@@ -1563,9 +1567,13 @@ static void gen_set_yaddr(TCGv addr)
     gen_set_addr(addr, cpu_rampY, cpu_r[29], cpu_r[28]);
 }
 
-static void gen_set_zaddr(TCGv addr)
+static void gen_set_zaddr(DisasContext *ctx, TCGv addr, bool ram)
 {
-    gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+    if (!ram || avr_feature(ctx->env, AVR_FEATURE_LARGE_RAM)) {
+        gen_set_addr(addr, cpu_rampZ, cpu_r[31], cpu_r[30]);
+    } else {
+        gen_set_addr_short(addr, cpu_r[31], cpu_r[30]);
+    }
 }
 
 static TCGv gen_get_addr(TCGv H, TCGv M, TCGv L)
@@ -1588,9 +1596,16 @@ static TCGv gen_get_yaddr(void)
     return gen_get_addr(cpu_rampY, cpu_r[29], cpu_r[28]);
 }
 
-static TCGv gen_get_zaddr(void)
+static TCGv gen_get_zaddr(DisasContext *ctx, bool ram)
 {
-    return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
+    if (!ram || avr_feature(ctx->env, AVR_FEATURE_LARGE_RAM)) {
+        return gen_get_addr(cpu_rampZ, cpu_r[31], cpu_r[30]);
+    } else {
+        TCGv zero = tcg_const_i32(0);
+        TCGv res = gen_get_addr(zero, cpu_r[31], cpu_r[30]);
+        tcg_temp_free_i32(zero);
+        return res;
+    }
 }
 
 /*
@@ -1868,12 +1883,12 @@ static bool trans_LDDY(DisasContext *ctx, arg_LDDY *a)
 static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a)
 {
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     gen_data_load(ctx, Rd, addr);
     tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
 
-    gen_set_zaddr(addr);
+    gen_set_zaddr(ctx, addr, true);
 
     tcg_temp_free_i32(addr);
 
@@ -1883,12 +1898,12 @@ static bool trans_LDZ2(DisasContext *ctx, arg_LDZ2 *a)
 static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a)
 {
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
     gen_data_load(ctx, Rd, addr);
 
-    gen_set_zaddr(addr);
+    gen_set_zaddr(ctx, addr, true);
 
     tcg_temp_free_i32(addr);
 
@@ -1898,7 +1913,7 @@ static bool trans_LDZ3(DisasContext *ctx, arg_LDZ3 *a)
 static bool trans_LDDZ(DisasContext *ctx, arg_LDDZ *a)
 {
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
     gen_data_load(ctx, Rd, addr);
@@ -2088,12 +2103,12 @@ static bool trans_STDY(DisasContext *ctx, arg_STDY *a)
 static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a)
 {
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     gen_data_store(ctx, Rd, addr);
     tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
 
-    gen_set_zaddr(addr);
+    gen_set_zaddr(ctx, addr, true);
 
     tcg_temp_free_i32(addr);
 
@@ -2103,12 +2118,12 @@ static bool trans_STZ2(DisasContext *ctx, arg_STZ2 *a)
 static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a)
 {
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     tcg_gen_subi_tl(addr, addr, 1); /* addr = addr - 1 */
     gen_data_store(ctx, Rd, addr);
 
-    gen_set_zaddr(addr);
+    gen_set_zaddr(ctx, addr, true);
 
     tcg_temp_free_i32(addr);
 
@@ -2118,7 +2133,7 @@ static bool trans_STZ3(DisasContext *ctx, arg_STZ3 *a)
 static bool trans_STDZ(DisasContext *ctx, arg_STDZ *a)
 {
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     tcg_gen_addi_tl(addr, addr, a->imm); /* addr = addr + q */
     gen_data_store(ctx, Rd, addr);
@@ -2228,7 +2243,7 @@ static bool trans_ELPM1(DisasContext *ctx, arg_ELPM1 *a)
     }
 
     TCGv Rd = cpu_r[0];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, false);
 
     tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */
 
@@ -2244,7 +2259,7 @@ static bool trans_ELPM2(DisasContext *ctx, arg_ELPM2 *a)
     }
 
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, false);
 
     tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */
 
@@ -2260,11 +2275,11 @@ static bool trans_ELPMX(DisasContext *ctx, arg_ELPMX *a)
     }
 
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, false);
 
     tcg_gen_qemu_ld8u(Rd, addr, MMU_CODE_IDX); /* Rd = mem[addr] */
     tcg_gen_addi_tl(addr, addr, 1); /* addr = addr + 1 */
-    gen_set_zaddr(addr);
+    gen_set_zaddr(ctx, addr, false);
 
     tcg_temp_free_i32(addr);
 
@@ -2402,7 +2417,7 @@ static bool trans_XCH(DisasContext *ctx, arg_XCH *a)
 
     TCGv Rd = cpu_r[a->rd];
     TCGv t0 = tcg_temp_new_i32();
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
 
     gen_data_load(ctx, t0, addr);
     gen_data_store(ctx, Rd, addr);
@@ -2432,7 +2447,7 @@ static bool trans_LAS(DisasContext *ctx, arg_LAS *a)
     }
 
     TCGv Rr = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
     TCGv t0 = tcg_temp_new_i32();
     TCGv t1 = tcg_temp_new_i32();
 
@@ -2467,7 +2482,7 @@ static bool trans_LAC(DisasContext *ctx, arg_LAC *a)
     }
 
     TCGv Rr = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
     TCGv t0 = tcg_temp_new_i32();
     TCGv t1 = tcg_temp_new_i32();
 
@@ -2502,7 +2517,7 @@ static bool trans_LAT(DisasContext *ctx, arg_LAT *a)
     }
 
     TCGv Rd = cpu_r[a->rd];
-    TCGv addr = gen_get_zaddr();
+    TCGv addr = gen_get_zaddr(ctx, true);
     TCGv t0 = tcg_temp_new_i32();
     TCGv t1 = tcg_temp_new_i32();
 



  parent reply	other threads:[~2022-11-19  5:57 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-19  5:55 [PATCH 0/4] AVR target fixes Pavel Dovgalyuk
2022-11-19  5:55 ` [PATCH 1/4] target/avr: fix long address calculation Pavel Dovgalyuk
2022-11-19  5:55 ` Pavel Dovgalyuk [this message]
2022-11-19  5:56 ` [PATCH 3/4] target/avr: fix avr features processing Pavel Dovgalyuk
2022-11-19 16:04   ` Michael Rolnik
2022-11-19  5:56 ` [PATCH 4/4] target/avr: fix interrupt processing Pavel Dovgalyuk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=166883735975.1540909.16334439765982123298.stgit@pasha-ThinkPad-X280 \
    --to=pavel.dovgalyuk@ispras.ru \
    --cc=mrolnik@gmail.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.