From 4d2b2e766a5a60afdfa85652a328c967c248d47f Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:32 +0200 Subject: [PATCH 01/20] target/tricore: Introduce ISA 1.6.2 feature we also introduce the tc37x CPU that implements that ISA version. Acked-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-2-kbastian@mail.uni-paderborn.de> --- target/tricore/cpu.c | 13 +++++++++++++ target/tricore/cpu.h | 1 + 2 files changed, 14 insertions(+) diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c index 7fa113fed2..f15169bd1b 100644 --- a/target/tricore/cpu.c +++ b/target/tricore/cpu.c @@ -104,6 +104,10 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error **errp) } /* Some features automatically imply others */ + if (tricore_feature(env, TRICORE_FEATURE_162)) { + set_feature(env, TRICORE_FEATURE_161); + } + if (tricore_feature(env, TRICORE_FEATURE_161)) { set_feature(env, TRICORE_FEATURE_16); } @@ -164,6 +168,14 @@ static void tc27x_initfn(Object *obj) set_feature(&cpu->env, TRICORE_FEATURE_161); } +static void tc37x_initfn(Object *obj) +{ + TriCoreCPU *cpu = TRICORE_CPU(obj); + + set_feature(&cpu->env, TRICORE_FEATURE_162); +} + + #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps tricore_sysemu_ops = { @@ -226,6 +238,7 @@ static const TypeInfo tricore_cpu_type_infos[] = { DEFINE_TRICORE_CPU_TYPE("tc1796", tc1796_initfn), DEFINE_TRICORE_CPU_TYPE("tc1797", tc1797_initfn), DEFINE_TRICORE_CPU_TYPE("tc27x", tc27x_initfn), + DEFINE_TRICORE_CPU_TYPE("tc37x", tc37x_initfn), }; DEFINE_TYPES(tricore_cpu_type_infos) diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h index d98a3fb671..041fc0b6e5 100644 --- a/target/tricore/cpu.h +++ b/target/tricore/cpu.h @@ -273,6 +273,7 @@ enum tricore_features { TRICORE_FEATURE_131, TRICORE_FEATURE_16, TRICORE_FEATURE_161, + TRICORE_FEATURE_162, }; static inline int tricore_feature(CPUTriCoreState *env, int feature) From fd6f446a5e34f160cbdc9bb300d326cec0eca6c6 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:33 +0200 Subject: [PATCH 02/20] target/tricore: Add popcnt.w insn reported in https://gitlab.com/qemu-project/qemu/-/issues/1667 Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-3-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 7 +++++++ target/tricore/tricore-opcodes.h | 1 + 2 files changed, 8 insertions(+) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index cd33a1dcdd..26b284bcec 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -6197,6 +6197,13 @@ static void decode_rr_divide(DisasContext *ctx) generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; + case OPC2_32_RR_POPCNT_W: + if (has_feature(ctx, TRICORE_FEATURE_162)) { + tcg_gen_ctpop_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]); + } else { + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); + } + break; case OPC2_32_RR_DIV: if (has_feature(ctx, TRICORE_FEATURE_16)) { GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index f7135f183d..59aa39a7a5 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -1133,6 +1133,7 @@ enum { OPC2_32_RR_PARITY = 0x02, OPC2_32_RR_UNPACK = 0x08, OPC2_32_RR_CRC32 = 0x03, + OPC2_32_RR_POPCNT_W = 0x22, /* 1.6.2 only */ OPC2_32_RR_DIV = 0x20, OPC2_32_RR_DIV_U = 0x21, OPC2_32_RR_MUL_F = 0x04, From 73f874d9fe67bc0395d629d4d1ce083f61605ba5 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:34 +0200 Subject: [PATCH 03/20] target/tricore: Add LHA insn reported in https://gitlab.com/qemu-project/qemu/-/issues/1667 Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-4-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 14 ++++++++++++-- target/tricore/tricore-opcodes.h | 9 ++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 26b284bcec..898557d22a 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -7931,7 +7931,7 @@ static void decode_sys_interrupts(DisasContext *ctx) static void decode_32Bit_opc(DisasContext *ctx) { - int op1; + int op1, op2; int32_t r1, r2, r3; int32_t address, const16; int8_t b, const4; @@ -7982,9 +7982,19 @@ static void decode_32Bit_opc(DisasContext *ctx) tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW); tcg_gen_shli_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 16); break; - case OPC1_32_ABS_LEA: + case OPCM_32_ABS_LEA_LHA: address = MASK_OP_ABS_OFF18(ctx->opcode); r1 = MASK_OP_ABS_S1D(ctx->opcode); + + if (has_feature(ctx, TRICORE_FEATURE_162)) { + op2 = MASK_OP_ABS_OP2(ctx->opcode); + if (op2 == OPC2_32_ABS_LHA) { + tcg_gen_movi_tl(cpu_gpr_a[r1], address << 14); + break; + } + /* otherwise translate regular LEA */ + } + tcg_gen_movi_tl(cpu_gpr_a[r1], EA_ABS_FORMAT(address)); break; /* ABSB-format */ diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index 59aa39a7a5..9fab4bd75c 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -430,7 +430,7 @@ enum { OPCM_32_ABS_STOREB_H = 0x25, OPC1_32_ABS_STOREQ = 0x65, OPC1_32_ABS_LD_Q = 0x45, - OPC1_32_ABS_LEA = 0xc5, + OPCM_32_ABS_LEA_LHA = 0xc5, /* ABSB Format */ OPC1_32_ABSB_ST_T = 0xd5, /* B Format */ @@ -592,6 +592,13 @@ enum { OPC2_32_ABS_ST_B = 0x00, OPC2_32_ABS_ST_H = 0x02, }; + +/* OPCM_32_ABS_LEA_LHA */ +enum { + OPC2_32_ABS_LEA = 0x00, + OPC2_32_ABS_LHA = 0x01, +}; + /* * Bit Format */ From dc0b4368be92d85fc9fb2d48922149759c1f7804 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:35 +0200 Subject: [PATCH 04/20] target/tricore: Add crc32l.w insn reported in https://gitlab.com/qemu-project/qemu/-/issues/1667 Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-5-kbastian@mail.uni-paderborn.de> --- target/tricore/helper.h | 3 ++- target/tricore/op_helper.c | 10 +++++++++- target/tricore/translate.c | 12 ++++++++++-- target/tricore/tricore-opcodes.h | 3 ++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/target/tricore/helper.h b/target/tricore/helper.h index b64780c37d..24da5e97c0 100644 --- a/target/tricore/helper.h +++ b/target/tricore/helper.h @@ -131,7 +131,8 @@ DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32) DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32) DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32) /* crc32 */ -DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32) +DEF_HELPER_FLAGS_2(crc32_be, TCG_CALL_NO_RWG_SE, i32, i32, i32) +DEF_HELPER_FLAGS_2(crc32_le, TCG_CALL_NO_RWG_SE, i32, i32, i32) /* CSA */ DEF_HELPER_2(call, void, env, i32) DEF_HELPER_1(ret, void, env) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 54f54811d9..8ce404cb93 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -2284,7 +2284,7 @@ uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, return (result1 & 0xffff0000) | (result0 >> 16); } -uint32_t helper_crc32(uint32_t arg0, uint32_t arg1) +uint32_t helper_crc32_be(uint32_t arg0, uint32_t arg1) { uint8_t buf[4]; stl_be_p(buf, arg0); @@ -2292,6 +2292,14 @@ uint32_t helper_crc32(uint32_t arg0, uint32_t arg1) return crc32(arg1, buf, 4); } +uint32_t helper_crc32_le(uint32_t arg0, uint32_t arg1) +{ + uint8_t buf[4]; + stl_le_p(buf, arg0); + + return crc32(arg1, buf, 4); +} + /* context save area (CSA) related helpers */ static int cdc_increment(target_ulong *psw) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 898557d22a..250de80de5 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -6190,13 +6190,21 @@ static void decode_rr_divide(DisasContext *ctx) CHECK_REG_PAIR(r3); gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]); break; - case OPC2_32_RR_CRC32: + case OPC2_32_RR_CRC32: /* CRC32B.W in 1.6.2 */ if (has_feature(ctx, TRICORE_FEATURE_161)) { - gen_helper_crc32(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); + gen_helper_crc32_be(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } break; + case OPC2_32_RR_CRC32L_W: + if (has_feature(ctx, TRICORE_FEATURE_162)) { + gen_helper_crc32_le(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); + } else { + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); + } + break; + case OPC2_32_RR_POPCNT_W: if (has_feature(ctx, TRICORE_FEATURE_162)) { tcg_gen_ctpop_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]); diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index 9fab4bd75c..be07f82ec1 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -1139,7 +1139,8 @@ enum { OPC2_32_RR_DVINIT_U = 0x0a, OPC2_32_RR_PARITY = 0x02, OPC2_32_RR_UNPACK = 0x08, - OPC2_32_RR_CRC32 = 0x03, + OPC2_32_RR_CRC32 = 0x03, /* CRC32B.W in 1.6.2 */ + OPC2_32_RR_CRC32L_W = 0x07, /* 1.6.2 only */ OPC2_32_RR_POPCNT_W = 0x22, /* 1.6.2 only */ OPC2_32_RR_DIV = 0x20, OPC2_32_RR_DIV_U = 0x21, From 0eaafe33d03447f36ff152010836d501ba68c710 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:36 +0200 Subject: [PATCH 05/20] target/tricore: Add crc32.b insn reported in https://gitlab.com/qemu-project/qemu/-/issues/1667 Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-6-kbastian@mail.uni-paderborn.de> --- target/tricore/helper.h | 1 + target/tricore/op_helper.c | 8 ++++++++ target/tricore/translate.c | 7 +++++++ target/tricore/tricore-opcodes.h | 1 + 4 files changed, 17 insertions(+) diff --git a/target/tricore/helper.h b/target/tricore/helper.h index 24da5e97c0..a10576e09e 100644 --- a/target/tricore/helper.h +++ b/target/tricore/helper.h @@ -131,6 +131,7 @@ DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32) DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32) DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32) /* crc32 */ +DEF_HELPER_FLAGS_2(crc32b, TCG_CALL_NO_RWG_SE, i32, i32, i32) DEF_HELPER_FLAGS_2(crc32_be, TCG_CALL_NO_RWG_SE, i32, i32, i32) DEF_HELPER_FLAGS_2(crc32_le, TCG_CALL_NO_RWG_SE, i32, i32, i32) /* CSA */ diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 8ce404cb93..b6ef1462e4 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -2284,6 +2284,14 @@ uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, return (result1 & 0xffff0000) | (result0 >> 16); } +uint32_t helper_crc32b(uint32_t arg0, uint32_t arg1) +{ + uint8_t buf[1] = { arg0 & 0xff }; + + return crc32(arg1, buf, 1); +} + + uint32_t helper_crc32_be(uint32_t arg0, uint32_t arg1) { uint8_t buf[4]; diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 250de80de5..85526ef4db 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -6190,6 +6190,13 @@ static void decode_rr_divide(DisasContext *ctx) CHECK_REG_PAIR(r3); gen_unpack(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1]); break; + case OPC2_32_RR_CRC32_B: + if (has_feature(ctx, TRICORE_FEATURE_162)) { + gen_helper_crc32b(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); + } else { + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); + } + break; case OPC2_32_RR_CRC32: /* CRC32B.W in 1.6.2 */ if (has_feature(ctx, TRICORE_FEATURE_161)) { gen_helper_crc32_be(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]); diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index be07f82ec1..27f80e1702 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -1140,6 +1140,7 @@ enum { OPC2_32_RR_PARITY = 0x02, OPC2_32_RR_UNPACK = 0x08, OPC2_32_RR_CRC32 = 0x03, /* CRC32B.W in 1.6.2 */ + OPC2_32_RR_CRC32_B = 0x06, /* 1.6.2 only */ OPC2_32_RR_CRC32L_W = 0x07, /* 1.6.2 only */ OPC2_32_RR_POPCNT_W = 0x22, /* 1.6.2 only */ OPC2_32_RR_DIV = 0x20, From 4e3377bb5abe8914eec0650730536d5d48e22008 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:37 +0200 Subject: [PATCH 06/20] target/tricore: Add shuffle insn this is based on code by volumit (https://github.com/volumit/qemu/). Reported in https://gitlab.com/qemu-project/qemu/-/issues/1667 and https://gitlab.com/qemu-project/qemu/-/issues/1452. Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-7-kbastian@mail.uni-paderborn.de> --- target/tricore/helper.h | 1 + target/tricore/op_helper.c | 36 ++++++++++++++++++++++++++++++++ target/tricore/translate.c | 8 +++++++ target/tricore/tricore-opcodes.h | 1 + 4 files changed, 46 insertions(+) diff --git a/target/tricore/helper.h b/target/tricore/helper.h index a10576e09e..31d71eac7a 100644 --- a/target/tricore/helper.h +++ b/target/tricore/helper.h @@ -134,6 +134,7 @@ DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32) DEF_HELPER_FLAGS_2(crc32b, TCG_CALL_NO_RWG_SE, i32, i32, i32) DEF_HELPER_FLAGS_2(crc32_be, TCG_CALL_NO_RWG_SE, i32, i32, i32) DEF_HELPER_FLAGS_2(crc32_le, TCG_CALL_NO_RWG_SE, i32, i32, i32) +DEF_HELPER_FLAGS_2(shuffle, TCG_CALL_NO_RWG_SE, i32, i32, i32) /* CSA */ DEF_HELPER_2(call, void, env, i32) DEF_HELPER_1(ret, void, env) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index b6ef1462e4..026e15f3e0 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -2308,6 +2308,42 @@ uint32_t helper_crc32_le(uint32_t arg0, uint32_t arg1) return crc32(arg1, buf, 4); } +uint32_t helper_shuffle(uint32_t arg0, uint32_t arg1) +{ + uint32_t resb; + uint32_t byte_select; + uint32_t res = 0; + + byte_select = arg1 & 0x3; + resb = extract32(arg0, byte_select * 8, 8); + res |= resb << 0; + + byte_select = (arg1 >> 2) & 0x3; + resb = extract32(arg0, byte_select * 8, 8); + res |= resb << 8; + + byte_select = (arg1 >> 4) & 0x3; + resb = extract32(arg0, byte_select * 8, 8); + res |= resb << 16; + + byte_select = (arg1 >> 6) & 0x3; + resb = extract32(arg0, byte_select * 8, 8); + res |= resb << 24; + + if (arg1 & 0x100) { + /* Assign the correct nibble position. */ + res = ((res & 0xf0f0f0f0) >> 4) + | ((res & 0x0f0f0f0f) << 4); + /* Assign the correct bit position. */ + res = ((res & 0x88888888) >> 3) + | ((res & 0x44444444) >> 1) + | ((res & 0x22222222) << 1) + | ((res & 0x11111111) << 3); + } + + return res; +} + /* context save area (CSA) related helpers */ static int cdc_increment(target_ulong *psw) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 85526ef4db..a4c60e8ae2 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -5011,6 +5011,14 @@ static void decode_rc_logical_shift(DisasContext *ctx) case OPC2_32_RC_XOR: tcg_gen_xori_tl(cpu_gpr_d[r2], cpu_gpr_d[r1], const9); break; + case OPC2_32_RC_SHUFFLE: + if (has_feature(ctx, TRICORE_FEATURE_162)) { + TCGv temp = tcg_constant_i32(const9); + gen_helper_shuffle(cpu_gpr_d[r2], cpu_gpr_d[r1], temp); + } else { + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); + } + break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index 27f80e1702..af63926731 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -885,6 +885,7 @@ enum { OPC2_32_RC_SHAS = 0x02, OPC2_32_RC_XNOR = 0x0d, OPC2_32_RC_XOR = 0x0c, + OPC2_32_RC_SHUFFLE = 0x07, /* v1.6.2 only */ }; /* OPCM_32_RC_ACCUMULATOR */ enum { From 3b5d136db6484f2b625fb98cce4fd8b7ac26e348 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:38 +0200 Subject: [PATCH 07/20] target/tricore: Implement SYCSCALL insn Reviewed-by: Richard Henderson Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1452 Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-8-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index a4c60e8ae2..f01000efd4 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -5236,7 +5236,7 @@ static void decode_rc_serviceroutine(DisasContext *ctx) gen_helper_1arg(bisr, const9); break; case OPC2_32_RC_SYSCALL: - /* TODO: Add exception generation */ + generate_trap(ctx, TRAPC_SYSCALL, const9 & 0xff); break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); From 0b9f9b63c2d1e26cfe4e593f384898837c7c941f Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 14 Jun 2023 12:00:39 +0200 Subject: [PATCH 08/20] target/tricore: Add DISABLE insn variant this variant saves the 'IE' bit to a 'd' register. The 'IE' bitfield changed from ISA version 1.6.1, so we add icr_ie_offset to DisasContext as with the other DISABLE insn. Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230614100039.1337971-9-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 11 ++++++++++- target/tricore/tricore-opcodes.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index f01000efd4..6712d98f6e 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -75,7 +75,7 @@ typedef struct DisasContext { int mem_idx; uint32_t hflags, saved_hflags; uint64_t features; - uint32_t icr_ie_mask; + uint32_t icr_ie_mask, icr_ie_offset; } DisasContext; static int has_feature(DisasContext *ctx, int feature) @@ -7883,6 +7883,13 @@ static void decode_sys_interrupts(DisasContext *ctx) case OPC2_32_SYS_DISABLE: tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask); break; + case OPC2_32_SYS_DISABLE_D: + if (has_feature(ctx, TRICORE_FEATURE_16)) { + tcg_gen_extract_tl(cpu_gpr_d[r1], cpu_ICR, ctx->icr_ie_offset, 1); + tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask); + } else { + generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); + } case OPC2_32_SYS_DSYNC: break; case OPC2_32_SYS_ENABLE: @@ -8302,8 +8309,10 @@ static void tricore_tr_init_disas_context(DisasContextBase *dcbase, ctx->features = env->features; if (has_feature(ctx, TRICORE_FEATURE_161)) { ctx->icr_ie_mask = R_ICR_IE_161_MASK; + ctx->icr_ie_offset = R_ICR_IE_161_SHIFT; } else { ctx->icr_ie_mask = R_ICR_IE_13_MASK; + ctx->icr_ie_offset = R_ICR_IE_13_SHIFT; } } diff --git a/target/tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index af63926731..bc62b73173 100644 --- a/target/tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h @@ -1467,6 +1467,7 @@ enum { enum { OPC2_32_SYS_DEBUG = 0x04, OPC2_32_SYS_DISABLE = 0x0d, + OPC2_32_SYS_DISABLE_D = 0x0f, /* 1.6 up */ OPC2_32_SYS_DSYNC = 0x12, OPC2_32_SYS_ENABLE = 0x0c, OPC2_32_SYS_ISYNC = 0x13, From d34b092cab606a47a0d76edde45aab7100bb2435 Mon Sep 17 00:00:00 2001 From: Siqi Chen Date: Mon, 12 Jun 2023 13:32:42 +0200 Subject: [PATCH 09/20] target/tricore: Fix out-of-bounds index in imask instruction When translating "imask" instruction of Tricore architecture, QEMU did not check whether the register index was out of bounds, resulting in a global-buffer-overflow. Reviewed-by: Bastian Koppelmann Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1698 Reported-by: Siqi Chen Signed-off-by: Siqi Chen Signed-off-by: Bastian Koppelmann Message-Id: <20230612065633.149152-1-coc.cyqh@gmail.com> Message-Id: <20230612113245.56667-2-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 6712d98f6e..74faad4794 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -5339,6 +5339,7 @@ static void decode_rcrw_insert(DisasContext *ctx) switch (op2) { case OPC2_32_RCRW_IMASK: + CHECK_REG_PAIR(r4); tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f); tcg_gen_movi_tl(temp2, (1 << width) - 1); tcg_gen_shl_tl(cpu_gpr_d[r4 + 1], temp2, temp); From 5434557ffc5b46f178ccf325517db2b1f5e2c037 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Mon, 12 Jun 2023 13:32:43 +0200 Subject: [PATCH 10/20] target/tricore: Correctly fix saving PSW.CDE to CSA on call we don't want to save PSW.CDC to the CSA, but PSW.CDE must be saved. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1699 Signed-off-by: Bastian Koppelmann Message-Id: <20230612113245.56667-3-kbastian@mail.uni-paderborn.de> --- target/tricore/op_helper.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 026e15f3e0..9a7a26b171 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -2499,7 +2499,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc) } /* PSW.CDE = 1;*/ psw |= MASK_PSW_CDE; - psw_write(env, psw); + /* + * we need to save PSW.CDE and not PSW.CDC into the CSAs. psw already + * contains the CDC from cdc_increment(), so we cannot call psw_write() + * here. + */ + env->PSW |= MASK_PSW_CDE; /* tmp_FCX = FCX; */ tmp_FCX = env->FCX; From 6991777ec4b2a344d47bddec62744bedd9883d78 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Mon, 12 Jun 2023 13:32:44 +0200 Subject: [PATCH 11/20] target/tricore: Add CHECK_REG_PAIR() for insn accessing 64 bit regs some insns were not checking if an even index was used to access a 64 bit register. In the worst case that could lead to a buffer overflow as reported in https://gitlab.com/qemu-project/qemu/-/issues/1698. Reported-by: Siqi Chen Signed-off-by: Bastian Koppelmann Message-Id: <20230612113245.56667-4-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 74faad4794..d1b319e374 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -309,6 +309,7 @@ static void gen_cmpswap(DisasContext *ctx, int reg, TCGv ea) { TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); + CHECK_REG_PAIR(reg); tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL); tcg_gen_movcond_tl(TCG_COND_EQ, temp2, cpu_gpr_d[reg+1], temp, cpu_gpr_d[reg], temp); @@ -321,7 +322,7 @@ static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea) TCGv temp = tcg_temp_new(); TCGv temp2 = tcg_temp_new(); TCGv temp3 = tcg_temp_new(); - + CHECK_REG_PAIR(reg); tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL); tcg_gen_and_tl(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg+1]); tcg_gen_andc_tl(temp3, temp, cpu_gpr_d[reg+1]); @@ -3219,6 +3220,7 @@ static void decode_src_opc(DisasContext *ctx, int op1) break; case OPC1_16_SRC_MOV_E: if (has_feature(ctx, TRICORE_FEATURE_16)) { + CHECK_REG_PAIR(r1); tcg_gen_movi_tl(cpu_gpr_d[r1], const4); tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31); } else { @@ -6180,6 +6182,7 @@ static void decode_rr_divide(DisasContext *ctx) tcg_gen_sari_tl(cpu_gpr_d[r3+1], cpu_gpr_d[r1], 31); break; case OPC2_32_RR_DVINIT_U: + CHECK_REG_PAIR(r3); /* overflow = (D[b] == 0) */ tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r2], 0); tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31); @@ -6230,6 +6233,7 @@ static void decode_rr_divide(DisasContext *ctx) break; case OPC2_32_RR_DIV: if (has_feature(ctx, TRICORE_FEATURE_16)) { + CHECK_REG_PAIR(r3); GEN_HELPER_RR(divide, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { @@ -6238,6 +6242,7 @@ static void decode_rr_divide(DisasContext *ctx) break; case OPC2_32_RR_DIV_U: if (has_feature(ctx, TRICORE_FEATURE_16)) { + CHECK_REG_PAIR(r3); GEN_HELPER_RR(divide_u, cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1], cpu_gpr_d[r2]); } else { @@ -6764,6 +6769,8 @@ static void decode_rrr2_msub(DisasContext *ctx) cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; case OPC2_32_RRR2_MSUB_U_64: + CHECK_REG_PAIR(r4); + CHECK_REG_PAIR(r3); gen_msubu64_d(cpu_gpr_d[r4], cpu_gpr_d[r4+1], cpu_gpr_d[r1], cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r2]); break; @@ -7847,7 +7854,7 @@ static void decode_rrrw_extract_insert(DisasContext *ctx) break; case OPC2_32_RRRW_IMASK: temp2 = tcg_temp_new(); - + CHECK_REG_PAIR(r4); tcg_gen_andi_tl(temp, cpu_gpr_d[r3], 0x1f); tcg_gen_movi_tl(temp2, (1 << width) - 1); tcg_gen_shl_tl(temp2, temp2, temp); From 82736612e75b84f51d8f3529cb35fa3835de5741 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Mon, 12 Jun 2023 13:32:45 +0200 Subject: [PATCH 12/20] target/tricore: Fix helper_ret() not correctly restoring PSW We are always taking the TRICORE_FEATURE_13 branch as every CPU has TRICORE_FEATURE_13. For CPUs with ISA > 1.3 we have to take the else branch. We fix this by inverting the condition. We check for TRICORE_FEATURE_131, which every CPU except TRICORE_FEATURE_13 CPUs have. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1700 Signed-off-by: Bastian Koppelmann Message-Id: <20230612113245.56667-5-kbastian@mail.uni-paderborn.de> --- target/tricore/op_helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index 9a7a26b171..821a4b67cb 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -2584,12 +2584,12 @@ void helper_ret(CPUTriCoreState *env) /* PCXI = new_PCXI; */ env->PCXI = new_PCXI; - if (tricore_feature(env, TRICORE_FEATURE_13)) { - /* PSW = new_PSW */ - psw_write(env, new_PSW); - } else { + if (tricore_feature(env, TRICORE_FEATURE_131)) { /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); + } else { /* TRICORE_FEATURE_13 only */ + /* PSW = new_PSW */ + psw_write(env, new_PSW); } } From 8da70480f59b4fd423918ac756747c1e35f6f53a Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:22:55 +0200 Subject: [PATCH 13/20] target/tricore: Fix RR_JLI clobbering reg A[11] if A[r1] == A[11], then we would overwrite the destination address of the jump with the return address. Reported-by: Richard Henderson Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-2-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index d1b319e374..cca52c75b2 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -6064,8 +6064,8 @@ static void decode_rr_idirect(DisasContext *ctx) tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); break; case OPC2_32_RR_JLI: - tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], ~0x1); + tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn); break; case OPC2_32_RR_CALLI: gen_helper_1arg(call, ctx->pc_succ_insn); From 1706e04f6e807431b460b4109ab65bb469adc53a Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:22:56 +0200 Subject: [PATCH 14/20] target/tricore: Introduce DISAS_TARGET_EXIT this replaces all calls to tcg_gen_exit_tb() and moves them to tricore_tb_stop(). Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-3-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index cca52c75b2..ef74e9f234 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -37,6 +37,7 @@ #include "exec/helper-info.c.inc" #undef HELPER_H +#define DISAS_EXIT DISAS_TARGET_0 /* * TCG registers @@ -2836,6 +2837,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) gen_save_pc(dest); tcg_gen_lookup_and_goto_ptr(); } + ctx->base.is_jmp = DISAS_NORETURN; } static void generate_trap(DisasContext *ctx, int class, int tin) @@ -2896,8 +2898,7 @@ static void gen_fret(DisasContext *ctx) tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL); tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4); tcg_gen_mov_tl(cpu_PC, temp); - tcg_gen_exit_tb(NULL, 0); - ctx->base.is_jmp = DISAS_NORETURN; + ctx->base.is_jmp = DISAS_EXIT; } static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, @@ -2996,12 +2997,12 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, /* SR-format jumps */ case OPC1_16_SR_JI: tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe); - tcg_gen_exit_tb(NULL, 0); + ctx->base.is_jmp = DISAS_EXIT; break; case OPC2_32_SYS_RET: case OPC2_16_SR_RET: gen_helper_ret(cpu_env); - tcg_gen_exit_tb(NULL, 0); + ctx->base.is_jmp = DISAS_EXIT; break; /* B-format */ case OPC1_32_B_CALLA: @@ -3153,7 +3154,6 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1, default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } - ctx->base.is_jmp = DISAS_NORETURN; } @@ -3495,8 +3495,7 @@ static void decode_sr_system(DisasContext *ctx) break; case OPC2_16_SR_RFE: gen_helper_rfe(cpu_env); - tcg_gen_exit_tb(NULL, 0); - ctx->base.is_jmp = DISAS_NORETURN; + ctx->base.is_jmp = DISAS_EXIT; break; case OPC2_16_SR_DEBUG: /* raise EXCP_DEBUG */ @@ -6078,8 +6077,7 @@ static void decode_rr_idirect(DisasContext *ctx) default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } - tcg_gen_exit_tb(NULL, 0); - ctx->base.is_jmp = DISAS_NORETURN; + ctx->base.is_jmp = DISAS_EXIT; } static void decode_rr_divide(DisasContext *ctx) @@ -7915,8 +7913,7 @@ static void decode_sys_interrupts(DisasContext *ctx) break; case OPC2_32_SYS_RFE: gen_helper_rfe(cpu_env); - tcg_gen_exit_tb(NULL, 0); - ctx->base.is_jmp = DISAS_NORETURN; + ctx->base.is_jmp = DISAS_EXIT; break; case OPC2_32_SYS_RFM: if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { @@ -7928,8 +7925,7 @@ static void decode_sys_interrupts(DisasContext *ctx) tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 1, l1); gen_helper_rfm(cpu_env); gen_set_label(l1); - tcg_gen_exit_tb(NULL, 0); - ctx->base.is_jmp = DISAS_NORETURN; + ctx->base.is_jmp = DISAS_EXIT; } else { /* generate privilege trap */ } @@ -8391,6 +8387,9 @@ static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_TOO_MANY: gen_goto_tb(ctx, 0, ctx->base.pc_next); break; + case DISAS_EXIT: + tcg_gen_exit_tb(NULL, 0); + break; case DISAS_NORETURN: break; default: From 2dbd73bf17f4c6bf016709d995ea46477cb6133c Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:22:57 +0200 Subject: [PATCH 15/20] target/tricore: ENABLE exit to main-loop so we can recognize exceptions after re-enabling interrupts. Reviewed-by: Richard Henderson Reported-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-4-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index ef74e9f234..98e2767d21 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -38,6 +38,7 @@ #undef HELPER_H #define DISAS_EXIT DISAS_TARGET_0 +#define DISAS_EXIT_UPDATE DISAS_TARGET_1 /* * TCG registers @@ -7900,6 +7901,7 @@ static void decode_sys_interrupts(DisasContext *ctx) break; case OPC2_32_SYS_ENABLE: tcg_gen_ori_tl(cpu_ICR, cpu_ICR, ctx->icr_ie_mask); + ctx->base.is_jmp = DISAS_EXIT_UPDATE; break; case OPC2_32_SYS_ISYNC: break; @@ -8387,6 +8389,9 @@ static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_TOO_MANY: gen_goto_tb(ctx, 0, ctx->base.pc_next); break; + case DISAS_EXIT_UPDATE: + gen_save_pc(ctx->base.pc_next); + /* fall through */ case DISAS_EXIT: tcg_gen_exit_tb(NULL, 0); break; From d8f466af7cad3a997c3f9d0396f2a63826fee239 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:22:58 +0200 Subject: [PATCH 16/20] target/tricore: Indirect jump insns use tcg_gen_lookup_and_goto_ptr() Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-5-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 98e2767d21..fb6f0caa24 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -39,6 +39,7 @@ #define DISAS_EXIT DISAS_TARGET_0 #define DISAS_EXIT_UPDATE DISAS_TARGET_1 +#define DISAS_JUMP DISAS_TARGET_2 /* * TCG registers @@ -6077,8 +6078,9 @@ static void decode_rr_idirect(DisasContext *ctx) break; default: generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); + return; } - ctx->base.is_jmp = DISAS_EXIT; + ctx->base.is_jmp = DISAS_JUMP; } static void decode_rr_divide(DisasContext *ctx) @@ -8395,6 +8397,9 @@ static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_EXIT: tcg_gen_exit_tb(NULL, 0); break; + case DISAS_JUMP: + tcg_gen_lookup_and_goto_ptr(); + break; case DISAS_NORETURN: break; default: From 878d1b6a90173d61859f1b5083266d2bbc3db17c Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:22:59 +0200 Subject: [PATCH 17/20] target/tricore: Introduce priv tb flag Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-6-kbastian@mail.uni-paderborn.de> --- target/tricore/cpu.h | 17 ++++++++++++----- target/tricore/translate.c | 14 ++++++++------ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h index 041fc0b6e5..257fcf3cee 100644 --- a/target/tricore/cpu.h +++ b/target/tricore/cpu.h @@ -263,10 +263,11 @@ void icr_set_ie(CPUTriCoreState *env, uint32_t val); #define MASK_DBGSR_PEVT 0x40 #define MASK_DBGSR_EVTSRC 0x1f00 -#define TRICORE_HFLAG_KUU 0x3 -#define TRICORE_HFLAG_UM0 0x00002 /* user mode-0 flag */ -#define TRICORE_HFLAG_UM1 0x00001 /* user mode-1 flag */ -#define TRICORE_HFLAG_SM 0x00000 /* kernel mode flag */ +enum tricore_priv_levels { + TRICORE_PRIV_UM0 = 0x0, /* user mode-0 flag */ + TRICORE_PRIV_UM1 = 0x1, /* user mode-1 flag */ + TRICORE_PRIV_SM = 0x2, /* kernel mode flag */ +}; enum tricore_features { TRICORE_FEATURE_13, @@ -378,15 +379,21 @@ static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch) #include "exec/cpu-all.h" +FIELD(TB_FLAGS, PRIV, 0, 2) + void cpu_state_reset(CPUTriCoreState *s); void tricore_tcg_init(void); static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *flags) { + uint32_t new_flags = 0; *pc = env->PC; *cs_base = 0; - *flags = 0; + + new_flags |= FIELD_DP32(new_flags, TB_FLAGS, PRIV, + extract32(env->PSW, 10, 2)); + *flags = new_flags; } #define TRICORE_CPU_TYPE_SUFFIX "-" TYPE_TRICORE_CPU diff --git a/target/tricore/translate.c b/target/tricore/translate.c index fb6f0caa24..6932a54663 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -76,7 +76,7 @@ typedef struct DisasContext { uint32_t opcode; /* Routine used to access memory */ int mem_idx; - uint32_t hflags, saved_hflags; + int priv; uint64_t features; uint32_t icr_ie_mask, icr_ie_offset; } DisasContext; @@ -378,7 +378,7 @@ static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset) static inline void gen_mtcr(DisasContext *ctx, TCGv r1, int32_t offset) { - if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { + if (ctx->priv == TRICORE_PRIV_SM) { /* since we're caching PSW make this a special case */ if (offset == 0xfe04) { gen_helper_psw_write(cpu_env, r1); @@ -7920,7 +7920,7 @@ static void decode_sys_interrupts(DisasContext *ctx) ctx->base.is_jmp = DISAS_EXIT; break; case OPC2_32_SYS_RFM: - if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) { + if (ctx->priv == TRICORE_PRIV_SM) { tmp = tcg_temp_new(); l1 = gen_new_label(); @@ -7942,8 +7942,7 @@ static void decode_sys_interrupts(DisasContext *ctx) break; case OPC2_32_SYS_RESTORE: if (has_feature(ctx, TRICORE_FEATURE_16)) { - if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM || - (ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_UM1) { + if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) { tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1); } /* else raise privilege trap */ } else { @@ -8313,7 +8312,10 @@ static void tricore_tr_init_disas_context(DisasContextBase *dcbase, DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUTriCoreState *env = cs->env_ptr; ctx->mem_idx = cpu_mmu_index(env, false); - ctx->hflags = (uint32_t)ctx->base.tb->flags; + + uint32_t tb_flags = (uint32_t)ctx->base.tb->flags; + ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV); + ctx->features = env->features; if (has_feature(ctx, TRICORE_FEATURE_161)) { ctx->icr_ie_mask = R_ICR_IE_161_MASK; From 57b9c589b621b40f3a81662ad1aa960ab6a60497 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:23:00 +0200 Subject: [PATCH 18/20] target/tricore: Implement privilege level for all insns Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-7-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 43 +++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 6932a54663..82b61e912e 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -388,7 +388,7 @@ static inline void gen_mtcr(DisasContext *ctx, TCGv r1, } } } else { - /* generate privilege trap */ + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); } } @@ -3375,7 +3375,11 @@ static void decode_sc_opc(DisasContext *ctx, int op1) tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16); break; case OPC1_16_SC_BISR: - gen_helper_1arg(bisr, const16 & 0xff); + if (ctx->priv == TRICORE_PRIV_SM) { + gen_helper_1arg(bisr, const16 & 0xff); + } else { + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); + } break; case OPC1_16_SC_LD_A: gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL); @@ -5236,7 +5240,11 @@ static void decode_rc_serviceroutine(DisasContext *ctx) switch (op2) { case OPC2_32_RC_BISR: - gen_helper_1arg(bisr, const9); + if (ctx->priv == TRICORE_PRIV_SM) { + gen_helper_1arg(bisr, const9); + } else { + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); + } break; case OPC2_32_RC_SYSCALL: generate_trap(ctx, TRAPC_SYSCALL, const9 & 0xff); @@ -7890,20 +7898,33 @@ static void decode_sys_interrupts(DisasContext *ctx) /* raise EXCP_DEBUG */ break; case OPC2_32_SYS_DISABLE: - tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask); + if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) { + tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask); + } else { + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); + } break; case OPC2_32_SYS_DISABLE_D: if (has_feature(ctx, TRICORE_FEATURE_16)) { - tcg_gen_extract_tl(cpu_gpr_d[r1], cpu_ICR, ctx->icr_ie_offset, 1); - tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask); + if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) { + tcg_gen_extract_tl(cpu_gpr_d[r1], cpu_ICR, + ctx->icr_ie_offset, 1); + tcg_gen_andi_tl(cpu_ICR, cpu_ICR, ~ctx->icr_ie_mask); + } else { + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); + } } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } case OPC2_32_SYS_DSYNC: break; case OPC2_32_SYS_ENABLE: - tcg_gen_ori_tl(cpu_ICR, cpu_ICR, ctx->icr_ie_mask); - ctx->base.is_jmp = DISAS_EXIT_UPDATE; + if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) { + tcg_gen_ori_tl(cpu_ICR, cpu_ICR, ctx->icr_ie_mask); + ctx->base.is_jmp = DISAS_EXIT_UPDATE; + } else { + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); + } break; case OPC2_32_SYS_ISYNC: break; @@ -7931,7 +7952,7 @@ static void decode_sys_interrupts(DisasContext *ctx) gen_set_label(l1); ctx->base.is_jmp = DISAS_EXIT; } else { - /* generate privilege trap */ + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); } break; case OPC2_32_SYS_RSLCX: @@ -7944,7 +7965,9 @@ static void decode_sys_interrupts(DisasContext *ctx) if (has_feature(ctx, TRICORE_FEATURE_16)) { if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) { tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1); - } /* else raise privilege trap */ + } else { + generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); + } } else { generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC); } From 19a18edd8860064d3dbe71bc5315347bcfeb4c24 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:23:01 +0200 Subject: [PATCH 19/20] target/tricore: Honour privilege changes on PSW write the CPU can change the privilege level by writing the corresponding bits in PSW. If this happens all instructions after this 'mtcr' in the TB are translated with the wrong privilege level. So we have to exit to the cpu_loop() and start translating again with the new privilege level. Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-8-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 82b61e912e..9e408f44ec 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -334,7 +334,6 @@ static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea) tcg_gen_mov_tl(cpu_gpr_d[reg], temp); } - /* We generate loads and store to core special function register (csfr) through the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3 makros R, A and E, which allow read-only, all and endinit protected access. @@ -382,6 +381,7 @@ static inline void gen_mtcr(DisasContext *ctx, TCGv r1, /* since we're caching PSW make this a special case */ if (offset == 0xfe04) { gen_helper_psw_write(cpu_env, r1); + ctx->base.is_jmp = DISAS_EXIT_UPDATE; } else { switch (offset) { #include "csfr.h.inc" From a9c37abdff65a07d0191123a21d318c4d8cc7f33 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 21 Jun 2023 16:23:02 +0200 Subject: [PATCH 20/20] target/tricore: Fix ICR.IE offset in RESTORE insn from ISA v1.6.1 onwards the bit position of ICR.IE changed. ctx->icr_ie_offset contains the correct value for the ISA version used by the vCPU. We also need to exit this tb here, as we might have enabled interrupts. Reviewed-by: Richard Henderson Signed-off-by: Bastian Koppelmann Message-Id: <20230621142302.1648383-9-kbastian@mail.uni-paderborn.de> --- target/tricore/translate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 9e408f44ec..2f32463d4d 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -7964,7 +7964,9 @@ static void decode_sys_interrupts(DisasContext *ctx) case OPC2_32_SYS_RESTORE: if (has_feature(ctx, TRICORE_FEATURE_16)) { if (ctx->priv == TRICORE_PRIV_SM || ctx->priv == TRICORE_PRIV_UM1) { - tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], 8, 1); + tcg_gen_deposit_tl(cpu_ICR, cpu_ICR, cpu_gpr_d[r1], + ctx->icr_ie_offset, 1); + ctx->base.is_jmp = DISAS_EXIT_UPDATE; } else { generate_trap(ctx, TRAPC_PROT, TIN1_PRIV); }