From: Martin Mohring <martin.mohring@opensuse.org>
To: edgar.iglesias@gmail.com
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [6966] SH: Improve movca.l/ocbi emulation.
Date: Thu, 02 Apr 2009 17:50:52 +0200 [thread overview]
Message-ID: <49D4DEDC.3040902@opensuse.org> (raw)
In-Reply-To: <E1Lp9a3-0007GN-3F@cvs.savannah.gnu.org>
Hi,
could it have been in these changes that i get a linking error for qemu
user sh4 on host linux/i586 now? Or was that introduced before?
See my other post for the error messages?
Martin
Edgar E. Iglesias wrote:
> Revision: 6966
> http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6966
> Author: edgar_igl
> Date: 2009-04-01 23:10:46 +0000 (Wed, 01 Apr 2009)
> Log Message:
> -----------
> SH: Improve movca.l/ocbi emulation.
>
> Author: Vladimir Prus <vladimir@codesourcery.com>
>
> Fix movcal.l/ocbi emulation.
>
> * target-sh4/cpu.h (memory_content): New.
> (CPUSH4State): New fields movcal_backup and movcal_backup_tail.
> * target-sh4/helper.h (helper_movcal)
> (helper_discard_movcal_backup, helper_ocbi): New.
> * target-sh4/op_helper.c (helper_movcal)
> (helper_discard_movcal_backup, helper_ocbi): New.
> * target-sh4/translate.c (DisasContext): New field has_movcal.
> (sh4_defs): Update CVS for SH7785.
> (cpu_sh4_init): Initialize env->movcal_backup_tail.
> (_decode_opc): Discard movca.l-backup.
> Make use of helper_movcal and helper_ocbi.
> (gen_intermediate_code_internal): Initialize has_movcal to 1.
>
> Thanks to Shin-ichiro KAWASAKI and Paul Mundt for valuable feedback.
>
> Acked-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
>
> Modified Paths:
> --------------
> trunk/target-sh4/cpu.h
> trunk/target-sh4/helper.c
> trunk/target-sh4/helper.h
> trunk/target-sh4/op_helper.c
> trunk/target-sh4/translate.c
>
> Modified: trunk/target-sh4/cpu.h
> ===================================================================
> --- trunk/target-sh4/cpu.h 2009-04-01 12:27:59 UTC (rev 6965)
> +++ trunk/target-sh4/cpu.h 2009-04-01 23:10:46 UTC (rev 6966)
> @@ -100,6 +100,12 @@
> SH_FEATURE_BCR3_AND_BCR4 = 2,
> };
>
> +typedef struct memory_content {
> + uint32_t address;
> + uint32_t value;
> + struct memory_content *next;
> +} memory_content;
> +
> typedef struct CPUSH4State {
> int id; /* CPU model */
>
> @@ -148,6 +154,8 @@
> tlb_t itlb[ITLB_SIZE]; /* instruction translation table */
> void *intc_handle;
> int intr_at_halt; /* SR_BL ignored during sleep */
> + memory_content *movcal_backup;
> + memory_content **movcal_backup_tail;
> } CPUSH4State;
>
> CPUSH4State *cpu_sh4_init(const char *cpu_model);
> @@ -162,6 +170,8 @@
> void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
> uint32_t mem_value);
>
> +int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr);
> +
> static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)
> {
> env->gbr = newtls;
> @@ -293,6 +303,8 @@
> env->flags = tb->flags;
> }
>
> +#define TB_FLAG_PENDING_MOVCA (1 << 4)
> +
> static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
> target_ulong *cs_base, int *flags)
> {
> @@ -302,7 +314,8 @@
> | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */
> | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
> | (env->sr & (SR_MD | SR_RB)) /* Bits 29-30 */
> - | (env->sr & SR_FD); /* Bit 15 */
> + | (env->sr & SR_FD) /* Bit 15 */
> + | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
> }
>
> #endif /* _CPU_SH4_H */
>
> Modified: trunk/target-sh4/helper.c
> ===================================================================
> --- trunk/target-sh4/helper.c 2009-04-01 12:27:59 UTC (rev 6965)
> +++ trunk/target-sh4/helper.c 2009-04-01 23:10:46 UTC (rev 6966)
> @@ -644,4 +644,48 @@
> }
> }
>
> +int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
> +{
> + int n;
> + int use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
> +
> + /* check area */
> + if (env->sr & SR_MD) {
> + /* For previledged mode, P2 and P4 area is not cachable. */
> + if ((0xA0000000 <= addr && addr < 0xC0000000) || 0xE0000000 <= addr)
> + return 0;
> + } else {
> + /* For user mode, only U0 area is cachable. */
> + if (0x80000000 <= addr)
> + return 0;
> + }
> +
> + /*
> + * TODO : Evaluate CCR and check if the cache is on or off.
> + * Now CCR is not in CPUSH4State, but in SH7750State.
> + * When you move the ccr inot CPUSH4State, the code will be
> + * as follows.
> + */
> +#if 0
> + /* check if operand cache is enabled or not. */
> + if (!(env->ccr & 1))
> + return 0;
> #endif
> +
> + /* if MMU is off, no check for TLB. */
> + if (env->mmucr & MMUCR_AT)
> + return 1;
> +
> + /* check TLB */
> + n = find_tlb_entry(env, addr, env->itlb, ITLB_SIZE, use_asid);
> + if (n >= 0)
> + return env->itlb[n].c;
> +
> + n = find_tlb_entry(env, addr, env->utlb, UTLB_SIZE, use_asid);
> + if (n >= 0)
> + return env->utlb[n].c;
> +
> + return 0;
> +}
> +
> +#endif
>
> Modified: trunk/target-sh4/helper.h
> ===================================================================
> --- trunk/target-sh4/helper.h 2009-04-01 12:27:59 UTC (rev 6965)
> +++ trunk/target-sh4/helper.h 2009-04-01 23:10:46 UTC (rev 6966)
> @@ -9,6 +9,10 @@
> DEF_HELPER_1(sleep, void, i32)
> DEF_HELPER_1(trapa, void, i32)
>
> +DEF_HELPER_2(movcal, void, i32, i32)
> +DEF_HELPER_0(discard_movcal_backup, void)
> +DEF_HELPER_1(ocbi, void, i32)
> +
> DEF_HELPER_2(addv, i32, i32, i32)
> DEF_HELPER_2(addc, i32, i32, i32)
> DEF_HELPER_2(subv, i32, i32, i32)
>
> Modified: trunk/target-sh4/op_helper.c
> ===================================================================
> --- trunk/target-sh4/op_helper.c 2009-04-01 12:27:59 UTC (rev 6965)
> +++ trunk/target-sh4/op_helper.c 2009-04-01 23:10:46 UTC (rev 6966)
> @@ -18,6 +18,7 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
> */
> #include <assert.h>
> +#include <stdlib.h>
> #include "exec.h"
> #include "helper.h"
>
> @@ -122,6 +123,57 @@
> cpu_loop_exit();
> }
>
> +void helper_movcal(uint32_t address, uint32_t value)
> +{
> + if (cpu_sh4_is_cached (env, address))
> + {
> + memory_content *r = malloc (sizeof(memory_content));
> + r->address = address;
> + r->value = value;
> + r->next = NULL;
> +
> + *(env->movcal_backup_tail) = r;
> + env->movcal_backup_tail = &(r->next);
> + }
> +}
> +
> +void helper_discard_movcal_backup(void)
> +{
> + memory_content *current = env->movcal_backup;
> +
> + while(current)
> + {
> + memory_content *next = current->next;
> + free (current);
> + env->movcal_backup = current = next;
> + if (current == 0)
> + env->movcal_backup_tail = &(env->movcal_backup);
> + }
> +}
> +
> +void helper_ocbi(uint32_t address)
> +{
> + memory_content **current = &(env->movcal_backup);
> + while (*current)
> + {
> + uint32_t a = (*current)->address;
> + if ((a & ~0x1F) == (address & ~0x1F))
> + {
> + memory_content *next = (*current)->next;
> + stl(a, (*current)->value);
> +
> + if (next == 0)
> + {
> + env->movcal_backup_tail = current;
> + }
> +
> + free (*current);
> + *current = next;
> + break;
> + }
> + }
> +}
> +
> uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
> {
> uint32_t tmp0, tmp1;
>
> Modified: trunk/target-sh4/translate.c
> ===================================================================
> --- trunk/target-sh4/translate.c 2009-04-01 12:27:59 UTC (rev 6965)
> +++ trunk/target-sh4/translate.c 2009-04-01 23:10:46 UTC (rev 6966)
> @@ -50,6 +50,7 @@
> uint32_t delayed_pc;
> int singlestep_enabled;
> uint32_t features;
> + int has_movcal;
> } DisasContext;
>
> #if defined(CONFIG_USER_ONLY)
> @@ -283,6 +284,7 @@
> env = qemu_mallocz(sizeof(CPUSH4State));
> env->features = def->features;
> cpu_exec_init(env);
> + env->movcal_backup_tail = &(env->movcal_backup);
> sh4_translate_init();
> env->cpu_model_str = cpu_model;
> cpu_sh4_reset(env);
> @@ -495,6 +497,37 @@
>
> static void _decode_opc(DisasContext * ctx)
> {
> + /* This code tries to make movcal emulation sufficiently
> + accurate for Linux purposes. This instruction writes
> + memory, and prior to that, always allocates a cache line.
> + It is used in two contexts:
> + - in memcpy, where data is copied in blocks, the first write
> + of to a block uses movca.l for performance.
> + - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
> + to flush the cache. Here, the data written by movcal.l is never
> + written to memory, and the data written is just bogus.
> +
> + To simulate this, we simulate movcal.l, we store the value to memory,
> + but we also remember the previous content. If we see ocbi, we check
> + if movcal.l for that address was done previously. If so, the write should
> + not have hit the memory, so we restore the previous content.
> + When we see an instruction that is neither movca.l
> + nor ocbi, the previous content is discarded.
> +
> + To optimize, we only try to flush stores when we're at the start of
> + TB, or if we already saw movca.l in this TB and did not flush stores
> + yet. */
> + if (ctx->has_movcal)
> + {
> + int opcode = ctx->opcode & 0xf0ff;
> + if (opcode != 0x0093 /* ocbi */
> + && opcode != 0x00c3 /* movca.l */)
> + {
> + gen_helper_discard_movcal_backup ();
> + ctx->has_movcal = 0;
> + }
> + }
> +
> #if 0
> fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
> #endif
> @@ -1545,7 +1578,13 @@
> }
> return;
> case 0x00c3: /* movca.l R0,@Rm */
> - tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
> + {
> + TCGv val = tcg_temp_new();
> + tcg_gen_qemu_ld32u(val, REG(B11_8), ctx->memidx);
> + gen_helper_movcal (REG(B11_8), val);
> + tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
> + }
> + ctx->has_movcal = 1;
> return;
> case 0x40a9:
> /* MOVUA.L @Rm,R0 (Rm) -> R0
> @@ -1594,9 +1633,7 @@
> break;
> case 0x0093: /* ocbi @Rn */
> {
> - TCGv dummy = tcg_temp_new();
> - tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
> - tcg_temp_free(dummy);
> + gen_helper_ocbi (REG(B11_8));
> }
> return;
> case 0x00a3: /* ocbp @Rn */
> @@ -1876,6 +1913,7 @@
> ctx.tb = tb;
> ctx.singlestep_enabled = env->singlestep_enabled;
> ctx.features = env->features;
> + ctx.has_movcal = (tb->flags & TB_FLAG_PENDING_MOVCA);
>
> #ifdef DEBUG_DISAS
> qemu_log_mask(CPU_LOG_TB_CPU,
>
>
>
>
next prev parent reply other threads:[~2009-04-02 15:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-01 23:10 [Qemu-devel] [6966] SH: Improve movca.l/ocbi emulation Edgar E. Iglesias
2009-04-02 15:50 ` Martin Mohring [this message]
2009-04-03 5:31 ` [Qemu-devel] " Vladimir Prus
2009-04-03 7:35 ` Edgar E. Iglesias
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=49D4DEDC.3040902@opensuse.org \
--to=martin.mohring@opensuse.org \
--cc=edgar.iglesias@gmail.com \
--cc=qemu-devel@nongnu.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.