[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 3/7] target/ppc: Isolated SPR read/write callbacks
From: |
Fabiano Rosas |
Subject: |
Re: [PATCH v2 3/7] target/ppc: Isolated SPR read/write callbacks |
Date: |
Thu, 29 Apr 2021 17:42:16 -0300 |
"Bruno Larsen (billionai)" <bruno.larsen@eldorado.org.br> writes:
> Moved all SPR read/write callback, and some related functions, to a
> new file specific for it. These callbacks are TCG only, so separating
> them is required to support the flag disable-tcg.
>
> Making the spr_noaccess function not static, and moving the define to
> internal.h is required, as spr_tcg.c.inc has to be included after
> SPR_NOACCESS has been used.
>
> Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> ---
> target/ppc/internal.h | 3 +
> target/ppc/spr_tcg.c.inc | 1033 +++++++++++++++++++++++++++++++
> target/ppc/translate.c | 49 +-
> target/ppc/translate_init.c.inc | 981 -----------------------------
> 4 files changed, 1039 insertions(+), 1027 deletions(-)
> create mode 100644 target/ppc/spr_tcg.c.inc
>
> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> index 184ba6d6b3..1de15acfbd 100644
> --- a/target/ppc/internal.h
> +++ b/target/ppc/internal.h
> @@ -228,4 +228,7 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu);
> void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
> gchar *ppc_gdb_arch_name(CPUState *cs);
>
> +void spr_noaccess(DisasContext *ctx, int gprn, int sprn);
> +#define SPR_NOACCESS (&spr_noaccess)
> +
> #endif /* PPC_INTERNAL_H */
> diff --git a/target/ppc/spr_tcg.c.inc b/target/ppc/spr_tcg.c.inc
> new file mode 100644
> index 0000000000..48274dd52b
> --- /dev/null
> +++ b/target/ppc/spr_tcg.c.inc
> @@ -0,0 +1,1033 @@
> +#include "exec/translator.h"
This is already in translate.c.
> +
> +/*****************************************************************************/
> +/* Reader and writer functions for SPRs */
> +
> +/* I really see no reason to keep these gen_*_xer */
> +/* instead of just leaving the code in the spr_*_xer */
Ok, let's do this for the next version then.
> +static void gen_read_xer(DisasContext *ctx, TCGv dst)
> +{
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + TCGv t2 = tcg_temp_new();
> + tcg_gen_mov_tl(dst, cpu_xer);
> + tcg_gen_shli_tl(t0, cpu_so, XER_SO);
> + tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
> + tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
> + tcg_gen_or_tl(t0, t0, t1);
> + tcg_gen_or_tl(dst, dst, t2);
> + tcg_gen_or_tl(dst, dst, t0);
> + if (is_isa300(ctx)) {
> + tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32);
> + tcg_gen_or_tl(dst, dst, t0);
> + tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32);
> + tcg_gen_or_tl(dst, dst, t0);
> + }
> + tcg_temp_free(t0);
> + tcg_temp_free(t1);
> + tcg_temp_free(t2);
> +}
> +
> +static void gen_write_xer(TCGv src)
> +{
> + /* Write all flags, while reading back check for isa300 */
> + tcg_gen_andi_tl(cpu_xer, src,
> + ~((1u << XER_SO) |
> + (1u << XER_OV) | (1u << XER_OV32) |
> + (1u << XER_CA) | (1u << XER_CA32)));
> + tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1);
> + tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1);
> + tcg_gen_extract_tl(cpu_so, src, XER_SO, 1);
> + tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1);
> + tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1);
> +}
<snip>
> +/* User read access to SPR */
> +/* USPRx */
> +/* UMMCRx */
> +/* UPMCx */
> +/* USIA */
> +/* UDECR */
> +static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
> +{
> + gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
> +}
> +
> +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
> +static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
> +{
> + gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
> +}
> +#endif
> +
You missed this:
/* SPR common to all non-embedded PowerPC */
> +#if !defined(CONFIG_USER_ONLY)
> +static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
> +{
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_stop_exception(ctx);
> + }
> +}
> +
> +static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
> +{
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_stop_exception(ctx);
> + }
> +}
> +#endif
> +
> +/* SPR common to all non-embedded PowerPC, except 601 */
> +/* Time base */
> +static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
> +{
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_end();
> + gen_stop_exception(ctx);
> + }
> +}
> +
> +static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
> +{
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_start();
> + }
> + gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
> + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> + gen_io_end();
> + gen_stop_exception(ctx);
> + }
> +}
<snip>
> +static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
> +{
> + int sprn_offs;
> +
> + if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
> + sprn_offs = sprn - SPR_BOOKE_IVOR0;
> + } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
> + sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
> + } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
> + sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
> + } else {
> + printf("Trying to write an unknown exception vector %d %03x\n",
> + sprn, sprn);
> + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> + return;
> + }
> +
> + TCGv t0 = tcg_temp_new();
> + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
> + tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
> + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState,
> excp_vectors[sprn_offs]));
> + gen_store_spr(sprn, t0);
> + tcg_temp_free(t0);
> +}
> +#endif
> +
> +#ifdef TARGET_PPC64
#ifndef CONFIG_USER_ONLY
> +static void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
> +{
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + TCGv t2 = tcg_temp_new();
> +
> + /*
> + * Note, the HV=1 PR=0 case is handled earlier by simply using
> + * spr_write_generic for HV mode in the SPR table
> + */
> +
> + /* Build insertion mask into t1 based on context */
> + if (ctx->pr) {
> + gen_load_spr(t1, SPR_UAMOR);
> + } else {
> + gen_load_spr(t1, SPR_AMOR);
> + }
> +
> + /* Mask new bits into t2 */
> + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
> +
> + /* Load AMR and clear new bits in t0 */
> + gen_load_spr(t0, SPR_AMR);
> + tcg_gen_andc_tl(t0, t0, t1);
> +
> + /* Or'in new bits and write it out */
> + tcg_gen_or_tl(t0, t0, t2);
> + gen_store_spr(SPR_AMR, t0);
> + spr_store_dump_spr(SPR_AMR);
> +
> + tcg_temp_free(t0);
> + tcg_temp_free(t1);
> + tcg_temp_free(t2);
> +}
> +
> +static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
> +{
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + TCGv t2 = tcg_temp_new();
> +
> + /*
> + * Note, the HV=1 case is handled earlier by simply using
> + * spr_write_generic for HV mode in the SPR table
> + */
> +
> + /* Build insertion mask into t1 based on context */
> + gen_load_spr(t1, SPR_AMOR);
> +
> + /* Mask new bits into t2 */
> + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
> +
> + /* Load AMR and clear new bits in t0 */
> + gen_load_spr(t0, SPR_UAMOR);
> + tcg_gen_andc_tl(t0, t0, t1);
> +
> + /* Or'in new bits and write it out */
> + tcg_gen_or_tl(t0, t0, t2);
> + gen_store_spr(SPR_UAMOR, t0);
> + spr_store_dump_spr(SPR_UAMOR);
> +
> + tcg_temp_free(t0);
> + tcg_temp_free(t1);
> + tcg_temp_free(t2);
> +}
> +
> +static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
> +{
> + TCGv t0 = tcg_temp_new();
> + TCGv t1 = tcg_temp_new();
> + TCGv t2 = tcg_temp_new();
> +
> + /*
> + * Note, the HV=1 case is handled earlier by simply using
> + * spr_write_generic for HV mode in the SPR table
> + */
> +
> + /* Build insertion mask into t1 based on context */
> + gen_load_spr(t1, SPR_AMOR);
> +
> + /* Mask new bits into t2 */
> + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
> +
> + /* Load AMR and clear new bits in t0 */
> + gen_load_spr(t0, SPR_IAMR);
> + tcg_gen_andc_tl(t0, t0, t1);
> +
> + /* Or'in new bits and write it out */
> + tcg_gen_or_tl(t0, t0, t2);
> + gen_store_spr(SPR_IAMR, t0);
> + spr_store_dump_spr(SPR_IAMR);
> +
> + tcg_temp_free(t0);
> + tcg_temp_free(t1);
> + tcg_temp_free(t2);
> +}
#endif /* CONFIG_USER_ONLY */
> +#endif
> +
> +#if !defined(CONFIG_USER_ONLY)
> +static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
> +{
> + gen_helper_fixup_thrm(cpu_env);
> + gen_load_spr(cpu_gpr[gprn], sprn);
> + spr_load_dump_spr(sprn);
> +}
<snip>
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index b319d409c6..a6e677fa6d 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -36,6 +36,7 @@
> #include "exec/translator.h"
> #include "exec/log.h"
> #include "qemu/atomic128.h"
> +#include "internal.h"
This is already included.
- [PATCH v2 0/7] target/ppc: untangle cpu init from translation, Bruno Larsen (billionai), 2021/04/29
- [PATCH v2 1/7] target/ppc: move opcode table logic to translate.c, Bruno Larsen (billionai), 2021/04/29
- [PATCH v2 2/7] target/ppc: Created !TCG SPR registration macro, Bruno Larsen (billionai), 2021/04/29
- [PATCH v2 3/7] target/ppc: Isolated SPR read/write callbacks, Bruno Larsen (billionai), 2021/04/29
- [PATCH v2 4/7] target/ppc: turned SPR R/W callbacks not static, Bruno Larsen (billionai), 2021/04/29
- [PATCH v2 5/7] target/ppc: removed VSCR from SPR registration, Bruno Larsen (billionai), 2021/04/29
- [PATCH v2 6/7] target/ttc: renamed SPR registration functions, Bruno Larsen (billionai), 2021/04/29