diff options
author | Stefan Hajnoczi | 2022-11-04 16:01:00 +0100 |
---|---|---|
committer | Stefan Hajnoczi | 2022-11-04 16:01:00 +0100 |
commit | 7a033008cc1865bfda3f2d6b92885439ae202009 (patch) | |
tree | 4eb072b4509af7c1f61b8aa57188c61d42441324 /target | |
parent | Merge tag 'linux-user-for-7.2-pull-request' of https://gitlab.com/laurent_viv... (diff) | |
parent | target/loongarch: Fix emulation of float-point disable exception (diff) | |
download | qemu-7a033008cc1865bfda3f2d6b92885439ae202009.tar.gz qemu-7a033008cc1865bfda3f2d6b92885439ae202009.tar.xz qemu-7a033008cc1865bfda3f2d6b92885439ae202009.zip |
Merge tag 'pull-loongarch-20221104' of https://gitlab.com/gaosong/qemu into staging
pull-loongarch-20221104
v2:
- fix win32 build error;
- Add Rui Wang' patches.
# -----BEGIN PGP SIGNATURE-----
#
# iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCY2TZsAAKCRBAov/yOSY+
# 30kyA/9VEYvFQaXM9RP78OoiK0bANiByTCQMXCAuos1wXui/FwAcqE9YWXZStzH0
# MHdT2PyH680w9aKjhHuPbGs5xU911cQ94SPWzcTtM4HfEH+3N7RBfF0gS7MA+DLa
# 92vLqEIDC6SbAlY4/CRJVJmOl58d4uhEUUpq6eVzmJHcA3W5qw==
# =wblG
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 04 Nov 2022 05:21:52 EDT
# gpg: using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF
# gpg: Good signature from "Song Gao <m17746591750@163.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: B8FF 1DA0 D2FD CB2D A09C 6C2C 40A2 FFF2 3926 3EDF
* tag 'pull-loongarch-20221104' of https://gitlab.com/gaosong/qemu:
target/loongarch: Fix emulation of float-point disable exception
target/loongarch: Adjust the layout of hardware flags bit fields
target/loongarch: Fix raise_mmu_exception() set wrong exception_index
target/loongarch: Add exception subcode
hw/loongarch: Add TPM device for LoongArch virt machine
hw/loongarch: Improve fdt for LoongArch virt machine
hw/loongarch: Load FDT table into dram memory space
hw/intc: Fix LoongArch extioi coreisr accessing
hw/intc: Convert the memops to with_attrs in LoongArch extioi
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/loongarch/cpu.c | 10 | ||||
-rw-r--r-- | target/loongarch/cpu.h | 69 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_farith.c.inc | 30 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_fcmp.c.inc | 11 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_fmemory.c.inc | 34 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_fmov.c.inc | 29 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_privileged.c.inc | 2 | ||||
-rw-r--r-- | target/loongarch/iocsr_helper.c | 19 | ||||
-rw-r--r-- | target/loongarch/tlb_helper.c | 5 | ||||
-rw-r--r-- | target/loongarch/translate.c | 6 |
10 files changed, 162 insertions, 53 deletions
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 49393d95d8..46b04cbdad 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -48,6 +48,7 @@ static const char * const excp_names[] = { [EXCCODE_BRK] = "Break", [EXCCODE_INE] = "Instruction Non-Existent", [EXCCODE_IPE] = "Instruction privilege error", + [EXCCODE_FPD] = "Floating Point Disabled", [EXCCODE_FPE] = "Floating Point Exception", [EXCCODE_DBP] = "Debug breakpoint", [EXCCODE_BCE] = "Bound Check Exception", @@ -177,6 +178,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) } QEMU_FALLTHROUGH; case EXCCODE_PIF: + case EXCCODE_ADEF: cause = cs->exception_index; update_badinstr = 0; break; @@ -184,6 +186,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) case EXCCODE_BRK: case EXCCODE_INE: case EXCCODE_IPE: + case EXCCODE_FPD: case EXCCODE_FPE: case EXCCODE_BCE: env->CSR_BADV = env->pc; @@ -220,7 +223,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, PC, (env->pc >> 2)); } else { - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause); + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, + EXCODE_MCODE(cause)); + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE, + EXCODE_SUBCODE(cause)); env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV, FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV)); env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE, @@ -257,7 +263,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->pc = env->CSR_TLBRENTRY; } else { env->pc = env->CSR_EENTRY; - env->pc += cause * vec_size; + env->pc += EXCODE_MCODE(cause) * vec_size; } qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index dce999aaac..08c1f6baa1 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -14,6 +14,7 @@ #include "qemu/timer.h" #include "exec/memory.h" #include "hw/sysbus.h" +#include "cpu-csr.h" #define IOCSRF_TEMP 0 #define IOCSRF_NODECNT 1 @@ -75,33 +76,37 @@ FIELD(FCSR0, CAUSE, 24, 5) #define FP_DIV0 8 #define FP_INVALID 16 -#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */ -#define EXCCODE_INT 0 -#define EXCCODE_PIL 1 -#define EXCCODE_PIS 2 -#define EXCCODE_PIF 3 -#define EXCCODE_PME 4 -#define EXCCODE_PNR 5 -#define EXCCODE_PNX 6 -#define EXCCODE_PPI 7 -#define EXCCODE_ADEF 8 /* Different exception subcode */ -#define EXCCODE_ADEM 8 -#define EXCCODE_ALE 9 -#define EXCCODE_BCE 10 -#define EXCCODE_SYS 11 -#define EXCCODE_BRK 12 -#define EXCCODE_INE 13 -#define EXCCODE_IPE 14 -#define EXCCODE_FPD 15 -#define EXCCODE_SXD 16 -#define EXCCODE_ASXD 17 -#define EXCCODE_FPE 18 /* Different exception subcode */ -#define EXCCODE_VFPE 18 -#define EXCCODE_WPEF 19 /* Different exception subcode */ -#define EXCCODE_WPEM 19 -#define EXCCODE_BTD 20 -#define EXCCODE_BTE 21 -#define EXCCODE_DBP 26 /* Reserved subcode used for debug */ +#define EXCODE(code, subcode) ( ((subcode) << 6) | (code) ) +#define EXCODE_MCODE(code) ( (code) & 0x3f ) +#define EXCODE_SUBCODE(code) ( (code) >> 6 ) + +#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */ +#define EXCCODE_INT EXCODE(0, 0) +#define EXCCODE_PIL EXCODE(1, 0) +#define EXCCODE_PIS EXCODE(2, 0) +#define EXCCODE_PIF EXCODE(3, 0) +#define EXCCODE_PME EXCODE(4, 0) +#define EXCCODE_PNR EXCODE(5, 0) +#define EXCCODE_PNX EXCODE(6, 0) +#define EXCCODE_PPI EXCODE(7, 0) +#define EXCCODE_ADEF EXCODE(8, 0) /* Different exception subcode */ +#define EXCCODE_ADEM EXCODE(8, 1) +#define EXCCODE_ALE EXCODE(9, 0) +#define EXCCODE_BCE EXCODE(10, 0) +#define EXCCODE_SYS EXCODE(11, 0) +#define EXCCODE_BRK EXCODE(12, 0) +#define EXCCODE_INE EXCODE(13, 0) +#define EXCCODE_IPE EXCODE(14, 0) +#define EXCCODE_FPD EXCODE(15, 0) +#define EXCCODE_SXD EXCODE(16, 0) +#define EXCCODE_ASXD EXCODE(17, 0) +#define EXCCODE_FPE EXCODE(18, 0) /* Different exception subcode */ +#define EXCCODE_VFPE EXCODE(18, 1) +#define EXCCODE_WPEF EXCODE(19, 0) /* Different exception subcode */ +#define EXCCODE_WPEM EXCODE(19, 1) +#define EXCCODE_BTD EXCODE(20, 0) +#define EXCCODE_BTE EXCODE(21, 0) +#define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */ /* cpucfg[0] bits */ FIELD(CPUCFG0, PRID, 0, 32) @@ -387,6 +392,13 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) #endif } +/* + * LoongArch CPUs hardware flags. + */ +#define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */ +#define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */ +#define HW_FLAGS_EUEN_FPE 0x04 + static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, target_ulong *pc, target_ulong *cs_base, @@ -394,7 +406,8 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, { *pc = env->pc; *cs_base = 0; - *flags = cpu_mmu_index(env, false); + *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); + *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; } void loongarch_cpu_list(void); diff --git a/target/loongarch/insn_trans/trans_farith.c.inc b/target/loongarch/insn_trans/trans_farith.c.inc index 7bb3f41aee..e2dec75dfb 100644 --- a/target/loongarch/insn_trans/trans_farith.c.inc +++ b/target/loongarch/insn_trans/trans_farith.c.inc @@ -3,9 +3,22 @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ +#ifndef CONFIG_USER_ONLY +#define CHECK_FPE do { \ + if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \ + generate_exception(ctx, EXCCODE_FPD); \ + return false; \ + } \ +} while (0) +#else +#define CHECK_FPE +#endif + static bool gen_fff(DisasContext *ctx, arg_fff *a, void (*func)(TCGv, TCGv_env, TCGv, TCGv)) { + CHECK_FPE; + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]); return true; } @@ -13,6 +26,8 @@ static bool gen_fff(DisasContext *ctx, arg_fff *a, static bool gen_ff(DisasContext *ctx, arg_ff *a, void (*func)(TCGv, TCGv_env, TCGv)) { + CHECK_FPE; + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]); return true; } @@ -22,6 +37,9 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a, int flag) { TCGv_i32 tflag = tcg_constant_i32(flag); + + CHECK_FPE; + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], cpu_fpr[a->fa], tflag); return true; @@ -29,18 +47,24 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a, static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a) { + CHECK_FPE; + tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31); return true; } static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a) { + CHECK_FPE; + tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63); return true; } static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) { + CHECK_FPE; + tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31)); gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); return true; @@ -48,12 +72,16 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a) { + CHECK_FPE; + tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63)); return true; } static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) { + CHECK_FPE; + tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x80000000); gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); return true; @@ -61,6 +89,8 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a) { + CHECK_FPE; + tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000000000000000LL); return true; } diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc b/target/loongarch/insn_trans/trans_fcmp.c.inc index 93a6a2230f..2ccf646ccb 100644 --- a/target/loongarch/insn_trans/trans_fcmp.c.inc +++ b/target/loongarch/insn_trans/trans_fcmp.c.inc @@ -25,10 +25,13 @@ static uint32_t get_fcmp_flags(int cond) static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) { - TCGv var = tcg_temp_new(); + TCGv var; uint32_t flags; void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32); + CHECK_FPE; + + var = tcg_temp_new(); fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s); flags = get_fcmp_flags(a->fcond >> 1); @@ -41,9 +44,13 @@ static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) { - TCGv var = tcg_temp_new(); + TCGv var; uint32_t flags; void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32); + + CHECK_FPE; + + var = tcg_temp_new(); fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d); flags = get_fcmp_flags(a->fcond >> 1); diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc b/target/loongarch/insn_trans/trans_fmemory.c.inc index 74ee98f63a..3025a1d3e9 100644 --- a/target/loongarch/insn_trans/trans_fmemory.c.inc +++ b/target/loongarch/insn_trans/trans_fmemory.c.inc @@ -15,6 +15,8 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); TCGv temp = NULL; + CHECK_FPE; + if (a->imm) { temp = tcg_temp_new(); tcg_gen_addi_tl(temp, addr, a->imm); @@ -36,6 +38,8 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); TCGv temp = NULL; + CHECK_FPE; + if (a->imm) { temp = tcg_temp_new(); tcg_gen_addi_tl(temp, addr, a->imm); @@ -54,8 +58,11 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); maybe_nanbox_load(cpu_fpr[a->fd], mop); @@ -68,8 +75,11 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + + CHECK_FPE; + addr = tcg_temp_new(); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); tcg_temp_free(addr); @@ -81,8 +91,11 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); gen_helper_asrtgt_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); @@ -96,8 +109,11 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + + CHECK_FPE; + addr = tcg_temp_new(); gen_helper_asrtgt_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); @@ -110,8 +126,11 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); gen_helper_asrtle_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); @@ -125,8 +144,11 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + + CHECK_FPE; + addr = tcg_temp_new(); gen_helper_asrtle_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc b/target/loongarch/insn_trans/trans_fmov.c.inc index 5537e3dd35..8e5106db4e 100644 --- a/target/loongarch/insn_trans/trans_fmov.c.inc +++ b/target/loongarch/insn_trans/trans_fmov.c.inc @@ -10,8 +10,11 @@ static const uint32_t fcsr_mask[4] = { static bool trans_fsel(DisasContext *ctx, arg_fsel *a) { TCGv zero = tcg_constant_tl(0); - TCGv cond = tcg_temp_new(); + TCGv cond; + CHECK_FPE; + + cond = tcg_temp_new(); tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca])); tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero, cpu_fpr[a->fj], cpu_fpr[a->fk]); @@ -26,6 +29,8 @@ static bool gen_f2f(DisasContext *ctx, arg_ff *a, TCGv dest = cpu_fpr[a->fd]; TCGv src = cpu_fpr[a->fj]; + CHECK_FPE; + func(dest, src); if (nanbox) { gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); @@ -39,6 +44,8 @@ static bool gen_r2f(DisasContext *ctx, arg_fr *a, { TCGv src = gpr_src(ctx, a->rj, EXT_NONE); + CHECK_FPE; + func(cpu_fpr[a->fd], src); return true; } @@ -48,6 +55,8 @@ static bool gen_f2r(DisasContext *ctx, arg_rf *a, { TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + CHECK_FPE; + func(dest, cpu_fpr[a->fj]); gen_set_gpr(a->rd, dest, EXT_NONE); @@ -59,6 +68,8 @@ static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) uint32_t mask = fcsr_mask[a->fcsrd]; TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE); + CHECK_FPE; + if (mask == UINT32_MAX) { tcg_gen_st32_i64(Rj, cpu_env, offsetof(CPULoongArchState, fcsr0)); } else { @@ -90,6 +101,8 @@ static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) { TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + CHECK_FPE; + tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0)); tcg_gen_andi_i64(dest, dest, fcsr_mask[a->fcsrs]); gen_set_gpr(a->rd, dest, EXT_NONE); @@ -114,8 +127,11 @@ static void gen_movfrh2gr_s(TCGv dest, TCGv src) static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) { - TCGv t0 = tcg_temp_new(); + TCGv t0; + + CHECK_FPE; + t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1); tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); tcg_temp_free(t0); @@ -125,6 +141,8 @@ static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) { + CHECK_FPE; + tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env, offsetof(CPULoongArchState, cf[a->cj & 0x7])); return true; @@ -132,8 +150,11 @@ static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) { - TCGv t0 = tcg_temp_new(); + TCGv t0; + CHECK_FPE; + + t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, gpr_src(ctx, a->rj, EXT_NONE), 0x1); tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); tcg_temp_free(t0); @@ -143,6 +164,8 @@ static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) { + CHECK_FPE; + tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env, offsetof(CPULoongArchState, cf[a->cj & 0x7])); return true; diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc index 9c4dcbfcfb..ff3a6d95ae 100644 --- a/target/loongarch/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/insn_trans/trans_privileged.c.inc @@ -159,7 +159,7 @@ static const CSRInfo csr_info[] = { static bool check_plv(DisasContext *ctx) { - if (ctx->base.tb->flags == MMU_USER_IDX) { + if (ctx->mem_idx == MMU_USER_IDX) { generate_exception(ctx, EXCCODE_IPE); return true; } diff --git a/target/loongarch/iocsr_helper.c b/target/loongarch/iocsr_helper.c index 0e9c537dc7..505853e17b 100644 --- a/target/loongarch/iocsr_helper.c +++ b/target/loongarch/iocsr_helper.c @@ -14,54 +14,57 @@ #include "exec/cpu_ldst.h" #include "tcg/tcg-ldst.h" +#define GET_MEMTXATTRS(cas) \ + ((MemTxAttrs){.requester_id = env_cpu(cas)->cpu_index}) + uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr) { return address_space_ldub(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr) { return address_space_lduw(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr) { return address_space_ldl(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr) { return address_space_ldq(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stb(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stw(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stl(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stq(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c index 610b6d123c..d2f8fb0c60 100644 --- a/target/loongarch/tlb_helper.c +++ b/target/loongarch/tlb_helper.c @@ -229,7 +229,8 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address, switch (tlb_error) { default: case TLBRET_BADADDR: - cs->exception_index = EXCCODE_ADEM; + cs->exception_index = access_type == MMU_INST_FETCH + ? EXCCODE_ADEF : EXCCODE_ADEM; break; case TLBRET_NOMATCH: /* No TLB match for a mapped address */ @@ -643,7 +644,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, CPULoongArchState *env = &cpu->env; hwaddr physical; int prot; - int ret = TLBRET_BADADDR; + int ret; /* Data access */ ret = get_physical_address(env, &physical, &prot, address, diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 6091772349..31462b2b61 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -75,7 +75,11 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, DisasContext *ctx = container_of(dcbase, DisasContext, base); ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; - ctx->mem_idx = ctx->base.tb->flags; + if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) { + ctx->mem_idx = ctx->base.tb->flags & HW_FLAGS_PLV_MASK; + } else { + ctx->mem_idx = MMU_DA_IDX; + } /* Bound the number of insns to execute to those left on the page. */ bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; |