1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | The following changes since commit 946e9bccf12f2bcc3ca471b820738fb22d14fc80: |
---|---|---|---|
2 | 2 | ||
3 | The following changes since commit c5fbdd60cf1fb52f01bdfe342b6fa65d5343e1b1: | 3 | Merge tag 'samuel-thibault' of https://people.debian.org/~sthibault/qemu into staging (2022-09-06 08:31:24 -0400) |
4 | |||
5 | Merge tag 'qemu-sparc-20211121' of git://github.com/mcayland/qemu into staging (2021-11-21 14:12:25 +0100) | ||
6 | 4 | ||
7 | are available in the Git repository at: | 5 | are available in the Git repository at: |
8 | 6 | ||
9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211122 | 7 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220907 |
10 | 8 | ||
11 | for you to fetch changes up to 526e7443027c71fe7b04c29df529e1f9f425f9e3: | 9 | for you to fetch changes up to f0551560b5c01b1dcbed1ac46ca0bd1155330f5f: |
12 | 10 | ||
13 | hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset (2021-11-22 10:46:22 +1000) | 11 | target/riscv: Update the privilege field for sscofpmf CSRs (2022-09-07 09:19:15 +0200) |
14 | 12 | ||
15 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
16 | Seventh RISC-V PR for QEMU 6.2 | 14 | First RISC-V PR for QEMU 7.2 |
17 | 15 | ||
18 | - Deprecate IF_NONE for SiFive OTP | 16 | * Update [m|h]tinst CSR in interrupt handling |
19 | - Don't reset SiFive OTP content | 17 | * Force disable extensions if priv spec version does not match |
18 | * fix shifts shamt value for rv128c | ||
19 | * move zmmul out of the experimental | ||
20 | * virt: pass random seed to fdt | ||
21 | * Add checks for supported extension combinations | ||
22 | * Upgrade OpenSBI to v1.1 | ||
23 | * Fix typo and restore Pointer Masking functionality for RISC-V | ||
24 | * Add mask agnostic behaviour (rvv_ma_all_1s) for vector extension | ||
25 | * Add Zihintpause support | ||
26 | * opentitan: bump opentitan version | ||
27 | * microchip_pfsoc: fix kernel panics due to missing peripherals | ||
28 | * Remove additional priv version check for mcountinhibit | ||
29 | * virt machine device tree improvements | ||
30 | * Add xicondops in ISA entry | ||
31 | * Use official extension names for AIA CSRs | ||
20 | 32 | ||
21 | ---------------------------------------------------------------- | 33 | ---------------------------------------------------------------- |
22 | Philippe Mathieu-Daudé (1): | 34 | Alexey Baturo (1): |
23 | hw/misc/sifive_u_otp: Do not reset OTP content on hardware reset | 35 | target/riscv: Fix typo and restore Pointer Masking functionality for RISC-V |
24 | 36 | ||
25 | Thomas Huth (1): | 37 | Anup Patel (3): |
26 | hw/misc/sifive_u_otp: Use IF_PFLASH for the OTP device instead of IF_NONE | 38 | target/riscv: Update [m|h]tinst CSR in riscv_cpu_do_interrupt() |
39 | target/riscv: Force disable extensions if priv spec version does not match | ||
40 | target/riscv: Use official extension names for AIA CSRs | ||
27 | 41 | ||
28 | docs/about/deprecated.rst | 6 ++++++ | 42 | Atish Patra (9): |
29 | hw/misc/sifive_u_otp.c | 22 +++++++++++++--------- | 43 | target/riscv: Remove additional priv version check for mcountinhibit |
30 | 2 files changed, 19 insertions(+), 9 deletions(-) | 44 | hw/intc: Move mtimer/mtimecmp to aclint |
45 | target/riscv: Add stimecmp support | ||
46 | target/riscv: Add vstimecmp support | ||
47 | target/riscv: Add sscofpmf extension support | ||
48 | target/riscv: Simplify counter predicate function | ||
49 | target/riscv: Add few cache related PMU events | ||
50 | hw/riscv: virt: Add PMU DT node to the device tree | ||
51 | target/riscv: Update the privilege field for sscofpmf CSRs | ||
31 | 52 | ||
53 | Bin Meng (2): | ||
54 | roms/opensbi: Upgrade from v1.0 to v1.1 | ||
55 | docs: List kvm as a supported accelerator on RISC-V | ||
56 | |||
57 | Conor Dooley (5): | ||
58 | hw/riscv: microchip_pfsoc: fix kernel panics due to missing peripherals | ||
59 | hw/riscv: virt: fix uart node name | ||
60 | hw/riscv: virt: fix the plic's address cells | ||
61 | hw/riscv: virt: fix syscon subnode paths | ||
62 | hw/core: fix platform bus node name | ||
63 | |||
64 | Daniel Henrique Barboza (1): | ||
65 | hw/riscv: remove 'fdt' param from riscv_setup_rom_reset_vec() | ||
66 | |||
67 | Dao Lu (1): | ||
68 | target/riscv: Add Zihintpause support | ||
69 | |||
70 | Frédéric Pétrot (1): | ||
71 | target/riscv: fix shifts shamt value for rv128c | ||
72 | |||
73 | Jason A. Donenfeld (1): | ||
74 | hw/riscv: virt: pass random seed to fdt | ||
75 | |||
76 | Rahul Pathak (1): | ||
77 | target/riscv: Add xicondops in ISA entry | ||
78 | |||
79 | Weiwei Li (8): | ||
80 | target/riscv: move zmmul out of the experimental properties | ||
81 | target/riscv: Add check for supported privilege mode combinations | ||
82 | target/riscv: H extension depends on I extension | ||
83 | target/riscv: Fix checkpatch warning may triggered in csr_ops table | ||
84 | target/riscv: Add check for csrs existed with U extension | ||
85 | target/riscv: Fix checks in hmode/hmode32 | ||
86 | target/riscv: Simplify the check in hmode to reuse the check in riscv_csrrw_check | ||
87 | target/riscv: Fix priority of csr related check in riscv_csrrw_check | ||
88 | |||
89 | Wilfred Mallawa (1): | ||
90 | hw/riscv: opentitan: bump opentitan version | ||
91 | |||
92 | Yueh-Ting (eop) Chen (9): | ||
93 | target/riscv: rvv: Add mask agnostic for vv instructions | ||
94 | target/riscv: rvv: Add mask agnostic for vector load / store instructions | ||
95 | target/riscv: rvv: Add mask agnostic for vx instructions | ||
96 | target/riscv: rvv: Add mask agnostic for vector integer shift instructions | ||
97 | target/riscv: rvv: Add mask agnostic for vector integer comparison instructions | ||
98 | target/riscv: rvv: Add mask agnostic for vector fix-point arithmetic instructions | ||
99 | target/riscv: rvv: Add mask agnostic for vector floating-point instructions | ||
100 | target/riscv: rvv: Add mask agnostic for vector mask instructions | ||
101 | target/riscv: rvv: Add mask agnostic for vector permutation instructions | ||
102 | |||
103 | eopXD (1): | ||
104 | target/riscv: rvv: Add option 'rvv_ma_all_1s' to enable optional mask agnostic behavior | ||
105 | |||
106 | docs/about/build-platforms.rst | 2 +- | ||
107 | include/hw/intc/riscv_aclint.h | 2 + | ||
108 | include/hw/riscv/boot.h | 2 +- | ||
109 | include/hw/riscv/microchip_pfsoc.h | 14 +- | ||
110 | include/hw/riscv/opentitan.h | 11 +- | ||
111 | include/hw/riscv/virt.h | 1 + | ||
112 | include/hw/timer/ibex_timer.h | 2 + | ||
113 | target/riscv/cpu.h | 48 +- | ||
114 | target/riscv/cpu_bits.h | 63 ++ | ||
115 | target/riscv/instmap.h | 45 + | ||
116 | target/riscv/internals.h | 5 +- | ||
117 | target/riscv/pmu.h | 8 + | ||
118 | target/riscv/time_helper.h | 30 + | ||
119 | target/riscv/insn16.decode | 7 +- | ||
120 | target/riscv/insn32.decode | 7 +- | ||
121 | disas/riscv.c | 27 +- | ||
122 | hw/core/sysbus-fdt.c | 2 +- | ||
123 | hw/intc/riscv_aclint.c | 48 +- | ||
124 | hw/intc/riscv_imsic.c | 4 +- | ||
125 | hw/riscv/boot.c | 4 +- | ||
126 | hw/riscv/microchip_pfsoc.c | 69 +- | ||
127 | hw/riscv/opentitan.c | 12 +- | ||
128 | hw/riscv/shakti_c.c | 3 +- | ||
129 | hw/riscv/spike.c | 2 +- | ||
130 | hw/riscv/virt.c | 45 +- | ||
131 | hw/timer/ibex_timer.c | 18 +- | ||
132 | target/riscv/cpu.c | 204 +++-- | ||
133 | target/riscv/cpu_helper.c | 293 ++++++- | ||
134 | target/riscv/csr.c | 1038 +++++++++++++++--------- | ||
135 | target/riscv/machine.c | 8 +- | ||
136 | target/riscv/pmu.c | 425 +++++++++- | ||
137 | target/riscv/time_helper.c | 114 +++ | ||
138 | target/riscv/translate.c | 24 +- | ||
139 | target/riscv/vector_helper.c | 152 +++- | ||
140 | target/riscv/insn_trans/trans_rvi.c.inc | 16 + | ||
141 | target/riscv/insn_trans/trans_rvv.c.inc | 28 + | ||
142 | pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | Bin 108504 -> 117704 bytes | ||
143 | pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | Bin 105296 -> 115344 bytes | ||
144 | roms/opensbi | 2 +- | ||
145 | target/riscv/meson.build | 3 +- | ||
146 | 40 files changed, 2229 insertions(+), 559 deletions(-) | ||
147 | create mode 100644 target/riscv/time_helper.h | ||
148 | create mode 100644 target/riscv/time_helper.c | ||
149 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Anup Patel <apatel@ventanamicro.com> | ||
1 | 2 | ||
3 | We should write transformed instruction encoding of the trapped | ||
4 | instruction in [m|h]tinst CSR at time of taking trap as defined | ||
5 | by the RISC-V privileged specification v1.12. | ||
6 | |||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Signed-off-by: Anup Patel <apatel@ventanamicro.com> | ||
9 | Acked-by: dramforever <dramforever@live.com> | ||
10 | Message-Id: <20220630061150.905174-2-apatel@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/cpu.h | 5 + | ||
14 | target/riscv/instmap.h | 45 +++++++ | ||
15 | target/riscv/cpu_helper.c | 252 +++++++++++++++++++++++++++++++++++++- | ||
16 | 3 files changed, 296 insertions(+), 6 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/cpu.h | ||
21 | +++ b/target/riscv/cpu.h | ||
22 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | ||
23 | /* Signals whether the current exception occurred with two-stage address | ||
24 | translation active. */ | ||
25 | bool two_stage_lookup; | ||
26 | + /* | ||
27 | + * Signals whether the current exception occurred while doing two-stage | ||
28 | + * address translation for the VS-stage page table walk. | ||
29 | + */ | ||
30 | + bool two_stage_indirect_lookup; | ||
31 | |||
32 | target_ulong scounteren; | ||
33 | target_ulong mcounteren; | ||
34 | diff --git a/target/riscv/instmap.h b/target/riscv/instmap.h | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/riscv/instmap.h | ||
37 | +++ b/target/riscv/instmap.h | ||
38 | @@ -XXX,XX +XXX,XX @@ enum { | ||
39 | OPC_RISC_CSRRWI = OPC_RISC_SYSTEM | (0x5 << 12), | ||
40 | OPC_RISC_CSRRSI = OPC_RISC_SYSTEM | (0x6 << 12), | ||
41 | OPC_RISC_CSRRCI = OPC_RISC_SYSTEM | (0x7 << 12), | ||
42 | + | ||
43 | + OPC_RISC_HLVHSV = OPC_RISC_SYSTEM | (0x4 << 12), | ||
44 | }; | ||
45 | |||
46 | #define MASK_OP_FP_LOAD(op) (MASK_OP_MAJOR(op) | (op & (0x7 << 12))) | ||
47 | @@ -XXX,XX +XXX,XX @@ enum { | ||
48 | | (extract32(inst, 12, 8) << 12) \ | ||
49 | | (sextract64(inst, 31, 1) << 20)) | ||
50 | |||
51 | +#define GET_FUNCT3(inst) extract32(inst, 12, 3) | ||
52 | +#define GET_FUNCT7(inst) extract32(inst, 25, 7) | ||
53 | #define GET_RM(inst) extract32(inst, 12, 3) | ||
54 | #define GET_RS3(inst) extract32(inst, 27, 5) | ||
55 | #define GET_RS1(inst) extract32(inst, 15, 5) | ||
56 | #define GET_RS2(inst) extract32(inst, 20, 5) | ||
57 | #define GET_RD(inst) extract32(inst, 7, 5) | ||
58 | #define GET_IMM(inst) sextract64(inst, 20, 12) | ||
59 | +#define SET_RS1(inst, val) deposit32(inst, 15, 5, val) | ||
60 | +#define SET_RS2(inst, val) deposit32(inst, 20, 5, val) | ||
61 | +#define SET_RD(inst, val) deposit32(inst, 7, 5, val) | ||
62 | +#define SET_I_IMM(inst, val) deposit32(inst, 20, 12, val) | ||
63 | +#define SET_S_IMM(inst, val) \ | ||
64 | + deposit32(deposit32(inst, 7, 5, val), 25, 7, (val) >> 5) | ||
65 | |||
66 | /* RVC decoding macros */ | ||
67 | #define GET_C_IMM(inst) (extract32(inst, 2, 5) \ | ||
68 | @@ -XXX,XX +XXX,XX @@ enum { | ||
69 | | (extract32(inst, 5, 1) << 6)) | ||
70 | #define GET_C_LD_IMM(inst) ((extract16(inst, 10, 3) << 3) \ | ||
71 | | (extract16(inst, 5, 2) << 6)) | ||
72 | +#define GET_C_SW_IMM(inst) GET_C_LW_IMM(inst) | ||
73 | +#define GET_C_SD_IMM(inst) GET_C_LD_IMM(inst) | ||
74 | #define GET_C_J_IMM(inst) ((extract32(inst, 3, 3) << 1) \ | ||
75 | | (extract32(inst, 11, 1) << 4) \ | ||
76 | | (extract32(inst, 2, 1) << 5) \ | ||
77 | @@ -XXX,XX +XXX,XX @@ enum { | ||
78 | #define GET_C_RS1S(inst) (8 + extract16(inst, 7, 3)) | ||
79 | #define GET_C_RS2S(inst) (8 + extract16(inst, 2, 3)) | ||
80 | |||
81 | +#define GET_C_FUNC(inst) extract32(inst, 13, 3) | ||
82 | +#define GET_C_OP(inst) extract32(inst, 0, 2) | ||
83 | + | ||
84 | +enum { | ||
85 | + /* RVC Quadrants */ | ||
86 | + OPC_RISC_C_OP_QUAD0 = 0x0, | ||
87 | + OPC_RISC_C_OP_QUAD1 = 0x1, | ||
88 | + OPC_RISC_C_OP_QUAD2 = 0x2 | ||
89 | +}; | ||
90 | + | ||
91 | +enum { | ||
92 | + /* RVC Quadrant 0 */ | ||
93 | + OPC_RISC_C_FUNC_ADDI4SPN = 0x0, | ||
94 | + OPC_RISC_C_FUNC_FLD_LQ = 0x1, | ||
95 | + OPC_RISC_C_FUNC_LW = 0x2, | ||
96 | + OPC_RISC_C_FUNC_FLW_LD = 0x3, | ||
97 | + OPC_RISC_C_FUNC_FSD_SQ = 0x5, | ||
98 | + OPC_RISC_C_FUNC_SW = 0x6, | ||
99 | + OPC_RISC_C_FUNC_FSW_SD = 0x7 | ||
100 | +}; | ||
101 | + | ||
102 | +enum { | ||
103 | + /* RVC Quadrant 2 */ | ||
104 | + OPC_RISC_C_FUNC_SLLI_SLLI64 = 0x0, | ||
105 | + OPC_RISC_C_FUNC_FLDSP_LQSP = 0x1, | ||
106 | + OPC_RISC_C_FUNC_LWSP = 0x2, | ||
107 | + OPC_RISC_C_FUNC_FLWSP_LDSP = 0x3, | ||
108 | + OPC_RISC_C_FUNC_JR_MV_EBREAK_JALR_ADD = 0x4, | ||
109 | + OPC_RISC_C_FUNC_FSDSP_SQSP = 0x5, | ||
110 | + OPC_RISC_C_FUNC_SWSP = 0x6, | ||
111 | + OPC_RISC_C_FUNC_FSWSP_SDSP = 0x7 | ||
112 | +}; | ||
113 | + | ||
114 | #endif | ||
115 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
116 | index XXXXXXX..XXXXXXX 100644 | ||
117 | --- a/target/riscv/cpu_helper.c | ||
118 | +++ b/target/riscv/cpu_helper.c | ||
119 | @@ -XXX,XX +XXX,XX @@ | ||
120 | #include "qemu/main-loop.h" | ||
121 | #include "cpu.h" | ||
122 | #include "exec/exec-all.h" | ||
123 | +#include "instmap.h" | ||
124 | #include "tcg/tcg-op.h" | ||
125 | #include "trace.h" | ||
126 | #include "semihosting/common-semi.h" | ||
127 | @@ -XXX,XX +XXX,XX @@ restart: | ||
128 | |||
129 | static void raise_mmu_exception(CPURISCVState *env, target_ulong address, | ||
130 | MMUAccessType access_type, bool pmp_violation, | ||
131 | - bool first_stage, bool two_stage) | ||
132 | + bool first_stage, bool two_stage, | ||
133 | + bool two_stage_indirect) | ||
134 | { | ||
135 | CPUState *cs = env_cpu(env); | ||
136 | int page_fault_exceptions, vm; | ||
137 | @@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address, | ||
138 | } | ||
139 | env->badaddr = address; | ||
140 | env->two_stage_lookup = two_stage; | ||
141 | + env->two_stage_indirect_lookup = two_stage_indirect; | ||
142 | } | ||
143 | |||
144 | hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) | ||
145 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, | ||
146 | env->badaddr = addr; | ||
147 | env->two_stage_lookup = riscv_cpu_virt_enabled(env) || | ||
148 | riscv_cpu_two_stage_lookup(mmu_idx); | ||
149 | + env->two_stage_indirect_lookup = false; | ||
150 | cpu_loop_exit_restore(cs, retaddr); | ||
151 | } | ||
152 | |||
153 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, | ||
154 | env->badaddr = addr; | ||
155 | env->two_stage_lookup = riscv_cpu_virt_enabled(env) || | ||
156 | riscv_cpu_two_stage_lookup(mmu_idx); | ||
157 | + env->two_stage_indirect_lookup = false; | ||
158 | cpu_loop_exit_restore(cs, retaddr); | ||
159 | } | ||
160 | |||
161 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
162 | bool pmp_violation = false; | ||
163 | bool first_stage_error = true; | ||
164 | bool two_stage_lookup = false; | ||
165 | + bool two_stage_indirect_error = false; | ||
166 | int ret = TRANSLATE_FAIL; | ||
167 | int mode = mmu_idx; | ||
168 | /* default TLB page size */ | ||
169 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
170 | */ | ||
171 | if (ret == TRANSLATE_G_STAGE_FAIL) { | ||
172 | first_stage_error = false; | ||
173 | + two_stage_indirect_error = true; | ||
174 | access_type = MMU_DATA_LOAD; | ||
175 | } | ||
176 | |||
177 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
178 | raise_mmu_exception(env, address, access_type, pmp_violation, | ||
179 | first_stage_error, | ||
180 | riscv_cpu_virt_enabled(env) || | ||
181 | - riscv_cpu_two_stage_lookup(mmu_idx)); | ||
182 | + riscv_cpu_two_stage_lookup(mmu_idx), | ||
183 | + two_stage_indirect_error); | ||
184 | cpu_loop_exit_restore(cs, retaddr); | ||
185 | } | ||
186 | |||
187 | return true; | ||
188 | } | ||
189 | + | ||
190 | +static target_ulong riscv_transformed_insn(CPURISCVState *env, | ||
191 | + target_ulong insn, | ||
192 | + target_ulong taddr) | ||
193 | +{ | ||
194 | + target_ulong xinsn = 0; | ||
195 | + target_ulong access_rs1 = 0, access_imm = 0, access_size = 0; | ||
196 | + | ||
197 | + /* | ||
198 | + * Only Quadrant 0 and Quadrant 2 of RVC instruction space need to | ||
199 | + * be uncompressed. The Quadrant 1 of RVC instruction space need | ||
200 | + * not be transformed because these instructions won't generate | ||
201 | + * any load/store trap. | ||
202 | + */ | ||
203 | + | ||
204 | + if ((insn & 0x3) != 0x3) { | ||
205 | + /* Transform 16bit instruction into 32bit instruction */ | ||
206 | + switch (GET_C_OP(insn)) { | ||
207 | + case OPC_RISC_C_OP_QUAD0: /* Quadrant 0 */ | ||
208 | + switch (GET_C_FUNC(insn)) { | ||
209 | + case OPC_RISC_C_FUNC_FLD_LQ: | ||
210 | + if (riscv_cpu_xlen(env) != 128) { /* C.FLD (RV32/64) */ | ||
211 | + xinsn = OPC_RISC_FLD; | ||
212 | + xinsn = SET_RD(xinsn, GET_C_RS2S(insn)); | ||
213 | + access_rs1 = GET_C_RS1S(insn); | ||
214 | + access_imm = GET_C_LD_IMM(insn); | ||
215 | + access_size = 8; | ||
216 | + } | ||
217 | + break; | ||
218 | + case OPC_RISC_C_FUNC_LW: /* C.LW */ | ||
219 | + xinsn = OPC_RISC_LW; | ||
220 | + xinsn = SET_RD(xinsn, GET_C_RS2S(insn)); | ||
221 | + access_rs1 = GET_C_RS1S(insn); | ||
222 | + access_imm = GET_C_LW_IMM(insn); | ||
223 | + access_size = 4; | ||
224 | + break; | ||
225 | + case OPC_RISC_C_FUNC_FLW_LD: | ||
226 | + if (riscv_cpu_xlen(env) == 32) { /* C.FLW (RV32) */ | ||
227 | + xinsn = OPC_RISC_FLW; | ||
228 | + xinsn = SET_RD(xinsn, GET_C_RS2S(insn)); | ||
229 | + access_rs1 = GET_C_RS1S(insn); | ||
230 | + access_imm = GET_C_LW_IMM(insn); | ||
231 | + access_size = 4; | ||
232 | + } else { /* C.LD (RV64/RV128) */ | ||
233 | + xinsn = OPC_RISC_LD; | ||
234 | + xinsn = SET_RD(xinsn, GET_C_RS2S(insn)); | ||
235 | + access_rs1 = GET_C_RS1S(insn); | ||
236 | + access_imm = GET_C_LD_IMM(insn); | ||
237 | + access_size = 8; | ||
238 | + } | ||
239 | + break; | ||
240 | + case OPC_RISC_C_FUNC_FSD_SQ: | ||
241 | + if (riscv_cpu_xlen(env) != 128) { /* C.FSD (RV32/64) */ | ||
242 | + xinsn = OPC_RISC_FSD; | ||
243 | + xinsn = SET_RS2(xinsn, GET_C_RS2S(insn)); | ||
244 | + access_rs1 = GET_C_RS1S(insn); | ||
245 | + access_imm = GET_C_SD_IMM(insn); | ||
246 | + access_size = 8; | ||
247 | + } | ||
248 | + break; | ||
249 | + case OPC_RISC_C_FUNC_SW: /* C.SW */ | ||
250 | + xinsn = OPC_RISC_SW; | ||
251 | + xinsn = SET_RS2(xinsn, GET_C_RS2S(insn)); | ||
252 | + access_rs1 = GET_C_RS1S(insn); | ||
253 | + access_imm = GET_C_SW_IMM(insn); | ||
254 | + access_size = 4; | ||
255 | + break; | ||
256 | + case OPC_RISC_C_FUNC_FSW_SD: | ||
257 | + if (riscv_cpu_xlen(env) == 32) { /* C.FSW (RV32) */ | ||
258 | + xinsn = OPC_RISC_FSW; | ||
259 | + xinsn = SET_RS2(xinsn, GET_C_RS2S(insn)); | ||
260 | + access_rs1 = GET_C_RS1S(insn); | ||
261 | + access_imm = GET_C_SW_IMM(insn); | ||
262 | + access_size = 4; | ||
263 | + } else { /* C.SD (RV64/RV128) */ | ||
264 | + xinsn = OPC_RISC_SD; | ||
265 | + xinsn = SET_RS2(xinsn, GET_C_RS2S(insn)); | ||
266 | + access_rs1 = GET_C_RS1S(insn); | ||
267 | + access_imm = GET_C_SD_IMM(insn); | ||
268 | + access_size = 8; | ||
269 | + } | ||
270 | + break; | ||
271 | + default: | ||
272 | + break; | ||
273 | + } | ||
274 | + break; | ||
275 | + case OPC_RISC_C_OP_QUAD2: /* Quadrant 2 */ | ||
276 | + switch (GET_C_FUNC(insn)) { | ||
277 | + case OPC_RISC_C_FUNC_FLDSP_LQSP: | ||
278 | + if (riscv_cpu_xlen(env) != 128) { /* C.FLDSP (RV32/64) */ | ||
279 | + xinsn = OPC_RISC_FLD; | ||
280 | + xinsn = SET_RD(xinsn, GET_C_RD(insn)); | ||
281 | + access_rs1 = 2; | ||
282 | + access_imm = GET_C_LDSP_IMM(insn); | ||
283 | + access_size = 8; | ||
284 | + } | ||
285 | + break; | ||
286 | + case OPC_RISC_C_FUNC_LWSP: /* C.LWSP */ | ||
287 | + xinsn = OPC_RISC_LW; | ||
288 | + xinsn = SET_RD(xinsn, GET_C_RD(insn)); | ||
289 | + access_rs1 = 2; | ||
290 | + access_imm = GET_C_LWSP_IMM(insn); | ||
291 | + access_size = 4; | ||
292 | + break; | ||
293 | + case OPC_RISC_C_FUNC_FLWSP_LDSP: | ||
294 | + if (riscv_cpu_xlen(env) == 32) { /* C.FLWSP (RV32) */ | ||
295 | + xinsn = OPC_RISC_FLW; | ||
296 | + xinsn = SET_RD(xinsn, GET_C_RD(insn)); | ||
297 | + access_rs1 = 2; | ||
298 | + access_imm = GET_C_LWSP_IMM(insn); | ||
299 | + access_size = 4; | ||
300 | + } else { /* C.LDSP (RV64/RV128) */ | ||
301 | + xinsn = OPC_RISC_LD; | ||
302 | + xinsn = SET_RD(xinsn, GET_C_RD(insn)); | ||
303 | + access_rs1 = 2; | ||
304 | + access_imm = GET_C_LDSP_IMM(insn); | ||
305 | + access_size = 8; | ||
306 | + } | ||
307 | + break; | ||
308 | + case OPC_RISC_C_FUNC_FSDSP_SQSP: | ||
309 | + if (riscv_cpu_xlen(env) != 128) { /* C.FSDSP (RV32/64) */ | ||
310 | + xinsn = OPC_RISC_FSD; | ||
311 | + xinsn = SET_RS2(xinsn, GET_C_RS2(insn)); | ||
312 | + access_rs1 = 2; | ||
313 | + access_imm = GET_C_SDSP_IMM(insn); | ||
314 | + access_size = 8; | ||
315 | + } | ||
316 | + break; | ||
317 | + case OPC_RISC_C_FUNC_SWSP: /* C.SWSP */ | ||
318 | + xinsn = OPC_RISC_SW; | ||
319 | + xinsn = SET_RS2(xinsn, GET_C_RS2(insn)); | ||
320 | + access_rs1 = 2; | ||
321 | + access_imm = GET_C_SWSP_IMM(insn); | ||
322 | + access_size = 4; | ||
323 | + break; | ||
324 | + case 7: | ||
325 | + if (riscv_cpu_xlen(env) == 32) { /* C.FSWSP (RV32) */ | ||
326 | + xinsn = OPC_RISC_FSW; | ||
327 | + xinsn = SET_RS2(xinsn, GET_C_RS2(insn)); | ||
328 | + access_rs1 = 2; | ||
329 | + access_imm = GET_C_SWSP_IMM(insn); | ||
330 | + access_size = 4; | ||
331 | + } else { /* C.SDSP (RV64/RV128) */ | ||
332 | + xinsn = OPC_RISC_SD; | ||
333 | + xinsn = SET_RS2(xinsn, GET_C_RS2(insn)); | ||
334 | + access_rs1 = 2; | ||
335 | + access_imm = GET_C_SDSP_IMM(insn); | ||
336 | + access_size = 8; | ||
337 | + } | ||
338 | + break; | ||
339 | + default: | ||
340 | + break; | ||
341 | + } | ||
342 | + break; | ||
343 | + default: | ||
344 | + break; | ||
345 | + } | ||
346 | + | ||
347 | + /* | ||
348 | + * Clear Bit1 of transformed instruction to indicate that | ||
349 | + * original insruction was a 16bit instruction | ||
350 | + */ | ||
351 | + xinsn &= ~((target_ulong)0x2); | ||
352 | + } else { | ||
353 | + /* Transform 32bit (or wider) instructions */ | ||
354 | + switch (MASK_OP_MAJOR(insn)) { | ||
355 | + case OPC_RISC_ATOMIC: | ||
356 | + xinsn = insn; | ||
357 | + access_rs1 = GET_RS1(insn); | ||
358 | + access_size = 1 << GET_FUNCT3(insn); | ||
359 | + break; | ||
360 | + case OPC_RISC_LOAD: | ||
361 | + case OPC_RISC_FP_LOAD: | ||
362 | + xinsn = SET_I_IMM(insn, 0); | ||
363 | + access_rs1 = GET_RS1(insn); | ||
364 | + access_imm = GET_IMM(insn); | ||
365 | + access_size = 1 << GET_FUNCT3(insn); | ||
366 | + break; | ||
367 | + case OPC_RISC_STORE: | ||
368 | + case OPC_RISC_FP_STORE: | ||
369 | + xinsn = SET_S_IMM(insn, 0); | ||
370 | + access_rs1 = GET_RS1(insn); | ||
371 | + access_imm = GET_STORE_IMM(insn); | ||
372 | + access_size = 1 << GET_FUNCT3(insn); | ||
373 | + break; | ||
374 | + case OPC_RISC_SYSTEM: | ||
375 | + if (MASK_OP_SYSTEM(insn) == OPC_RISC_HLVHSV) { | ||
376 | + xinsn = insn; | ||
377 | + access_rs1 = GET_RS1(insn); | ||
378 | + access_size = 1 << ((GET_FUNCT7(insn) >> 1) & 0x3); | ||
379 | + access_size = 1 << access_size; | ||
380 | + } | ||
381 | + break; | ||
382 | + default: | ||
383 | + break; | ||
384 | + } | ||
385 | + } | ||
386 | + | ||
387 | + if (access_size) { | ||
388 | + xinsn = SET_RS1(xinsn, (taddr - (env->gpr[access_rs1] + access_imm)) & | ||
389 | + (access_size - 1)); | ||
390 | + } | ||
391 | + | ||
392 | + return xinsn; | ||
393 | +} | ||
394 | #endif /* !CONFIG_USER_ONLY */ | ||
395 | |||
396 | /* | ||
397 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
398 | target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK; | ||
399 | uint64_t deleg = async ? env->mideleg : env->medeleg; | ||
400 | target_ulong tval = 0; | ||
401 | + target_ulong tinst = 0; | ||
402 | target_ulong htval = 0; | ||
403 | target_ulong mtval2 = 0; | ||
404 | |||
405 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
406 | if (!async) { | ||
407 | /* set tval to badaddr for traps with address information */ | ||
408 | switch (cause) { | ||
409 | - case RISCV_EXCP_INST_GUEST_PAGE_FAULT: | ||
410 | case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT: | ||
411 | case RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT: | ||
412 | - case RISCV_EXCP_INST_ADDR_MIS: | ||
413 | - case RISCV_EXCP_INST_ACCESS_FAULT: | ||
414 | case RISCV_EXCP_LOAD_ADDR_MIS: | ||
415 | case RISCV_EXCP_STORE_AMO_ADDR_MIS: | ||
416 | case RISCV_EXCP_LOAD_ACCESS_FAULT: | ||
417 | case RISCV_EXCP_STORE_AMO_ACCESS_FAULT: | ||
418 | - case RISCV_EXCP_INST_PAGE_FAULT: | ||
419 | case RISCV_EXCP_LOAD_PAGE_FAULT: | ||
420 | case RISCV_EXCP_STORE_PAGE_FAULT: | ||
421 | write_gva = env->two_stage_lookup; | ||
422 | tval = env->badaddr; | ||
423 | + if (env->two_stage_indirect_lookup) { | ||
424 | + /* | ||
425 | + * special pseudoinstruction for G-stage fault taken while | ||
426 | + * doing VS-stage page table walk. | ||
427 | + */ | ||
428 | + tinst = (riscv_cpu_xlen(env) == 32) ? 0x00002000 : 0x00003000; | ||
429 | + } else { | ||
430 | + /* | ||
431 | + * The "Addr. Offset" field in transformed instruction is | ||
432 | + * non-zero only for misaligned access. | ||
433 | + */ | ||
434 | + tinst = riscv_transformed_insn(env, env->bins, tval); | ||
435 | + } | ||
436 | + break; | ||
437 | + case RISCV_EXCP_INST_GUEST_PAGE_FAULT: | ||
438 | + case RISCV_EXCP_INST_ADDR_MIS: | ||
439 | + case RISCV_EXCP_INST_ACCESS_FAULT: | ||
440 | + case RISCV_EXCP_INST_PAGE_FAULT: | ||
441 | + write_gva = env->two_stage_lookup; | ||
442 | + tval = env->badaddr; | ||
443 | + if (env->two_stage_indirect_lookup) { | ||
444 | + /* | ||
445 | + * special pseudoinstruction for G-stage fault taken while | ||
446 | + * doing VS-stage page table walk. | ||
447 | + */ | ||
448 | + tinst = (riscv_cpu_xlen(env) == 32) ? 0x00002000 : 0x00003000; | ||
449 | + } | ||
450 | break; | ||
451 | case RISCV_EXCP_ILLEGAL_INST: | ||
452 | case RISCV_EXCP_VIRT_INSTRUCTION_FAULT: | ||
453 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
454 | env->sepc = env->pc; | ||
455 | env->stval = tval; | ||
456 | env->htval = htval; | ||
457 | + env->htinst = tinst; | ||
458 | env->pc = (env->stvec >> 2 << 2) + | ||
459 | ((async && (env->stvec & 3) == 1) ? cause * 4 : 0); | ||
460 | riscv_cpu_set_mode(env, PRV_S); | ||
461 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
462 | env->mepc = env->pc; | ||
463 | env->mtval = tval; | ||
464 | env->mtval2 = mtval2; | ||
465 | + env->mtinst = tinst; | ||
466 | env->pc = (env->mtvec >> 2 << 2) + | ||
467 | ((async && (env->mtvec & 3) == 1) ? cause * 4 : 0); | ||
468 | riscv_cpu_set_mode(env, PRV_M); | ||
469 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | ||
470 | */ | ||
471 | |||
472 | env->two_stage_lookup = false; | ||
473 | + env->two_stage_indirect_lookup = false; | ||
474 | #endif | ||
475 | cs->exception_index = RISCV_EXCP_NONE; /* mark handled to qemu */ | ||
476 | } | ||
477 | -- | ||
478 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Anup Patel <apatel@ventanamicro.com> | ||
1 | 2 | ||
3 | We should disable extensions in riscv_cpu_realize() if minimum required | ||
4 | priv spec version is not satisfied. This also ensures that machines with | ||
5 | priv spec v1.11 (or lower) cannot enable H, V, and various multi-letter | ||
6 | extensions. | ||
7 | |||
8 | Fixes: a775398be2e9 ("target/riscv: Add isa extenstion strings to the device tree") | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Signed-off-by: Anup Patel <apatel@ventanamicro.com> | ||
11 | Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com> | ||
12 | Message-Id: <20220630061150.905174-3-apatel@ventanamicro.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/cpu.c | 150 ++++++++++++++++++++++++++++----------------- | ||
16 | 1 file changed, 94 insertions(+), 56 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/cpu.c | ||
21 | +++ b/target/riscv/cpu.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; | ||
23 | |||
24 | struct isa_ext_data { | ||
25 | const char *name; | ||
26 | - bool enabled; | ||
27 | + bool multi_letter; | ||
28 | + int min_version; | ||
29 | + int ext_enable_offset; | ||
30 | }; | ||
31 | |||
32 | +#define ISA_EXT_DATA_ENTRY(_name, _m_letter, _min_ver, _prop) \ | ||
33 | +{#_name, _m_letter, _min_ver, offsetof(struct RISCVCPUConfig, _prop)} | ||
34 | + | ||
35 | +/** | ||
36 | + * Here are the ordering rules of extension naming defined by RISC-V | ||
37 | + * specification : | ||
38 | + * 1. All extensions should be separated from other multi-letter extensions | ||
39 | + * by an underscore. | ||
40 | + * 2. The first letter following the 'Z' conventionally indicates the most | ||
41 | + * closely related alphabetical extension category, IMAFDQLCBKJTPVH. | ||
42 | + * If multiple 'Z' extensions are named, they should be ordered first | ||
43 | + * by category, then alphabetically within a category. | ||
44 | + * 3. Standard supervisor-level extensions (starts with 'S') should be | ||
45 | + * listed after standard unprivileged extensions. If multiple | ||
46 | + * supervisor-level extensions are listed, they should be ordered | ||
47 | + * alphabetically. | ||
48 | + * 4. Non-standard extensions (starts with 'X') must be listed after all | ||
49 | + * standard extensions. They must be separated from other multi-letter | ||
50 | + * extensions by an underscore. | ||
51 | + */ | ||
52 | +static const struct isa_ext_data isa_edata_arr[] = { | ||
53 | + ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h), | ||
54 | + ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v), | ||
55 | + ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr), | ||
56 | + ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei), | ||
57 | + ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh), | ||
58 | + ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin), | ||
59 | + ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx), | ||
60 | + ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx), | ||
61 | + ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba), | ||
62 | + ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb), | ||
63 | + ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc), | ||
64 | + ISA_EXT_DATA_ENTRY(zbkb, true, PRIV_VERSION_1_12_0, ext_zbkb), | ||
65 | + ISA_EXT_DATA_ENTRY(zbkc, true, PRIV_VERSION_1_12_0, ext_zbkc), | ||
66 | + ISA_EXT_DATA_ENTRY(zbkx, true, PRIV_VERSION_1_12_0, ext_zbkx), | ||
67 | + ISA_EXT_DATA_ENTRY(zbs, true, PRIV_VERSION_1_12_0, ext_zbs), | ||
68 | + ISA_EXT_DATA_ENTRY(zk, true, PRIV_VERSION_1_12_0, ext_zk), | ||
69 | + ISA_EXT_DATA_ENTRY(zkn, true, PRIV_VERSION_1_12_0, ext_zkn), | ||
70 | + ISA_EXT_DATA_ENTRY(zknd, true, PRIV_VERSION_1_12_0, ext_zknd), | ||
71 | + ISA_EXT_DATA_ENTRY(zkne, true, PRIV_VERSION_1_12_0, ext_zkne), | ||
72 | + ISA_EXT_DATA_ENTRY(zknh, true, PRIV_VERSION_1_12_0, ext_zknh), | ||
73 | + ISA_EXT_DATA_ENTRY(zkr, true, PRIV_VERSION_1_12_0, ext_zkr), | ||
74 | + ISA_EXT_DATA_ENTRY(zks, true, PRIV_VERSION_1_12_0, ext_zks), | ||
75 | + ISA_EXT_DATA_ENTRY(zksed, true, PRIV_VERSION_1_12_0, ext_zksed), | ||
76 | + ISA_EXT_DATA_ENTRY(zksh, true, PRIV_VERSION_1_12_0, ext_zksh), | ||
77 | + ISA_EXT_DATA_ENTRY(zkt, true, PRIV_VERSION_1_12_0, ext_zkt), | ||
78 | + ISA_EXT_DATA_ENTRY(zve32f, true, PRIV_VERSION_1_12_0, ext_zve32f), | ||
79 | + ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f), | ||
80 | + ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx), | ||
81 | + ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
82 | + ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval), | ||
83 | + ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), | ||
84 | + ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt), | ||
85 | +}; | ||
86 | + | ||
87 | +static bool isa_ext_is_enabled(RISCVCPU *cpu, | ||
88 | + const struct isa_ext_data *edata) | ||
89 | +{ | ||
90 | + bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset; | ||
91 | + | ||
92 | + return *ext_enabled; | ||
93 | +} | ||
94 | + | ||
95 | +static void isa_ext_update_enabled(RISCVCPU *cpu, | ||
96 | + const struct isa_ext_data *edata, bool en) | ||
97 | +{ | ||
98 | + bool *ext_enabled = (void *)&cpu->cfg + edata->ext_enable_offset; | ||
99 | + | ||
100 | + *ext_enabled = en; | ||
101 | +} | ||
102 | + | ||
103 | const char * const riscv_int_regnames[] = { | ||
104 | "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1", | ||
105 | "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3", | ||
106 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
107 | CPURISCVState *env = &cpu->env; | ||
108 | RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev); | ||
109 | CPUClass *cc = CPU_CLASS(mcc); | ||
110 | - int priv_version = -1; | ||
111 | + int i, priv_version = -1; | ||
112 | Error *local_err = NULL; | ||
113 | |||
114 | cpu_exec_realizefn(cs, &local_err); | ||
115 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
116 | set_priv_version(env, priv_version); | ||
117 | } | ||
118 | |||
119 | + /* Force disable extensions if priv spec version does not match */ | ||
120 | + for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { | ||
121 | + if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) && | ||
122 | + (env->priv_ver < isa_edata_arr[i].min_version)) { | ||
123 | + isa_ext_update_enabled(cpu, &isa_edata_arr[i], false); | ||
124 | +#ifndef CONFIG_USER_ONLY | ||
125 | + warn_report("disabling %s extension for hart 0x%lx because " | ||
126 | + "privilege spec version does not match", | ||
127 | + isa_edata_arr[i].name, (unsigned long)env->mhartid); | ||
128 | +#else | ||
129 | + warn_report("disabling %s extension because " | ||
130 | + "privilege spec version does not match", | ||
131 | + isa_edata_arr[i].name); | ||
132 | +#endif | ||
133 | + } | ||
134 | + } | ||
135 | + | ||
136 | if (cpu->cfg.mmu) { | ||
137 | riscv_set_feature(env, RISCV_FEATURE_MMU); | ||
138 | } | ||
139 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) | ||
140 | device_class_set_props(dc, riscv_cpu_properties); | ||
141 | } | ||
142 | |||
143 | -#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop} | ||
144 | - | ||
145 | static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) | ||
146 | { | ||
147 | char *old = *isa_str; | ||
148 | char *new = *isa_str; | ||
149 | int i; | ||
150 | |||
151 | - /** | ||
152 | - * Here are the ordering rules of extension naming defined by RISC-V | ||
153 | - * specification : | ||
154 | - * 1. All extensions should be separated from other multi-letter extensions | ||
155 | - * by an underscore. | ||
156 | - * 2. The first letter following the 'Z' conventionally indicates the most | ||
157 | - * closely related alphabetical extension category, IMAFDQLCBKJTPVH. | ||
158 | - * If multiple 'Z' extensions are named, they should be ordered first | ||
159 | - * by category, then alphabetically within a category. | ||
160 | - * 3. Standard supervisor-level extensions (starts with 'S') should be | ||
161 | - * listed after standard unprivileged extensions. If multiple | ||
162 | - * supervisor-level extensions are listed, they should be ordered | ||
163 | - * alphabetically. | ||
164 | - * 4. Non-standard extensions (starts with 'X') must be listed after all | ||
165 | - * standard extensions. They must be separated from other multi-letter | ||
166 | - * extensions by an underscore. | ||
167 | - */ | ||
168 | - struct isa_ext_data isa_edata_arr[] = { | ||
169 | - ISA_EDATA_ENTRY(zicsr, ext_icsr), | ||
170 | - ISA_EDATA_ENTRY(zifencei, ext_ifencei), | ||
171 | - ISA_EDATA_ENTRY(zmmul, ext_zmmul), | ||
172 | - ISA_EDATA_ENTRY(zfh, ext_zfh), | ||
173 | - ISA_EDATA_ENTRY(zfhmin, ext_zfhmin), | ||
174 | - ISA_EDATA_ENTRY(zfinx, ext_zfinx), | ||
175 | - ISA_EDATA_ENTRY(zdinx, ext_zdinx), | ||
176 | - ISA_EDATA_ENTRY(zba, ext_zba), | ||
177 | - ISA_EDATA_ENTRY(zbb, ext_zbb), | ||
178 | - ISA_EDATA_ENTRY(zbc, ext_zbc), | ||
179 | - ISA_EDATA_ENTRY(zbkb, ext_zbkb), | ||
180 | - ISA_EDATA_ENTRY(zbkc, ext_zbkc), | ||
181 | - ISA_EDATA_ENTRY(zbkx, ext_zbkx), | ||
182 | - ISA_EDATA_ENTRY(zbs, ext_zbs), | ||
183 | - ISA_EDATA_ENTRY(zk, ext_zk), | ||
184 | - ISA_EDATA_ENTRY(zkn, ext_zkn), | ||
185 | - ISA_EDATA_ENTRY(zknd, ext_zknd), | ||
186 | - ISA_EDATA_ENTRY(zkne, ext_zkne), | ||
187 | - ISA_EDATA_ENTRY(zknh, ext_zknh), | ||
188 | - ISA_EDATA_ENTRY(zkr, ext_zkr), | ||
189 | - ISA_EDATA_ENTRY(zks, ext_zks), | ||
190 | - ISA_EDATA_ENTRY(zksed, ext_zksed), | ||
191 | - ISA_EDATA_ENTRY(zksh, ext_zksh), | ||
192 | - ISA_EDATA_ENTRY(zkt, ext_zkt), | ||
193 | - ISA_EDATA_ENTRY(zve32f, ext_zve32f), | ||
194 | - ISA_EDATA_ENTRY(zve64f, ext_zve64f), | ||
195 | - ISA_EDATA_ENTRY(zhinx, ext_zhinx), | ||
196 | - ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin), | ||
197 | - ISA_EDATA_ENTRY(svinval, ext_svinval), | ||
198 | - ISA_EDATA_ENTRY(svnapot, ext_svnapot), | ||
199 | - ISA_EDATA_ENTRY(svpbmt, ext_svpbmt), | ||
200 | - }; | ||
201 | - | ||
202 | for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { | ||
203 | - if (isa_edata_arr[i].enabled) { | ||
204 | + if (isa_edata_arr[i].multi_letter && | ||
205 | + isa_ext_is_enabled(cpu, &isa_edata_arr[i])) { | ||
206 | new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL); | ||
207 | g_free(old); | ||
208 | old = new; | ||
209 | -- | ||
210 | 2.37.2 | diff view generated by jsdifflib |
1 | From: Philippe Mathieu-Daudé <f4bug@amsat.org> | 1 | From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> |
---|---|---|---|
2 | 2 | ||
3 | Once a "One Time Programmable" is programmed, it shouldn't be reset. | 3 | For rv128c shifts, a shamt of 0 is a shamt of 64, while for rv32c/rv64c |
4 | it stays 0 and is a hint instruction that does not change processor state. | ||
5 | For rv128c right shifts, the 6-bit shamt is in addition sign extended to | ||
6 | 7 bits. | ||
4 | 7 | ||
5 | Do not re-initialize the OTP content in the DeviceReset handler, | 8 | Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> |
6 | initialize it once in the DeviceRealize one. | 9 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> |
7 | 10 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | |
8 | Fixes: 9fb45c62ae8 ("riscv: sifive: Implement a model for SiFive FU540 OTP") | 11 | Message-Id: <20220710110451.245567-1-frederic.petrot@univ-grenoble-alpes.fr> |
9 | Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-Id: <20211119104757.331579-1-f4bug@amsat.org> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 13 | --- |
14 | hw/misc/sifive_u_otp.c | 13 +++++-------- | 14 | target/riscv/insn16.decode | 7 ++++--- |
15 | 1 file changed, 5 insertions(+), 8 deletions(-) | 15 | disas/riscv.c | 27 +++++++++++++++++++++------ |
16 | target/riscv/translate.c | 20 ++++++++++++++++++-- | ||
17 | 3 files changed, 43 insertions(+), 11 deletions(-) | ||
16 | 18 | ||
17 | diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c | 19 | diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode |
18 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/hw/misc/sifive_u_otp.c | 21 | --- a/target/riscv/insn16.decode |
20 | +++ b/hw/misc/sifive_u_otp.c | 22 | +++ b/target/riscv/insn16.decode |
21 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) | 23 | @@ -XXX,XX +XXX,XX @@ |
22 | 24 | %imm_cb 12:s1 5:2 2:1 10:2 3:2 !function=ex_shift_1 | |
23 | if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) { | 25 | %imm_cj 12:s1 8:1 9:2 6:1 7:1 2:1 11:1 3:3 !function=ex_shift_1 |
24 | error_setg(errp, "failed to read the initial flash content"); | 26 | |
25 | + return; | 27 | -%shimm_6bit 12:1 2:5 !function=ex_rvc_shifti |
26 | } | 28 | +%shlimm_6bit 12:1 2:5 !function=ex_rvc_shiftli |
27 | } | 29 | +%shrimm_6bit 12:1 2:5 !function=ex_rvc_shiftri |
28 | } | 30 | %uimm_6bit_lq 2:4 12:1 6:1 !function=ex_shift_4 |
29 | -} | 31 | %uimm_6bit_ld 2:3 12:1 5:2 !function=ex_shift_3 |
30 | - | 32 | %uimm_6bit_lw 2:2 12:1 4:3 !function=ex_shift_2 |
31 | -static void sifive_u_otp_reset(DeviceState *dev) | 33 | @@ -XXX,XX +XXX,XX @@ |
32 | -{ | 34 | @c_addi16sp ... . ..... ..... .. &i imm=%imm_addi16sp rs1=2 rd=2 |
33 | - SiFiveUOTPState *s = SIFIVE_U_OTP(dev); | 35 | |
34 | 36 | @c_shift ... . .. ... ..... .. \ | |
35 | /* Initialize all fuses' initial value to 0xFFs */ | 37 | - &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shimm_6bit |
36 | memset(s->fuse, 0xff, sizeof(s->fuse)); | 38 | + &shift rd=%rs1_3 rs1=%rs1_3 shamt=%shrimm_6bit |
37 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_reset(DeviceState *dev) | 39 | @c_shift2 ... . .. ... ..... .. \ |
38 | serial_data = s->serial; | 40 | - &shift rd=%rd rs1=%rd shamt=%shimm_6bit |
39 | if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD, | 41 | + &shift rd=%rd rs1=%rd shamt=%shlimm_6bit |
40 | &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { | 42 | |
41 | - error_report("write error index<%d>", index); | 43 | @c_andi ... . .. ... ..... .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3 |
42 | + error_setg(errp, "failed to write index<%d>", index); | 44 | |
43 | + return; | 45 | diff --git a/disas/riscv.c b/disas/riscv.c |
44 | } | 46 | index XXXXXXX..XXXXXXX 100644 |
45 | 47 | --- a/disas/riscv.c | |
46 | serial_data = ~(s->serial); | 48 | +++ b/disas/riscv.c |
47 | if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD, | 49 | @@ -XXX,XX +XXX,XX @@ static int32_t operand_sbimm12(rv_inst inst) |
48 | &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { | 50 | ((inst << 56) >> 63) << 11; |
49 | - error_report("write error index<%d>", index + 1); | ||
50 | + error_setg(errp, "failed to write index<%d>", index + 1); | ||
51 | + return; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data) | ||
56 | |||
57 | device_class_set_props(dc, sifive_u_otp_properties); | ||
58 | dc->realize = sifive_u_otp_realize; | ||
59 | - dc->reset = sifive_u_otp_reset; | ||
60 | } | 51 | } |
61 | 52 | ||
62 | static const TypeInfo sifive_u_otp_info = { | 53 | -static uint32_t operand_cimmsh6(rv_inst inst) |
54 | +static uint32_t operand_cimmshl6(rv_inst inst, rv_isa isa) | ||
55 | { | ||
56 | - return ((inst << 51) >> 63) << 5 | | ||
57 | + int imm = ((inst << 51) >> 63) << 5 | | ||
58 | (inst << 57) >> 59; | ||
59 | + if (isa == rv128) { | ||
60 | + imm = imm ? imm : 64; | ||
61 | + } | ||
62 | + return imm; | ||
63 | +} | ||
64 | + | ||
65 | +static uint32_t operand_cimmshr6(rv_inst inst, rv_isa isa) | ||
66 | +{ | ||
67 | + int imm = ((inst << 51) >> 63) << 5 | | ||
68 | + (inst << 57) >> 59; | ||
69 | + if (isa == rv128) { | ||
70 | + imm = imm | (imm & 32) << 1; | ||
71 | + imm = imm ? imm : 64; | ||
72 | + } | ||
73 | + return imm; | ||
74 | } | ||
75 | |||
76 | static int32_t operand_cimmi(rv_inst inst) | ||
77 | @@ -XXX,XX +XXX,XX @@ static uint32_t operand_rnum(rv_inst inst) | ||
78 | |||
79 | /* decode operands */ | ||
80 | |||
81 | -static void decode_inst_operands(rv_decode *dec) | ||
82 | +static void decode_inst_operands(rv_decode *dec, rv_isa isa) | ||
83 | { | ||
84 | rv_inst inst = dec->inst; | ||
85 | dec->codec = opcode_data[dec->op].codec; | ||
86 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec) | ||
87 | case rv_codec_cb_sh6: | ||
88 | dec->rd = dec->rs1 = operand_crs1rdq(inst) + 8; | ||
89 | dec->rs2 = rv_ireg_zero; | ||
90 | - dec->imm = operand_cimmsh6(inst); | ||
91 | + dec->imm = operand_cimmshr6(inst, isa); | ||
92 | break; | ||
93 | case rv_codec_ci: | ||
94 | dec->rd = dec->rs1 = operand_crs1rd(inst); | ||
95 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec) | ||
96 | case rv_codec_ci_sh6: | ||
97 | dec->rd = dec->rs1 = operand_crs1rd(inst); | ||
98 | dec->rs2 = rv_ireg_zero; | ||
99 | - dec->imm = operand_cimmsh6(inst); | ||
100 | + dec->imm = operand_cimmshl6(inst, isa); | ||
101 | break; | ||
102 | case rv_codec_ci_16sp: | ||
103 | dec->rd = rv_ireg_sp; | ||
104 | @@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst) | ||
105 | dec.pc = pc; | ||
106 | dec.inst = inst; | ||
107 | decode_inst_opcode(&dec, isa); | ||
108 | - decode_inst_operands(&dec); | ||
109 | + decode_inst_operands(&dec, isa); | ||
110 | decode_inst_decompress(&dec, isa); | ||
111 | decode_inst_lift_pseudo(&dec); | ||
112 | format_inst(buf, buflen, 16, &dec); | ||
113 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
114 | index XXXXXXX..XXXXXXX 100644 | ||
115 | --- a/target/riscv/translate.c | ||
116 | +++ b/target/riscv/translate.c | ||
117 | @@ -XXX,XX +XXX,XX @@ static int ex_rvc_register(DisasContext *ctx, int reg) | ||
118 | return 8 + reg; | ||
119 | } | ||
120 | |||
121 | -static int ex_rvc_shifti(DisasContext *ctx, int imm) | ||
122 | +static int ex_rvc_shiftli(DisasContext *ctx, int imm) | ||
123 | { | ||
124 | /* For RV128 a shamt of 0 means a shift by 64. */ | ||
125 | - return imm ? imm : 64; | ||
126 | + if (get_ol(ctx) == MXL_RV128) { | ||
127 | + imm = imm ? imm : 64; | ||
128 | + } | ||
129 | + return imm; | ||
130 | +} | ||
131 | + | ||
132 | +static int ex_rvc_shiftri(DisasContext *ctx, int imm) | ||
133 | +{ | ||
134 | + /* | ||
135 | + * For RV128 a shamt of 0 means a shift by 64, furthermore, for right | ||
136 | + * shifts, the shamt is sign-extended. | ||
137 | + */ | ||
138 | + if (get_ol(ctx) == MXL_RV128) { | ||
139 | + imm = imm | (imm & 32) << 1; | ||
140 | + imm = imm ? imm : 64; | ||
141 | + } | ||
142 | + return imm; | ||
143 | } | ||
144 | |||
145 | /* Include the auto-generated decoder for 32 bit insn */ | ||
63 | -- | 146 | -- |
64 | 2.31.1 | 147 | 2.37.2 |
65 | 148 | ||
66 | 149 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | - Zmmul is ratified and is now version 1.0 | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-Id: <20220710101546.3907-1-liweiwei@iscas.ac.cn> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/cpu.c | 3 ++- | ||
12 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
13 | |||
14 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/cpu.c | ||
17 | +++ b/target/riscv/cpu.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
19 | DEFINE_PROP_BOOL("zhinx", RISCVCPU, cfg.ext_zhinx, false), | ||
20 | DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false), | ||
21 | |||
22 | + DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false), | ||
23 | + | ||
24 | /* Vendor-specific custom extensions */ | ||
25 | DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false), | ||
26 | |||
27 | /* These are experimental so mark with 'x-' */ | ||
28 | DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), | ||
29 | - DEFINE_PROP_BOOL("x-zmmul", RISCVCPU, cfg.ext_zmmul, false), | ||
30 | /* ePMP 0.9.3 */ | ||
31 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), | ||
32 | DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false), | ||
33 | -- | ||
34 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Jason A. Donenfeld" <Jason@zx2c4.com> | ||
1 | 2 | ||
3 | If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to | ||
4 | initialize early. Set this using the usual guest random number | ||
5 | generation function. This is confirmed to successfully initialize the | ||
6 | RNG on Linux 5.19-rc2. | ||
7 | |||
8 | Cc: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> | ||
10 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
11 | Message-Id: <20220613115810.178210-1-Jason@zx2c4.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | hw/riscv/virt.c | 6 ++++++ | ||
15 | 1 file changed, 6 insertions(+) | ||
16 | |||
17 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/riscv/virt.c | ||
20 | +++ b/hw/riscv/virt.c | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | #include "qemu/osdep.h" | ||
23 | #include "qemu/units.h" | ||
24 | #include "qemu/error-report.h" | ||
25 | +#include "qemu/guest-random.h" | ||
26 | #include "qapi/error.h" | ||
27 | #include "hw/boards.h" | ||
28 | #include "hw/loader.h" | ||
29 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, | ||
30 | MachineState *mc = MACHINE(s); | ||
31 | uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1; | ||
32 | uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1; | ||
33 | + uint8_t rng_seed[32]; | ||
34 | |||
35 | if (mc->dtb) { | ||
36 | mc->fdt = load_device_tree(mc->dtb, &s->fdt_size); | ||
37 | @@ -XXX,XX +XXX,XX @@ update_bootargs: | ||
38 | if (cmdline && *cmdline) { | ||
39 | qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline); | ||
40 | } | ||
41 | + | ||
42 | + /* Pass seed to RNG */ | ||
43 | + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); | ||
44 | + qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed)); | ||
45 | } | ||
46 | |||
47 | static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, | ||
48 | -- | ||
49 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | There are 3 suggested privilege mode combinations listed in section 1.2 | ||
4 | of the riscv-privileged spec(draft-20220717): | ||
5 | 1) M, 2) M, U 3) M, S, U | ||
6 | |||
7 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
8 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
11 | Message-Id: <20220718130955.11899-2-liweiwei@iscas.ac.cn> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/cpu.c | 6 ++++++ | ||
15 | 1 file changed, 6 insertions(+) | ||
16 | |||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/cpu.c | ||
20 | +++ b/target/riscv/cpu.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
22 | return; | ||
23 | } | ||
24 | |||
25 | + if (cpu->cfg.ext_s && !cpu->cfg.ext_u) { | ||
26 | + error_setg(errp, | ||
27 | + "Setting S extension without U extension is illegal"); | ||
28 | + return; | ||
29 | + } | ||
30 | + | ||
31 | if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { | ||
32 | error_setg(errp, "F extension requires Zicsr"); | ||
33 | return; | ||
34 | -- | ||
35 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | Add check for "H depends on an I base integer ISA with 32 x registers" | ||
4 | which is stated at the beginning of chapter 8 of the riscv-privileged | ||
5 | spec(draft-20220717) | ||
6 | |||
7 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
8 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
11 | Message-Id: <20220718130955.11899-3-liweiwei@iscas.ac.cn> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/cpu.c | 6 ++++++ | ||
15 | 1 file changed, 6 insertions(+) | ||
16 | |||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/cpu.c | ||
20 | +++ b/target/riscv/cpu.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
22 | return; | ||
23 | } | ||
24 | |||
25 | + if (cpu->cfg.ext_h && !cpu->cfg.ext_i) { | ||
26 | + error_setg(errp, | ||
27 | + "H depends on an I base integer ISA with 32 x registers"); | ||
28 | + return; | ||
29 | + } | ||
30 | + | ||
31 | if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { | ||
32 | error_setg(errp, "F extension requires Zicsr"); | ||
33 | return; | ||
34 | -- | ||
35 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | Fix the lines with over 80 characters | ||
4 | |||
5 | Fix the lines which are obviously misalgined with other lines in the | ||
6 | same group | ||
7 | |||
8 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
9 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
12 | Message-Id: <20220718130955.11899-4-liweiwei@iscas.ac.cn> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/csr.c | 441 ++++++++++++++++++++++++--------------------- | ||
16 | 1 file changed, 234 insertions(+), 207 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/csr.c | ||
21 | +++ b/target/riscv/csr.c | ||
22 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
23 | [CSR_FRM] = { "frm", fs, read_frm, write_frm }, | ||
24 | [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr }, | ||
25 | /* Vector CSRs */ | ||
26 | - [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart, | ||
27 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
28 | - [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat, | ||
29 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
30 | - [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm, | ||
31 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
32 | - [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr, | ||
33 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
34 | - [CSR_VL] = { "vl", vs, read_vl, | ||
35 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
36 | - [CSR_VTYPE] = { "vtype", vs, read_vtype, | ||
37 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
38 | - [CSR_VLENB] = { "vlenb", vs, read_vlenb, | ||
39 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
40 | + [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart, | ||
41 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
42 | + [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat, | ||
43 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
44 | + [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm, | ||
45 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
46 | + [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr, | ||
47 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
48 | + [CSR_VL] = { "vl", vs, read_vl, | ||
49 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
50 | + [CSR_VTYPE] = { "vtype", vs, read_vtype, | ||
51 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
52 | + [CSR_VLENB] = { "vlenb", vs, read_vlenb, | ||
53 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
54 | /* User Timers and Counters */ | ||
55 | [CSR_CYCLE] = { "cycle", ctr, read_hpmcounter }, | ||
56 | [CSR_INSTRET] = { "instret", ctr, read_hpmcounter }, | ||
57 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
58 | |||
59 | #if !defined(CONFIG_USER_ONLY) | ||
60 | /* Machine Timers and Counters */ | ||
61 | - [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, write_mhpmcounter}, | ||
62 | - [CSR_MINSTRET] = { "minstret", any, read_hpmcounter, write_mhpmcounter}, | ||
63 | - [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh, write_mhpmcounterh}, | ||
64 | - [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh, write_mhpmcounterh}, | ||
65 | + [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, | ||
66 | + write_mhpmcounter }, | ||
67 | + [CSR_MINSTRET] = { "minstret", any, read_hpmcounter, | ||
68 | + write_mhpmcounter }, | ||
69 | + [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh, | ||
70 | + write_mhpmcounterh }, | ||
71 | + [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh, | ||
72 | + write_mhpmcounterh }, | ||
73 | |||
74 | /* Machine Information Registers */ | ||
75 | [CSR_MVENDORID] = { "mvendorid", any, read_mvendorid }, | ||
76 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
77 | [CSR_MHARTID] = { "mhartid", any, read_mhartid }, | ||
78 | |||
79 | [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero, | ||
80 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
81 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
82 | /* Machine Trap Setup */ | ||
83 | - [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL, | ||
84 | - read_mstatus_i128 }, | ||
85 | - [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL, | ||
86 | - read_misa_i128 }, | ||
87 | - [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg }, | ||
88 | - [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg }, | ||
89 | - [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie }, | ||
90 | - [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec }, | ||
91 | - [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren }, | ||
92 | - | ||
93 | - [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush }, | ||
94 | + [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, | ||
95 | + NULL, read_mstatus_i128 }, | ||
96 | + [CSR_MISA] = { "misa", any, read_misa, write_misa, | ||
97 | + NULL, read_misa_i128 }, | ||
98 | + [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg }, | ||
99 | + [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg }, | ||
100 | + [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie }, | ||
101 | + [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec }, | ||
102 | + [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, | ||
103 | + write_mcounteren }, | ||
104 | + | ||
105 | + [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, | ||
106 | + write_mstatush }, | ||
107 | |||
108 | /* Machine Trap Handling */ | ||
109 | - [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, NULL, | ||
110 | - read_mscratch_i128, write_mscratch_i128 }, | ||
111 | + [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch, | ||
112 | + NULL, read_mscratch_i128, write_mscratch_i128 }, | ||
113 | [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc }, | ||
114 | [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause }, | ||
115 | [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, | ||
116 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
117 | [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg }, | ||
118 | |||
119 | /* Machine-Level Interrupts (AIA) */ | ||
120 | - [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei }, | ||
121 | - [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi }, | ||
122 | + [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei }, | ||
123 | + [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi }, | ||
124 | |||
125 | /* Virtual Interrupts for Supervisor Level (AIA) */ | ||
126 | - [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore }, | ||
127 | - [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore }, | ||
128 | + [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore }, | ||
129 | + [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore }, | ||
130 | |||
131 | /* Machine-Level High-Half CSRs (AIA) */ | ||
132 | [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh }, | ||
133 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
134 | |||
135 | /* Execution environment configuration */ | ||
136 | [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg, | ||
137 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
138 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
139 | [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh, | ||
140 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
141 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
142 | [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg, | ||
143 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
144 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
145 | [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg, | ||
146 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
147 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
148 | [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh, | ||
149 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
150 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
151 | |||
152 | /* Supervisor Trap Setup */ | ||
153 | - [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL, | ||
154 | - read_sstatus_i128 }, | ||
155 | - [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie }, | ||
156 | - [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec }, | ||
157 | - [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren }, | ||
158 | + [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, | ||
159 | + NULL, read_sstatus_i128 }, | ||
160 | + [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie }, | ||
161 | + [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec }, | ||
162 | + [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, | ||
163 | + write_scounteren }, | ||
164 | |||
165 | /* Supervisor Trap Handling */ | ||
166 | - [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, NULL, | ||
167 | - read_sscratch_i128, write_sscratch_i128 }, | ||
168 | + [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch, | ||
169 | + NULL, read_sscratch_i128, write_sscratch_i128 }, | ||
170 | [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc }, | ||
171 | [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause }, | ||
172 | - [CSR_STVAL] = { "stval", smode, read_stval, write_stval }, | ||
173 | + [CSR_STVAL] = { "stval", smode, read_stval, write_stval }, | ||
174 | [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip }, | ||
175 | |||
176 | /* Supervisor Protection and Translation */ | ||
177 | - [CSR_SATP] = { "satp", smode, read_satp, write_satp }, | ||
178 | + [CSR_SATP] = { "satp", smode, read_satp, write_satp }, | ||
179 | |||
180 | /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */ | ||
181 | [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect }, | ||
182 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
183 | [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh }, | ||
184 | [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph }, | ||
185 | |||
186 | - [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus, | ||
187 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
188 | - [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg, | ||
189 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
190 | + [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus, | ||
191 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
192 | + [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg, | ||
193 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
194 | [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg, | ||
195 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
196 | - [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip, | ||
197 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
198 | - [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip, | ||
199 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
200 | - [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie, | ||
201 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
202 | - [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren, | ||
203 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
204 | - [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie, | ||
205 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
206 | - [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval, | ||
207 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
208 | - [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst, | ||
209 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
210 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
211 | + [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip, | ||
212 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
213 | + [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip, | ||
214 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
215 | + [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie, | ||
216 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
217 | + [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, | ||
218 | + write_hcounteren, | ||
219 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
220 | + [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie, | ||
221 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
222 | + [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval, | ||
223 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
224 | + [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst, | ||
225 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
226 | [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, | ||
227 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
228 | - [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp, | ||
229 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
230 | - [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta, | ||
231 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
232 | - [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah, | ||
233 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
234 | - | ||
235 | - [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus, | ||
236 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
237 | - [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip, | ||
238 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
239 | - [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie , | ||
240 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
241 | - [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec, | ||
242 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
243 | - [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch, | ||
244 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
245 | - [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc, | ||
246 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
247 | - [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause, | ||
248 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
249 | - [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval, | ||
250 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
251 | - [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp, | ||
252 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
253 | - | ||
254 | - [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2, | ||
255 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
256 | - [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst, | ||
257 | - .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
258 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
259 | + [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp, | ||
260 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
261 | + [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, | ||
262 | + write_htimedelta, | ||
263 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
264 | + [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, | ||
265 | + write_htimedeltah, | ||
266 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
267 | + | ||
268 | + [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, | ||
269 | + write_vsstatus, | ||
270 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
271 | + [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip, | ||
272 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
273 | + [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie , | ||
274 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
275 | + [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec, | ||
276 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
277 | + [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, | ||
278 | + write_vsscratch, | ||
279 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
280 | + [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc, | ||
281 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
282 | + [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause, | ||
283 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
284 | + [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval, | ||
285 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
286 | + [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp, | ||
287 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
288 | + | ||
289 | + [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2, | ||
290 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
291 | + [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst, | ||
292 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
293 | |||
294 | /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ | ||
295 | [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore }, | ||
296 | - [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl }, | ||
297 | - [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 }, | ||
298 | - [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 }, | ||
299 | + [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, | ||
300 | + write_hvictl }, | ||
301 | + [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, | ||
302 | + write_hviprio1 }, | ||
303 | + [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, | ||
304 | + write_hviprio2 }, | ||
305 | |||
306 | /* | ||
307 | * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) | ||
308 | */ | ||
309 | - [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, rmw_xiselect }, | ||
310 | - [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg }, | ||
311 | + [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, | ||
312 | + rmw_xiselect }, | ||
313 | + [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg }, | ||
314 | |||
315 | /* VS-Level Interrupts (H-extension with AIA) */ | ||
316 | [CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei }, | ||
317 | [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi }, | ||
318 | |||
319 | /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ | ||
320 | - [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh }, | ||
321 | - [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore }, | ||
322 | + [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, | ||
323 | + rmw_hidelegh }, | ||
324 | + [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, | ||
325 | + write_ignore }, | ||
326 | [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph }, | ||
327 | - [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h }, | ||
328 | - [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h }, | ||
329 | + [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, | ||
330 | + write_hviprio1h }, | ||
331 | + [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, | ||
332 | + write_hviprio2h }, | ||
333 | [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh }, | ||
334 | [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph }, | ||
335 | |||
336 | /* Physical Memory Protection */ | ||
337 | [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg, | ||
338 | - .min_priv_ver = PRIV_VERSION_1_11_0 }, | ||
339 | + .min_priv_ver = PRIV_VERSION_1_11_0 }, | ||
340 | [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg }, | ||
341 | [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg }, | ||
342 | [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg }, | ||
343 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
344 | [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata }, | ||
345 | |||
346 | /* User Pointer Masking */ | ||
347 | - [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte }, | ||
348 | - [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask }, | ||
349 | - [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, write_upmbase }, | ||
350 | + [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte }, | ||
351 | + [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, | ||
352 | + write_upmmask }, | ||
353 | + [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase, | ||
354 | + write_upmbase }, | ||
355 | /* Machine Pointer Masking */ | ||
356 | - [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte }, | ||
357 | - [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, write_mpmmask }, | ||
358 | - [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, write_mpmbase }, | ||
359 | + [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte }, | ||
360 | + [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask, | ||
361 | + write_mpmmask }, | ||
362 | + [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase, | ||
363 | + write_mpmbase }, | ||
364 | /* Supervisor Pointer Masking */ | ||
365 | - [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte }, | ||
366 | - [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, write_spmmask }, | ||
367 | - [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase }, | ||
368 | + [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte }, | ||
369 | + [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask, | ||
370 | + write_spmmask }, | ||
371 | + [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, | ||
372 | + write_spmbase }, | ||
373 | |||
374 | /* Performance Counters */ | ||
375 | [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter }, | ||
376 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
377 | [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_hpmcounter }, | ||
378 | |||
379 | [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_hpmcounter, | ||
380 | - write_mhpmcounter }, | ||
381 | + write_mhpmcounter }, | ||
382 | [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_hpmcounter, | ||
383 | - write_mhpmcounter }, | ||
384 | + write_mhpmcounter }, | ||
385 | [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_hpmcounter, | ||
386 | - write_mhpmcounter }, | ||
387 | + write_mhpmcounter }, | ||
388 | [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_hpmcounter, | ||
389 | - write_mhpmcounter }, | ||
390 | + write_mhpmcounter }, | ||
391 | [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_hpmcounter, | ||
392 | - write_mhpmcounter }, | ||
393 | + write_mhpmcounter }, | ||
394 | [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_hpmcounter, | ||
395 | - write_mhpmcounter }, | ||
396 | + write_mhpmcounter }, | ||
397 | [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_hpmcounter, | ||
398 | - write_mhpmcounter }, | ||
399 | + write_mhpmcounter }, | ||
400 | [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_hpmcounter, | ||
401 | - write_mhpmcounter }, | ||
402 | + write_mhpmcounter }, | ||
403 | [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_hpmcounter, | ||
404 | - write_mhpmcounter }, | ||
405 | + write_mhpmcounter }, | ||
406 | [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_hpmcounter, | ||
407 | - write_mhpmcounter }, | ||
408 | + write_mhpmcounter }, | ||
409 | [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_hpmcounter, | ||
410 | - write_mhpmcounter }, | ||
411 | + write_mhpmcounter }, | ||
412 | [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_hpmcounter, | ||
413 | - write_mhpmcounter }, | ||
414 | + write_mhpmcounter }, | ||
415 | [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_hpmcounter, | ||
416 | - write_mhpmcounter }, | ||
417 | + write_mhpmcounter }, | ||
418 | [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_hpmcounter, | ||
419 | - write_mhpmcounter }, | ||
420 | + write_mhpmcounter }, | ||
421 | [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_hpmcounter, | ||
422 | - write_mhpmcounter }, | ||
423 | + write_mhpmcounter }, | ||
424 | [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_hpmcounter, | ||
425 | - write_mhpmcounter }, | ||
426 | + write_mhpmcounter }, | ||
427 | [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_hpmcounter, | ||
428 | - write_mhpmcounter }, | ||
429 | + write_mhpmcounter }, | ||
430 | [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_hpmcounter, | ||
431 | - write_mhpmcounter }, | ||
432 | + write_mhpmcounter }, | ||
433 | [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_hpmcounter, | ||
434 | - write_mhpmcounter }, | ||
435 | + write_mhpmcounter }, | ||
436 | [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_hpmcounter, | ||
437 | - write_mhpmcounter }, | ||
438 | + write_mhpmcounter }, | ||
439 | [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_hpmcounter, | ||
440 | - write_mhpmcounter }, | ||
441 | + write_mhpmcounter }, | ||
442 | [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_hpmcounter, | ||
443 | - write_mhpmcounter }, | ||
444 | + write_mhpmcounter }, | ||
445 | [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_hpmcounter, | ||
446 | - write_mhpmcounter }, | ||
447 | + write_mhpmcounter }, | ||
448 | [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_hpmcounter, | ||
449 | - write_mhpmcounter }, | ||
450 | + write_mhpmcounter }, | ||
451 | [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_hpmcounter, | ||
452 | - write_mhpmcounter }, | ||
453 | + write_mhpmcounter }, | ||
454 | [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_hpmcounter, | ||
455 | - write_mhpmcounter }, | ||
456 | + write_mhpmcounter }, | ||
457 | [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_hpmcounter, | ||
458 | - write_mhpmcounter }, | ||
459 | + write_mhpmcounter }, | ||
460 | [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_hpmcounter, | ||
461 | - write_mhpmcounter }, | ||
462 | + write_mhpmcounter }, | ||
463 | [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_hpmcounter, | ||
464 | - write_mhpmcounter }, | ||
465 | + write_mhpmcounter }, | ||
466 | |||
467 | [CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit, | ||
468 | - write_mcountinhibit, .min_priv_ver = PRIV_VERSION_1_11_0 }, | ||
469 | + write_mcountinhibit, | ||
470 | + .min_priv_ver = PRIV_VERSION_1_11_0 }, | ||
471 | |||
472 | [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent, | ||
473 | - write_mhpmevent }, | ||
474 | + write_mhpmevent }, | ||
475 | [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent, | ||
476 | - write_mhpmevent }, | ||
477 | + write_mhpmevent }, | ||
478 | [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_mhpmevent, | ||
479 | - write_mhpmevent }, | ||
480 | + write_mhpmevent }, | ||
481 | [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_mhpmevent, | ||
482 | - write_mhpmevent }, | ||
483 | + write_mhpmevent }, | ||
484 | [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_mhpmevent, | ||
485 | - write_mhpmevent }, | ||
486 | + write_mhpmevent }, | ||
487 | [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_mhpmevent, | ||
488 | - write_mhpmevent }, | ||
489 | + write_mhpmevent }, | ||
490 | [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_mhpmevent, | ||
491 | - write_mhpmevent }, | ||
492 | + write_mhpmevent }, | ||
493 | [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_mhpmevent, | ||
494 | - write_mhpmevent }, | ||
495 | + write_mhpmevent }, | ||
496 | [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_mhpmevent, | ||
497 | - write_mhpmevent }, | ||
498 | + write_mhpmevent }, | ||
499 | [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_mhpmevent, | ||
500 | - write_mhpmevent }, | ||
501 | + write_mhpmevent }, | ||
502 | [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_mhpmevent, | ||
503 | - write_mhpmevent }, | ||
504 | + write_mhpmevent }, | ||
505 | [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_mhpmevent, | ||
506 | - write_mhpmevent }, | ||
507 | + write_mhpmevent }, | ||
508 | [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_mhpmevent, | ||
509 | - write_mhpmevent }, | ||
510 | + write_mhpmevent }, | ||
511 | [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_mhpmevent, | ||
512 | - write_mhpmevent }, | ||
513 | + write_mhpmevent }, | ||
514 | [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_mhpmevent, | ||
515 | - write_mhpmevent }, | ||
516 | + write_mhpmevent }, | ||
517 | [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_mhpmevent, | ||
518 | - write_mhpmevent }, | ||
519 | + write_mhpmevent }, | ||
520 | [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_mhpmevent, | ||
521 | - write_mhpmevent }, | ||
522 | + write_mhpmevent }, | ||
523 | [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_mhpmevent, | ||
524 | - write_mhpmevent }, | ||
525 | + write_mhpmevent }, | ||
526 | [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_mhpmevent, | ||
527 | - write_mhpmevent }, | ||
528 | + write_mhpmevent }, | ||
529 | [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_mhpmevent, | ||
530 | - write_mhpmevent }, | ||
531 | + write_mhpmevent }, | ||
532 | [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_mhpmevent, | ||
533 | - write_mhpmevent }, | ||
534 | + write_mhpmevent }, | ||
535 | [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_mhpmevent, | ||
536 | - write_mhpmevent }, | ||
537 | + write_mhpmevent }, | ||
538 | [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_mhpmevent, | ||
539 | - write_mhpmevent }, | ||
540 | + write_mhpmevent }, | ||
541 | [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_mhpmevent, | ||
542 | - write_mhpmevent }, | ||
543 | + write_mhpmevent }, | ||
544 | [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_mhpmevent, | ||
545 | - write_mhpmevent }, | ||
546 | + write_mhpmevent }, | ||
547 | [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_mhpmevent, | ||
548 | - write_mhpmevent }, | ||
549 | + write_mhpmevent }, | ||
550 | [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_mhpmevent, | ||
551 | - write_mhpmevent }, | ||
552 | + write_mhpmevent }, | ||
553 | [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_mhpmevent, | ||
554 | - write_mhpmevent }, | ||
555 | + write_mhpmevent }, | ||
556 | [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent, | ||
557 | - write_mhpmevent }, | ||
558 | + write_mhpmevent }, | ||
559 | |||
560 | [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh }, | ||
561 | [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh }, | ||
562 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
563 | [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_hpmcounterh }, | ||
564 | |||
565 | [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", mctr32, read_hpmcounterh, | ||
566 | - write_mhpmcounterh }, | ||
567 | + write_mhpmcounterh }, | ||
568 | [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", mctr32, read_hpmcounterh, | ||
569 | - write_mhpmcounterh }, | ||
570 | + write_mhpmcounterh }, | ||
571 | [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", mctr32, read_hpmcounterh, | ||
572 | - write_mhpmcounterh }, | ||
573 | + write_mhpmcounterh }, | ||
574 | [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", mctr32, read_hpmcounterh, | ||
575 | - write_mhpmcounterh }, | ||
576 | + write_mhpmcounterh }, | ||
577 | [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", mctr32, read_hpmcounterh, | ||
578 | - write_mhpmcounterh }, | ||
579 | + write_mhpmcounterh }, | ||
580 | [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", mctr32, read_hpmcounterh, | ||
581 | - write_mhpmcounterh }, | ||
582 | + write_mhpmcounterh }, | ||
583 | [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", mctr32, read_hpmcounterh, | ||
584 | - write_mhpmcounterh }, | ||
585 | + write_mhpmcounterh }, | ||
586 | [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32, read_hpmcounterh, | ||
587 | - write_mhpmcounterh }, | ||
588 | + write_mhpmcounterh }, | ||
589 | [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32, read_hpmcounterh, | ||
590 | - write_mhpmcounterh }, | ||
591 | + write_mhpmcounterh }, | ||
592 | [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32, read_hpmcounterh, | ||
593 | - write_mhpmcounterh }, | ||
594 | + write_mhpmcounterh }, | ||
595 | [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32, read_hpmcounterh, | ||
596 | - write_mhpmcounterh }, | ||
597 | + write_mhpmcounterh }, | ||
598 | [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32, read_hpmcounterh, | ||
599 | - write_mhpmcounterh }, | ||
600 | + write_mhpmcounterh }, | ||
601 | [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32, read_hpmcounterh, | ||
602 | - write_mhpmcounterh }, | ||
603 | + write_mhpmcounterh }, | ||
604 | [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32, read_hpmcounterh, | ||
605 | - write_mhpmcounterh }, | ||
606 | + write_mhpmcounterh }, | ||
607 | [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32, read_hpmcounterh, | ||
608 | - write_mhpmcounterh }, | ||
609 | + write_mhpmcounterh }, | ||
610 | [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32, read_hpmcounterh, | ||
611 | - write_mhpmcounterh }, | ||
612 | + write_mhpmcounterh }, | ||
613 | [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32, read_hpmcounterh, | ||
614 | - write_mhpmcounterh }, | ||
615 | + write_mhpmcounterh }, | ||
616 | [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32, read_hpmcounterh, | ||
617 | - write_mhpmcounterh }, | ||
618 | + write_mhpmcounterh }, | ||
619 | [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32, read_hpmcounterh, | ||
620 | - write_mhpmcounterh }, | ||
621 | + write_mhpmcounterh }, | ||
622 | [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32, read_hpmcounterh, | ||
623 | - write_mhpmcounterh }, | ||
624 | + write_mhpmcounterh }, | ||
625 | [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32, read_hpmcounterh, | ||
626 | - write_mhpmcounterh }, | ||
627 | + write_mhpmcounterh }, | ||
628 | [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32, read_hpmcounterh, | ||
629 | - write_mhpmcounterh }, | ||
630 | + write_mhpmcounterh }, | ||
631 | [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32, read_hpmcounterh, | ||
632 | - write_mhpmcounterh }, | ||
633 | + write_mhpmcounterh }, | ||
634 | [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32, read_hpmcounterh, | ||
635 | - write_mhpmcounterh }, | ||
636 | + write_mhpmcounterh }, | ||
637 | [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32, read_hpmcounterh, | ||
638 | - write_mhpmcounterh }, | ||
639 | + write_mhpmcounterh }, | ||
640 | [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32, read_hpmcounterh, | ||
641 | - write_mhpmcounterh }, | ||
642 | + write_mhpmcounterh }, | ||
643 | [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32, read_hpmcounterh, | ||
644 | - write_mhpmcounterh }, | ||
645 | + write_mhpmcounterh }, | ||
646 | [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32, read_hpmcounterh, | ||
647 | - write_mhpmcounterh }, | ||
648 | + write_mhpmcounterh }, | ||
649 | [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh, | ||
650 | - write_mhpmcounterh }, | ||
651 | + write_mhpmcounterh }, | ||
652 | #endif /* !CONFIG_USER_ONLY */ | ||
653 | }; | ||
654 | -- | ||
655 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | Add umode/umode32 predicate for mcounteren, menvcfg/menvcfgh | ||
4 | |||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
9 | Message-Id: <20220718130955.11899-5-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/csr.c | 24 +++++++++++++++++++++--- | ||
13 | 1 file changed, 21 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/csr.c | ||
18 | +++ b/target/riscv/csr.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static RISCVException hmode32(CPURISCVState *env, int csrno) | ||
20 | |||
21 | } | ||
22 | |||
23 | +static RISCVException umode(CPURISCVState *env, int csrno) | ||
24 | +{ | ||
25 | + if (riscv_has_ext(env, RVU)) { | ||
26 | + return RISCV_EXCP_NONE; | ||
27 | + } | ||
28 | + | ||
29 | + return RISCV_EXCP_ILLEGAL_INST; | ||
30 | +} | ||
31 | + | ||
32 | +static RISCVException umode32(CPURISCVState *env, int csrno) | ||
33 | +{ | ||
34 | + if (riscv_cpu_mxl(env) != MXL_RV32) { | ||
35 | + return RISCV_EXCP_ILLEGAL_INST; | ||
36 | + } | ||
37 | + | ||
38 | + return umode(env, csrno); | ||
39 | +} | ||
40 | + | ||
41 | /* Checks if PointerMasking registers could be accessed */ | ||
42 | static RISCVException pointer_masking(CPURISCVState *env, int csrno) | ||
43 | { | ||
44 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
45 | [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg }, | ||
46 | [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie }, | ||
47 | [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec }, | ||
48 | - [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, | ||
49 | + [CSR_MCOUNTEREN] = { "mcounteren", umode, read_mcounteren, | ||
50 | write_mcounteren }, | ||
51 | |||
52 | [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, | ||
53 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
54 | [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph }, | ||
55 | |||
56 | /* Execution environment configuration */ | ||
57 | - [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg, | ||
58 | + [CSR_MENVCFG] = { "menvcfg", umode, read_menvcfg, write_menvcfg, | ||
59 | .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
60 | - [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh, | ||
61 | + [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh, | ||
62 | .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
63 | [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg, | ||
64 | .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
65 | -- | ||
66 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | Add check for the implicit dependence between H and S | ||
4 | |||
5 | Csrs only existed in RV32 will not trigger virtual instruction fault | ||
6 | when not in RV32 based on section 8.6.1 of riscv-privileged spec | ||
7 | (draft-20220717) | ||
8 | |||
9 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
11 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-Id: <20220718130955.11899-6-liweiwei@iscas.ac.cn> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/cpu.c | 5 +++++ | ||
17 | target/riscv/csr.c | 9 ++------- | ||
18 | 2 files changed, 7 insertions(+), 7 deletions(-) | ||
19 | |||
20 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/target/riscv/cpu.c | ||
23 | +++ b/target/riscv/cpu.c | ||
24 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
25 | return; | ||
26 | } | ||
27 | |||
28 | + if (cpu->cfg.ext_h && !cpu->cfg.ext_s) { | ||
29 | + error_setg(errp, "H extension implicitly requires S-mode"); | ||
30 | + return; | ||
31 | + } | ||
32 | + | ||
33 | if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) { | ||
34 | error_setg(errp, "F extension requires Zicsr"); | ||
35 | return; | ||
36 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/target/riscv/csr.c | ||
39 | +++ b/target/riscv/csr.c | ||
40 | @@ -XXX,XX +XXX,XX @@ static int aia_smode32(CPURISCVState *env, int csrno) | ||
41 | |||
42 | static RISCVException hmode(CPURISCVState *env, int csrno) | ||
43 | { | ||
44 | - if (riscv_has_ext(env, RVS) && | ||
45 | - riscv_has_ext(env, RVH)) { | ||
46 | + if (riscv_has_ext(env, RVH)) { | ||
47 | /* Hypervisor extension is supported */ | ||
48 | if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) || | ||
49 | env->priv == PRV_M) { | ||
50 | @@ -XXX,XX +XXX,XX @@ static RISCVException hmode(CPURISCVState *env, int csrno) | ||
51 | static RISCVException hmode32(CPURISCVState *env, int csrno) | ||
52 | { | ||
53 | if (riscv_cpu_mxl(env) != MXL_RV32) { | ||
54 | - if (!riscv_cpu_virt_enabled(env)) { | ||
55 | - return RISCV_EXCP_ILLEGAL_INST; | ||
56 | - } else { | ||
57 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
58 | - } | ||
59 | + return RISCV_EXCP_ILLEGAL_INST; | ||
60 | } | ||
61 | |||
62 | return hmode(env, csrno); | ||
63 | -- | ||
64 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | Just add 1 to the effective privledge level when in HS mode, then reuse | ||
4 | the check of 'effective_priv < csr_priv' in riscv_csrrw_check to replace | ||
5 | the privilege level related check in hmode. Then, hmode will only check | ||
6 | whether H extension is supported. | ||
7 | |||
8 | When accessing Hypervior CSRs: | ||
9 | 1) If accessing from M privilege level, the check of | ||
10 | 'effective_priv< csr_priv' passes, returns hmode(...) which will return | ||
11 | RISCV_EXCP_ILLEGAL_INST when H extension is not supported and return | ||
12 | RISCV_EXCP_NONE otherwise. | ||
13 | 2) If accessing from HS privilege level, effective_priv will add 1, | ||
14 | the check passes and also returns hmode(...) too. | ||
15 | 3) If accessing from VS/VU privilege level, the check fails, and | ||
16 | returns RISCV_EXCP_VIRT_INSTRUCTION_FAULT | ||
17 | 4) If accessing from U privilege level, the check fails, and returns | ||
18 | RISCV_EXCP_ILLEGAL_INST | ||
19 | |||
20 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
21 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
22 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
23 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
24 | Message-Id: <20220718130955.11899-7-liweiwei@iscas.ac.cn> | ||
25 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
26 | --- | ||
27 | target/riscv/csr.c | 18 +++++------------- | ||
28 | 1 file changed, 5 insertions(+), 13 deletions(-) | ||
29 | |||
30 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/target/riscv/csr.c | ||
33 | +++ b/target/riscv/csr.c | ||
34 | @@ -XXX,XX +XXX,XX @@ static int aia_smode32(CPURISCVState *env, int csrno) | ||
35 | static RISCVException hmode(CPURISCVState *env, int csrno) | ||
36 | { | ||
37 | if (riscv_has_ext(env, RVH)) { | ||
38 | - /* Hypervisor extension is supported */ | ||
39 | - if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) || | ||
40 | - env->priv == PRV_M) { | ||
41 | - return RISCV_EXCP_NONE; | ||
42 | - } else { | ||
43 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
44 | - } | ||
45 | + return RISCV_EXCP_NONE; | ||
46 | } | ||
47 | |||
48 | return RISCV_EXCP_ILLEGAL_INST; | ||
49 | @@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, | ||
50 | #if !defined(CONFIG_USER_ONLY) | ||
51 | int csr_priv, effective_priv = env->priv; | ||
52 | |||
53 | - if (riscv_has_ext(env, RVH) && env->priv == PRV_S) { | ||
54 | + if (riscv_has_ext(env, RVH) && env->priv == PRV_S && | ||
55 | + !riscv_cpu_virt_enabled(env)) { | ||
56 | /* | ||
57 | - * We are in either HS or VS mode. | ||
58 | - * Add 1 to the effective privledge level to allow us to access the | ||
59 | - * Hypervisor CSRs. The `hmode` predicate will determine if access | ||
60 | - * should be allowed(HS) or if a virtual instruction exception should be | ||
61 | - * raised(VS). | ||
62 | + * We are in HS mode. Add 1 to the effective privledge level to | ||
63 | + * allow us to access the Hypervisor CSRs. | ||
64 | */ | ||
65 | effective_priv++; | ||
66 | } | ||
67 | -- | ||
68 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng.cn@gmail.com> | ||
1 | 2 | ||
3 | Upgrade OpenSBI from v1.0 to v1.1 and the pre-built bios images. | ||
4 | |||
5 | The v1.1 release includes the following commits: | ||
6 | |||
7 | 5b99603 lib: utils/ipi: Fix size check in aclint_mswi_cold_init() | ||
8 | 6dde435 lib: utils/sys: Extend HTIF library to allow custom base address | ||
9 | 8257262 platform: sifive_fu740: do not use a global in da9063_reset/shutdown | ||
10 | fb688d9 platform: sifive_fu740: fix reset when watchdog is running | ||
11 | 5d025eb lib: fix pointer of type 'void *' used in arithmetic | ||
12 | 632f593 lib: sbi: Map only the counters enabled in hardware | ||
13 | 3b7c204 lib: sbi: Disable interrupt during config matching | ||
14 | a26dc60 lib: sbi: Disable interrupt and inhibit counting in M-mode during init | ||
15 | 5d53b55 Makefile: fix build with binutils 2.38 | ||
16 | 6ad8917 lib: fix compilation when strings.h is included | ||
17 | ce4c018 lib: utils/serial: Round UART8250 baud rate divisor to nearest integer | ||
18 | 01250d0 include: sbi: Add AIA related CSR defines | ||
19 | 8f96070 lib: sbi: Detect AIA CSRs at boot-time | ||
20 | 65b4c7c lib: sbi: Use AIA CSRs for local interrupts when available | ||
21 | 222132f lib: sbi: Add sbi_trap_set_external_irqfn() API | ||
22 | 5f56314 lib: utils/irqchip: Allow multiple FDT irqchip drivers | ||
23 | 1050940 include: sbi: Introduce nascent_init() platform callback | ||
24 | 55e79f8 lib: sbi: Enable mie.MEIE bit for IPIs based on external interrupts. | ||
25 | 9f73669 lib: utils/irqchip: Add IMSIC library | ||
26 | 811da5c lib: utils/irqchip: Add FDT based driver for IMSIC | ||
27 | 7127aaa lib: utils: Disable appropriate IMSIC DT nodes in fdt_fixups() | ||
28 | 9979265 lib: utils/irqchip: Add APLIC initialization library | ||
29 | 3461219 lib: utils/irqchip: Add FDT based driver for APLIC | ||
30 | 8e2ef4f lib: utils: Disable appropriate APLIC DT nodes in fdt_fixups() | ||
31 | 3a69cc1 lib: sbi: fix typo in is_region_subset | ||
32 | f2ccf2f lib: sbi: verbose sbi_domain_root_add_memregion | ||
33 | f3f4604 lib: sbi: Add a simple external interrupt handling framework | ||
34 | 4998a71 lib: utils: serial: Initial commit of xlnx-uartlite | ||
35 | 2dfbd3c lib: pmp_set/pmp_get moved errors from runtime to compile time | ||
36 | b6b7220 firmware: Fix code for accessing hart_count and stack_size | ||
37 | d552fc8 lib: Add error messages via conditional compilation for the future | ||
38 | 555bdb1 include: Use static asserts for SBI_PLATFORM_xxx_OFFSET defines | ||
39 | 1b42d3a include: Use static asserts for SBI_SCRATCH_xxx_OFFSET defines | ||
40 | 7924a0b include: Use static asserts for FW_DYNAMIC_INFO_xxx_OFFSET defines | ||
41 | 722f80d include: Add defines for [m|h|s]envcfg CSRs | ||
42 | 31fecad lib: sbi: Detect menvcfg CSR at boot time | ||
43 | 47d6765 lib: sbi: Enable Zicbo[m|z] extensions in the menvcfg CSR | ||
44 | 794986f lib: sbi: Enable Svpbmt extension in the menvcfg CSR | ||
45 | 499601a lib: sbi: Add Smstateen extension defines | ||
46 | d44568a lib: sbi: Detect Smstateen CSRs at boot-time | ||
47 | 3383d6a lib: irqchip/imsic: configure mstateen | ||
48 | 5c5cbb5 lib: utils/serial: support 'reg-offset' property | ||
49 | c1e47d0 include: correct the definition of MSTATUS_VS | ||
50 | 9cd95e1 lib: sbi/hart: preserve csr validation value | ||
51 | 4035ae9 docs: pmu: Improve the PMU DT bindings | ||
52 | d62f6da lib: sbi: Implement Sstc extension | ||
53 | 474a9d4 lib: sbi: Fix mstatus_init() for RV32 when Sscofpmf is not available | ||
54 | e576b3e include: sbi: Define SBI_PMU_HW_EVENT_MAX to 256 | ||
55 | b0c9df5 lib: sbi: Fix mhpmeventh access for rv32 in absence of sscofpmf | ||
56 | 1a754bb lib: sbi: Detect and print privileged spec version | ||
57 | 5a6be99 lib: sbi: Remove 's' and 'u' from misa_string() output | ||
58 | 5b8b377 lib: sbi: Update the name of ISA string printed at boot time | ||
59 | d4b563c lib: sbi: Remove MCOUNTEREN and SCOUNTEREN hart features | ||
60 | dbc3d8f lib: sbi: Remove MCOUNTINHIBT hart feature | ||
61 | 97a17c2 lib: sbi: Remove MENVCFG hart feature | ||
62 | a6ab94f lib: sbi: Fix AIA feature detection | ||
63 | cad6c91 lib: sbi: Convert hart features into hart extensions | ||
64 | be4903a lib: sbi: Detect hart features only once for each hart | ||
65 | 994ace3 lib: sbi: Add sbi_hart_update_extension() function | ||
66 | 023f0ad lib: sbi_platform: Add callback to populate HART extensions | ||
67 | f726f2d Makefile: Allow generated C source to be anywhere in build directory | ||
68 | 7fb474b Makefile: Add support for generating C array at compile time | ||
69 | 73cf511 lib: utils/reset: Generate FDT reset driver list at compile-time | ||
70 | 1e62705 lib: utils/serial: Generate FDT serial driver list at compile-time | ||
71 | bfeb305 lib: utils/timer: Generate FDT timer driver list at compile-time | ||
72 | 3a69d12 lib: utils/irqchip: Generate FDT irqchip driver list at compile-time | ||
73 | 4ee0c57 lib: utils/ipi: Generate FDT ipi driver list at compile-time | ||
74 | 998ed43 lib: utils/i2c: Generate FDT i2c adapter driver list at compile-time | ||
75 | 4eacd82 lib: utils/gpio: Generate FDT gpio driver list at compile-time | ||
76 | a3a3c60 platform: generic: Generate platform override module list at compile-time | ||
77 | 9a7a677 platform: generic: Move Sifive platform overrides into own directory | ||
78 | 851c14d lib: utils/irqchip: fix typo when checking for CPU node | ||
79 | 90a9dd2 lib: utils/fdt: introduce fdt_node_is_enabled() | ||
80 | 616da52 lib: utils: check if CPU node is enabled | ||
81 | 575bb4e platform: generic: check if CPU node is enabled | ||
82 | 1bc67db lib: utils/fdt: rename fdt_parse_max_hart_id | ||
83 | f067bb8 lib: sbi: fix system_opcode_insn | ||
84 | fab0379 lib: utils/fdt: Require match data to be const | ||
85 | 295e5f3 lib: sbi_timer: Drop unnecessary get_platform_ticks wrapper | ||
86 | ff65bfe lib: sbi_illegal_insn: Constify illegal_insn_table | ||
87 | cb8271c lib: sbi_illegal_insn: Add emulation for fence.tso | ||
88 | adc3388 lib: sbi_trap: Redirect exception based on hedeleg | ||
89 | ce1d618 platform: generic: add overrides for vendor extensions | ||
90 | b20ed9f lib: sbi_hsm: Call a device hook during hart resume | ||
91 | 79e42eb lib: sbi_hsm: Assume a consistent resume address | ||
92 | 2ea7799 lib: irqchip/plic: Constify plic_data pointers | ||
93 | 8c362e7 lib: irqchip/plic: Factor out a context init function | ||
94 | 415ecf2 lib: irqchip/plic: Add context save/restore helpers | ||
95 | 2b79b69 lib: irqchip/plic: Add priority save/restore helpers | ||
96 | 69be3df lib: utils/irqchip: Add FDT wrappers for PLIC save/restore functions | ||
97 | 5e56758 lib: utils/irqchip: Add wrapper for T-HEAD PLIC delegation | ||
98 | 9dc5ec5 platform: Add HSM implementation for Allwinner D1 | ||
99 | 551c70c include: sbi: Add mtinst/htinst psuedoinstructions | ||
100 | 187127f lib: sbi: Fixup tinst for exceptions in sbi_misaligned_*() | ||
101 | a07402a lib: sbi: Fix tval and tinst for sbi_get_insn() | ||
102 | c653001 lib: utils: Remove CSRs that set/clear an IMSIC interrupt file bits | ||
103 | 7738345 lib: utils/timer: Add a separate compatible for the D1 CLINT | ||
104 | d76a196 lib: irqchip/plic: fix typo in plic_warm_irqchip_init | ||
105 | 6f1fe98 lib: utils/timer: Remove Allwinner D1 CLINT compatibles | ||
106 | c6fdbcf include: sbi: Change spec version to 1.0 | ||
107 | 3f66465 lib: pmu: allow to use the highest available counter | ||
108 | 4489876 include: Bump-up version to 1.1 | ||
109 | |||
110 | Signed-off-by: Bin Meng <bmeng.cn@gmail.com> | ||
111 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
112 | Message-Id: <20220713090613.204046-1-bmeng.cn@gmail.com> | ||
113 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
114 | --- | ||
115 | .../opensbi-riscv32-generic-fw_dynamic.bin | Bin 108504 -> 117704 bytes | ||
116 | .../opensbi-riscv64-generic-fw_dynamic.bin | Bin 105296 -> 115344 bytes | ||
117 | roms/opensbi | 2 +- | ||
118 | 3 files changed, 1 insertion(+), 1 deletion(-) | ||
119 | |||
120 | diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | ||
121 | index XXXXXXX..XXXXXXX 100644 | ||
122 | Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ | ||
123 | diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | ||
124 | index XXXXXXX..XXXXXXX 100644 | ||
125 | Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ | ||
126 | diff --git a/roms/opensbi b/roms/opensbi | ||
127 | index XXXXXXX..XXXXXXX 160000 | ||
128 | --- a/roms/opensbi | ||
129 | +++ b/roms/opensbi | ||
130 | @@ -1 +1 @@ | ||
131 | -Subproject commit 48f91ee9c960f048c4a7d1da4447d31e04931e38 | ||
132 | +Subproject commit 4489876e933d8ba0d8bc6c64bae71e295d45faac | ||
133 | -- | ||
134 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Alexey Baturo <baturo.alexey@gmail.com> | ||
1 | 2 | ||
3 | Fixes: 4302bef9e178 ("target/riscv: Calculate address according to XLEN") | ||
4 | Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Message-Id: <20220717101543.478533-2-space.monkey.delivers@gmail.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | --- | ||
9 | target/riscv/translate.c | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/target/riscv/translate.c | ||
15 | +++ b/target/riscv/translate.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm) | ||
17 | |||
18 | tcg_gen_addi_tl(addr, src1, imm); | ||
19 | if (ctx->pm_mask_enabled) { | ||
20 | - tcg_gen_and_tl(addr, addr, pm_mask); | ||
21 | + tcg_gen_andc_tl(addr, addr, pm_mask); | ||
22 | } else if (get_xl(ctx) == MXL_RV32) { | ||
23 | tcg_gen_ext32u_tl(addr, addr); | ||
24 | } | ||
25 | -- | ||
26 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Bin Meng <bin.meng@windriver.com> | ||
1 | 2 | ||
3 | Since commit fbf43c7dbf18 ("target/riscv: enable riscv kvm accel"), | ||
4 | KVM accelerator is supported on RISC-V. Let's document it. | ||
5 | |||
6 | Signed-off-by: Bin Meng <bin.meng@windriver.com> | ||
7 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Message-Id: <20220719082635.3741878-1-bin.meng@windriver.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | docs/about/build-platforms.rst | 2 +- | ||
13 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/docs/about/build-platforms.rst | ||
18 | +++ b/docs/about/build-platforms.rst | ||
19 | @@ -XXX,XX +XXX,XX @@ Those hosts are officially supported, with various accelerators: | ||
20 | * - PPC | ||
21 | - kvm, tcg | ||
22 | * - RISC-V | ||
23 | - - tcg | ||
24 | + - kvm, tcg | ||
25 | * - s390x | ||
26 | - kvm, tcg | ||
27 | * - SPARC | ||
28 | -- | ||
29 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | According to v-spec, mask agnostic behavior can be either kept as | ||
4 | undisturbed or set elements' bits to all 1s. To distinguish the | ||
5 | difference of mask policies, QEMU should be able to simulate the mask | ||
6 | agnostic behavior as "set mask elements' bits to all 1s". | ||
7 | |||
8 | There are multiple possibility for agnostic elements according to | ||
9 | v-spec. The main intent of this patch-set tries to add option that | ||
10 | can distinguish between mask policies. Setting agnostic elements to | ||
11 | all 1s allows QEMU to express this. | ||
12 | |||
13 | This is the first commit regarding the optional mask agnostic | ||
14 | behavior. Follow-up commits will add this optional behavior | ||
15 | for all rvv instructions. | ||
16 | |||
17 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
18 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
19 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
21 | Message-Id: <165570784143.17634.35095816584573691-1@git.sr.ht> | ||
22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
23 | --- | ||
24 | target/riscv/cpu.h | 2 ++ | ||
25 | target/riscv/internals.h | 5 +++-- | ||
26 | target/riscv/cpu_helper.c | 2 ++ | ||
27 | target/riscv/translate.c | 2 ++ | ||
28 | target/riscv/vector_helper.c | 8 ++++++++ | ||
29 | target/riscv/insn_trans/trans_rvv.c.inc | 3 +++ | ||
30 | 6 files changed, 20 insertions(+), 2 deletions(-) | ||
31 | |||
32 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/target/riscv/cpu.h | ||
35 | +++ b/target/riscv/cpu.h | ||
36 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
37 | bool ext_zve64f; | ||
38 | bool ext_zmmul; | ||
39 | bool rvv_ta_all_1s; | ||
40 | + bool rvv_ma_all_1s; | ||
41 | |||
42 | uint32_t mvendorid; | ||
43 | uint64_t marchid; | ||
44 | @@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, XL, 20, 2) | ||
45 | FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1) | ||
46 | FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1) | ||
47 | FIELD(TB_FLAGS, VTA, 24, 1) | ||
48 | +FIELD(TB_FLAGS, VMA, 25, 1) | ||
49 | |||
50 | #ifdef TARGET_RISCV32 | ||
51 | #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) | ||
52 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/target/riscv/internals.h | ||
55 | +++ b/target/riscv/internals.h | ||
56 | @@ -XXX,XX +XXX,XX @@ FIELD(VDATA, VM, 0, 1) | ||
57 | FIELD(VDATA, LMUL, 1, 3) | ||
58 | FIELD(VDATA, VTA, 4, 1) | ||
59 | FIELD(VDATA, VTA_ALL_1S, 5, 1) | ||
60 | -FIELD(VDATA, NF, 6, 4) | ||
61 | -FIELD(VDATA, WD, 6, 1) | ||
62 | +FIELD(VDATA, VMA, 6, 1) | ||
63 | +FIELD(VDATA, NF, 7, 4) | ||
64 | +FIELD(VDATA, WD, 7, 1) | ||
65 | |||
66 | /* float point classify helpers */ | ||
67 | target_ulong fclass_h(uint64_t frs1); | ||
68 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/riscv/cpu_helper.c | ||
71 | +++ b/target/riscv/cpu_helper.c | ||
72 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, | ||
73 | flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); | ||
74 | flags = FIELD_DP32(flags, TB_FLAGS, VTA, | ||
75 | FIELD_EX64(env->vtype, VTYPE, VTA)); | ||
76 | + flags = FIELD_DP32(flags, TB_FLAGS, VMA, | ||
77 | + FIELD_EX64(env->vtype, VTYPE, VMA)); | ||
78 | } else { | ||
79 | flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); | ||
80 | } | ||
81 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/target/riscv/translate.c | ||
84 | +++ b/target/riscv/translate.c | ||
85 | @@ -XXX,XX +XXX,XX @@ typedef struct DisasContext { | ||
86 | int8_t lmul; | ||
87 | uint8_t sew; | ||
88 | uint8_t vta; | ||
89 | + uint8_t vma; | ||
90 | bool cfg_vta_all_1s; | ||
91 | target_ulong vstart; | ||
92 | bool vl_eq_vlmax; | ||
93 | @@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
94 | ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW); | ||
95 | ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3); | ||
96 | ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s; | ||
97 | + ctx->vma = FIELD_EX32(tb_flags, TB_FLAGS, VMA) && cpu->cfg.rvv_ma_all_1s; | ||
98 | ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s; | ||
99 | ctx->vstart = env->vstart; | ||
100 | ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX); | ||
101 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
102 | index XXXXXXX..XXXXXXX 100644 | ||
103 | --- a/target/riscv/vector_helper.c | ||
104 | +++ b/target/riscv/vector_helper.c | ||
105 | @@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_vta(uint32_t desc) | ||
106 | return FIELD_EX32(simd_data(desc), VDATA, VTA); | ||
107 | } | ||
108 | |||
109 | +static inline uint32_t vext_vma(uint32_t desc) | ||
110 | +{ | ||
111 | + return FIELD_EX32(simd_data(desc), VDATA, VMA); | ||
112 | +} | ||
113 | + | ||
114 | static inline uint32_t vext_vta_all_1s(uint32_t desc) | ||
115 | { | ||
116 | return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S); | ||
117 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2, | ||
118 | uint32_t vl = env->vl; | ||
119 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
120 | uint32_t vta = vext_vta(desc); | ||
121 | + uint32_t vma = vext_vma(desc); | ||
122 | uint32_t i; | ||
123 | |||
124 | for (i = env->vstart; i < vl; i++) { | ||
125 | if (!vm && !vext_elem_mask(v0, i)) { | ||
126 | + /* set masked-off elements to 1s */ | ||
127 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
128 | continue; | ||
129 | } | ||
130 | fn(vd, vs1, vs2, i); | ||
131 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
132 | index XXXXXXX..XXXXXXX 100644 | ||
133 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
134 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
135 | @@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn, | ||
136 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
137 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
138 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
139 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
140 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
141 | vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2), | ||
142 | cpu_env, s->cfg_ptr->vlen / 8, | ||
143 | @@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a, | ||
144 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
145 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
146 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
147 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
148 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
149 | vreg_ofs(s, a->rs1), | ||
150 | vreg_ofs(s, a->rs2), | ||
151 | @@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a, | ||
152 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
153 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
154 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
155 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
156 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
157 | vreg_ofs(s, a->rs1), | ||
158 | vreg_ofs(s, a->rs2), | ||
159 | -- | ||
160 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-2@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 35 +++++++++++++++++-------- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 5 ++++ | ||
12 | 2 files changed, 29 insertions(+), 11 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, | ||
19 | uint32_t esz = 1 << log2_esz; | ||
20 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
21 | uint32_t vta = vext_vta(desc); | ||
22 | + uint32_t vma = vext_vma(desc); | ||
23 | |||
24 | for (i = env->vstart; i < env->vl; i++, env->vstart++) { | ||
25 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
26 | - continue; | ||
27 | - } | ||
28 | - | ||
29 | k = 0; | ||
30 | while (k < nf) { | ||
31 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
32 | + /* set masked-off elements to 1s */ | ||
33 | + vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz, | ||
34 | + (i + k * max_elems + 1) * esz); | ||
35 | + k++; | ||
36 | + continue; | ||
37 | + } | ||
38 | target_ulong addr = base + stride * i + (k << log2_esz); | ||
39 | ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra); | ||
40 | k++; | ||
41 | @@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base, | ||
42 | uint32_t esz = 1 << log2_esz; | ||
43 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
44 | uint32_t vta = vext_vta(desc); | ||
45 | + uint32_t vma = vext_vma(desc); | ||
46 | |||
47 | /* load bytes from guest memory */ | ||
48 | for (i = env->vstart; i < env->vl; i++, env->vstart++) { | ||
49 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
50 | - continue; | ||
51 | - } | ||
52 | - | ||
53 | k = 0; | ||
54 | while (k < nf) { | ||
55 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
56 | + /* set masked-off elements to 1s */ | ||
57 | + vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz, | ||
58 | + (i + k * max_elems + 1) * esz); | ||
59 | + k++; | ||
60 | + continue; | ||
61 | + } | ||
62 | abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz); | ||
63 | ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra); | ||
64 | k++; | ||
65 | @@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base, | ||
66 | uint32_t esz = 1 << log2_esz; | ||
67 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
68 | uint32_t vta = vext_vta(desc); | ||
69 | + uint32_t vma = vext_vma(desc); | ||
70 | target_ulong addr, offset, remain; | ||
71 | |||
72 | /* probe every access*/ | ||
73 | @@ -XXX,XX +XXX,XX @@ ProbeSuccess: | ||
74 | } | ||
75 | for (i = env->vstart; i < env->vl; i++) { | ||
76 | k = 0; | ||
77 | - if (!vm && !vext_elem_mask(v0, i)) { | ||
78 | - continue; | ||
79 | - } | ||
80 | while (k < nf) { | ||
81 | + if (!vm && !vext_elem_mask(v0, i)) { | ||
82 | + /* set masked-off elements to 1s */ | ||
83 | + vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz, | ||
84 | + (i + k * max_elems + 1) * esz); | ||
85 | + k++; | ||
86 | + continue; | ||
87 | + } | ||
88 | target_ulong addr = base + ((i * nf + k) << log2_esz); | ||
89 | ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra); | ||
90 | k++; | ||
91 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
92 | index XXXXXXX..XXXXXXX 100644 | ||
93 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
94 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
95 | @@ -XXX,XX +XXX,XX @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
96 | data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
97 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
98 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
99 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
100 | return ldst_us_trans(a->rd, a->rs1, data, fn, s, false); | ||
101 | } | ||
102 | |||
103 | @@ -XXX,XX +XXX,XX @@ static bool ld_us_mask_op(DisasContext *s, arg_vlm_v *a, uint8_t eew) | ||
104 | data = FIELD_DP32(data, VDATA, NF, 1); | ||
105 | /* Mask destination register are always tail-agnostic */ | ||
106 | data = FIELD_DP32(data, VDATA, VTA, s->cfg_vta_all_1s); | ||
107 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
108 | return ldst_us_trans(a->rd, a->rs1, data, fn, s, false); | ||
109 | } | ||
110 | |||
111 | @@ -XXX,XX +XXX,XX @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
112 | data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
113 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
114 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
115 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
116 | return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
117 | } | ||
118 | |||
119 | @@ -XXX,XX +XXX,XX @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew) | ||
120 | data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
121 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
122 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
123 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
124 | return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false); | ||
125 | } | ||
126 | |||
127 | @@ -XXX,XX +XXX,XX @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew) | ||
128 | data = FIELD_DP32(data, VDATA, LMUL, emul); | ||
129 | data = FIELD_DP32(data, VDATA, NF, a->nf); | ||
130 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
131 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
132 | return ldff_trans(a->rd, a->rs1, data, fn, s); | ||
133 | } | ||
134 | |||
135 | -- | ||
136 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-3@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 3 +++ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 2 ++ | ||
12 | 2 files changed, 5 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2, | ||
19 | uint32_t vl = env->vl; | ||
20 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
21 | uint32_t vta = vext_vta(desc); | ||
22 | + uint32_t vma = vext_vma(desc); | ||
23 | uint32_t i; | ||
24 | |||
25 | for (i = env->vstart; i < vl; i++) { | ||
26 | if (!vm && !vext_elem_mask(v0, i)) { | ||
27 | + /* set masked-off elements to 1s */ | ||
28 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
29 | continue; | ||
30 | } | ||
31 | fn(vd, s1, vs2, i); | ||
32 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
35 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
36 | @@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm, | ||
37 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
38 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
39 | data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); | ||
40 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
41 | desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8, | ||
42 | s->cfg_ptr->vlen / 8, data)); | ||
43 | |||
44 | @@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm, | ||
45 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
46 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
47 | data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); | ||
48 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
49 | desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8, | ||
50 | s->cfg_ptr->vlen / 8, data)); | ||
51 | |||
52 | -- | ||
53 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-4@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 7 +++++++ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 1 + | ||
12 | 2 files changed, 8 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
19 | uint32_t esz = sizeof(TS1); \ | ||
20 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
21 | uint32_t vta = vext_vta(desc); \ | ||
22 | + uint32_t vma = vext_vma(desc); \ | ||
23 | uint32_t i; \ | ||
24 | \ | ||
25 | for (i = env->vstart; i < vl; i++) { \ | ||
26 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
27 | + /* set masked-off elements to 1s */ \ | ||
28 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
29 | continue; \ | ||
30 | } \ | ||
31 | TS1 s1 = *((TS1 *)vs1 + HS1(i)); \ | ||
32 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \ | ||
33 | uint32_t total_elems = \ | ||
34 | vext_get_total_elems(env, desc, esz); \ | ||
35 | uint32_t vta = vext_vta(desc); \ | ||
36 | + uint32_t vma = vext_vma(desc); \ | ||
37 | uint32_t i; \ | ||
38 | \ | ||
39 | for (i = env->vstart; i < vl; i++) { \ | ||
40 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
41 | + /* set masked-off elements to 1s */ \ | ||
42 | + vext_set_elems_1s(vd, vma, i * esz, \ | ||
43 | + (i + 1) * esz); \ | ||
44 | continue; \ | ||
45 | } \ | ||
46 | TS2 s2 = *((TS2 *)vs2 + HS2(i)); \ | ||
47 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
50 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
51 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
52 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
53 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
54 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
55 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
56 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
57 | vreg_ofs(s, a->rs1), \ | ||
58 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
59 | -- | ||
60 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-5@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 10 ++++++++++ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 1 + | ||
12 | 2 files changed, 11 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
19 | uint32_t vl = env->vl; \ | ||
20 | uint32_t total_elems = env_archcpu(env)->cfg.vlen; \ | ||
21 | uint32_t vta_all_1s = vext_vta_all_1s(desc); \ | ||
22 | + uint32_t vma = vext_vma(desc); \ | ||
23 | uint32_t i; \ | ||
24 | \ | ||
25 | for (i = env->vstart; i < vl; i++) { \ | ||
26 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
27 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
28 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
29 | + /* set masked-off elements to 1s */ \ | ||
30 | + if (vma) { \ | ||
31 | + vext_set_elem_mask(vd, i, 1); \ | ||
32 | + } \ | ||
33 | continue; \ | ||
34 | } \ | ||
35 | vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \ | ||
36 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
37 | uint32_t vl = env->vl; \ | ||
38 | uint32_t total_elems = env_archcpu(env)->cfg.vlen; \ | ||
39 | uint32_t vta_all_1s = vext_vta_all_1s(desc); \ | ||
40 | + uint32_t vma = vext_vma(desc); \ | ||
41 | uint32_t i; \ | ||
42 | \ | ||
43 | for (i = env->vstart; i < vl; i++) { \ | ||
44 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
45 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
46 | + /* set masked-off elements to 1s */ \ | ||
47 | + if (vma) { \ | ||
48 | + vext_set_elem_mask(vd, i, 1); \ | ||
49 | + } \ | ||
50 | continue; \ | ||
51 | } \ | ||
52 | vext_set_elem_mask(vd, i, \ | ||
53 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
56 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
57 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
58 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
59 | data = \ | ||
60 | FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\ | ||
61 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
62 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
63 | vreg_ofs(s, a->rs1), \ | ||
64 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
65 | -- | ||
66 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-6@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 26 ++++++++++++++++---------- | ||
11 | 1 file changed, 16 insertions(+), 10 deletions(-) | ||
12 | |||
13 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/vector_helper.c | ||
16 | +++ b/target/riscv/vector_helper.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static inline void | ||
18 | vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2, | ||
19 | CPURISCVState *env, | ||
20 | uint32_t vl, uint32_t vm, int vxrm, | ||
21 | - opivv2_rm_fn *fn) | ||
22 | + opivv2_rm_fn *fn, uint32_t vma, uint32_t esz) | ||
23 | { | ||
24 | for (uint32_t i = env->vstart; i < vl; i++) { | ||
25 | if (!vm && !vext_elem_mask(v0, i)) { | ||
26 | + /* set masked-off elements to 1s */ | ||
27 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
28 | continue; | ||
29 | } | ||
30 | fn(vd, vs1, vs2, i, env, vxrm); | ||
31 | @@ -XXX,XX +XXX,XX @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2, | ||
32 | uint32_t vl = env->vl; | ||
33 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
34 | uint32_t vta = vext_vta(desc); | ||
35 | + uint32_t vma = vext_vma(desc); | ||
36 | |||
37 | switch (env->vxrm) { | ||
38 | case 0: /* rnu */ | ||
39 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
40 | - env, vl, vm, 0, fn); | ||
41 | + env, vl, vm, 0, fn, vma, esz); | ||
42 | break; | ||
43 | case 1: /* rne */ | ||
44 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
45 | - env, vl, vm, 1, fn); | ||
46 | + env, vl, vm, 1, fn, vma, esz); | ||
47 | break; | ||
48 | case 2: /* rdn */ | ||
49 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
50 | - env, vl, vm, 2, fn); | ||
51 | + env, vl, vm, 2, fn, vma, esz); | ||
52 | break; | ||
53 | default: /* rod */ | ||
54 | vext_vv_rm_1(vd, v0, vs1, vs2, | ||
55 | - env, vl, vm, 3, fn); | ||
56 | + env, vl, vm, 3, fn, vma, esz); | ||
57 | break; | ||
58 | } | ||
59 | /* set tail elements to 1s */ | ||
60 | @@ -XXX,XX +XXX,XX @@ static inline void | ||
61 | vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2, | ||
62 | CPURISCVState *env, | ||
63 | uint32_t vl, uint32_t vm, int vxrm, | ||
64 | - opivx2_rm_fn *fn) | ||
65 | + opivx2_rm_fn *fn, uint32_t vma, uint32_t esz) | ||
66 | { | ||
67 | for (uint32_t i = env->vstart; i < vl; i++) { | ||
68 | if (!vm && !vext_elem_mask(v0, i)) { | ||
69 | + /* set masked-off elements to 1s */ | ||
70 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); | ||
71 | continue; | ||
72 | } | ||
73 | fn(vd, s1, vs2, i, env, vxrm); | ||
74 | @@ -XXX,XX +XXX,XX @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2, | ||
75 | uint32_t vl = env->vl; | ||
76 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); | ||
77 | uint32_t vta = vext_vta(desc); | ||
78 | + uint32_t vma = vext_vma(desc); | ||
79 | |||
80 | switch (env->vxrm) { | ||
81 | case 0: /* rnu */ | ||
82 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
83 | - env, vl, vm, 0, fn); | ||
84 | + env, vl, vm, 0, fn, vma, esz); | ||
85 | break; | ||
86 | case 1: /* rne */ | ||
87 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
88 | - env, vl, vm, 1, fn); | ||
89 | + env, vl, vm, 1, fn, vma, esz); | ||
90 | break; | ||
91 | case 2: /* rdn */ | ||
92 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
93 | - env, vl, vm, 2, fn); | ||
94 | + env, vl, vm, 2, fn, vma, esz); | ||
95 | break; | ||
96 | default: /* rod */ | ||
97 | vext_vx_rm_1(vd, v0, s1, vs2, | ||
98 | - env, vl, vm, 3, fn); | ||
99 | + env, vl, vm, 3, fn, vma, esz); | ||
100 | break; | ||
101 | } | ||
102 | /* set tail elements to 1s */ | ||
103 | -- | ||
104 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-7@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 26 +++++++++++++++++++++++++ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 12 ++++++++++++ | ||
12 | 2 files changed, 38 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \ | ||
19 | uint32_t total_elems = \ | ||
20 | vext_get_total_elems(env, desc, ESZ); \ | ||
21 | uint32_t vta = vext_vta(desc); \ | ||
22 | + uint32_t vma = vext_vma(desc); \ | ||
23 | uint32_t i; \ | ||
24 | \ | ||
25 | for (i = env->vstart; i < vl; i++) { \ | ||
26 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
27 | + /* set masked-off elements to 1s */ \ | ||
28 | + vext_set_elems_1s(vd, vma, i * ESZ, \ | ||
29 | + (i + 1) * ESZ); \ | ||
30 | continue; \ | ||
31 | } \ | ||
32 | do_##NAME(vd, vs1, vs2, i, env); \ | ||
33 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, \ | ||
34 | uint32_t total_elems = \ | ||
35 | vext_get_total_elems(env, desc, ESZ); \ | ||
36 | uint32_t vta = vext_vta(desc); \ | ||
37 | + uint32_t vma = vext_vma(desc); \ | ||
38 | uint32_t i; \ | ||
39 | \ | ||
40 | for (i = env->vstart; i < vl; i++) { \ | ||
41 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
42 | + /* set masked-off elements to 1s */ \ | ||
43 | + vext_set_elems_1s(vd, vma, i * ESZ, \ | ||
44 | + (i + 1) * ESZ); \ | ||
45 | continue; \ | ||
46 | } \ | ||
47 | do_##NAME(vd, s1, vs2, i, env); \ | ||
48 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
49 | uint32_t total_elems = \ | ||
50 | vext_get_total_elems(env, desc, ESZ); \ | ||
51 | uint32_t vta = vext_vta(desc); \ | ||
52 | + uint32_t vma = vext_vma(desc); \ | ||
53 | uint32_t i; \ | ||
54 | \ | ||
55 | if (vl == 0) { \ | ||
56 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
57 | } \ | ||
58 | for (i = env->vstart; i < vl; i++) { \ | ||
59 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
60 | + /* set masked-off elements to 1s */ \ | ||
61 | + vext_set_elems_1s(vd, vma, i * ESZ, \ | ||
62 | + (i + 1) * ESZ); \ | ||
63 | continue; \ | ||
64 | } \ | ||
65 | do_##NAME(vd, vs2, i, env); \ | ||
66 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
67 | uint32_t vl = env->vl; \ | ||
68 | uint32_t total_elems = env_archcpu(env)->cfg.vlen; \ | ||
69 | uint32_t vta_all_1s = vext_vta_all_1s(desc); \ | ||
70 | + uint32_t vma = vext_vma(desc); \ | ||
71 | uint32_t i; \ | ||
72 | \ | ||
73 | for (i = env->vstart; i < vl; i++) { \ | ||
74 | ETYPE s1 = *((ETYPE *)vs1 + H(i)); \ | ||
75 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
76 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
77 | + /* set masked-off elements to 1s */ \ | ||
78 | + if (vma) { \ | ||
79 | + vext_set_elem_mask(vd, i, 1); \ | ||
80 | + } \ | ||
81 | continue; \ | ||
82 | } \ | ||
83 | vext_set_elem_mask(vd, i, \ | ||
84 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \ | ||
85 | uint32_t vl = env->vl; \ | ||
86 | uint32_t total_elems = env_archcpu(env)->cfg.vlen; \ | ||
87 | uint32_t vta_all_1s = vext_vta_all_1s(desc); \ | ||
88 | + uint32_t vma = vext_vma(desc); \ | ||
89 | uint32_t i; \ | ||
90 | \ | ||
91 | for (i = env->vstart; i < vl; i++) { \ | ||
92 | ETYPE s2 = *((ETYPE *)vs2 + H(i)); \ | ||
93 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
94 | + /* set masked-off elements to 1s */ \ | ||
95 | + if (vma) { \ | ||
96 | + vext_set_elem_mask(vd, i, 1); \ | ||
97 | + } \ | ||
98 | continue; \ | ||
99 | } \ | ||
100 | vext_set_elem_mask(vd, i, \ | ||
101 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
102 | uint32_t total_elems = \ | ||
103 | vext_get_total_elems(env, desc, ESZ); \ | ||
104 | uint32_t vta = vext_vta(desc); \ | ||
105 | + uint32_t vma = vext_vma(desc); \ | ||
106 | uint32_t i; \ | ||
107 | \ | ||
108 | for (i = env->vstart; i < vl; i++) { \ | ||
109 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
110 | + /* set masked-off elements to 1s */ \ | ||
111 | + vext_set_elems_1s(vd, vma, i * ESZ, \ | ||
112 | + (i + 1) * ESZ); \ | ||
113 | continue; \ | ||
114 | } \ | ||
115 | do_##NAME(vd, vs2, i); \ | ||
116 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
119 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
120 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
121 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
122 | data = \ | ||
123 | FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\ | ||
124 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
125 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
126 | vreg_ofs(s, a->rs1), \ | ||
127 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
128 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
129 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
130 | data = FIELD_DP32(data, VDATA, VTA_ALL_1S, \ | ||
131 | s->cfg_vta_all_1s); \ | ||
132 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
133 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
134 | fns[s->sew - 1], s); \ | ||
135 | } \ | ||
136 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
137 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
138 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
139 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
140 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
141 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
142 | vreg_ofs(s, a->rs1), \ | ||
143 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
144 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
145 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
146 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
147 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
148 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
149 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
150 | fns[s->sew - 1], s); \ | ||
151 | } \ | ||
152 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
153 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
154 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
155 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
156 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
157 | tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
158 | vreg_ofs(s, a->rs1), \ | ||
159 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
160 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \ | ||
161 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
162 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
163 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
164 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
165 | return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ | ||
166 | fns[s->sew - 1], s); \ | ||
167 | } \ | ||
168 | @@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a, | ||
169 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
170 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
171 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
172 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
173 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
174 | vreg_ofs(s, a->rs2), cpu_env, | ||
175 | s->cfg_ptr->vlen / 8, | ||
176 | @@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a) | ||
177 | TCGv_i32 desc; | ||
178 | uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul); | ||
179 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
180 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
181 | static gen_helper_vmv_vx * const fns[3] = { | ||
182 | gen_helper_vmv_v_x_h, | ||
183 | gen_helper_vmv_v_x_w, | ||
184 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
185 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
186 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
187 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
188 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
189 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
190 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
191 | s->cfg_ptr->vlen / 8, \ | ||
192 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
193 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
194 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
195 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
196 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
197 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
198 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
199 | s->cfg_ptr->vlen / 8, \ | ||
200 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
201 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
202 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
203 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
204 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
205 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
206 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
207 | s->cfg_ptr->vlen / 8, \ | ||
208 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
209 | data = FIELD_DP32(data, VDATA, VM, a->vm); \ | ||
210 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
211 | data = FIELD_DP32(data, VDATA, VTA, s->vta); \ | ||
212 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
213 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \ | ||
214 | vreg_ofs(s, a->rs2), cpu_env, \ | ||
215 | s->cfg_ptr->vlen / 8, \ | ||
216 | -- | ||
217 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-8@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 11 +++++++++++ | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 3 +++ | ||
12 | 2 files changed, 14 insertions(+) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env, | ||
19 | uint32_t vl = env->vl; | ||
20 | uint32_t total_elems = env_archcpu(env)->cfg.vlen; | ||
21 | uint32_t vta_all_1s = vext_vta_all_1s(desc); | ||
22 | + uint32_t vma = vext_vma(desc); | ||
23 | int i; | ||
24 | bool first_mask_bit = false; | ||
25 | |||
26 | for (i = env->vstart; i < vl; i++) { | ||
27 | if (!vm && !vext_elem_mask(v0, i)) { | ||
28 | + /* set masked-off elements to 1s */ | ||
29 | + if (vma) { | ||
30 | + vext_set_elem_mask(vd, i, 1); | ||
31 | + } | ||
32 | continue; | ||
33 | } | ||
34 | /* write a zero to all following active elements */ | ||
35 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env, \ | ||
36 | uint32_t esz = sizeof(ETYPE); \ | ||
37 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
38 | uint32_t vta = vext_vta(desc); \ | ||
39 | + uint32_t vma = vext_vma(desc); \ | ||
40 | uint32_t sum = 0; \ | ||
41 | int i; \ | ||
42 | \ | ||
43 | for (i = env->vstart; i < vl; i++) { \ | ||
44 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
45 | + /* set masked-off elements to 1s */ \ | ||
46 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
47 | continue; \ | ||
48 | } \ | ||
49 | *((ETYPE *)vd + H(i)) = sum; \ | ||
50 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc) \ | ||
51 | uint32_t esz = sizeof(ETYPE); \ | ||
52 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
53 | uint32_t vta = vext_vta(desc); \ | ||
54 | + uint32_t vma = vext_vma(desc); \ | ||
55 | int i; \ | ||
56 | \ | ||
57 | for (i = env->vstart; i < vl; i++) { \ | ||
58 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
59 | + /* set masked-off elements to 1s */ \ | ||
60 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
61 | continue; \ | ||
62 | } \ | ||
63 | *((ETYPE *)vd + H(i)) = i; \ | ||
64 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
65 | index XXXXXXX..XXXXXXX 100644 | ||
66 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
67 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
68 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \ | ||
69 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ | ||
70 | data = \ | ||
71 | FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\ | ||
72 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); \ | ||
73 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \ | ||
74 | vreg_ofs(s, 0), vreg_ofs(s, a->rs2), \ | ||
75 | cpu_env, s->cfg_ptr->vlen / 8, \ | ||
76 | @@ -XXX,XX +XXX,XX @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a) | ||
77 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
78 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
79 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
80 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
81 | static gen_helper_gvec_3_ptr * const fns[4] = { | ||
82 | gen_helper_viota_m_b, gen_helper_viota_m_h, | ||
83 | gen_helper_viota_m_w, gen_helper_viota_m_d, | ||
84 | @@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a) | ||
85 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
86 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
87 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
88 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
89 | static gen_helper_gvec_2_ptr * const fns[4] = { | ||
90 | gen_helper_vid_v_b, gen_helper_vid_v_h, | ||
91 | gen_helper_vid_v_w, gen_helper_vid_v_d, | ||
92 | -- | ||
93 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: "Yueh-Ting (eop) Chen" <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
4 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
5 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Message-Id: <165570784143.17634.35095816584573691-9@git.sr.ht> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/vector_helper.c | 26 +++++++++++++++++++++++-- | ||
11 | target/riscv/insn_trans/trans_rvv.c.inc | 1 + | ||
12 | 2 files changed, 25 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/vector_helper.c | ||
17 | +++ b/target/riscv/vector_helper.c | ||
18 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
19 | uint32_t esz = sizeof(ETYPE); \ | ||
20 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
21 | uint32_t vta = vext_vta(desc); \ | ||
22 | + uint32_t vma = vext_vma(desc); \ | ||
23 | target_ulong offset = s1, i_min, i; \ | ||
24 | \ | ||
25 | i_min = MAX(env->vstart, offset); \ | ||
26 | for (i = i_min; i < vl; i++) { \ | ||
27 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
28 | + /* set masked-off elements to 1s */ \ | ||
29 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
30 | continue; \ | ||
31 | } \ | ||
32 | *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \ | ||
33 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
34 | uint32_t esz = sizeof(ETYPE); \ | ||
35 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
36 | uint32_t vta = vext_vta(desc); \ | ||
37 | + uint32_t vma = vext_vma(desc); \ | ||
38 | target_ulong i_max, i; \ | ||
39 | \ | ||
40 | i_max = MAX(MIN(s1 < vlmax ? vlmax - s1 : 0, vl), env->vstart); \ | ||
41 | for (i = env->vstart; i < i_max; ++i) { \ | ||
42 | - if (vm || vext_elem_mask(v0, i)) { \ | ||
43 | - *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \ | ||
44 | + if (!vm && !vext_elem_mask(v0, i)) { \ | ||
45 | + /* set masked-off elements to 1s */ \ | ||
46 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
47 | + continue; \ | ||
48 | } \ | ||
49 | + *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1)); \ | ||
50 | } \ | ||
51 | \ | ||
52 | for (i = i_max; i < vl; ++i) { \ | ||
53 | @@ -XXX,XX +XXX,XX @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, target_ulong s1, \ | ||
54 | uint32_t esz = sizeof(ETYPE); \ | ||
55 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
56 | uint32_t vta = vext_vta(desc); \ | ||
57 | + uint32_t vma = vext_vma(desc); \ | ||
58 | uint32_t i; \ | ||
59 | \ | ||
60 | for (i = env->vstart; i < vl; i++) { \ | ||
61 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
62 | + /* set masked-off elements to 1s */ \ | ||
63 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
64 | continue; \ | ||
65 | } \ | ||
66 | if (i == 0) { \ | ||
67 | @@ -XXX,XX +XXX,XX @@ static void vslide1down_##BITWIDTH(void *vd, void *v0, target_ulong s1, \ | ||
68 | uint32_t esz = sizeof(ETYPE); \ | ||
69 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
70 | uint32_t vta = vext_vta(desc); \ | ||
71 | + uint32_t vma = vext_vma(desc); \ | ||
72 | uint32_t i; \ | ||
73 | \ | ||
74 | for (i = env->vstart; i < vl; i++) { \ | ||
75 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
76 | + /* set masked-off elements to 1s */ \ | ||
77 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
78 | continue; \ | ||
79 | } \ | ||
80 | if (i == vl - 1) { \ | ||
81 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ | ||
82 | uint32_t esz = sizeof(TS2); \ | ||
83 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
84 | uint32_t vta = vext_vta(desc); \ | ||
85 | + uint32_t vma = vext_vma(desc); \ | ||
86 | uint64_t index; \ | ||
87 | uint32_t i; \ | ||
88 | \ | ||
89 | for (i = env->vstart; i < vl; i++) { \ | ||
90 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
91 | + /* set masked-off elements to 1s */ \ | ||
92 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
93 | continue; \ | ||
94 | } \ | ||
95 | index = *((TS1 *)vs1 + HS1(i)); \ | ||
96 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ | ||
97 | uint32_t esz = sizeof(ETYPE); \ | ||
98 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
99 | uint32_t vta = vext_vta(desc); \ | ||
100 | + uint32_t vma = vext_vma(desc); \ | ||
101 | uint64_t index = s1; \ | ||
102 | uint32_t i; \ | ||
103 | \ | ||
104 | for (i = env->vstart; i < vl; i++) { \ | ||
105 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
106 | + /* set masked-off elements to 1s */ \ | ||
107 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
108 | continue; \ | ||
109 | } \ | ||
110 | if (index >= vlmax) { \ | ||
111 | @@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, \ | ||
112 | uint32_t esz = sizeof(ETYPE); \ | ||
113 | uint32_t total_elems = vext_get_total_elems(env, desc, esz); \ | ||
114 | uint32_t vta = vext_vta(desc); \ | ||
115 | + uint32_t vma = vext_vma(desc); \ | ||
116 | uint32_t i; \ | ||
117 | \ | ||
118 | for (i = env->vstart; i < vl; i++) { \ | ||
119 | if (!vm && !vext_elem_mask(v0, i)) { \ | ||
120 | + /* set masked-off elements to 1s */ \ | ||
121 | + vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz); \ | ||
122 | continue; \ | ||
123 | } \ | ||
124 | *((ETYPE *)vd + HD(i)) = *((DTYPE *)vs2 + HS1(i)); \ | ||
125 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
128 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
129 | @@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq) | ||
130 | data = FIELD_DP32(data, VDATA, VM, a->vm); | ||
131 | data = FIELD_DP32(data, VDATA, LMUL, s->lmul); | ||
132 | data = FIELD_DP32(data, VDATA, VTA, s->vta); | ||
133 | + data = FIELD_DP32(data, VDATA, VMA, s->vma); | ||
134 | |||
135 | tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), | ||
136 | vreg_ofs(s, a->rs2), cpu_env, | ||
137 | -- | ||
138 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: eopXD <eop.chen@sifive.com> | ||
1 | 2 | ||
3 | According to v-spec, mask agnostic behavior can be either kept as | ||
4 | undisturbed or set elements' bits to all 1s. To distinguish the | ||
5 | difference of mask policies, QEMU should be able to simulate the mask | ||
6 | agnostic behavior as "set mask elements' bits to all 1s". | ||
7 | |||
8 | There are multiple possibility for agnostic elements according to | ||
9 | v-spec. The main intent of this patch-set tries to add option that | ||
10 | can distinguish between mask policies. Setting agnostic elements to | ||
11 | all 1s allows QEMU to express this. | ||
12 | |||
13 | This commit adds option 'rvv_ma_all_1s' is added to enable the | ||
14 | behavior, it is default as disabled. | ||
15 | |||
16 | Signed-off-by: eop Chen <eop.chen@sifive.com> | ||
17 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
18 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | Message-Id: <165570784143.17634.35095816584573691-10@git.sr.ht> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | --- | ||
23 | target/riscv/cpu.c | 1 + | ||
24 | 1 file changed, 1 insertion(+) | ||
25 | |||
26 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/target/riscv/cpu.c | ||
29 | +++ b/target/riscv/cpu.c | ||
30 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
31 | DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false), | ||
32 | |||
33 | DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false), | ||
34 | + DEFINE_PROP_BOOL("rvv_ma_all_1s", RISCVCPU, cfg.rvv_ma_all_1s, false), | ||
35 | DEFINE_PROP_END_OF_LIST(), | ||
36 | }; | ||
37 | |||
38 | -- | ||
39 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Dao Lu <daolu@rivosinc.com> | ||
1 | 2 | ||
3 | Added support for RISC-V PAUSE instruction from Zihintpause extension, | ||
4 | enabled by default. | ||
5 | |||
6 | Tested-by: Heiko Stuebner <heiko@sntech.de> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Signed-off-by: Dao Lu <daolu@rivosinc.com> | ||
9 | Message-Id: <20220725034728.2620750-2-daolu@rivosinc.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/cpu.h | 1 + | ||
13 | target/riscv/insn32.decode | 7 ++++++- | ||
14 | target/riscv/cpu.c | 2 ++ | ||
15 | target/riscv/insn_trans/trans_rvi.c.inc | 16 ++++++++++++++++ | ||
16 | 4 files changed, 25 insertions(+), 1 deletion(-) | ||
17 | |||
18 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/cpu.h | ||
21 | +++ b/target/riscv/cpu.h | ||
22 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
23 | bool ext_zkt; | ||
24 | bool ext_ifencei; | ||
25 | bool ext_icsr; | ||
26 | + bool ext_zihintpause; | ||
27 | bool ext_svinval; | ||
28 | bool ext_svnapot; | ||
29 | bool ext_svpbmt; | ||
30 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/target/riscv/insn32.decode | ||
33 | +++ b/target/riscv/insn32.decode | ||
34 | @@ -XXX,XX +XXX,XX @@ srl 0000000 ..... ..... 101 ..... 0110011 @r | ||
35 | sra 0100000 ..... ..... 101 ..... 0110011 @r | ||
36 | or 0000000 ..... ..... 110 ..... 0110011 @r | ||
37 | and 0000000 ..... ..... 111 ..... 0110011 @r | ||
38 | -fence ---- pred:4 succ:4 ----- 000 ----- 0001111 | ||
39 | + | ||
40 | +{ | ||
41 | + pause 0000 0001 0000 00000 000 00000 0001111 | ||
42 | + fence ---- pred:4 succ:4 ----- 000 ----- 0001111 | ||
43 | +} | ||
44 | + | ||
45 | fence_i ---- ---- ---- ----- 001 ----- 0001111 | ||
46 | csrrw ............ ..... 001 ..... 1110011 @csr | ||
47 | csrrs ............ ..... 010 ..... 1110011 @csr | ||
48 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/riscv/cpu.c | ||
51 | +++ b/target/riscv/cpu.c | ||
52 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
53 | ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v), | ||
54 | ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr), | ||
55 | ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei), | ||
56 | + ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause), | ||
57 | ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh), | ||
58 | ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin), | ||
59 | ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx), | ||
60 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
61 | DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), | ||
62 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | ||
63 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | ||
64 | + DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true), | ||
65 | DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false), | ||
66 | DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false), | ||
67 | DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false), | ||
68 | diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/riscv/insn_trans/trans_rvi.c.inc | ||
71 | +++ b/target/riscv/insn_trans/trans_rvi.c.inc | ||
72 | @@ -XXX,XX +XXX,XX @@ static bool trans_srad(DisasContext *ctx, arg_srad *a) | ||
73 | return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl, NULL); | ||
74 | } | ||
75 | |||
76 | +static bool trans_pause(DisasContext *ctx, arg_pause *a) | ||
77 | +{ | ||
78 | + if (!ctx->cfg_ptr->ext_zihintpause) { | ||
79 | + return false; | ||
80 | + } | ||
81 | + | ||
82 | + /* | ||
83 | + * PAUSE is a no-op in QEMU, | ||
84 | + * end the TB and return to main loop | ||
85 | + */ | ||
86 | + gen_set_pc_imm(ctx, ctx->pc_succ_insn); | ||
87 | + tcg_gen_exit_tb(NULL, 0); | ||
88 | + ctx->base.is_jmp = DISAS_NORETURN; | ||
89 | + | ||
90 | + return true; | ||
91 | +} | ||
92 | |||
93 | static bool trans_fence(DisasContext *ctx, arg_fence *a) | ||
94 | { | ||
95 | -- | ||
96 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <danielhb413@gmail.com> | ||
1 | 2 | ||
3 | The 'fdt' param is not being used in riscv_setup_rom_reset_vec(). | ||
4 | Simplify the API by removing it. While we're at it, remove the redundant | ||
5 | 'return' statement at the end of function. | ||
6 | |||
7 | Cc: Palmer Dabbelt <palmer@dabbelt.com> | ||
8 | Cc: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Cc: Bin Meng <bin.meng@windriver.com> | ||
10 | Cc: Vijai Kumar K <vijai@behindbytes.com> | ||
11 | Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> | ||
12 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Message-Id: <20220728181926.2123771-1-danielhb413@gmail.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | include/hw/riscv/boot.h | 2 +- | ||
18 | hw/riscv/boot.c | 4 +--- | ||
19 | hw/riscv/microchip_pfsoc.c | 2 +- | ||
20 | hw/riscv/shakti_c.c | 3 +-- | ||
21 | hw/riscv/spike.c | 2 +- | ||
22 | hw/riscv/virt.c | 2 +- | ||
23 | 6 files changed, 6 insertions(+), 9 deletions(-) | ||
24 | |||
25 | diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/include/hw/riscv/boot.h | ||
28 | +++ b/include/hw/riscv/boot.h | ||
29 | @@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts | ||
30 | hwaddr saddr, | ||
31 | hwaddr rom_base, hwaddr rom_size, | ||
32 | uint64_t kernel_entry, | ||
33 | - uint64_t fdt_load_addr, void *fdt); | ||
34 | + uint64_t fdt_load_addr); | ||
35 | void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, | ||
36 | hwaddr rom_size, | ||
37 | uint32_t reset_vec_size, | ||
38 | diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/hw/riscv/boot.c | ||
41 | +++ b/hw/riscv/boot.c | ||
42 | @@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts | ||
43 | hwaddr start_addr, | ||
44 | hwaddr rom_base, hwaddr rom_size, | ||
45 | uint64_t kernel_entry, | ||
46 | - uint64_t fdt_load_addr, void *fdt) | ||
47 | + uint64_t fdt_load_addr) | ||
48 | { | ||
49 | int i; | ||
50 | uint32_t start_addr_hi32 = 0x00000000; | ||
51 | @@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts | ||
52 | rom_base, &address_space_memory); | ||
53 | riscv_rom_copy_firmware_info(machine, rom_base, rom_size, sizeof(reset_vec), | ||
54 | kernel_entry); | ||
55 | - | ||
56 | - return; | ||
57 | } | ||
58 | |||
59 | void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr) | ||
60 | diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/hw/riscv/microchip_pfsoc.c | ||
63 | +++ b/hw/riscv/microchip_pfsoc.c | ||
64 | @@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine) | ||
65 | riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr, | ||
66 | memmap[MICROCHIP_PFSOC_ENVM_DATA].base, | ||
67 | memmap[MICROCHIP_PFSOC_ENVM_DATA].size, | ||
68 | - kernel_entry, fdt_load_addr, machine->fdt); | ||
69 | + kernel_entry, fdt_load_addr); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c | ||
74 | index XXXXXXX..XXXXXXX 100644 | ||
75 | --- a/hw/riscv/shakti_c.c | ||
76 | +++ b/hw/riscv/shakti_c.c | ||
77 | @@ -XXX,XX +XXX,XX @@ static void shakti_c_machine_state_init(MachineState *mstate) | ||
78 | riscv_setup_rom_reset_vec(mstate, &sms->soc.cpus, | ||
79 | shakti_c_memmap[SHAKTI_C_RAM].base, | ||
80 | shakti_c_memmap[SHAKTI_C_ROM].base, | ||
81 | - shakti_c_memmap[SHAKTI_C_ROM].size, 0, 0, | ||
82 | - NULL); | ||
83 | + shakti_c_memmap[SHAKTI_C_ROM].size, 0, 0); | ||
84 | if (mstate->firmware) { | ||
85 | riscv_load_firmware(mstate->firmware, | ||
86 | shakti_c_memmap[SHAKTI_C_RAM].base, | ||
87 | diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c | ||
88 | index XXXXXXX..XXXXXXX 100644 | ||
89 | --- a/hw/riscv/spike.c | ||
90 | +++ b/hw/riscv/spike.c | ||
91 | @@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine) | ||
92 | riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base, | ||
93 | memmap[SPIKE_MROM].base, | ||
94 | memmap[SPIKE_MROM].size, kernel_entry, | ||
95 | - fdt_load_addr, s->fdt); | ||
96 | + fdt_load_addr); | ||
97 | |||
98 | /* initialize HTIF using symbols found in load_kernel */ | ||
99 | htif_mm_init(system_memory, mask_rom, | ||
100 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
101 | index XXXXXXX..XXXXXXX 100644 | ||
102 | --- a/hw/riscv/virt.c | ||
103 | +++ b/hw/riscv/virt.c | ||
104 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data) | ||
105 | riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr, | ||
106 | virt_memmap[VIRT_MROM].base, | ||
107 | virt_memmap[VIRT_MROM].size, kernel_entry, | ||
108 | - fdt_load_addr, machine->fdt); | ||
109 | + fdt_load_addr); | ||
110 | |||
111 | /* | ||
112 | * Only direct boot kernel is currently supported for KVM VM, | ||
113 | -- | ||
114 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | ||
1 | 2 | ||
3 | Normally, riscv_csrrw_check is called when executing Zicsr instructions. | ||
4 | And we can only do access control for existed CSRs. So the priority of | ||
5 | CSR related check, from highest to lowest, should be as follows: | ||
6 | 1) check whether Zicsr is supported: raise RISCV_EXCP_ILLEGAL_INST if not | ||
7 | 2) check whether csr is existed: raise RISCV_EXCP_ILLEGAL_INST if not | ||
8 | 3) do access control: raise RISCV_EXCP_ILLEGAL_INST or RISCV_EXCP_VIRT_ | ||
9 | INSTRUCTION_FAULT if not allowed | ||
10 | |||
11 | The predicates contain parts of function of both 2) and 3), So they need | ||
12 | to be placed in the middle of riscv_csrrw_check | ||
13 | |||
14 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
15 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
16 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | Message-Id: <20220803123652.3700-1-liweiwei@iscas.ac.cn> | ||
18 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | --- | ||
20 | target/riscv/csr.c | 44 +++++++++++++++++++++++++------------------- | ||
21 | 1 file changed, 25 insertions(+), 19 deletions(-) | ||
22 | |||
23 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/target/riscv/csr.c | ||
26 | +++ b/target/riscv/csr.c | ||
27 | @@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, | ||
28 | /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */ | ||
29 | int read_only = get_field(csrno, 0xC00) == 3; | ||
30 | int csr_min_priv = csr_ops[csrno].min_priv_ver; | ||
31 | + | ||
32 | + /* ensure the CSR extension is enabled. */ | ||
33 | + if (!cpu->cfg.ext_icsr) { | ||
34 | + return RISCV_EXCP_ILLEGAL_INST; | ||
35 | + } | ||
36 | + | ||
37 | + if (env->priv_ver < csr_min_priv) { | ||
38 | + return RISCV_EXCP_ILLEGAL_INST; | ||
39 | + } | ||
40 | + | ||
41 | + /* check predicate */ | ||
42 | + if (!csr_ops[csrno].predicate) { | ||
43 | + return RISCV_EXCP_ILLEGAL_INST; | ||
44 | + } | ||
45 | + | ||
46 | + if (write_mask && read_only) { | ||
47 | + return RISCV_EXCP_ILLEGAL_INST; | ||
48 | + } | ||
49 | + | ||
50 | + RISCVException ret = csr_ops[csrno].predicate(env, csrno); | ||
51 | + if (ret != RISCV_EXCP_NONE) { | ||
52 | + return ret; | ||
53 | + } | ||
54 | + | ||
55 | #if !defined(CONFIG_USER_ONLY) | ||
56 | int csr_priv, effective_priv = env->priv; | ||
57 | |||
58 | @@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, | ||
59 | return RISCV_EXCP_ILLEGAL_INST; | ||
60 | } | ||
61 | #endif | ||
62 | - if (write_mask && read_only) { | ||
63 | - return RISCV_EXCP_ILLEGAL_INST; | ||
64 | - } | ||
65 | - | ||
66 | - /* ensure the CSR extension is enabled. */ | ||
67 | - if (!cpu->cfg.ext_icsr) { | ||
68 | - return RISCV_EXCP_ILLEGAL_INST; | ||
69 | - } | ||
70 | - | ||
71 | - /* check predicate */ | ||
72 | - if (!csr_ops[csrno].predicate) { | ||
73 | - return RISCV_EXCP_ILLEGAL_INST; | ||
74 | - } | ||
75 | - | ||
76 | - if (env->priv_ver < csr_min_priv) { | ||
77 | - return RISCV_EXCP_ILLEGAL_INST; | ||
78 | - } | ||
79 | - | ||
80 | - return csr_ops[csrno].predicate(env, csrno); | ||
81 | + return RISCV_EXCP_NONE; | ||
82 | } | ||
83 | |||
84 | static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno, | ||
85 | -- | ||
86 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Wilfred Mallawa <wilfred.mallawa@wdc.com> | ||
1 | 2 | ||
3 | The following patch updates opentitan to match the new configuration, | ||
4 | as per, lowRISC/opentitan@217a0168ba118503c166a9587819e3811eeb0c0c | ||
5 | |||
6 | Note: with this patch we now skip the usage of the opentitan | ||
7 | `boot_rom`. The Opentitan boot rom contains hw verification | ||
8 | for devies which we are currently not supporting in qemu. As of now, | ||
9 | the `boot_rom` has no major significance, however, would be good to | ||
10 | support in the future. | ||
11 | |||
12 | Tested by running utests from the latest tock [1] | ||
13 | (that supports this version of OT). | ||
14 | |||
15 | [1] https://github.com/tock/tock/pull/3056 | ||
16 | |||
17 | Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> | ||
18 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | Message-Id: <20220812005229.358850-1-wilfred.mallawa@opensource.wdc.com> | ||
20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
21 | --- | ||
22 | include/hw/riscv/opentitan.h | 11 ++++++----- | ||
23 | hw/riscv/opentitan.c | 12 ++++++++---- | ||
24 | 2 files changed, 14 insertions(+), 9 deletions(-) | ||
25 | |||
26 | diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/include/hw/riscv/opentitan.h | ||
29 | +++ b/include/hw/riscv/opentitan.h | ||
30 | @@ -XXX,XX +XXX,XX @@ enum { | ||
31 | IBEX_DEV_TIMER, | ||
32 | IBEX_DEV_SENSOR_CTRL, | ||
33 | IBEX_DEV_OTP_CTRL, | ||
34 | + IBEX_DEV_LC_CTRL, | ||
35 | IBEX_DEV_PWRMGR, | ||
36 | IBEX_DEV_RSTMGR, | ||
37 | IBEX_DEV_CLKMGR, | ||
38 | @@ -XXX,XX +XXX,XX @@ enum { | ||
39 | IBEX_UART0_RX_BREAK_ERR_IRQ = 6, | ||
40 | IBEX_UART0_RX_TIMEOUT_IRQ = 7, | ||
41 | IBEX_UART0_RX_PARITY_ERR_IRQ = 8, | ||
42 | - IBEX_TIMER_TIMEREXPIRED0_0 = 126, | ||
43 | - IBEX_SPI_HOST0_ERR_IRQ = 150, | ||
44 | - IBEX_SPI_HOST0_SPI_EVENT_IRQ = 151, | ||
45 | - IBEX_SPI_HOST1_ERR_IRQ = 152, | ||
46 | - IBEX_SPI_HOST1_SPI_EVENT_IRQ = 153, | ||
47 | + IBEX_TIMER_TIMEREXPIRED0_0 = 127, | ||
48 | + IBEX_SPI_HOST0_ERR_IRQ = 151, | ||
49 | + IBEX_SPI_HOST0_SPI_EVENT_IRQ = 152, | ||
50 | + IBEX_SPI_HOST1_ERR_IRQ = 153, | ||
51 | + IBEX_SPI_HOST1_SPI_EVENT_IRQ = 154, | ||
52 | }; | ||
53 | |||
54 | #endif | ||
55 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/hw/riscv/opentitan.c | ||
58 | +++ b/hw/riscv/opentitan.c | ||
59 | @@ -XXX,XX +XXX,XX @@ | ||
60 | #include "sysemu/sysemu.h" | ||
61 | |||
62 | static const MemMapEntry ibex_memmap[] = { | ||
63 | - [IBEX_DEV_ROM] = { 0x00008000, 16 * KiB }, | ||
64 | - [IBEX_DEV_RAM] = { 0x10000000, 0x10000 }, | ||
65 | - [IBEX_DEV_FLASH] = { 0x20000000, 0x80000 }, | ||
66 | + [IBEX_DEV_ROM] = { 0x00008000, 0x8000 }, | ||
67 | + [IBEX_DEV_RAM] = { 0x10000000, 0x20000 }, | ||
68 | + [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 }, | ||
69 | [IBEX_DEV_UART] = { 0x40000000, 0x1000 }, | ||
70 | [IBEX_DEV_GPIO] = { 0x40040000, 0x1000 }, | ||
71 | [IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x1000 }, | ||
72 | @@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = { | ||
73 | [IBEX_DEV_TIMER] = { 0x40100000, 0x1000 }, | ||
74 | [IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 }, | ||
75 | [IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 }, | ||
76 | + [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 }, | ||
77 | [IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 }, | ||
78 | [IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 }, | ||
79 | [IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 }, | ||
80 | @@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp) | ||
81 | &error_abort); | ||
82 | object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus, | ||
83 | &error_abort); | ||
84 | - object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8080, &error_abort); | ||
85 | + object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x20000490, | ||
86 | + &error_abort); | ||
87 | sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal); | ||
88 | |||
89 | /* Boot ROM */ | ||
90 | @@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp) | ||
91 | memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size); | ||
92 | create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl", | ||
93 | memmap[IBEX_DEV_OTP_CTRL].base, memmap[IBEX_DEV_OTP_CTRL].size); | ||
94 | + create_unimplemented_device("riscv.lowrisc.ibex.lc_ctrl", | ||
95 | + memmap[IBEX_DEV_LC_CTRL].base, memmap[IBEX_DEV_LC_CTRL].size); | ||
96 | create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr", | ||
97 | memmap[IBEX_DEV_PWRMGR].base, memmap[IBEX_DEV_PWRMGR].size); | ||
98 | create_unimplemented_device("riscv.lowrisc.ibex.rstmgr", | ||
99 | -- | ||
100 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Conor Dooley <conor.dooley@microchip.com> | |
2 | |||
3 | Booting using "Direct Kernel Boot" for PolarFire SoC & skipping u-boot | ||
4 | entirely is probably not advisable, but it does at least show signs of | ||
5 | life. Recent Linux kernel versions make use of peripherals that are | ||
6 | missing definitions in QEMU and lead to kernel panics. These issues | ||
7 | almost certain rear their head for other methods of booting, but I was | ||
8 | unable to figure out a suitable HSS version that is recent enough to | ||
9 | support these peripherals & works with QEMU. | ||
10 | |||
11 | With these peripherals added, booting a kernel with the following hangs | ||
12 | hangs waiting for the system controller's hwrng, but the kernel no | ||
13 | longer panics. With the Linux driver for hwrng disabled, it boots to | ||
14 | console. | ||
15 | |||
16 | qemu-system-riscv64 -M microchip-icicle-kit \ | ||
17 | -m 2G -smp 5 \ | ||
18 | -kernel $(vmlinux_bin) \ | ||
19 | -dtb $(dtb)\ | ||
20 | -initrd $(initramfs) \ | ||
21 | -display none -serial null \ | ||
22 | -serial stdio | ||
23 | |||
24 | More peripherals are added than strictly required to fix the panics in | ||
25 | the hopes of avoiding a replication of this problem in the future. | ||
26 | Some of the peripherals which are in the device tree for recent kernels | ||
27 | are implemented in the FPGA fabric. The eMMC/SD mux, which exists as | ||
28 | an unimplemented device is replaced by a wider entry. This updated | ||
29 | entry covers both the mux & the remainder of the FPGA fabric connected | ||
30 | to the MSS using Fabric Interrconnect (FIC) 3. | ||
31 | |||
32 | Link: https://github.com/polarfire-soc/icicle-kit-reference-design#fabric-memory-map | ||
33 | Link: https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/SupportingCollateral/V1_4_Register_Map.zip | ||
34 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
35 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
36 | Message-Id: <20220813135127.2971754-1-mail@conchuod.ie> | ||
37 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
38 | --- | ||
39 | include/hw/riscv/microchip_pfsoc.h | 14 ++++++- | ||
40 | hw/riscv/microchip_pfsoc.c | 67 +++++++++++++++++++++++++++--- | ||
41 | 2 files changed, 74 insertions(+), 7 deletions(-) | ||
42 | |||
43 | diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/include/hw/riscv/microchip_pfsoc.h | ||
46 | +++ b/include/hw/riscv/microchip_pfsoc.h | ||
47 | @@ -XXX,XX +XXX,XX @@ enum { | ||
48 | MICROCHIP_PFSOC_L2LIM, | ||
49 | MICROCHIP_PFSOC_PLIC, | ||
50 | MICROCHIP_PFSOC_MMUART0, | ||
51 | + MICROCHIP_PFSOC_WDOG0, | ||
52 | MICROCHIP_PFSOC_SYSREG, | ||
53 | + MICROCHIP_PFSOC_AXISW, | ||
54 | MICROCHIP_PFSOC_MPUCFG, | ||
55 | + MICROCHIP_PFSOC_FMETER, | ||
56 | MICROCHIP_PFSOC_DDR_SGMII_PHY, | ||
57 | MICROCHIP_PFSOC_EMMC_SD, | ||
58 | MICROCHIP_PFSOC_DDR_CFG, | ||
59 | @@ -XXX,XX +XXX,XX @@ enum { | ||
60 | MICROCHIP_PFSOC_MMUART2, | ||
61 | MICROCHIP_PFSOC_MMUART3, | ||
62 | MICROCHIP_PFSOC_MMUART4, | ||
63 | + MICROCHIP_PFSOC_WDOG1, | ||
64 | + MICROCHIP_PFSOC_WDOG2, | ||
65 | + MICROCHIP_PFSOC_WDOG3, | ||
66 | + MICROCHIP_PFSOC_WDOG4, | ||
67 | MICROCHIP_PFSOC_SPI0, | ||
68 | MICROCHIP_PFSOC_SPI1, | ||
69 | + MICROCHIP_PFSOC_I2C0, | ||
70 | MICROCHIP_PFSOC_I2C1, | ||
71 | + MICROCHIP_PFSOC_CAN0, | ||
72 | + MICROCHIP_PFSOC_CAN1, | ||
73 | MICROCHIP_PFSOC_GEM0, | ||
74 | MICROCHIP_PFSOC_GEM1, | ||
75 | MICROCHIP_PFSOC_GPIO0, | ||
76 | MICROCHIP_PFSOC_GPIO1, | ||
77 | MICROCHIP_PFSOC_GPIO2, | ||
78 | + MICROCHIP_PFSOC_RTC, | ||
79 | MICROCHIP_PFSOC_ENVM_CFG, | ||
80 | MICROCHIP_PFSOC_ENVM_DATA, | ||
81 | + MICROCHIP_PFSOC_USB, | ||
82 | MICROCHIP_PFSOC_QSPI_XIP, | ||
83 | MICROCHIP_PFSOC_IOSCB, | ||
84 | - MICROCHIP_PFSOC_EMMC_SD_MUX, | ||
85 | + MICROCHIP_PFSOC_FABRIC_FIC3, | ||
86 | MICROCHIP_PFSOC_DRAM_LO, | ||
87 | MICROCHIP_PFSOC_DRAM_LO_ALIAS, | ||
88 | MICROCHIP_PFSOC_DRAM_HI, | ||
89 | diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c | ||
90 | index XXXXXXX..XXXXXXX 100644 | ||
91 | --- a/hw/riscv/microchip_pfsoc.c | ||
92 | +++ b/hw/riscv/microchip_pfsoc.c | ||
93 | @@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = { | ||
94 | [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 }, | ||
95 | [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 }, | ||
96 | [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 }, | ||
97 | + [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 }, | ||
98 | [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 }, | ||
99 | + [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 }, | ||
100 | [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 }, | ||
101 | + [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 }, | ||
102 | [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 }, | ||
103 | [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 }, | ||
104 | [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 }, | ||
105 | @@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = { | ||
106 | [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 }, | ||
107 | [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 }, | ||
108 | [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 }, | ||
109 | + [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 }, | ||
110 | + [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 }, | ||
111 | + [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 }, | ||
112 | + [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 }, | ||
113 | [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 }, | ||
114 | [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 }, | ||
115 | + [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 }, | ||
116 | [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 }, | ||
117 | + [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 }, | ||
118 | + [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 }, | ||
119 | [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 }, | ||
120 | [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 }, | ||
121 | [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 }, | ||
122 | [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 }, | ||
123 | [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 }, | ||
124 | + [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 }, | ||
125 | [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 }, | ||
126 | [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 }, | ||
127 | + [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 }, | ||
128 | [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 }, | ||
129 | [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 }, | ||
130 | - [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 }, | ||
131 | + [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 }, | ||
132 | [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 }, | ||
133 | [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 }, | ||
134 | [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 }, | ||
135 | @@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) | ||
136 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0, | ||
137 | memmap[MICROCHIP_PFSOC_SYSREG].base); | ||
138 | |||
139 | + /* AXISW */ | ||
140 | + create_unimplemented_device("microchip.pfsoc.axisw", | ||
141 | + memmap[MICROCHIP_PFSOC_AXISW].base, | ||
142 | + memmap[MICROCHIP_PFSOC_AXISW].size); | ||
143 | + | ||
144 | /* MPUCFG */ | ||
145 | create_unimplemented_device("microchip.pfsoc.mpucfg", | ||
146 | memmap[MICROCHIP_PFSOC_MPUCFG].base, | ||
147 | memmap[MICROCHIP_PFSOC_MPUCFG].size); | ||
148 | |||
149 | + /* FMETER */ | ||
150 | + create_unimplemented_device("microchip.pfsoc.fmeter", | ||
151 | + memmap[MICROCHIP_PFSOC_FMETER].base, | ||
152 | + memmap[MICROCHIP_PFSOC_FMETER].size); | ||
153 | + | ||
154 | /* DDR SGMII PHY */ | ||
155 | sysbus_realize(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), errp); | ||
156 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->ddr_sgmii_phy), 0, | ||
157 | @@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) | ||
158 | qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ), | ||
159 | serial_hd(4)); | ||
160 | |||
161 | + /* Watchdogs */ | ||
162 | + create_unimplemented_device("microchip.pfsoc.watchdog0", | ||
163 | + memmap[MICROCHIP_PFSOC_WDOG0].base, | ||
164 | + memmap[MICROCHIP_PFSOC_WDOG0].size); | ||
165 | + create_unimplemented_device("microchip.pfsoc.watchdog1", | ||
166 | + memmap[MICROCHIP_PFSOC_WDOG1].base, | ||
167 | + memmap[MICROCHIP_PFSOC_WDOG1].size); | ||
168 | + create_unimplemented_device("microchip.pfsoc.watchdog2", | ||
169 | + memmap[MICROCHIP_PFSOC_WDOG2].base, | ||
170 | + memmap[MICROCHIP_PFSOC_WDOG2].size); | ||
171 | + create_unimplemented_device("microchip.pfsoc.watchdog3", | ||
172 | + memmap[MICROCHIP_PFSOC_WDOG3].base, | ||
173 | + memmap[MICROCHIP_PFSOC_WDOG3].size); | ||
174 | + create_unimplemented_device("microchip.pfsoc.watchdog4", | ||
175 | + memmap[MICROCHIP_PFSOC_WDOG4].base, | ||
176 | + memmap[MICROCHIP_PFSOC_WDOG4].size); | ||
177 | + | ||
178 | /* SPI */ | ||
179 | create_unimplemented_device("microchip.pfsoc.spi0", | ||
180 | memmap[MICROCHIP_PFSOC_SPI0].base, | ||
181 | @@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) | ||
182 | memmap[MICROCHIP_PFSOC_SPI1].base, | ||
183 | memmap[MICROCHIP_PFSOC_SPI1].size); | ||
184 | |||
185 | - /* I2C1 */ | ||
186 | + /* I2C */ | ||
187 | + create_unimplemented_device("microchip.pfsoc.i2c0", | ||
188 | + memmap[MICROCHIP_PFSOC_I2C0].base, | ||
189 | + memmap[MICROCHIP_PFSOC_I2C0].size); | ||
190 | create_unimplemented_device("microchip.pfsoc.i2c1", | ||
191 | memmap[MICROCHIP_PFSOC_I2C1].base, | ||
192 | memmap[MICROCHIP_PFSOC_I2C1].size); | ||
193 | |||
194 | + /* CAN */ | ||
195 | + create_unimplemented_device("microchip.pfsoc.can0", | ||
196 | + memmap[MICROCHIP_PFSOC_CAN0].base, | ||
197 | + memmap[MICROCHIP_PFSOC_CAN0].size); | ||
198 | + create_unimplemented_device("microchip.pfsoc.can1", | ||
199 | + memmap[MICROCHIP_PFSOC_CAN1].base, | ||
200 | + memmap[MICROCHIP_PFSOC_CAN1].size); | ||
201 | + | ||
202 | + /* USB */ | ||
203 | + create_unimplemented_device("microchip.pfsoc.usb", | ||
204 | + memmap[MICROCHIP_PFSOC_USB].base, | ||
205 | + memmap[MICROCHIP_PFSOC_USB].size); | ||
206 | + | ||
207 | /* GEMs */ | ||
208 | |||
209 | nd = &nd_table[0]; | ||
210 | @@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) | ||
211 | sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0, | ||
212 | memmap[MICROCHIP_PFSOC_IOSCB].base); | ||
213 | |||
214 | - /* eMMC/SD mux */ | ||
215 | - create_unimplemented_device("microchip.pfsoc.emmc_sd_mux", | ||
216 | - memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base, | ||
217 | - memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size); | ||
218 | + /* FPGA Fabric */ | ||
219 | + create_unimplemented_device("microchip.pfsoc.fabricfic3", | ||
220 | + memmap[MICROCHIP_PFSOC_FABRIC_FIC3].base, | ||
221 | + memmap[MICROCHIP_PFSOC_FABRIC_FIC3].size); | ||
222 | |||
223 | /* QSPI Flash */ | ||
224 | memory_region_init_rom(qspi_xip_mem, OBJECT(dev), | ||
225 | -- | ||
226 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | With .min_priv_version, additiona priv version check is uncessary | ||
4 | for mcountinhibit read/write functions. | ||
5 | |||
6 | Reviewed-by: Heiko Stuebner <heiko@sntech.de> | ||
7 | Tested-by: Heiko Stuebner <heiko@sntech.de> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
10 | Message-Id: <20220816232321.558250-7-atishp@rivosinc.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/csr.c | 8 -------- | ||
14 | 1 file changed, 8 deletions(-) | ||
15 | |||
16 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/target/riscv/csr.c | ||
19 | +++ b/target/riscv/csr.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mtvec(CPURISCVState *env, int csrno, | ||
21 | static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno, | ||
22 | target_ulong *val) | ||
23 | { | ||
24 | - if (env->priv_ver < PRIV_VERSION_1_11_0) { | ||
25 | - return RISCV_EXCP_ILLEGAL_INST; | ||
26 | - } | ||
27 | - | ||
28 | *val = env->mcountinhibit; | ||
29 | return RISCV_EXCP_NONE; | ||
30 | } | ||
31 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno, | ||
32 | int cidx; | ||
33 | PMUCTRState *counter; | ||
34 | |||
35 | - if (env->priv_ver < PRIV_VERSION_1_11_0) { | ||
36 | - return RISCV_EXCP_ILLEGAL_INST; | ||
37 | - } | ||
38 | - | ||
39 | env->mcountinhibit = val; | ||
40 | |||
41 | /* Check if any other counter is also monitoring cycles/instructions */ | ||
42 | -- | ||
43 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Conor Dooley <conor.dooley@microchip.com> | ||
1 | 2 | ||
3 | "uart" is not a node name that complies with the dt-schema. | ||
4 | Change the node name to "serial" to ix warnings seen during | ||
5 | dt-validate on a dtbdump of the virt machine such as: | ||
6 | /stuff/qemu/qemu.dtb: uart@10000000: $nodename:0: 'uart@10000000' does not match '^serial(@.*)?$' | ||
7 | From schema: /stuff/linux/Documentation/devicetree/bindings/serial/8250.yaml | ||
8 | |||
9 | Reported-by: Rob Herring <robh@kernel.org> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
12 | Message-id: 20220810184612.157317-2-mail@conchuod.ie | ||
13 | Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/ | ||
14 | Fixes: 04331d0b56 ("RISC-V VirtIO Machine") | ||
15 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | --- | ||
18 | hw/riscv/virt.c | 2 +- | ||
19 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
20 | |||
21 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/hw/riscv/virt.c | ||
24 | +++ b/hw/riscv/virt.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap, | ||
26 | char *name; | ||
27 | MachineState *mc = MACHINE(s); | ||
28 | |||
29 | - name = g_strdup_printf("/soc/uart@%lx", (long)memmap[VIRT_UART0].base); | ||
30 | + name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base); | ||
31 | qemu_fdt_add_subnode(mc->fdt, name); | ||
32 | qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a"); | ||
33 | qemu_fdt_setprop_cells(mc->fdt, name, "reg", | ||
34 | -- | ||
35 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Conor Dooley <conor.dooley@microchip.com> | ||
1 | 2 | ||
3 | When optional AIA PLIC support was added the to the virt machine, the | ||
4 | address cells property was removed leading the issues with dt-validate | ||
5 | on a dump from the virt machine: | ||
6 | /stuff/qemu/qemu.dtb: plic@c000000: '#address-cells' is a required property | ||
7 | From schema: /stuff/linux/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml | ||
8 | Add back the property to suppress the warning. | ||
9 | |||
10 | Reported-by: Rob Herring <robh@kernel.org> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
13 | Message-id: 20220810184612.157317-3-mail@conchuod.ie | ||
14 | Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/ | ||
15 | Fixes: e6faee6585 ("hw/riscv: virt: Add optional AIA APLIC support to virt machine") | ||
16 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | --- | ||
19 | include/hw/riscv/virt.h | 1 + | ||
20 | hw/riscv/virt.c | 2 ++ | ||
21 | 2 files changed, 3 insertions(+) | ||
22 | |||
23 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/include/hw/riscv/virt.h | ||
26 | +++ b/include/hw/riscv/virt.h | ||
27 | @@ -XXX,XX +XXX,XX @@ enum { | ||
28 | |||
29 | #define FDT_PCI_ADDR_CELLS 3 | ||
30 | #define FDT_PCI_INT_CELLS 1 | ||
31 | +#define FDT_PLIC_ADDR_CELLS 0 | ||
32 | #define FDT_PLIC_INT_CELLS 1 | ||
33 | #define FDT_APLIC_INT_CELLS 2 | ||
34 | #define FDT_IMSIC_INT_CELLS 0 | ||
35 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/hw/riscv/virt.c | ||
38 | +++ b/hw/riscv/virt.c | ||
39 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s, | ||
40 | qemu_fdt_add_subnode(mc->fdt, plic_name); | ||
41 | qemu_fdt_setprop_cell(mc->fdt, plic_name, | ||
42 | "#interrupt-cells", FDT_PLIC_INT_CELLS); | ||
43 | + qemu_fdt_setprop_cell(mc->fdt, plic_name, | ||
44 | + "#address-cells", FDT_PLIC_ADDR_CELLS); | ||
45 | qemu_fdt_setprop_string_array(mc->fdt, plic_name, "compatible", | ||
46 | (char **)&plic_compat, | ||
47 | ARRAY_SIZE(plic_compat)); | ||
48 | -- | ||
49 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Conor Dooley <conor.dooley@microchip.com> | ||
1 | 2 | ||
3 | The reset and poweroff features of the syscon were originally added to | ||
4 | top level, which is a valid path for a syscon subnode. Subsequently a | ||
5 | reorganisation was carried out while implementing NUMA in which the | ||
6 | subnodes were moved into the /soc node. As /soc is a "simple-bus", this | ||
7 | path is invalid, and so dt-validate produces the following warnings: | ||
8 | |||
9 | /stuff/qemu/qemu.dtb: soc: poweroff: {'value': [[21845]], 'offset': [[0]], 'regmap': [[4]], 'compatible': ['syscon-poweroff']} should not be valid under {'type': 'object'} | ||
10 | From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml | ||
11 | /stuff/qemu/qemu.dtb: soc: reboot: {'value': [[30583]], 'offset': [[0]], 'regmap': [[4]], 'compatible': ['syscon-reboot']} should not be valid under {'type': 'object'} | ||
12 | From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml | ||
13 | |||
14 | Move the syscon subnodes back to the top level and silence the warnings. | ||
15 | |||
16 | Reported-by: Rob Herring <robh@kernel.org> | ||
17 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
18 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | Message-id: 20220810184612.157317-4-mail@conchuod.ie | ||
20 | Link: https://lore.kernel.org/linux-riscv/20220803170552.GA2250266-robh@kernel.org/ | ||
21 | Fixes: 18df0b4695 ("hw/riscv: virt: Allow creating multiple NUMA sockets") | ||
22 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
23 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
24 | --- | ||
25 | hw/riscv/virt.c | 4 ++-- | ||
26 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
27 | |||
28 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/hw/riscv/virt.c | ||
31 | +++ b/hw/riscv/virt.c | ||
32 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap, | ||
33 | test_phandle = qemu_fdt_get_phandle(mc->fdt, name); | ||
34 | g_free(name); | ||
35 | |||
36 | - name = g_strdup_printf("/soc/reboot"); | ||
37 | + name = g_strdup_printf("/reboot"); | ||
38 | qemu_fdt_add_subnode(mc->fdt, name); | ||
39 | qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot"); | ||
40 | qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle); | ||
41 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap, | ||
42 | qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET); | ||
43 | g_free(name); | ||
44 | |||
45 | - name = g_strdup_printf("/soc/poweroff"); | ||
46 | + name = g_strdup_printf("/poweroff"); | ||
47 | qemu_fdt_add_subnode(mc->fdt, name); | ||
48 | qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff"); | ||
49 | qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle); | ||
50 | -- | ||
51 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Conor Dooley <conor.dooley@microchip.com> | ||
1 | 2 | ||
3 | "platform" is not a valid name for a bus node in dt-schema, so warnings | ||
4 | can be see in dt-validate on a dump of the riscv virt dtb: | ||
5 | |||
6 | /stuff/qemu/qemu.dtb: platform@4000000: $nodename:0: 'platform@4000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$' | ||
7 | From schema: /home/conor/.local/lib/python3.9/site-packages/dtschema/schemas/simple-bus.yaml | ||
8 | "platform-bus" is a valid name, so use that instead. | ||
9 | |||
10 | CC: Rob Herring <robh@kernel.org> | ||
11 | Fixes: 11d306b9df ("hw/arm/sysbus-fdt: helpers for platform bus nodes addition") | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Signed-off-by: Conor Dooley <conor.dooley@microchip.com> | ||
14 | Message-id: 20220810184612.157317-5-mail@conchuod.ie | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | hw/core/sysbus-fdt.c | 2 +- | ||
18 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
19 | |||
20 | diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/hw/core/sysbus-fdt.c | ||
23 | +++ b/hw/core/sysbus-fdt.c | ||
24 | @@ -XXX,XX +XXX,XX @@ void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, | ||
25 | |||
26 | assert(fdt); | ||
27 | |||
28 | - node = g_strdup_printf("/platform@%"PRIx64, addr); | ||
29 | + node = g_strdup_printf("/platform-bus@%"PRIx64, addr); | ||
30 | |||
31 | /* Create a /platform node that we can put all devices into */ | ||
32 | qemu_fdt_add_subnode(fdt, node); | ||
33 | -- | ||
34 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Rahul Pathak <rpathak@ventanamicro.com> | ||
1 | 2 | ||
3 | XVentanaCondOps is Ventana custom extension. Add | ||
4 | its extension entry in the ISA Ext array | ||
5 | |||
6 | Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-id: 20220816045408.1231135-1-rpathak@ventanamicro.com | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/cpu.c | 1 + | ||
12 | 1 file changed, 1 insertion(+) | ||
13 | |||
14 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/target/riscv/cpu.c | ||
17 | +++ b/target/riscv/cpu.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
19 | ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval), | ||
20 | ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), | ||
21 | ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt), | ||
22 | + ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps), | ||
23 | }; | ||
24 | |||
25 | static bool isa_ext_is_enabled(RISCVCPU *cpu, | ||
26 | -- | ||
27 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | 1 | From: Anup Patel <apatel@ventanamicro.com> | |
2 | |||
3 | The arch review of AIA spec is completed and we now have official | ||
4 | extension names for AIA: Smaia (M-mode AIA CSRs) and Ssaia (S-mode | ||
5 | AIA CSRs). | ||
6 | |||
7 | Refer, section 1.6 of the latest AIA v0.3.1 stable specification at | ||
8 | https://github.com/riscv/riscv-aia/releases/download/0.3.1-draft.32/riscv-interrupts-032.pdf) | ||
9 | |||
10 | Based on above, we update QEMU RISC-V to: | ||
11 | 1) Have separate config options for Smaia and Ssaia extensions | ||
12 | which replace RISCV_FEATURE_AIA in CPU features | ||
13 | 2) Not generate AIA INTC compatible string in virt machine | ||
14 | |||
15 | Signed-off-by: Anup Patel <apatel@ventanamicro.com> | ||
16 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
17 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | Message-id: 20220820042958.377018-1-apatel@ventanamicro.com | ||
19 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | --- | ||
21 | target/riscv/cpu.h | 4 ++-- | ||
22 | hw/intc/riscv_imsic.c | 4 +++- | ||
23 | hw/riscv/virt.c | 13 ++----------- | ||
24 | target/riscv/cpu.c | 9 ++++----- | ||
25 | target/riscv/cpu_helper.c | 3 ++- | ||
26 | target/riscv/csr.c | 24 ++++++++++++++++++------ | ||
27 | 6 files changed, 31 insertions(+), 26 deletions(-) | ||
28 | |||
29 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/cpu.h | ||
32 | +++ b/target/riscv/cpu.h | ||
33 | @@ -XXX,XX +XXX,XX @@ enum { | ||
34 | RISCV_FEATURE_PMP, | ||
35 | RISCV_FEATURE_EPMP, | ||
36 | RISCV_FEATURE_MISA, | ||
37 | - RISCV_FEATURE_AIA, | ||
38 | RISCV_FEATURE_DEBUG | ||
39 | }; | ||
40 | |||
41 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
42 | bool ext_zve32f; | ||
43 | bool ext_zve64f; | ||
44 | bool ext_zmmul; | ||
45 | + bool ext_smaia; | ||
46 | + bool ext_ssaia; | ||
47 | bool rvv_ta_all_1s; | ||
48 | bool rvv_ma_all_1s; | ||
49 | |||
50 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
51 | bool mmu; | ||
52 | bool pmp; | ||
53 | bool epmp; | ||
54 | - bool aia; | ||
55 | bool debug; | ||
56 | uint64_t resetvec; | ||
57 | |||
58 | diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/hw/intc/riscv_imsic.c | ||
61 | +++ b/hw/intc/riscv_imsic.c | ||
62 | @@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp) | ||
63 | |||
64 | /* Force select AIA feature and setup CSR read-modify-write callback */ | ||
65 | if (env) { | ||
66 | - riscv_set_feature(env, RISCV_FEATURE_AIA); | ||
67 | if (!imsic->mmode) { | ||
68 | + rcpu->cfg.ext_ssaia = true; | ||
69 | riscv_cpu_set_geilen(env, imsic->num_pages - 1); | ||
70 | + } else { | ||
71 | + rcpu->cfg.ext_smaia = true; | ||
72 | } | ||
73 | riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S, | ||
74 | riscv_imsic_rmw, imsic); | ||
75 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
76 | index XXXXXXX..XXXXXXX 100644 | ||
77 | --- a/hw/riscv/virt.c | ||
78 | +++ b/hw/riscv/virt.c | ||
79 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, | ||
80 | qemu_fdt_add_subnode(mc->fdt, intc_name); | ||
81 | qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle", | ||
82 | intc_phandles[cpu]); | ||
83 | - if (riscv_feature(&s->soc[socket].harts[cpu].env, | ||
84 | - RISCV_FEATURE_AIA)) { | ||
85 | - static const char * const compat[2] = { | ||
86 | - "riscv,cpu-intc-aia", "riscv,cpu-intc" | ||
87 | - }; | ||
88 | - qemu_fdt_setprop_string_array(mc->fdt, intc_name, "compatible", | ||
89 | - (char **)&compat, ARRAY_SIZE(compat)); | ||
90 | - } else { | ||
91 | - qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible", | ||
92 | - "riscv,cpu-intc"); | ||
93 | - } | ||
94 | + qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible", | ||
95 | + "riscv,cpu-intc"); | ||
96 | qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0); | ||
97 | qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1); | ||
98 | |||
99 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/target/riscv/cpu.c | ||
102 | +++ b/target/riscv/cpu.c | ||
103 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
104 | ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f), | ||
105 | ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx), | ||
106 | ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
107 | + ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia), | ||
108 | + ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia), | ||
109 | ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval), | ||
110 | ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), | ||
111 | ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt), | ||
112 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
113 | } | ||
114 | } | ||
115 | |||
116 | - if (cpu->cfg.aia) { | ||
117 | - riscv_set_feature(env, RISCV_FEATURE_AIA); | ||
118 | - } | ||
119 | - | ||
120 | if (cpu->cfg.debug) { | ||
121 | riscv_set_feature(env, RISCV_FEATURE_DEBUG); | ||
122 | } | ||
123 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
124 | DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), | ||
125 | /* ePMP 0.9.3 */ | ||
126 | DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), | ||
127 | - DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false), | ||
128 | + DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false), | ||
129 | + DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false), | ||
130 | |||
131 | DEFINE_PROP_END_OF_LIST(), | ||
132 | }; | ||
133 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
134 | index XXXXXXX..XXXXXXX 100644 | ||
135 | --- a/target/riscv/cpu_helper.c | ||
136 | +++ b/target/riscv/cpu_helper.c | ||
137 | @@ -XXX,XX +XXX,XX @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env, | ||
138 | int extirq, unsigned int extirq_def_prio, | ||
139 | uint64_t pending, uint8_t *iprio) | ||
140 | { | ||
141 | + RISCVCPU *cpu = env_archcpu(env); | ||
142 | int irq, best_irq = RISCV_EXCP_NONE; | ||
143 | unsigned int prio, best_prio = UINT_MAX; | ||
144 | |||
145 | @@ -XXX,XX +XXX,XX @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env, | ||
146 | } | ||
147 | |||
148 | irq = ctz64(pending); | ||
149 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
150 | + if (!((extirq == IRQ_M_EXT) ? cpu->cfg.ext_smaia : cpu->cfg.ext_ssaia)) { | ||
151 | return irq; | ||
152 | } | ||
153 | |||
154 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
155 | index XXXXXXX..XXXXXXX 100644 | ||
156 | --- a/target/riscv/csr.c | ||
157 | +++ b/target/riscv/csr.c | ||
158 | @@ -XXX,XX +XXX,XX @@ static RISCVException any32(CPURISCVState *env, int csrno) | ||
159 | |||
160 | static int aia_any(CPURISCVState *env, int csrno) | ||
161 | { | ||
162 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
163 | + RISCVCPU *cpu = env_archcpu(env); | ||
164 | + | ||
165 | + if (!cpu->cfg.ext_smaia) { | ||
166 | return RISCV_EXCP_ILLEGAL_INST; | ||
167 | } | ||
168 | |||
169 | @@ -XXX,XX +XXX,XX @@ static int aia_any(CPURISCVState *env, int csrno) | ||
170 | |||
171 | static int aia_any32(CPURISCVState *env, int csrno) | ||
172 | { | ||
173 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
174 | + RISCVCPU *cpu = env_archcpu(env); | ||
175 | + | ||
176 | + if (!cpu->cfg.ext_smaia) { | ||
177 | return RISCV_EXCP_ILLEGAL_INST; | ||
178 | } | ||
179 | |||
180 | @@ -XXX,XX +XXX,XX @@ static int smode32(CPURISCVState *env, int csrno) | ||
181 | |||
182 | static int aia_smode(CPURISCVState *env, int csrno) | ||
183 | { | ||
184 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
185 | + RISCVCPU *cpu = env_archcpu(env); | ||
186 | + | ||
187 | + if (!cpu->cfg.ext_ssaia) { | ||
188 | return RISCV_EXCP_ILLEGAL_INST; | ||
189 | } | ||
190 | |||
191 | @@ -XXX,XX +XXX,XX @@ static int aia_smode(CPURISCVState *env, int csrno) | ||
192 | |||
193 | static int aia_smode32(CPURISCVState *env, int csrno) | ||
194 | { | ||
195 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
196 | + RISCVCPU *cpu = env_archcpu(env); | ||
197 | + | ||
198 | + if (!cpu->cfg.ext_ssaia) { | ||
199 | return RISCV_EXCP_ILLEGAL_INST; | ||
200 | } | ||
201 | |||
202 | @@ -XXX,XX +XXX,XX @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno) | ||
203 | |||
204 | static int aia_hmode(CPURISCVState *env, int csrno) | ||
205 | { | ||
206 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
207 | + RISCVCPU *cpu = env_archcpu(env); | ||
208 | + | ||
209 | + if (!cpu->cfg.ext_ssaia) { | ||
210 | return RISCV_EXCP_ILLEGAL_INST; | ||
211 | } | ||
212 | |||
213 | @@ -XXX,XX +XXX,XX @@ static int aia_hmode(CPURISCVState *env, int csrno) | ||
214 | |||
215 | static int aia_hmode32(CPURISCVState *env, int csrno) | ||
216 | { | ||
217 | - if (!riscv_feature(env, RISCV_FEATURE_AIA)) { | ||
218 | + RISCVCPU *cpu = env_archcpu(env); | ||
219 | + | ||
220 | + if (!cpu->cfg.ext_ssaia) { | ||
221 | return RISCV_EXCP_ILLEGAL_INST; | ||
222 | } | ||
223 | |||
224 | -- | ||
225 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | Historically, The mtime/mtimecmp has been part of the CPU because | ||
4 | they are per hart entities. However, they actually belong to aclint | ||
5 | which is a MMIO device. | ||
6 | |||
7 | Move them to the ACLINT device. This also emulates the real hardware | ||
8 | more closely. | ||
9 | |||
10 | Reviewed-by: Anup Patel <anup@brainfault.org> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
13 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
14 | Message-Id: <20220824221357.41070-2-atishp@rivosinc.com> | ||
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
16 | --- | ||
17 | include/hw/intc/riscv_aclint.h | 2 ++ | ||
18 | include/hw/timer/ibex_timer.h | 2 ++ | ||
19 | target/riscv/cpu.h | 2 -- | ||
20 | hw/intc/riscv_aclint.c | 48 ++++++++++++++++++++++++---------- | ||
21 | hw/timer/ibex_timer.c | 18 +++++-------- | ||
22 | target/riscv/machine.c | 5 ++-- | ||
23 | 6 files changed, 47 insertions(+), 30 deletions(-) | ||
24 | |||
25 | diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/include/hw/intc/riscv_aclint.h | ||
28 | +++ b/include/hw/intc/riscv_aclint.h | ||
29 | @@ -XXX,XX +XXX,XX @@ typedef struct RISCVAclintMTimerState { | ||
30 | /*< private >*/ | ||
31 | SysBusDevice parent_obj; | ||
32 | uint64_t time_delta; | ||
33 | + uint64_t *timecmp; | ||
34 | + QEMUTimer **timers; | ||
35 | |||
36 | /*< public >*/ | ||
37 | MemoryRegion mmio; | ||
38 | diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/include/hw/timer/ibex_timer.h | ||
41 | +++ b/include/hw/timer/ibex_timer.h | ||
42 | @@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IbexTimerState, IBEX_TIMER) | ||
43 | struct IbexTimerState { | ||
44 | /* <private> */ | ||
45 | SysBusDevice parent_obj; | ||
46 | + uint64_t mtimecmp; | ||
47 | + QEMUTimer *mtimer; /* Internal timer for M-mode interrupt */ | ||
48 | |||
49 | /* <public> */ | ||
50 | MemoryRegion mmio; | ||
51 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/target/riscv/cpu.h | ||
54 | +++ b/target/riscv/cpu.h | ||
55 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | ||
56 | /* temporary htif regs */ | ||
57 | uint64_t mfromhost; | ||
58 | uint64_t mtohost; | ||
59 | - uint64_t timecmp; | ||
60 | |||
61 | /* physical memory protection */ | ||
62 | pmp_table_t pmp_state; | ||
63 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | ||
64 | float_status fp_status; | ||
65 | |||
66 | /* Fields from here on are preserved across CPU reset. */ | ||
67 | - QEMUTimer *timer; /* Internal timer */ | ||
68 | |||
69 | hwaddr kernel_addr; | ||
70 | hwaddr fdt_addr; | ||
71 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c | ||
72 | index XXXXXXX..XXXXXXX 100644 | ||
73 | --- a/hw/intc/riscv_aclint.c | ||
74 | +++ b/hw/intc/riscv_aclint.c | ||
75 | @@ -XXX,XX +XXX,XX @@ | ||
76 | #include "hw/intc/riscv_aclint.h" | ||
77 | #include "qemu/timer.h" | ||
78 | #include "hw/irq.h" | ||
79 | +#include "migration/vmstate.h" | ||
80 | |||
81 | typedef struct riscv_aclint_mtimer_callback { | ||
82 | RISCVAclintMTimerState *s; | ||
83 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, | ||
84 | |||
85 | uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); | ||
86 | |||
87 | - cpu->env.timecmp = value; | ||
88 | - if (cpu->env.timecmp <= rtc_r) { | ||
89 | + /* Compute the relative hartid w.r.t the socket */ | ||
90 | + hartid = hartid - mtimer->hartid_base; | ||
91 | + | ||
92 | + mtimer->timecmp[hartid] = value; | ||
93 | + if (mtimer->timecmp[hartid] <= rtc_r) { | ||
94 | /* | ||
95 | * If we're setting an MTIMECMP value in the "past", | ||
96 | * immediately raise the timer interrupt | ||
97 | */ | ||
98 | - qemu_irq_raise(mtimer->timer_irqs[hartid - mtimer->hartid_base]); | ||
99 | + qemu_irq_raise(mtimer->timer_irqs[hartid]); | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | /* otherwise, set up the future timer interrupt */ | ||
104 | - qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]); | ||
105 | - diff = cpu->env.timecmp - rtc_r; | ||
106 | + qemu_irq_lower(mtimer->timer_irqs[hartid]); | ||
107 | + diff = mtimer->timecmp[hartid] - rtc_r; | ||
108 | /* back to ns (note args switched in muldiv64) */ | ||
109 | uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); | ||
110 | |||
111 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, | ||
112 | next = MIN(next, INT64_MAX); | ||
113 | } | ||
114 | |||
115 | - timer_mod(cpu->env.timer, next); | ||
116 | + timer_mod(mtimer->timers[hartid], next); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | @@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, | ||
121 | "aclint-mtimer: invalid hartid: %zu", hartid); | ||
122 | } else if ((addr & 0x7) == 0) { | ||
123 | /* timecmp_lo for RV32/RV64 or timecmp for RV64 */ | ||
124 | - uint64_t timecmp = env->timecmp; | ||
125 | + uint64_t timecmp = mtimer->timecmp[hartid]; | ||
126 | return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp; | ||
127 | } else if ((addr & 0x7) == 4) { | ||
128 | /* timecmp_hi */ | ||
129 | - uint64_t timecmp = env->timecmp; | ||
130 | + uint64_t timecmp = mtimer->timecmp[hartid]; | ||
131 | return (timecmp >> 32) & 0xFFFFFFFF; | ||
132 | } else { | ||
133 | qemu_log_mask(LOG_UNIMP, | ||
134 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
135 | } else if ((addr & 0x7) == 0) { | ||
136 | if (size == 4) { | ||
137 | /* timecmp_lo for RV32/RV64 */ | ||
138 | - uint64_t timecmp_hi = env->timecmp >> 32; | ||
139 | + uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32; | ||
140 | riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
141 | timecmp_hi << 32 | (value & 0xFFFFFFFF)); | ||
142 | } else { | ||
143 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
144 | } else if ((addr & 0x7) == 4) { | ||
145 | if (size == 4) { | ||
146 | /* timecmp_hi for RV32/RV64 */ | ||
147 | - uint64_t timecmp_lo = env->timecmp; | ||
148 | + uint64_t timecmp_lo = mtimer->timecmp[hartid]; | ||
149 | riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
150 | value << 32 | (timecmp_lo & 0xFFFFFFFF)); | ||
151 | } else { | ||
152 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
153 | } | ||
154 | riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), | ||
155 | mtimer->hartid_base + i, | ||
156 | - env->timecmp); | ||
157 | + mtimer->timecmp[i]); | ||
158 | } | ||
159 | return; | ||
160 | } | ||
161 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) | ||
162 | s->timer_irqs = g_new(qemu_irq, s->num_harts); | ||
163 | qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts); | ||
164 | |||
165 | + s->timers = g_new0(QEMUTimer *, s->num_harts); | ||
166 | + s->timecmp = g_new0(uint64_t, s->num_harts); | ||
167 | /* Claim timer interrupt bits */ | ||
168 | for (i = 0; i < s->num_harts; i++) { | ||
169 | RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); | ||
170 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type) | ||
171 | riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8); | ||
172 | } | ||
173 | |||
174 | +static const VMStateDescription vmstate_riscv_mtimer = { | ||
175 | + .name = "riscv_mtimer", | ||
176 | + .version_id = 1, | ||
177 | + .minimum_version_id = 1, | ||
178 | + .fields = (VMStateField[]) { | ||
179 | + VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState, | ||
180 | + num_harts, 0, | ||
181 | + vmstate_info_uint64, uint64_t), | ||
182 | + VMSTATE_END_OF_LIST() | ||
183 | + } | ||
184 | +}; | ||
185 | + | ||
186 | static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) | ||
187 | { | ||
188 | DeviceClass *dc = DEVICE_CLASS(klass); | ||
189 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) | ||
190 | device_class_set_props(dc, riscv_aclint_mtimer_properties); | ||
191 | ResettableClass *rc = RESETTABLE_CLASS(klass); | ||
192 | rc->phases.enter = riscv_aclint_mtimer_reset_enter; | ||
193 | + dc->vmsd = &vmstate_riscv_mtimer; | ||
194 | } | ||
195 | |||
196 | static const TypeInfo riscv_aclint_mtimer_info = { | ||
197 | @@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, | ||
198 | { | ||
199 | int i; | ||
200 | DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER); | ||
201 | + RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev); | ||
202 | |||
203 | assert(num_harts <= RISCV_ACLINT_MAX_HARTS); | ||
204 | assert(!(addr & 0x7)); | ||
205 | @@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, | ||
206 | riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev); | ||
207 | } | ||
208 | |||
209 | - cb->s = RISCV_ACLINT_MTIMER(dev); | ||
210 | + cb->s = s; | ||
211 | cb->num = i; | ||
212 | - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
213 | + s->timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
214 | &riscv_aclint_mtimer_cb, cb); | ||
215 | - env->timecmp = 0; | ||
216 | + s->timecmp[i] = 0; | ||
217 | |||
218 | qdev_connect_gpio_out(dev, i, | ||
219 | qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER)); | ||
220 | diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c | ||
221 | index XXXXXXX..XXXXXXX 100644 | ||
222 | --- a/hw/timer/ibex_timer.c | ||
223 | +++ b/hw/timer/ibex_timer.c | ||
224 | @@ -XXX,XX +XXX,XX @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq) | ||
225 | |||
226 | static void ibex_timer_update_irqs(IbexTimerState *s) | ||
227 | { | ||
228 | - CPUState *cs = qemu_get_cpu(0); | ||
229 | - RISCVCPU *cpu = RISCV_CPU(cs); | ||
230 | uint64_t value = s->timer_compare_lower0 | | ||
231 | ((uint64_t)s->timer_compare_upper0 << 32); | ||
232 | uint64_t next, diff; | ||
233 | @@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s) | ||
234 | } | ||
235 | |||
236 | /* Update the CPUs mtimecmp */ | ||
237 | - cpu->env.timecmp = value; | ||
238 | + s->mtimecmp = value; | ||
239 | |||
240 | - if (cpu->env.timecmp <= now) { | ||
241 | + if (s->mtimecmp <= now) { | ||
242 | /* | ||
243 | * If the mtimecmp was in the past raise the interrupt now. | ||
244 | */ | ||
245 | @@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s) | ||
246 | qemu_irq_lower(s->m_timer_irq); | ||
247 | qemu_set_irq(s->irq, false); | ||
248 | |||
249 | - diff = cpu->env.timecmp - now; | ||
250 | + diff = s->mtimecmp - now; | ||
251 | next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + | ||
252 | muldiv64(diff, | ||
253 | NANOSECONDS_PER_SECOND, | ||
254 | @@ -XXX,XX +XXX,XX @@ static void ibex_timer_update_irqs(IbexTimerState *s) | ||
255 | |||
256 | if (next < qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) { | ||
257 | /* We overflowed the timer, just set it as large as we can */ | ||
258 | - timer_mod(cpu->env.timer, 0x7FFFFFFFFFFFFFFF); | ||
259 | + timer_mod(s->mtimer, 0x7FFFFFFFFFFFFFFF); | ||
260 | } else { | ||
261 | - timer_mod(cpu->env.timer, next); | ||
262 | + timer_mod(s->mtimer, next); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | @@ -XXX,XX +XXX,XX @@ static void ibex_timer_reset(DeviceState *dev) | ||
267 | { | ||
268 | IbexTimerState *s = IBEX_TIMER(dev); | ||
269 | |||
270 | - CPUState *cpu = qemu_get_cpu(0); | ||
271 | - CPURISCVState *env = cpu->env_ptr; | ||
272 | - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
273 | + s->mtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
274 | &ibex_timer_cb, s); | ||
275 | - env->timecmp = 0; | ||
276 | + s->mtimecmp = 0; | ||
277 | |||
278 | s->timer_ctrl = 0x00000000; | ||
279 | s->timer_cfg0 = 0x00010000; | ||
280 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | ||
281 | index XXXXXXX..XXXXXXX 100644 | ||
282 | --- a/target/riscv/machine.c | ||
283 | +++ b/target/riscv/machine.c | ||
284 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu_ctr_state = { | ||
285 | |||
286 | const VMStateDescription vmstate_riscv_cpu = { | ||
287 | .name = "cpu", | ||
288 | - .version_id = 3, | ||
289 | - .minimum_version_id = 3, | ||
290 | + .version_id = 4, | ||
291 | + .minimum_version_id = 4, | ||
292 | .post_load = riscv_cpu_post_load, | ||
293 | .fields = (VMStateField[]) { | ||
294 | VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32), | ||
295 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = { | ||
296 | VMSTATE_UINTTL(env.mscratch, RISCVCPU), | ||
297 | VMSTATE_UINT64(env.mfromhost, RISCVCPU), | ||
298 | VMSTATE_UINT64(env.mtohost, RISCVCPU), | ||
299 | - VMSTATE_UINT64(env.timecmp, RISCVCPU), | ||
300 | |||
301 | VMSTATE_END_OF_LIST() | ||
302 | }, | ||
303 | -- | ||
304 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | stimecmp allows the supervisor mode to update stimecmp CSR directly | ||
4 | to program the next timer interrupt. This CSR is part of the Sstc | ||
5 | extension which was ratified recently. | ||
6 | |||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
9 | Message-Id: <20220824221357.41070-3-atishp@rivosinc.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/cpu.h | 5 ++ | ||
13 | target/riscv/cpu_bits.h | 4 ++ | ||
14 | target/riscv/time_helper.h | 30 ++++++++++++ | ||
15 | target/riscv/cpu.c | 9 ++++ | ||
16 | target/riscv/csr.c | 86 +++++++++++++++++++++++++++++++++ | ||
17 | target/riscv/machine.c | 1 + | ||
18 | target/riscv/time_helper.c | 98 ++++++++++++++++++++++++++++++++++++++ | ||
19 | target/riscv/meson.build | 3 +- | ||
20 | 8 files changed, 235 insertions(+), 1 deletion(-) | ||
21 | create mode 100644 target/riscv/time_helper.h | ||
22 | create mode 100644 target/riscv/time_helper.c | ||
23 | |||
24 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/target/riscv/cpu.h | ||
27 | +++ b/target/riscv/cpu.h | ||
28 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | ||
29 | uint64_t mfromhost; | ||
30 | uint64_t mtohost; | ||
31 | |||
32 | + /* Sstc CSRs */ | ||
33 | + uint64_t stimecmp; | ||
34 | + | ||
35 | /* physical memory protection */ | ||
36 | pmp_table_t pmp_state; | ||
37 | target_ulong mseccfg; | ||
38 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | ||
39 | float_status fp_status; | ||
40 | |||
41 | /* Fields from here on are preserved across CPU reset. */ | ||
42 | + QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ | ||
43 | |||
44 | hwaddr kernel_addr; | ||
45 | hwaddr fdt_addr; | ||
46 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
47 | bool ext_ifencei; | ||
48 | bool ext_icsr; | ||
49 | bool ext_zihintpause; | ||
50 | + bool ext_sstc; | ||
51 | bool ext_svinval; | ||
52 | bool ext_svnapot; | ||
53 | bool ext_svpbmt; | ||
54 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/target/riscv/cpu_bits.h | ||
57 | +++ b/target/riscv/cpu_bits.h | ||
58 | @@ -XXX,XX +XXX,XX @@ | ||
59 | #define CSR_STVAL 0x143 | ||
60 | #define CSR_SIP 0x144 | ||
61 | |||
62 | +/* Sstc supervisor CSRs */ | ||
63 | +#define CSR_STIMECMP 0x14D | ||
64 | +#define CSR_STIMECMPH 0x15D | ||
65 | + | ||
66 | /* Supervisor Protection and Translation */ | ||
67 | #define CSR_SPTBR 0x180 | ||
68 | #define CSR_SATP 0x180 | ||
69 | diff --git a/target/riscv/time_helper.h b/target/riscv/time_helper.h | ||
70 | new file mode 100644 | ||
71 | index XXXXXXX..XXXXXXX | ||
72 | --- /dev/null | ||
73 | +++ b/target/riscv/time_helper.h | ||
74 | @@ -XXX,XX +XXX,XX @@ | ||
75 | +/* | ||
76 | + * RISC-V timer header file. | ||
77 | + * | ||
78 | + * Copyright (c) 2022 Rivos Inc. | ||
79 | + * | ||
80 | + * This program is free software; you can redistribute it and/or modify it | ||
81 | + * under the terms and conditions of the GNU General Public License, | ||
82 | + * version 2 or later, as published by the Free Software Foundation. | ||
83 | + * | ||
84 | + * This program is distributed in the hope it will be useful, but WITHOUT | ||
85 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
86 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
87 | + * more details. | ||
88 | + * | ||
89 | + * You should have received a copy of the GNU General Public License along with | ||
90 | + * this program. If not, see <http://www.gnu.org/licenses/>. | ||
91 | + */ | ||
92 | + | ||
93 | +#ifndef RISCV_TIME_HELPER_H | ||
94 | +#define RISCV_TIME_HELPER_H | ||
95 | + | ||
96 | +#include "cpu.h" | ||
97 | +#include "qemu/timer.h" | ||
98 | + | ||
99 | +void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer, | ||
100 | + uint64_t timecmp, uint64_t delta, | ||
101 | + uint32_t timer_irq); | ||
102 | +void riscv_timer_init(RISCVCPU *cpu); | ||
103 | + | ||
104 | +#endif | ||
105 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
106 | index XXXXXXX..XXXXXXX 100644 | ||
107 | --- a/target/riscv/cpu.c | ||
108 | +++ b/target/riscv/cpu.c | ||
109 | @@ -XXX,XX +XXX,XX @@ | ||
110 | #include "qemu/log.h" | ||
111 | #include "cpu.h" | ||
112 | #include "internals.h" | ||
113 | +#include "time_helper.h" | ||
114 | #include "exec/exec-all.h" | ||
115 | #include "qapi/error.h" | ||
116 | #include "qemu/error-report.h" | ||
117 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
118 | ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
119 | ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia), | ||
120 | ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia), | ||
121 | + ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc), | ||
122 | ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval), | ||
123 | ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), | ||
124 | ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt), | ||
125 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
126 | |||
127 | set_resetvec(env, cpu->cfg.resetvec); | ||
128 | |||
129 | +#ifndef CONFIG_USER_ONLY | ||
130 | + if (cpu->cfg.ext_sstc) { | ||
131 | + riscv_timer_init(cpu); | ||
132 | + } | ||
133 | +#endif /* CONFIG_USER_ONLY */ | ||
134 | + | ||
135 | /* Validate that MISA_MXL is set properly. */ | ||
136 | switch (env->misa_mxl_max) { | ||
137 | #ifdef TARGET_RISCV64 | ||
138 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
139 | DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false), | ||
140 | DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), | ||
141 | DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), | ||
142 | + DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true), | ||
143 | |||
144 | DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), | ||
145 | DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), | ||
146 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
147 | index XXXXXXX..XXXXXXX 100644 | ||
148 | --- a/target/riscv/csr.c | ||
149 | +++ b/target/riscv/csr.c | ||
150 | @@ -XXX,XX +XXX,XX @@ | ||
151 | #include "qemu/timer.h" | ||
152 | #include "cpu.h" | ||
153 | #include "pmu.h" | ||
154 | +#include "time_helper.h" | ||
155 | #include "qemu/main-loop.h" | ||
156 | #include "exec/exec-all.h" | ||
157 | #include "sysemu/cpu-timers.h" | ||
158 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_timeh(CPURISCVState *env, int csrno, | ||
159 | return RISCV_EXCP_NONE; | ||
160 | } | ||
161 | |||
162 | +static RISCVException sstc(CPURISCVState *env, int csrno) | ||
163 | +{ | ||
164 | + CPUState *cs = env_cpu(env); | ||
165 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
166 | + | ||
167 | + if (!cpu->cfg.ext_sstc || !env->rdtime_fn) { | ||
168 | + return RISCV_EXCP_ILLEGAL_INST; | ||
169 | + } | ||
170 | + | ||
171 | + if (env->priv == PRV_M) { | ||
172 | + return RISCV_EXCP_NONE; | ||
173 | + } | ||
174 | + | ||
175 | + /* | ||
176 | + * No need of separate function for rv32 as menvcfg stores both menvcfg | ||
177 | + * menvcfgh for RV32. | ||
178 | + */ | ||
179 | + if (!(get_field(env->mcounteren, COUNTEREN_TM) && | ||
180 | + get_field(env->menvcfg, MENVCFG_STCE))) { | ||
181 | + return RISCV_EXCP_ILLEGAL_INST; | ||
182 | + } | ||
183 | + | ||
184 | + return smode(env, csrno); | ||
185 | +} | ||
186 | + | ||
187 | +static RISCVException sstc_32(CPURISCVState *env, int csrno) | ||
188 | +{ | ||
189 | + if (riscv_cpu_mxl(env) != MXL_RV32) { | ||
190 | + return RISCV_EXCP_ILLEGAL_INST; | ||
191 | + } | ||
192 | + | ||
193 | + return sstc(env, csrno); | ||
194 | +} | ||
195 | + | ||
196 | +static RISCVException read_stimecmp(CPURISCVState *env, int csrno, | ||
197 | + target_ulong *val) | ||
198 | +{ | ||
199 | + *val = env->stimecmp; | ||
200 | + return RISCV_EXCP_NONE; | ||
201 | +} | ||
202 | + | ||
203 | +static RISCVException read_stimecmph(CPURISCVState *env, int csrno, | ||
204 | + target_ulong *val) | ||
205 | +{ | ||
206 | + *val = env->stimecmp >> 32; | ||
207 | + return RISCV_EXCP_NONE; | ||
208 | +} | ||
209 | + | ||
210 | +static RISCVException write_stimecmp(CPURISCVState *env, int csrno, | ||
211 | + target_ulong val) | ||
212 | +{ | ||
213 | + RISCVCPU *cpu = env_archcpu(env); | ||
214 | + | ||
215 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
216 | + env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val); | ||
217 | + } else { | ||
218 | + env->stimecmp = val; | ||
219 | + } | ||
220 | + | ||
221 | + riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP); | ||
222 | + | ||
223 | + return RISCV_EXCP_NONE; | ||
224 | +} | ||
225 | + | ||
226 | +static RISCVException write_stimecmph(CPURISCVState *env, int csrno, | ||
227 | + target_ulong val) | ||
228 | +{ | ||
229 | + RISCVCPU *cpu = env_archcpu(env); | ||
230 | + | ||
231 | + env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val); | ||
232 | + riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP); | ||
233 | + | ||
234 | + return RISCV_EXCP_NONE; | ||
235 | +} | ||
236 | + | ||
237 | /* Machine constants */ | ||
238 | |||
239 | #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP)) | ||
240 | @@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno, | ||
241 | new_val |= env->external_seip * MIP_SEIP; | ||
242 | } | ||
243 | |||
244 | + if (cpu->cfg.ext_sstc && (env->priv == PRV_M) && | ||
245 | + get_field(env->menvcfg, MENVCFG_STCE)) { | ||
246 | + /* sstc extension forbids STIP & VSTIP to be writeable in mip */ | ||
247 | + mask = mask & ~(MIP_STIP | MIP_VSTIP); | ||
248 | + } | ||
249 | + | ||
250 | if (mask) { | ||
251 | old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask)); | ||
252 | } else { | ||
253 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
254 | [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause }, | ||
255 | [CSR_STVAL] = { "stval", smode, read_stval, write_stval }, | ||
256 | [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip }, | ||
257 | + [CSR_STIMECMP] = { "stimecmp", sstc, read_stimecmp, write_stimecmp, | ||
258 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
259 | + [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph, | ||
260 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
261 | |||
262 | /* Supervisor Protection and Translation */ | ||
263 | [CSR_SATP] = { "satp", smode, read_satp, write_satp }, | ||
264 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | ||
265 | index XXXXXXX..XXXXXXX 100644 | ||
266 | --- a/target/riscv/machine.c | ||
267 | +++ b/target/riscv/machine.c | ||
268 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = { | ||
269 | VMSTATE_UINTTL(env.mscratch, RISCVCPU), | ||
270 | VMSTATE_UINT64(env.mfromhost, RISCVCPU), | ||
271 | VMSTATE_UINT64(env.mtohost, RISCVCPU), | ||
272 | + VMSTATE_UINT64(env.stimecmp, RISCVCPU), | ||
273 | |||
274 | VMSTATE_END_OF_LIST() | ||
275 | }, | ||
276 | diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c | ||
277 | new file mode 100644 | ||
278 | index XXXXXXX..XXXXXXX | ||
279 | --- /dev/null | ||
280 | +++ b/target/riscv/time_helper.c | ||
281 | @@ -XXX,XX +XXX,XX @@ | ||
282 | +/* | ||
283 | + * RISC-V timer helper implementation. | ||
284 | + * | ||
285 | + * Copyright (c) 2022 Rivos Inc. | ||
286 | + * | ||
287 | + * This program is free software; you can redistribute it and/or modify it | ||
288 | + * under the terms and conditions of the GNU General Public License, | ||
289 | + * version 2 or later, as published by the Free Software Foundation. | ||
290 | + * | ||
291 | + * This program is distributed in the hope it will be useful, but WITHOUT | ||
292 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
293 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
294 | + * more details. | ||
295 | + * | ||
296 | + * You should have received a copy of the GNU General Public License along with | ||
297 | + * this program. If not, see <http://www.gnu.org/licenses/>. | ||
298 | + */ | ||
299 | + | ||
300 | +#include "qemu/osdep.h" | ||
301 | +#include "qemu/log.h" | ||
302 | +#include "cpu_bits.h" | ||
303 | +#include "time_helper.h" | ||
304 | +#include "hw/intc/riscv_aclint.h" | ||
305 | + | ||
306 | +static void riscv_stimer_cb(void *opaque) | ||
307 | +{ | ||
308 | + RISCVCPU *cpu = opaque; | ||
309 | + riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1)); | ||
310 | +} | ||
311 | + | ||
312 | +/* | ||
313 | + * Called when timecmp is written to update the QEMU timer or immediately | ||
314 | + * trigger timer interrupt if mtimecmp <= current timer value. | ||
315 | + */ | ||
316 | +void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer, | ||
317 | + uint64_t timecmp, uint64_t delta, | ||
318 | + uint32_t timer_irq) | ||
319 | +{ | ||
320 | + uint64_t diff, ns_diff, next; | ||
321 | + CPURISCVState *env = &cpu->env; | ||
322 | + RISCVAclintMTimerState *mtimer = env->rdtime_fn_arg; | ||
323 | + uint32_t timebase_freq = mtimer->timebase_freq; | ||
324 | + uint64_t rtc_r = env->rdtime_fn(env->rdtime_fn_arg) + delta; | ||
325 | + | ||
326 | + if (timecmp <= rtc_r) { | ||
327 | + /* | ||
328 | + * If we're setting an stimecmp value in the "past", | ||
329 | + * immediately raise the timer interrupt | ||
330 | + */ | ||
331 | + riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1)); | ||
332 | + return; | ||
333 | + } | ||
334 | + | ||
335 | + /* Clear the [V]STIP bit in mip */ | ||
336 | + riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0)); | ||
337 | + | ||
338 | + /* otherwise, set up the future timer interrupt */ | ||
339 | + diff = timecmp - rtc_r; | ||
340 | + /* back to ns (note args switched in muldiv64) */ | ||
341 | + ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); | ||
342 | + | ||
343 | + /* | ||
344 | + * check if ns_diff overflowed and check if the addition would potentially | ||
345 | + * overflow | ||
346 | + */ | ||
347 | + if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) || | ||
348 | + ns_diff > INT64_MAX) { | ||
349 | + next = INT64_MAX; | ||
350 | + } else { | ||
351 | + /* | ||
352 | + * as it is very unlikely qemu_clock_get_ns will return a value | ||
353 | + * greater than INT64_MAX, no additional check is needed for an | ||
354 | + * unsigned integer overflow. | ||
355 | + */ | ||
356 | + next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff; | ||
357 | + /* | ||
358 | + * if ns_diff is INT64_MAX next may still be outside the range | ||
359 | + * of a signed integer. | ||
360 | + */ | ||
361 | + next = MIN(next, INT64_MAX); | ||
362 | + } | ||
363 | + | ||
364 | + timer_mod(timer, next); | ||
365 | +} | ||
366 | + | ||
367 | +void riscv_timer_init(RISCVCPU *cpu) | ||
368 | +{ | ||
369 | + CPURISCVState *env; | ||
370 | + | ||
371 | + if (!cpu) { | ||
372 | + return; | ||
373 | + } | ||
374 | + | ||
375 | + env = &cpu->env; | ||
376 | + env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu); | ||
377 | + env->stimecmp = 0; | ||
378 | + | ||
379 | +} | ||
380 | diff --git a/target/riscv/meson.build b/target/riscv/meson.build | ||
381 | index XXXXXXX..XXXXXXX 100644 | ||
382 | --- a/target/riscv/meson.build | ||
383 | +++ b/target/riscv/meson.build | ||
384 | @@ -XXX,XX +XXX,XX @@ riscv_softmmu_ss.add(files( | ||
385 | 'debug.c', | ||
386 | 'monitor.c', | ||
387 | 'machine.c', | ||
388 | - 'pmu.c' | ||
389 | + 'pmu.c', | ||
390 | + 'time_helper.c' | ||
391 | )) | ||
392 | |||
393 | target_arch += {'riscv': riscv_ss} | ||
394 | -- | ||
395 | 2.37.2 | diff view generated by jsdifflib |
1 | From: Thomas Huth <thuth@redhat.com> | 1 | From: Atish Patra <atishp@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | Configuring a drive with "if=none" is meant for creation of a backend | 3 | vstimecmp CSR allows the guest OS or to program the next guest timer |
4 | only, it should not get automatically assigned to a device frontend. | 4 | interrupt directly. Thus, hypervisor no longer need to inject the |
5 | Use "if=pflash" for the One-Time-Programmable device instead (like | 5 | timer interrupt to the guest if vstimecmp is used. This was ratified |
6 | it is e.g. also done for the efuse device in hw/arm/xlnx-zcu102.c). | 6 | as a part of the Sstc extension. |
7 | 7 | ||
8 | Since the old way of configuring the device has already been published | ||
9 | with the previous QEMU versions, we cannot remove this immediately, but | ||
10 | have to deprecate it and support it for at least two more releases. | ||
11 | |||
12 | Signed-off-by: Thomas Huth <thuth@redhat.com> | ||
13 | Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
14 | Reviewed-by: Markus Armbruster <armbru@redhat.com> | ||
15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
16 | Message-id: 20211119102549.217755-1-thuth@redhat.com | 9 | Signed-off-by: Atish Patra <atishp@rivosinc.com> |
10 | Message-Id: <20220824221357.41070-4-atishp@rivosinc.com> | ||
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
18 | --- | 12 | --- |
19 | docs/about/deprecated.rst | 6 ++++++ | 13 | target/riscv/cpu.h | 4 ++ |
20 | hw/misc/sifive_u_otp.c | 9 ++++++++- | 14 | target/riscv/cpu_bits.h | 4 ++ |
21 | 2 files changed, 14 insertions(+), 1 deletion(-) | 15 | target/riscv/cpu_helper.c | 11 +++-- |
16 | target/riscv/csr.c | 88 ++++++++++++++++++++++++++++++++++++-- | ||
17 | target/riscv/machine.c | 1 + | ||
18 | target/riscv/time_helper.c | 16 +++++++ | ||
19 | 6 files changed, 118 insertions(+), 6 deletions(-) | ||
22 | 20 | ||
23 | diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst | 21 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
24 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/docs/about/deprecated.rst | 23 | --- a/target/riscv/cpu.h |
26 | +++ b/docs/about/deprecated.rst | 24 | +++ b/target/riscv/cpu.h |
27 | @@ -XXX,XX +XXX,XX @@ as short-form boolean values, and passed to plugins as ``arg_name=on``. | 25 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { |
28 | However, short-form booleans are deprecated and full explicit ``arg_name=on`` | 26 | /* Sstc CSRs */ |
29 | form is preferred. | 27 | uint64_t stimecmp; |
30 | 28 | ||
31 | +``-drive if=none`` for the sifive_u OTP device (since 6.2) | 29 | + uint64_t vstimecmp; |
32 | +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' | 30 | + |
33 | + | 31 | /* physical memory protection */ |
34 | +Using ``-drive if=none`` to configure the OTP device of the sifive_u | 32 | pmp_table_t pmp_state; |
35 | +RISC-V machine is deprecated. Use ``-drive if=pflash`` instead. | 33 | target_ulong mseccfg; |
36 | + | 34 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { |
37 | 35 | ||
38 | QEMU Machine Protocol (QMP) commands | 36 | /* Fields from here on are preserved across CPU reset. */ |
39 | ------------------------------------ | 37 | QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ |
40 | diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c | 38 | + QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */ |
41 | index XXXXXXX..XXXXXXX 100644 | 39 | + bool vstime_irq; |
42 | --- a/hw/misc/sifive_u_otp.c | 40 | |
43 | +++ b/hw/misc/sifive_u_otp.c | 41 | hwaddr kernel_addr; |
44 | @@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) | 42 | hwaddr fdt_addr; |
45 | TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE); | 43 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h |
46 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); | 44 | index XXXXXXX..XXXXXXX 100644 |
47 | 45 | --- a/target/riscv/cpu_bits.h | |
48 | - dinfo = drive_get_next(IF_NONE); | 46 | +++ b/target/riscv/cpu_bits.h |
49 | + dinfo = drive_get_next(IF_PFLASH); | 47 | @@ -XXX,XX +XXX,XX @@ |
50 | + if (!dinfo) { | 48 | #define CSR_VSIP 0x244 |
51 | + dinfo = drive_get_next(IF_NONE); | 49 | #define CSR_VSATP 0x280 |
52 | + if (dinfo) { | 50 | |
53 | + warn_report("using \"-drive if=none\" for the OTP is deprecated, " | 51 | +/* Sstc virtual CSRs */ |
54 | + "use \"-drive if=pflash\" instead."); | 52 | +#define CSR_VSTIMECMP 0x24D |
53 | +#define CSR_VSTIMECMPH 0x25D | ||
54 | + | ||
55 | #define CSR_MTINST 0x34a | ||
56 | #define CSR_MTVAL2 0x34b | ||
57 | |||
58 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
59 | index XXXXXXX..XXXXXXX 100644 | ||
60 | --- a/target/riscv/cpu_helper.c | ||
61 | +++ b/target/riscv/cpu_helper.c | ||
62 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env) | ||
63 | { | ||
64 | uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN); | ||
65 | uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; | ||
66 | + uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0; | ||
67 | |||
68 | - return (env->mip | vsgein) & env->mie; | ||
69 | + return (env->mip | vsgein | vstip) & env->mie; | ||
70 | } | ||
71 | |||
72 | int riscv_cpu_mirq_pending(CPURISCVState *env) | ||
73 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) | ||
74 | { | ||
75 | CPURISCVState *env = &cpu->env; | ||
76 | CPUState *cs = CPU(cpu); | ||
77 | - uint64_t gein, vsgein = 0, old = env->mip; | ||
78 | + uint64_t gein, vsgein = 0, vstip = 0, old = env->mip; | ||
79 | bool locked = false; | ||
80 | |||
81 | if (riscv_cpu_virt_enabled(env)) { | ||
82 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) | ||
83 | vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; | ||
84 | } | ||
85 | |||
86 | + /* No need to update mip for VSTIP */ | ||
87 | + mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask; | ||
88 | + vstip = env->vstime_irq ? MIP_VSTIP : 0; | ||
89 | + | ||
90 | if (!qemu_mutex_iothread_locked()) { | ||
91 | locked = true; | ||
92 | qemu_mutex_lock_iothread(); | ||
93 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) | ||
94 | |||
95 | env->mip = (env->mip & ~mask) | (value & mask); | ||
96 | |||
97 | - if (env->mip | vsgein) { | ||
98 | + if (env->mip | vsgein | vstip) { | ||
99 | cpu_interrupt(cs, CPU_INTERRUPT_HARD); | ||
100 | } else { | ||
101 | cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); | ||
102 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
103 | index XXXXXXX..XXXXXXX 100644 | ||
104 | --- a/target/riscv/csr.c | ||
105 | +++ b/target/riscv/csr.c | ||
106 | @@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno) | ||
107 | { | ||
108 | CPUState *cs = env_cpu(env); | ||
109 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
110 | + bool hmode_check = false; | ||
111 | |||
112 | if (!cpu->cfg.ext_sstc || !env->rdtime_fn) { | ||
113 | return RISCV_EXCP_ILLEGAL_INST; | ||
114 | @@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno) | ||
115 | return RISCV_EXCP_ILLEGAL_INST; | ||
116 | } | ||
117 | |||
118 | - return smode(env, csrno); | ||
119 | + if (riscv_cpu_virt_enabled(env)) { | ||
120 | + if (!(get_field(env->hcounteren, COUNTEREN_TM) & | ||
121 | + get_field(env->henvcfg, HENVCFG_STCE))) { | ||
122 | + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
55 | + } | 123 | + } |
56 | + } | 124 | + } |
57 | if (dinfo) { | 125 | + |
58 | int ret; | 126 | + if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) { |
59 | uint64_t perm; | 127 | + hmode_check = true; |
128 | + } | ||
129 | + | ||
130 | + return hmode_check ? hmode(env, csrno) : smode(env, csrno); | ||
131 | } | ||
132 | |||
133 | static RISCVException sstc_32(CPURISCVState *env, int csrno) | ||
134 | @@ -XXX,XX +XXX,XX @@ static RISCVException sstc_32(CPURISCVState *env, int csrno) | ||
135 | return sstc(env, csrno); | ||
136 | } | ||
137 | |||
138 | +static RISCVException read_vstimecmp(CPURISCVState *env, int csrno, | ||
139 | + target_ulong *val) | ||
140 | +{ | ||
141 | + *val = env->vstimecmp; | ||
142 | + | ||
143 | + return RISCV_EXCP_NONE; | ||
144 | +} | ||
145 | + | ||
146 | +static RISCVException read_vstimecmph(CPURISCVState *env, int csrno, | ||
147 | + target_ulong *val) | ||
148 | +{ | ||
149 | + *val = env->vstimecmp >> 32; | ||
150 | + | ||
151 | + return RISCV_EXCP_NONE; | ||
152 | +} | ||
153 | + | ||
154 | +static RISCVException write_vstimecmp(CPURISCVState *env, int csrno, | ||
155 | + target_ulong val) | ||
156 | +{ | ||
157 | + RISCVCPU *cpu = env_archcpu(env); | ||
158 | + | ||
159 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
160 | + env->vstimecmp = deposit64(env->vstimecmp, 0, 32, (uint64_t)val); | ||
161 | + } else { | ||
162 | + env->vstimecmp = val; | ||
163 | + } | ||
164 | + | ||
165 | + riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp, | ||
166 | + env->htimedelta, MIP_VSTIP); | ||
167 | + | ||
168 | + return RISCV_EXCP_NONE; | ||
169 | +} | ||
170 | + | ||
171 | +static RISCVException write_vstimecmph(CPURISCVState *env, int csrno, | ||
172 | + target_ulong val) | ||
173 | +{ | ||
174 | + RISCVCPU *cpu = env_archcpu(env); | ||
175 | + | ||
176 | + env->vstimecmp = deposit64(env->vstimecmp, 32, 32, (uint64_t)val); | ||
177 | + riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp, | ||
178 | + env->htimedelta, MIP_VSTIP); | ||
179 | + | ||
180 | + return RISCV_EXCP_NONE; | ||
181 | +} | ||
182 | + | ||
183 | static RISCVException read_stimecmp(CPURISCVState *env, int csrno, | ||
184 | target_ulong *val) | ||
185 | { | ||
186 | - *val = env->stimecmp; | ||
187 | + if (riscv_cpu_virt_enabled(env)) { | ||
188 | + *val = env->vstimecmp; | ||
189 | + } else { | ||
190 | + *val = env->stimecmp; | ||
191 | + } | ||
192 | + | ||
193 | return RISCV_EXCP_NONE; | ||
194 | } | ||
195 | |||
196 | static RISCVException read_stimecmph(CPURISCVState *env, int csrno, | ||
197 | target_ulong *val) | ||
198 | { | ||
199 | - *val = env->stimecmp >> 32; | ||
200 | + if (riscv_cpu_virt_enabled(env)) { | ||
201 | + *val = env->vstimecmp >> 32; | ||
202 | + } else { | ||
203 | + *val = env->stimecmp >> 32; | ||
204 | + } | ||
205 | + | ||
206 | return RISCV_EXCP_NONE; | ||
207 | } | ||
208 | |||
209 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno, | ||
210 | { | ||
211 | RISCVCPU *cpu = env_archcpu(env); | ||
212 | |||
213 | + if (riscv_cpu_virt_enabled(env)) { | ||
214 | + return write_vstimecmp(env, csrno, val); | ||
215 | + } | ||
216 | + | ||
217 | if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
218 | env->stimecmp = deposit64(env->stimecmp, 0, 32, (uint64_t)val); | ||
219 | } else { | ||
220 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno, | ||
221 | { | ||
222 | RISCVCPU *cpu = env_archcpu(env); | ||
223 | |||
224 | + if (riscv_cpu_virt_enabled(env)) { | ||
225 | + return write_vstimecmph(env, csrno, val); | ||
226 | + } | ||
227 | + | ||
228 | env->stimecmp = deposit64(env->stimecmp, 32, 32, (uint64_t)val); | ||
229 | riscv_timer_write_timecmp(cpu, env->stimer, env->stimecmp, 0, MIP_STIP); | ||
230 | |||
231 | @@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno, | ||
232 | if (csrno != CSR_HVIP) { | ||
233 | gin = get_field(env->hstatus, HSTATUS_VGEIN); | ||
234 | old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0; | ||
235 | + old_mip |= env->vstime_irq ? MIP_VSTIP : 0; | ||
236 | } | ||
237 | |||
238 | if (ret_val) { | ||
239 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
240 | .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
241 | [CSR_STIMECMPH] = { "stimecmph", sstc_32, read_stimecmph, write_stimecmph, | ||
242 | .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
243 | + [CSR_VSTIMECMP] = { "vstimecmp", sstc, read_vstimecmp, | ||
244 | + write_vstimecmp, | ||
245 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
246 | + [CSR_VSTIMECMPH] = { "vstimecmph", sstc_32, read_vstimecmph, | ||
247 | + write_vstimecmph, | ||
248 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
249 | |||
250 | /* Supervisor Protection and Translation */ | ||
251 | [CSR_SATP] = { "satp", smode, read_satp, write_satp }, | ||
252 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | ||
253 | index XXXXXXX..XXXXXXX 100644 | ||
254 | --- a/target/riscv/machine.c | ||
255 | +++ b/target/riscv/machine.c | ||
256 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_hyper = { | ||
257 | VMSTATE_UINTTL(env.hgeie, RISCVCPU), | ||
258 | VMSTATE_UINTTL(env.hgeip, RISCVCPU), | ||
259 | VMSTATE_UINT64(env.htimedelta, RISCVCPU), | ||
260 | + VMSTATE_UINT64(env.vstimecmp, RISCVCPU), | ||
261 | |||
262 | VMSTATE_UINTTL(env.hvictl, RISCVCPU), | ||
263 | VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64), | ||
264 | diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c | ||
265 | index XXXXXXX..XXXXXXX 100644 | ||
266 | --- a/target/riscv/time_helper.c | ||
267 | +++ b/target/riscv/time_helper.c | ||
268 | @@ -XXX,XX +XXX,XX @@ | ||
269 | #include "time_helper.h" | ||
270 | #include "hw/intc/riscv_aclint.h" | ||
271 | |||
272 | +static void riscv_vstimer_cb(void *opaque) | ||
273 | +{ | ||
274 | + RISCVCPU *cpu = opaque; | ||
275 | + CPURISCVState *env = &cpu->env; | ||
276 | + env->vstime_irq = 1; | ||
277 | + riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1)); | ||
278 | +} | ||
279 | + | ||
280 | static void riscv_stimer_cb(void *opaque) | ||
281 | { | ||
282 | RISCVCPU *cpu = opaque; | ||
283 | @@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer, | ||
284 | * If we're setting an stimecmp value in the "past", | ||
285 | * immediately raise the timer interrupt | ||
286 | */ | ||
287 | + if (timer_irq == MIP_VSTIP) { | ||
288 | + env->vstime_irq = 1; | ||
289 | + } | ||
290 | riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1)); | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | + if (timer_irq == MIP_VSTIP) { | ||
295 | + env->vstime_irq = 0; | ||
296 | + } | ||
297 | /* Clear the [V]STIP bit in mip */ | ||
298 | riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0)); | ||
299 | |||
300 | @@ -XXX,XX +XXX,XX @@ void riscv_timer_init(RISCVCPU *cpu) | ||
301 | env->stimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_stimer_cb, cpu); | ||
302 | env->stimecmp = 0; | ||
303 | |||
304 | + env->vstimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_vstimer_cb, cpu); | ||
305 | + env->vstimecmp = 0; | ||
306 | } | ||
60 | -- | 307 | -- |
61 | 2.31.1 | 308 | 2.37.2 |
62 | |||
63 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions, | ||
4 | and 'cofpmf' for Count OverFlow and Privilege Mode Filtering) | ||
5 | extension allows the perf to handle overflow interrupts and filtering | ||
6 | support. This patch provides a framework for programmable | ||
7 | counters to leverage the extension. As the extension doesn't have any | ||
8 | provision for the overflow bit for fixed counters, the fixed events | ||
9 | can also be monitoring using programmable counters. The underlying | ||
10 | counters for cycle and instruction counters are always running. Thus, | ||
11 | a separate timer device is programmed to handle the overflow. | ||
12 | |||
13 | Tested-by: Heiko Stuebner <heiko@sntech.de> | ||
14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | Signed-off-by: Atish Patra <atish.patra@wdc.com> | ||
16 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
17 | Message-Id: <20220824221701.41932-2-atishp@rivosinc.com> | ||
18 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
19 | --- | ||
20 | target/riscv/cpu.h | 25 +++ | ||
21 | target/riscv/cpu_bits.h | 55 ++++++ | ||
22 | target/riscv/pmu.h | 7 + | ||
23 | target/riscv/cpu.c | 12 ++ | ||
24 | target/riscv/csr.c | 166 +++++++++++++++++- | ||
25 | target/riscv/machine.c | 1 + | ||
26 | target/riscv/pmu.c | 368 +++++++++++++++++++++++++++++++++++++++- | ||
27 | 7 files changed, 623 insertions(+), 11 deletions(-) | ||
28 | |||
29 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/cpu.h | ||
32 | +++ b/target/riscv/cpu.h | ||
33 | @@ -XXX,XX +XXX,XX @@ typedef struct PMUCTRState { | ||
34 | /* Snapshort value of a counter in RV32 */ | ||
35 | target_ulong mhpmcounterh_prev; | ||
36 | bool started; | ||
37 | + /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger */ | ||
38 | + target_ulong irq_overflow_left; | ||
39 | } PMUCTRState; | ||
40 | |||
41 | struct CPUArchState { | ||
42 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { | ||
43 | /* PMU event selector configured values. First three are unused*/ | ||
44 | target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS]; | ||
45 | |||
46 | + /* PMU event selector configured values for RV32*/ | ||
47 | + target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS]; | ||
48 | + | ||
49 | target_ulong sscratch; | ||
50 | target_ulong mscratch; | ||
51 | |||
52 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
53 | bool ext_zmmul; | ||
54 | bool ext_smaia; | ||
55 | bool ext_ssaia; | ||
56 | + bool ext_sscofpmf; | ||
57 | bool rvv_ta_all_1s; | ||
58 | bool rvv_ma_all_1s; | ||
59 | |||
60 | @@ -XXX,XX +XXX,XX @@ struct ArchCPU { | ||
61 | |||
62 | /* Configuration Settings */ | ||
63 | RISCVCPUConfig cfg; | ||
64 | + | ||
65 | + QEMUTimer *pmu_timer; | ||
66 | + /* A bitmask of Available programmable counters */ | ||
67 | + uint32_t pmu_avail_ctrs; | ||
68 | + /* Mapping of events to counters */ | ||
69 | + GHashTable *pmu_event_ctr_map; | ||
70 | }; | ||
71 | |||
72 | static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext) | ||
73 | @@ -XXX,XX +XXX,XX @@ enum { | ||
74 | CSR_TABLE_SIZE = 0x1000 | ||
75 | }; | ||
76 | |||
77 | +/** | ||
78 | + * The event id are encoded based on the encoding specified in the | ||
79 | + * SBI specification v0.3 | ||
80 | + */ | ||
81 | + | ||
82 | +enum riscv_pmu_event_idx { | ||
83 | + RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01, | ||
84 | + RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02, | ||
85 | + RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019, | ||
86 | + RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B, | ||
87 | + RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021, | ||
88 | +}; | ||
89 | + | ||
90 | /* CSR function table */ | ||
91 | extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE]; | ||
92 | |||
93 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/target/riscv/cpu_bits.h | ||
96 | +++ b/target/riscv/cpu_bits.h | ||
97 | @@ -XXX,XX +XXX,XX @@ | ||
98 | #define CSR_MHPMEVENT29 0x33d | ||
99 | #define CSR_MHPMEVENT30 0x33e | ||
100 | #define CSR_MHPMEVENT31 0x33f | ||
101 | + | ||
102 | +#define CSR_MHPMEVENT3H 0x723 | ||
103 | +#define CSR_MHPMEVENT4H 0x724 | ||
104 | +#define CSR_MHPMEVENT5H 0x725 | ||
105 | +#define CSR_MHPMEVENT6H 0x726 | ||
106 | +#define CSR_MHPMEVENT7H 0x727 | ||
107 | +#define CSR_MHPMEVENT8H 0x728 | ||
108 | +#define CSR_MHPMEVENT9H 0x729 | ||
109 | +#define CSR_MHPMEVENT10H 0x72a | ||
110 | +#define CSR_MHPMEVENT11H 0x72b | ||
111 | +#define CSR_MHPMEVENT12H 0x72c | ||
112 | +#define CSR_MHPMEVENT13H 0x72d | ||
113 | +#define CSR_MHPMEVENT14H 0x72e | ||
114 | +#define CSR_MHPMEVENT15H 0x72f | ||
115 | +#define CSR_MHPMEVENT16H 0x730 | ||
116 | +#define CSR_MHPMEVENT17H 0x731 | ||
117 | +#define CSR_MHPMEVENT18H 0x732 | ||
118 | +#define CSR_MHPMEVENT19H 0x733 | ||
119 | +#define CSR_MHPMEVENT20H 0x734 | ||
120 | +#define CSR_MHPMEVENT21H 0x735 | ||
121 | +#define CSR_MHPMEVENT22H 0x736 | ||
122 | +#define CSR_MHPMEVENT23H 0x737 | ||
123 | +#define CSR_MHPMEVENT24H 0x738 | ||
124 | +#define CSR_MHPMEVENT25H 0x739 | ||
125 | +#define CSR_MHPMEVENT26H 0x73a | ||
126 | +#define CSR_MHPMEVENT27H 0x73b | ||
127 | +#define CSR_MHPMEVENT28H 0x73c | ||
128 | +#define CSR_MHPMEVENT29H 0x73d | ||
129 | +#define CSR_MHPMEVENT30H 0x73e | ||
130 | +#define CSR_MHPMEVENT31H 0x73f | ||
131 | + | ||
132 | #define CSR_MHPMCOUNTER3H 0xb83 | ||
133 | #define CSR_MHPMCOUNTER4H 0xb84 | ||
134 | #define CSR_MHPMCOUNTER5H 0xb85 | ||
135 | @@ -XXX,XX +XXX,XX @@ | ||
136 | #define CSR_VSMTE 0x2c0 | ||
137 | #define CSR_VSPMMASK 0x2c1 | ||
138 | #define CSR_VSPMBASE 0x2c2 | ||
139 | +#define CSR_SCOUNTOVF 0xda0 | ||
140 | |||
141 | /* Crypto Extension */ | ||
142 | #define CSR_SEED 0x015 | ||
143 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { | ||
144 | #define IRQ_VS_EXT 10 | ||
145 | #define IRQ_M_EXT 11 | ||
146 | #define IRQ_S_GEXT 12 | ||
147 | +#define IRQ_PMU_OVF 13 | ||
148 | #define IRQ_LOCAL_MAX 16 | ||
149 | #define IRQ_LOCAL_GUEST_MAX (TARGET_LONG_BITS - 1) | ||
150 | |||
151 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { | ||
152 | #define MIP_VSEIP (1 << IRQ_VS_EXT) | ||
153 | #define MIP_MEIP (1 << IRQ_M_EXT) | ||
154 | #define MIP_SGEIP (1 << IRQ_S_GEXT) | ||
155 | +#define MIP_LCOFIP (1 << IRQ_PMU_OVF) | ||
156 | |||
157 | /* sip masks */ | ||
158 | #define SIP_SSIP MIP_SSIP | ||
159 | #define SIP_STIP MIP_STIP | ||
160 | #define SIP_SEIP MIP_SEIP | ||
161 | +#define SIP_LCOFIP MIP_LCOFIP | ||
162 | |||
163 | /* MIE masks */ | ||
164 | #define MIE_SEIE (1 << IRQ_S_EXT) | ||
165 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { | ||
166 | #define SEED_OPST_WAIT (0b01 << 30) | ||
167 | #define SEED_OPST_ES16 (0b10 << 30) | ||
168 | #define SEED_OPST_DEAD (0b11 << 30) | ||
169 | +/* PMU related bits */ | ||
170 | +#define MIE_LCOFIE (1 << IRQ_PMU_OVF) | ||
171 | + | ||
172 | +#define MHPMEVENT_BIT_OF BIT_ULL(63) | ||
173 | +#define MHPMEVENTH_BIT_OF BIT(31) | ||
174 | +#define MHPMEVENT_BIT_MINH BIT_ULL(62) | ||
175 | +#define MHPMEVENTH_BIT_MINH BIT(30) | ||
176 | +#define MHPMEVENT_BIT_SINH BIT_ULL(61) | ||
177 | +#define MHPMEVENTH_BIT_SINH BIT(29) | ||
178 | +#define MHPMEVENT_BIT_UINH BIT_ULL(60) | ||
179 | +#define MHPMEVENTH_BIT_UINH BIT(28) | ||
180 | +#define MHPMEVENT_BIT_VSINH BIT_ULL(59) | ||
181 | +#define MHPMEVENTH_BIT_VSINH BIT(27) | ||
182 | +#define MHPMEVENT_BIT_VUINH BIT_ULL(58) | ||
183 | +#define MHPMEVENTH_BIT_VUINH BIT(26) | ||
184 | + | ||
185 | +#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000) | ||
186 | +#define MHPMEVENT_IDX_MASK 0xFFFFF | ||
187 | +#define MHPMEVENT_SSCOF_RESVD 16 | ||
188 | + | ||
189 | #endif | ||
190 | diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h | ||
191 | index XXXXXXX..XXXXXXX 100644 | ||
192 | --- a/target/riscv/pmu.h | ||
193 | +++ b/target/riscv/pmu.h | ||
194 | @@ -XXX,XX +XXX,XX @@ bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env, | ||
195 | uint32_t target_ctr); | ||
196 | bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, | ||
197 | uint32_t target_ctr); | ||
198 | +void riscv_pmu_timer_cb(void *priv); | ||
199 | +int riscv_pmu_init(RISCVCPU *cpu, int num_counters); | ||
200 | +int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value, | ||
201 | + uint32_t ctr_idx); | ||
202 | +int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx); | ||
203 | +int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, | ||
204 | + uint32_t ctr_idx); | ||
205 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
206 | index XXXXXXX..XXXXXXX 100644 | ||
207 | --- a/target/riscv/cpu.c | ||
208 | +++ b/target/riscv/cpu.c | ||
209 | @@ -XXX,XX +XXX,XX @@ | ||
210 | #include "qemu/ctype.h" | ||
211 | #include "qemu/log.h" | ||
212 | #include "cpu.h" | ||
213 | +#include "pmu.h" | ||
214 | #include "internals.h" | ||
215 | #include "time_helper.h" | ||
216 | #include "exec/exec-all.h" | ||
217 | @@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = { | ||
218 | ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0, ext_zhinxmin), | ||
219 | ISA_EXT_DATA_ENTRY(smaia, true, PRIV_VERSION_1_12_0, ext_smaia), | ||
220 | ISA_EXT_DATA_ENTRY(ssaia, true, PRIV_VERSION_1_12_0, ext_ssaia), | ||
221 | + ISA_EXT_DATA_ENTRY(sscofpmf, true, PRIV_VERSION_1_12_0, ext_sscofpmf), | ||
222 | ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc), | ||
223 | ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval), | ||
224 | ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), | ||
225 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
226 | set_misa(env, env->misa_mxl, ext); | ||
227 | } | ||
228 | |||
229 | +#ifndef CONFIG_USER_ONLY | ||
230 | + if (cpu->cfg.pmu_num) { | ||
231 | + if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) { | ||
232 | + cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
233 | + riscv_pmu_timer_cb, cpu); | ||
234 | + } | ||
235 | + } | ||
236 | +#endif | ||
237 | + | ||
238 | riscv_cpu_register_gdb_regs_for_features(cs); | ||
239 | |||
240 | qemu_init_vcpu(cs); | ||
241 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = { | ||
242 | DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false), | ||
243 | DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true), | ||
244 | DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), | ||
245 | + DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false), | ||
246 | DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), | ||
247 | DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), | ||
248 | DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true), | ||
249 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
250 | index XXXXXXX..XXXXXXX 100644 | ||
251 | --- a/target/riscv/csr.c | ||
252 | +++ b/target/riscv/csr.c | ||
253 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
254 | CPUState *cs = env_cpu(env); | ||
255 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
256 | int ctr_index; | ||
257 | - int base_csrno = CSR_HPMCOUNTER3; | ||
258 | + int base_csrno = CSR_CYCLE; | ||
259 | bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false; | ||
260 | |||
261 | if (rv32 && csrno >= CSR_CYCLEH) { | ||
262 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
263 | } | ||
264 | ctr_index = csrno - base_csrno; | ||
265 | |||
266 | - if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) { | ||
267 | + if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) || | ||
268 | + (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) { | ||
269 | + goto skip_ext_pmu_check; | ||
270 | + } | ||
271 | + | ||
272 | + if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) { | ||
273 | /* No counter is enabled in PMU or the counter is out of range */ | ||
274 | return RISCV_EXCP_ILLEGAL_INST; | ||
275 | } | ||
276 | |||
277 | +skip_ext_pmu_check: | ||
278 | + | ||
279 | if (env->priv == PRV_S) { | ||
280 | switch (csrno) { | ||
281 | case CSR_CYCLE: | ||
282 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
283 | } | ||
284 | break; | ||
285 | case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: | ||
286 | - ctr_index = csrno - CSR_CYCLE; | ||
287 | if (!get_field(env->mcounteren, 1 << ctr_index)) { | ||
288 | return RISCV_EXCP_ILLEGAL_INST; | ||
289 | } | ||
290 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
291 | } | ||
292 | break; | ||
293 | case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: | ||
294 | - ctr_index = csrno - CSR_CYCLEH; | ||
295 | if (!get_field(env->mcounteren, 1 << ctr_index)) { | ||
296 | return RISCV_EXCP_ILLEGAL_INST; | ||
297 | } | ||
298 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
299 | } | ||
300 | break; | ||
301 | case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: | ||
302 | - ctr_index = csrno - CSR_CYCLE; | ||
303 | if (!get_field(env->hcounteren, 1 << ctr_index) && | ||
304 | get_field(env->mcounteren, 1 << ctr_index)) { | ||
305 | return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
306 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
307 | } | ||
308 | break; | ||
309 | case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: | ||
310 | - ctr_index = csrno - CSR_CYCLEH; | ||
311 | if (!get_field(env->hcounteren, 1 << ctr_index) && | ||
312 | get_field(env->mcounteren, 1 << ctr_index)) { | ||
313 | return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
314 | @@ -XXX,XX +XXX,XX @@ static RISCVException mctr32(CPURISCVState *env, int csrno) | ||
315 | return mctr(env, csrno); | ||
316 | } | ||
317 | |||
318 | +static RISCVException sscofpmf(CPURISCVState *env, int csrno) | ||
319 | +{ | ||
320 | + CPUState *cs = env_cpu(env); | ||
321 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
322 | + | ||
323 | + if (!cpu->cfg.ext_sscofpmf) { | ||
324 | + return RISCV_EXCP_ILLEGAL_INST; | ||
325 | + } | ||
326 | + | ||
327 | + return RISCV_EXCP_NONE; | ||
328 | +} | ||
329 | + | ||
330 | static RISCVException any(CPURISCVState *env, int csrno) | ||
331 | { | ||
332 | return RISCV_EXCP_NONE; | ||
333 | @@ -XXX,XX +XXX,XX @@ static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val) | ||
334 | static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val) | ||
335 | { | ||
336 | int evt_index = csrno - CSR_MCOUNTINHIBIT; | ||
337 | + uint64_t mhpmevt_val = val; | ||
338 | |||
339 | env->mhpmevent_val[evt_index] = val; | ||
340 | |||
341 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
342 | + mhpmevt_val = mhpmevt_val | | ||
343 | + ((uint64_t)env->mhpmeventh_val[evt_index] << 32); | ||
344 | + } | ||
345 | + riscv_pmu_update_event_map(env, mhpmevt_val, evt_index); | ||
346 | + | ||
347 | + return RISCV_EXCP_NONE; | ||
348 | +} | ||
349 | + | ||
350 | +static int read_mhpmeventh(CPURISCVState *env, int csrno, target_ulong *val) | ||
351 | +{ | ||
352 | + int evt_index = csrno - CSR_MHPMEVENT3H + 3; | ||
353 | + | ||
354 | + *val = env->mhpmeventh_val[evt_index]; | ||
355 | + | ||
356 | + return RISCV_EXCP_NONE; | ||
357 | +} | ||
358 | + | ||
359 | +static int write_mhpmeventh(CPURISCVState *env, int csrno, target_ulong val) | ||
360 | +{ | ||
361 | + int evt_index = csrno - CSR_MHPMEVENT3H + 3; | ||
362 | + uint64_t mhpmevth_val = val; | ||
363 | + uint64_t mhpmevt_val = env->mhpmevent_val[evt_index]; | ||
364 | + | ||
365 | + mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32); | ||
366 | + env->mhpmeventh_val[evt_index] = val; | ||
367 | + | ||
368 | + riscv_pmu_update_event_map(env, mhpmevt_val, evt_index); | ||
369 | + | ||
370 | return RISCV_EXCP_NONE; | ||
371 | } | ||
372 | |||
373 | @@ -XXX,XX +XXX,XX @@ static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val) | ||
374 | { | ||
375 | int ctr_idx = csrno - CSR_MCYCLE; | ||
376 | PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; | ||
377 | + uint64_t mhpmctr_val = val; | ||
378 | |||
379 | counter->mhpmcounter_val = val; | ||
380 | if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || | ||
381 | riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) { | ||
382 | counter->mhpmcounter_prev = get_ticks(false); | ||
383 | - } else { | ||
384 | + if (ctr_idx > 2) { | ||
385 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
386 | + mhpmctr_val = mhpmctr_val | | ||
387 | + ((uint64_t)counter->mhpmcounterh_val << 32); | ||
388 | + } | ||
389 | + riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx); | ||
390 | + } | ||
391 | + } else { | ||
392 | /* Other counters can keep incrementing from the given value */ | ||
393 | counter->mhpmcounter_prev = val; | ||
394 | } | ||
395 | @@ -XXX,XX +XXX,XX @@ static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val) | ||
396 | { | ||
397 | int ctr_idx = csrno - CSR_MCYCLEH; | ||
398 | PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; | ||
399 | + uint64_t mhpmctr_val = counter->mhpmcounter_val; | ||
400 | + uint64_t mhpmctrh_val = val; | ||
401 | |||
402 | counter->mhpmcounterh_val = val; | ||
403 | + mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32); | ||
404 | if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || | ||
405 | riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) { | ||
406 | counter->mhpmcounterh_prev = get_ticks(true); | ||
407 | + if (ctr_idx > 2) { | ||
408 | + riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx); | ||
409 | + } | ||
410 | } else { | ||
411 | counter->mhpmcounterh_prev = val; | ||
412 | } | ||
413 | @@ -XXX,XX +XXX,XX @@ static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val) | ||
414 | return riscv_pmu_read_ctr(env, val, true, ctr_index); | ||
415 | } | ||
416 | |||
417 | +static int read_scountovf(CPURISCVState *env, int csrno, target_ulong *val) | ||
418 | +{ | ||
419 | + int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT; | ||
420 | + int i; | ||
421 | + *val = 0; | ||
422 | + target_ulong *mhpm_evt_val; | ||
423 | + uint64_t of_bit_mask; | ||
424 | + | ||
425 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
426 | + mhpm_evt_val = env->mhpmeventh_val; | ||
427 | + of_bit_mask = MHPMEVENTH_BIT_OF; | ||
428 | + } else { | ||
429 | + mhpm_evt_val = env->mhpmevent_val; | ||
430 | + of_bit_mask = MHPMEVENT_BIT_OF; | ||
431 | + } | ||
432 | + | ||
433 | + for (i = mhpmevt_start; i < RV_MAX_MHPMEVENTS; i++) { | ||
434 | + if ((get_field(env->mcounteren, BIT(i))) && | ||
435 | + (mhpm_evt_val[i] & of_bit_mask)) { | ||
436 | + *val |= BIT(i); | ||
437 | + } | ||
438 | + } | ||
439 | + | ||
440 | + return RISCV_EXCP_NONE; | ||
441 | +} | ||
442 | + | ||
443 | static RISCVException read_time(CPURISCVState *env, int csrno, | ||
444 | target_ulong *val) | ||
445 | { | ||
446 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno, | ||
447 | /* Machine constants */ | ||
448 | |||
449 | #define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP)) | ||
450 | -#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP)) | ||
451 | +#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \ | ||
452 | + MIP_LCOFIP)) | ||
453 | #define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) | ||
454 | #define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS)) | ||
455 | |||
456 | @@ -XXX,XX +XXX,XX @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS & | ||
457 | static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | | ||
458 | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | | ||
459 | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS; | ||
460 | -static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; | ||
461 | +static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP | | ||
462 | + SIP_LCOFIP; | ||
463 | static const target_ulong hip_writable_mask = MIP_VSSIP; | ||
464 | static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP; | ||
465 | static const target_ulong vsip_writable_mask = MIP_VSSIP; | ||
466 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
467 | [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent, | ||
468 | write_mhpmevent }, | ||
469 | |||
470 | + [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh, | ||
471 | + write_mhpmeventh }, | ||
472 | + [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh, | ||
473 | + write_mhpmeventh }, | ||
474 | + [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh, | ||
475 | + write_mhpmeventh }, | ||
476 | + [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh, | ||
477 | + write_mhpmeventh }, | ||
478 | + [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh, | ||
479 | + write_mhpmeventh }, | ||
480 | + [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh, | ||
481 | + write_mhpmeventh }, | ||
482 | + [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh, | ||
483 | + write_mhpmeventh }, | ||
484 | + [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh, | ||
485 | + write_mhpmeventh }, | ||
486 | + [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh, | ||
487 | + write_mhpmeventh }, | ||
488 | + [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh, | ||
489 | + write_mhpmeventh }, | ||
490 | + [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh, | ||
491 | + write_mhpmeventh }, | ||
492 | + [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh, | ||
493 | + write_mhpmeventh }, | ||
494 | + [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh, | ||
495 | + write_mhpmeventh }, | ||
496 | + [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh, | ||
497 | + write_mhpmeventh }, | ||
498 | + [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh, | ||
499 | + write_mhpmeventh }, | ||
500 | + [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh, | ||
501 | + write_mhpmeventh }, | ||
502 | + [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh, | ||
503 | + write_mhpmeventh }, | ||
504 | + [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh, | ||
505 | + write_mhpmeventh }, | ||
506 | + [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh, | ||
507 | + write_mhpmeventh }, | ||
508 | + [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh, | ||
509 | + write_mhpmeventh }, | ||
510 | + [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh, | ||
511 | + write_mhpmeventh }, | ||
512 | + [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh, | ||
513 | + write_mhpmeventh }, | ||
514 | + [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh, | ||
515 | + write_mhpmeventh }, | ||
516 | + [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh, | ||
517 | + write_mhpmeventh }, | ||
518 | + [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh, | ||
519 | + write_mhpmeventh }, | ||
520 | + [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh, | ||
521 | + write_mhpmeventh }, | ||
522 | + [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh, | ||
523 | + write_mhpmeventh }, | ||
524 | + [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh, | ||
525 | + write_mhpmeventh }, | ||
526 | + [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh, | ||
527 | + write_mhpmeventh }, | ||
528 | + | ||
529 | [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh }, | ||
530 | [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh }, | ||
531 | [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_hpmcounterh }, | ||
532 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
533 | write_mhpmcounterh }, | ||
534 | [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh, | ||
535 | write_mhpmcounterh }, | ||
536 | + [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf }, | ||
537 | + | ||
538 | #endif /* !CONFIG_USER_ONLY */ | ||
539 | }; | ||
540 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | ||
541 | index XXXXXXX..XXXXXXX 100644 | ||
542 | --- a/target/riscv/machine.c | ||
543 | +++ b/target/riscv/machine.c | ||
544 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = { | ||
545 | VMSTATE_STRUCT_ARRAY(env.pmu_ctrs, RISCVCPU, RV_MAX_MHPMCOUNTERS, 0, | ||
546 | vmstate_pmu_ctr_state, PMUCTRState), | ||
547 | VMSTATE_UINTTL_ARRAY(env.mhpmevent_val, RISCVCPU, RV_MAX_MHPMEVENTS), | ||
548 | + VMSTATE_UINTTL_ARRAY(env.mhpmeventh_val, RISCVCPU, RV_MAX_MHPMEVENTS), | ||
549 | VMSTATE_UINTTL(env.sscratch, RISCVCPU), | ||
550 | VMSTATE_UINTTL(env.mscratch, RISCVCPU), | ||
551 | VMSTATE_UINT64(env.mfromhost, RISCVCPU), | ||
552 | diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c | ||
553 | index XXXXXXX..XXXXXXX 100644 | ||
554 | --- a/target/riscv/pmu.c | ||
555 | +++ b/target/riscv/pmu.c | ||
556 | @@ -XXX,XX +XXX,XX @@ | ||
557 | #include "qemu/osdep.h" | ||
558 | #include "cpu.h" | ||
559 | #include "pmu.h" | ||
560 | +#include "sysemu/cpu-timers.h" | ||
561 | + | ||
562 | +#define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */ | ||
563 | +#define MAKE_32BIT_MASK(shift, length) \ | ||
564 | + (((uint32_t)(~0UL) >> (32 - (length))) << (shift)) | ||
565 | + | ||
566 | +static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx) | ||
567 | +{ | ||
568 | + if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS || | ||
569 | + !(cpu->pmu_avail_ctrs & BIT(ctr_idx))) { | ||
570 | + return false; | ||
571 | + } else { | ||
572 | + return true; | ||
573 | + } | ||
574 | +} | ||
575 | + | ||
576 | +static bool riscv_pmu_counter_enabled(RISCVCPU *cpu, uint32_t ctr_idx) | ||
577 | +{ | ||
578 | + CPURISCVState *env = &cpu->env; | ||
579 | + | ||
580 | + if (riscv_pmu_counter_valid(cpu, ctr_idx) && | ||
581 | + !get_field(env->mcountinhibit, BIT(ctr_idx))) { | ||
582 | + return true; | ||
583 | + } else { | ||
584 | + return false; | ||
585 | + } | ||
586 | +} | ||
587 | + | ||
588 | +static int riscv_pmu_incr_ctr_rv32(RISCVCPU *cpu, uint32_t ctr_idx) | ||
589 | +{ | ||
590 | + CPURISCVState *env = &cpu->env; | ||
591 | + target_ulong max_val = UINT32_MAX; | ||
592 | + PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; | ||
593 | + bool virt_on = riscv_cpu_virt_enabled(env); | ||
594 | + | ||
595 | + /* Privilege mode filtering */ | ||
596 | + if ((env->priv == PRV_M && | ||
597 | + (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_MINH)) || | ||
598 | + (env->priv == PRV_S && virt_on && | ||
599 | + (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VSINH)) || | ||
600 | + (env->priv == PRV_U && virt_on && | ||
601 | + (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_VUINH)) || | ||
602 | + (env->priv == PRV_S && !virt_on && | ||
603 | + (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_SINH)) || | ||
604 | + (env->priv == PRV_U && !virt_on && | ||
605 | + (env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_UINH))) { | ||
606 | + return 0; | ||
607 | + } | ||
608 | + | ||
609 | + /* Handle the overflow scenario */ | ||
610 | + if (counter->mhpmcounter_val == max_val) { | ||
611 | + if (counter->mhpmcounterh_val == max_val) { | ||
612 | + counter->mhpmcounter_val = 0; | ||
613 | + counter->mhpmcounterh_val = 0; | ||
614 | + /* Generate interrupt only if OF bit is clear */ | ||
615 | + if (!(env->mhpmeventh_val[ctr_idx] & MHPMEVENTH_BIT_OF)) { | ||
616 | + env->mhpmeventh_val[ctr_idx] |= MHPMEVENTH_BIT_OF; | ||
617 | + riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1)); | ||
618 | + } | ||
619 | + } else { | ||
620 | + counter->mhpmcounterh_val++; | ||
621 | + } | ||
622 | + } else { | ||
623 | + counter->mhpmcounter_val++; | ||
624 | + } | ||
625 | + | ||
626 | + return 0; | ||
627 | +} | ||
628 | + | ||
629 | +static int riscv_pmu_incr_ctr_rv64(RISCVCPU *cpu, uint32_t ctr_idx) | ||
630 | +{ | ||
631 | + CPURISCVState *env = &cpu->env; | ||
632 | + PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; | ||
633 | + uint64_t max_val = UINT64_MAX; | ||
634 | + bool virt_on = riscv_cpu_virt_enabled(env); | ||
635 | + | ||
636 | + /* Privilege mode filtering */ | ||
637 | + if ((env->priv == PRV_M && | ||
638 | + (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_MINH)) || | ||
639 | + (env->priv == PRV_S && virt_on && | ||
640 | + (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VSINH)) || | ||
641 | + (env->priv == PRV_U && virt_on && | ||
642 | + (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_VUINH)) || | ||
643 | + (env->priv == PRV_S && !virt_on && | ||
644 | + (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_SINH)) || | ||
645 | + (env->priv == PRV_U && !virt_on && | ||
646 | + (env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_UINH))) { | ||
647 | + return 0; | ||
648 | + } | ||
649 | + | ||
650 | + /* Handle the overflow scenario */ | ||
651 | + if (counter->mhpmcounter_val == max_val) { | ||
652 | + counter->mhpmcounter_val = 0; | ||
653 | + /* Generate interrupt only if OF bit is clear */ | ||
654 | + if (!(env->mhpmevent_val[ctr_idx] & MHPMEVENT_BIT_OF)) { | ||
655 | + env->mhpmevent_val[ctr_idx] |= MHPMEVENT_BIT_OF; | ||
656 | + riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1)); | ||
657 | + } | ||
658 | + } else { | ||
659 | + counter->mhpmcounter_val++; | ||
660 | + } | ||
661 | + return 0; | ||
662 | +} | ||
663 | + | ||
664 | +int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx) | ||
665 | +{ | ||
666 | + uint32_t ctr_idx; | ||
667 | + int ret; | ||
668 | + CPURISCVState *env = &cpu->env; | ||
669 | + gpointer value; | ||
670 | + | ||
671 | + if (!cpu->cfg.pmu_num) { | ||
672 | + return 0; | ||
673 | + } | ||
674 | + value = g_hash_table_lookup(cpu->pmu_event_ctr_map, | ||
675 | + GUINT_TO_POINTER(event_idx)); | ||
676 | + if (!value) { | ||
677 | + return -1; | ||
678 | + } | ||
679 | + | ||
680 | + ctr_idx = GPOINTER_TO_UINT(value); | ||
681 | + if (!riscv_pmu_counter_enabled(cpu, ctr_idx) || | ||
682 | + get_field(env->mcountinhibit, BIT(ctr_idx))) { | ||
683 | + return -1; | ||
684 | + } | ||
685 | + | ||
686 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
687 | + ret = riscv_pmu_incr_ctr_rv32(cpu, ctr_idx); | ||
688 | + } else { | ||
689 | + ret = riscv_pmu_incr_ctr_rv64(cpu, ctr_idx); | ||
690 | + } | ||
691 | + | ||
692 | + return ret; | ||
693 | +} | ||
694 | |||
695 | bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env, | ||
696 | uint32_t target_ctr) | ||
697 | { | ||
698 | - return (target_ctr == 0) ? true : false; | ||
699 | + RISCVCPU *cpu; | ||
700 | + uint32_t event_idx; | ||
701 | + uint32_t ctr_idx; | ||
702 | + | ||
703 | + /* Fixed instret counter */ | ||
704 | + if (target_ctr == 2) { | ||
705 | + return true; | ||
706 | + } | ||
707 | + | ||
708 | + cpu = RISCV_CPU(env_cpu(env)); | ||
709 | + if (!cpu->pmu_event_ctr_map) { | ||
710 | + return false; | ||
711 | + } | ||
712 | + | ||
713 | + event_idx = RISCV_PMU_EVENT_HW_INSTRUCTIONS; | ||
714 | + ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map, | ||
715 | + GUINT_TO_POINTER(event_idx))); | ||
716 | + if (!ctr_idx) { | ||
717 | + return false; | ||
718 | + } | ||
719 | + | ||
720 | + return target_ctr == ctr_idx ? true : false; | ||
721 | } | ||
722 | |||
723 | bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr) | ||
724 | { | ||
725 | - return (target_ctr == 2) ? true : false; | ||
726 | + RISCVCPU *cpu; | ||
727 | + uint32_t event_idx; | ||
728 | + uint32_t ctr_idx; | ||
729 | + | ||
730 | + /* Fixed mcycle counter */ | ||
731 | + if (target_ctr == 0) { | ||
732 | + return true; | ||
733 | + } | ||
734 | + | ||
735 | + cpu = RISCV_CPU(env_cpu(env)); | ||
736 | + if (!cpu->pmu_event_ctr_map) { | ||
737 | + return false; | ||
738 | + } | ||
739 | + | ||
740 | + event_idx = RISCV_PMU_EVENT_HW_CPU_CYCLES; | ||
741 | + ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map, | ||
742 | + GUINT_TO_POINTER(event_idx))); | ||
743 | + | ||
744 | + /* Counter zero is not used for event_ctr_map */ | ||
745 | + if (!ctr_idx) { | ||
746 | + return false; | ||
747 | + } | ||
748 | + | ||
749 | + return (target_ctr == ctr_idx) ? true : false; | ||
750 | +} | ||
751 | + | ||
752 | +static gboolean pmu_remove_event_map(gpointer key, gpointer value, | ||
753 | + gpointer udata) | ||
754 | +{ | ||
755 | + return (GPOINTER_TO_UINT(value) == GPOINTER_TO_UINT(udata)) ? true : false; | ||
756 | +} | ||
757 | + | ||
758 | +static int64_t pmu_icount_ticks_to_ns(int64_t value) | ||
759 | +{ | ||
760 | + int64_t ret = 0; | ||
761 | + | ||
762 | + if (icount_enabled()) { | ||
763 | + ret = icount_to_ns(value); | ||
764 | + } else { | ||
765 | + ret = (NANOSECONDS_PER_SECOND / RISCV_TIMEBASE_FREQ) * value; | ||
766 | + } | ||
767 | + | ||
768 | + return ret; | ||
769 | +} | ||
770 | + | ||
771 | +int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value, | ||
772 | + uint32_t ctr_idx) | ||
773 | +{ | ||
774 | + uint32_t event_idx; | ||
775 | + RISCVCPU *cpu = RISCV_CPU(env_cpu(env)); | ||
776 | + | ||
777 | + if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map) { | ||
778 | + return -1; | ||
779 | + } | ||
780 | + | ||
781 | + /* | ||
782 | + * Expected mhpmevent value is zero for reset case. Remove the current | ||
783 | + * mapping. | ||
784 | + */ | ||
785 | + if (!value) { | ||
786 | + g_hash_table_foreach_remove(cpu->pmu_event_ctr_map, | ||
787 | + pmu_remove_event_map, | ||
788 | + GUINT_TO_POINTER(ctr_idx)); | ||
789 | + return 0; | ||
790 | + } | ||
791 | + | ||
792 | + event_idx = value & MHPMEVENT_IDX_MASK; | ||
793 | + if (g_hash_table_lookup(cpu->pmu_event_ctr_map, | ||
794 | + GUINT_TO_POINTER(event_idx))) { | ||
795 | + return 0; | ||
796 | + } | ||
797 | + | ||
798 | + switch (event_idx) { | ||
799 | + case RISCV_PMU_EVENT_HW_CPU_CYCLES: | ||
800 | + case RISCV_PMU_EVENT_HW_INSTRUCTIONS: | ||
801 | + case RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS: | ||
802 | + case RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS: | ||
803 | + case RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS: | ||
804 | + break; | ||
805 | + default: | ||
806 | + /* We don't support any raw events right now */ | ||
807 | + return -1; | ||
808 | + } | ||
809 | + g_hash_table_insert(cpu->pmu_event_ctr_map, GUINT_TO_POINTER(event_idx), | ||
810 | + GUINT_TO_POINTER(ctr_idx)); | ||
811 | + | ||
812 | + return 0; | ||
813 | +} | ||
814 | + | ||
815 | +static void pmu_timer_trigger_irq(RISCVCPU *cpu, | ||
816 | + enum riscv_pmu_event_idx evt_idx) | ||
817 | +{ | ||
818 | + uint32_t ctr_idx; | ||
819 | + CPURISCVState *env = &cpu->env; | ||
820 | + PMUCTRState *counter; | ||
821 | + target_ulong *mhpmevent_val; | ||
822 | + uint64_t of_bit_mask; | ||
823 | + int64_t irq_trigger_at; | ||
824 | + | ||
825 | + if (evt_idx != RISCV_PMU_EVENT_HW_CPU_CYCLES && | ||
826 | + evt_idx != RISCV_PMU_EVENT_HW_INSTRUCTIONS) { | ||
827 | + return; | ||
828 | + } | ||
829 | + | ||
830 | + ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map, | ||
831 | + GUINT_TO_POINTER(evt_idx))); | ||
832 | + if (!riscv_pmu_counter_enabled(cpu, ctr_idx)) { | ||
833 | + return; | ||
834 | + } | ||
835 | + | ||
836 | + if (riscv_cpu_mxl(env) == MXL_RV32) { | ||
837 | + mhpmevent_val = &env->mhpmeventh_val[ctr_idx]; | ||
838 | + of_bit_mask = MHPMEVENTH_BIT_OF; | ||
839 | + } else { | ||
840 | + mhpmevent_val = &env->mhpmevent_val[ctr_idx]; | ||
841 | + of_bit_mask = MHPMEVENT_BIT_OF; | ||
842 | + } | ||
843 | + | ||
844 | + counter = &env->pmu_ctrs[ctr_idx]; | ||
845 | + if (counter->irq_overflow_left > 0) { | ||
846 | + irq_trigger_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + | ||
847 | + counter->irq_overflow_left; | ||
848 | + timer_mod_anticipate_ns(cpu->pmu_timer, irq_trigger_at); | ||
849 | + counter->irq_overflow_left = 0; | ||
850 | + return; | ||
851 | + } | ||
852 | + | ||
853 | + if (cpu->pmu_avail_ctrs & BIT(ctr_idx)) { | ||
854 | + /* Generate interrupt only if OF bit is clear */ | ||
855 | + if (!(*mhpmevent_val & of_bit_mask)) { | ||
856 | + *mhpmevent_val |= of_bit_mask; | ||
857 | + riscv_cpu_update_mip(cpu, MIP_LCOFIP, BOOL_TO_MASK(1)); | ||
858 | + } | ||
859 | + } | ||
860 | +} | ||
861 | + | ||
862 | +/* Timer callback for instret and cycle counter overflow */ | ||
863 | +void riscv_pmu_timer_cb(void *priv) | ||
864 | +{ | ||
865 | + RISCVCPU *cpu = priv; | ||
866 | + | ||
867 | + /* Timer event was triggered only for these events */ | ||
868 | + pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_CPU_CYCLES); | ||
869 | + pmu_timer_trigger_irq(cpu, RISCV_PMU_EVENT_HW_INSTRUCTIONS); | ||
870 | +} | ||
871 | + | ||
872 | +int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, uint32_t ctr_idx) | ||
873 | +{ | ||
874 | + uint64_t overflow_delta, overflow_at; | ||
875 | + int64_t overflow_ns, overflow_left = 0; | ||
876 | + RISCVCPU *cpu = RISCV_CPU(env_cpu(env)); | ||
877 | + PMUCTRState *counter = &env->pmu_ctrs[ctr_idx]; | ||
878 | + | ||
879 | + if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->cfg.ext_sscofpmf) { | ||
880 | + return -1; | ||
881 | + } | ||
882 | + | ||
883 | + if (value) { | ||
884 | + overflow_delta = UINT64_MAX - value + 1; | ||
885 | + } else { | ||
886 | + overflow_delta = UINT64_MAX; | ||
887 | + } | ||
888 | + | ||
889 | + /* | ||
890 | + * QEMU supports only int64_t timers while RISC-V counters are uint64_t. | ||
891 | + * Compute the leftover and save it so that it can be reprogrammed again | ||
892 | + * when timer expires. | ||
893 | + */ | ||
894 | + if (overflow_delta > INT64_MAX) { | ||
895 | + overflow_left = overflow_delta - INT64_MAX; | ||
896 | + } | ||
897 | + | ||
898 | + if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || | ||
899 | + riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) { | ||
900 | + overflow_ns = pmu_icount_ticks_to_ns((int64_t)overflow_delta); | ||
901 | + overflow_left = pmu_icount_ticks_to_ns(overflow_left) ; | ||
902 | + } else { | ||
903 | + return -1; | ||
904 | + } | ||
905 | + overflow_at = (uint64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + overflow_ns; | ||
906 | + | ||
907 | + if (overflow_at > INT64_MAX) { | ||
908 | + overflow_left += overflow_at - INT64_MAX; | ||
909 | + counter->irq_overflow_left = overflow_left; | ||
910 | + overflow_at = INT64_MAX; | ||
911 | + } | ||
912 | + timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at); | ||
913 | + | ||
914 | + return 0; | ||
915 | +} | ||
916 | + | ||
917 | + | ||
918 | +int riscv_pmu_init(RISCVCPU *cpu, int num_counters) | ||
919 | +{ | ||
920 | + if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) { | ||
921 | + return -1; | ||
922 | + } | ||
923 | + | ||
924 | + cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal); | ||
925 | + if (!cpu->pmu_event_ctr_map) { | ||
926 | + /* PMU support can not be enabled */ | ||
927 | + qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n"); | ||
928 | + cpu->cfg.pmu_num = 0; | ||
929 | + return -1; | ||
930 | + } | ||
931 | + | ||
932 | + /* Create a bitmask of available programmable counters */ | ||
933 | + cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters); | ||
934 | + | ||
935 | + return 0; | ||
936 | } | ||
937 | -- | ||
938 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | All the hpmcounters and the fixed counters (CY, IR, TM) can be represented | ||
4 | as a unified counter. Thus, the predicate function doesn't need handle each | ||
5 | case separately. | ||
6 | |||
7 | Simplify the predicate function so that we just handle things differently | ||
8 | between RV32/RV64 and S/HS mode. | ||
9 | |||
10 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
11 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
13 | Message-Id: <20220824221701.41932-3-atishp@rivosinc.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/csr.c | 110 ++++----------------------------------------- | ||
17 | 1 file changed, 9 insertions(+), 101 deletions(-) | ||
18 | |||
19 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/riscv/csr.c | ||
22 | +++ b/target/riscv/csr.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
24 | CPUState *cs = env_cpu(env); | ||
25 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
26 | int ctr_index; | ||
27 | + target_ulong ctr_mask; | ||
28 | int base_csrno = CSR_CYCLE; | ||
29 | bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false; | ||
30 | |||
31 | @@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||
32 | base_csrno += 0x80; | ||
33 | } | ||
34 | ctr_index = csrno - base_csrno; | ||
35 | + ctr_mask = BIT(ctr_index); | ||
36 | |||
37 | if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) || | ||
38 | (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) { | ||
39 | goto skip_ext_pmu_check; | ||
40 | } | ||
41 | |||
42 | - if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) { | ||
43 | + if (!(cpu->pmu_avail_ctrs & ctr_mask)) { | ||
44 | /* No counter is enabled in PMU or the counter is out of range */ | ||
45 | return RISCV_EXCP_ILLEGAL_INST; | ||
46 | } | ||
47 | |||
48 | skip_ext_pmu_check: | ||
49 | |||
50 | - if (env->priv == PRV_S) { | ||
51 | - switch (csrno) { | ||
52 | - case CSR_CYCLE: | ||
53 | - if (!get_field(env->mcounteren, COUNTEREN_CY)) { | ||
54 | - return RISCV_EXCP_ILLEGAL_INST; | ||
55 | - } | ||
56 | - break; | ||
57 | - case CSR_TIME: | ||
58 | - if (!get_field(env->mcounteren, COUNTEREN_TM)) { | ||
59 | - return RISCV_EXCP_ILLEGAL_INST; | ||
60 | - } | ||
61 | - break; | ||
62 | - case CSR_INSTRET: | ||
63 | - if (!get_field(env->mcounteren, COUNTEREN_IR)) { | ||
64 | - return RISCV_EXCP_ILLEGAL_INST; | ||
65 | - } | ||
66 | - break; | ||
67 | - case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: | ||
68 | - if (!get_field(env->mcounteren, 1 << ctr_index)) { | ||
69 | - return RISCV_EXCP_ILLEGAL_INST; | ||
70 | - } | ||
71 | - break; | ||
72 | - } | ||
73 | - if (rv32) { | ||
74 | - switch (csrno) { | ||
75 | - case CSR_CYCLEH: | ||
76 | - if (!get_field(env->mcounteren, COUNTEREN_CY)) { | ||
77 | - return RISCV_EXCP_ILLEGAL_INST; | ||
78 | - } | ||
79 | - break; | ||
80 | - case CSR_TIMEH: | ||
81 | - if (!get_field(env->mcounteren, COUNTEREN_TM)) { | ||
82 | - return RISCV_EXCP_ILLEGAL_INST; | ||
83 | - } | ||
84 | - break; | ||
85 | - case CSR_INSTRETH: | ||
86 | - if (!get_field(env->mcounteren, COUNTEREN_IR)) { | ||
87 | - return RISCV_EXCP_ILLEGAL_INST; | ||
88 | - } | ||
89 | - break; | ||
90 | - case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: | ||
91 | - if (!get_field(env->mcounteren, 1 << ctr_index)) { | ||
92 | - return RISCV_EXCP_ILLEGAL_INST; | ||
93 | - } | ||
94 | - break; | ||
95 | - } | ||
96 | - } | ||
97 | + if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) || | ||
98 | + ((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask)))) { | ||
99 | + return RISCV_EXCP_ILLEGAL_INST; | ||
100 | } | ||
101 | |||
102 | if (riscv_cpu_virt_enabled(env)) { | ||
103 | - switch (csrno) { | ||
104 | - case CSR_CYCLE: | ||
105 | - if (!get_field(env->hcounteren, COUNTEREN_CY) && | ||
106 | - get_field(env->mcounteren, COUNTEREN_CY)) { | ||
107 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
108 | - } | ||
109 | - break; | ||
110 | - case CSR_TIME: | ||
111 | - if (!get_field(env->hcounteren, COUNTEREN_TM) && | ||
112 | - get_field(env->mcounteren, COUNTEREN_TM)) { | ||
113 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
114 | - } | ||
115 | - break; | ||
116 | - case CSR_INSTRET: | ||
117 | - if (!get_field(env->hcounteren, COUNTEREN_IR) && | ||
118 | - get_field(env->mcounteren, COUNTEREN_IR)) { | ||
119 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
120 | - } | ||
121 | - break; | ||
122 | - case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: | ||
123 | - if (!get_field(env->hcounteren, 1 << ctr_index) && | ||
124 | - get_field(env->mcounteren, 1 << ctr_index)) { | ||
125 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
126 | - } | ||
127 | - break; | ||
128 | - } | ||
129 | - if (rv32) { | ||
130 | - switch (csrno) { | ||
131 | - case CSR_CYCLEH: | ||
132 | - if (!get_field(env->hcounteren, COUNTEREN_CY) && | ||
133 | - get_field(env->mcounteren, COUNTEREN_CY)) { | ||
134 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
135 | - } | ||
136 | - break; | ||
137 | - case CSR_TIMEH: | ||
138 | - if (!get_field(env->hcounteren, COUNTEREN_TM) && | ||
139 | - get_field(env->mcounteren, COUNTEREN_TM)) { | ||
140 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
141 | - } | ||
142 | - break; | ||
143 | - case CSR_INSTRETH: | ||
144 | - if (!get_field(env->hcounteren, COUNTEREN_IR) && | ||
145 | - get_field(env->mcounteren, COUNTEREN_IR)) { | ||
146 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
147 | - } | ||
148 | - break; | ||
149 | - case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: | ||
150 | - if (!get_field(env->hcounteren, 1 << ctr_index) && | ||
151 | - get_field(env->mcounteren, 1 << ctr_index)) { | ||
152 | - return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
153 | - } | ||
154 | - break; | ||
155 | - } | ||
156 | + if (!get_field(env->hcounteren, ctr_mask) && | ||
157 | + get_field(env->mcounteren, ctr_mask)) { | ||
158 | + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
159 | } | ||
160 | } | ||
161 | #endif | ||
162 | -- | ||
163 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atish.patra@wdc.com> | ||
1 | 2 | ||
3 | Qemu can monitor the following cache related PMU events through | ||
4 | tlb_fill functions. | ||
5 | |||
6 | 1. DTLB load/store miss | ||
7 | 3. ITLB prefetch miss | ||
8 | |||
9 | Increment the PMU counter in tlb_fill function. | ||
10 | |||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Tested-by: Heiko Stuebner <heiko@sntech.de> | ||
13 | Signed-off-by: Atish Patra <atish.patra@wdc.com> | ||
14 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
15 | Message-Id: <20220824221701.41932-4-atishp@rivosinc.com> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | --- | ||
18 | target/riscv/cpu_helper.c | 25 +++++++++++++++++++++++++ | ||
19 | 1 file changed, 25 insertions(+) | ||
20 | |||
21 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/cpu_helper.c | ||
24 | +++ b/target/riscv/cpu_helper.c | ||
25 | @@ -XXX,XX +XXX,XX @@ | ||
26 | #include "qemu/log.h" | ||
27 | #include "qemu/main-loop.h" | ||
28 | #include "cpu.h" | ||
29 | +#include "pmu.h" | ||
30 | #include "exec/exec-all.h" | ||
31 | #include "instmap.h" | ||
32 | #include "tcg/tcg-op.h" | ||
33 | #include "trace.h" | ||
34 | #include "semihosting/common-semi.h" | ||
35 | +#include "cpu_bits.h" | ||
36 | |||
37 | int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) | ||
38 | { | ||
39 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, | ||
40 | cpu_loop_exit_restore(cs, retaddr); | ||
41 | } | ||
42 | |||
43 | + | ||
44 | +static void pmu_tlb_fill_incr_ctr(RISCVCPU *cpu, MMUAccessType access_type) | ||
45 | +{ | ||
46 | + enum riscv_pmu_event_idx pmu_event_type; | ||
47 | + | ||
48 | + switch (access_type) { | ||
49 | + case MMU_INST_FETCH: | ||
50 | + pmu_event_type = RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS; | ||
51 | + break; | ||
52 | + case MMU_DATA_LOAD: | ||
53 | + pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS; | ||
54 | + break; | ||
55 | + case MMU_DATA_STORE: | ||
56 | + pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS; | ||
57 | + break; | ||
58 | + default: | ||
59 | + return; | ||
60 | + } | ||
61 | + | ||
62 | + riscv_pmu_incr_ctr(cpu, pmu_event_type); | ||
63 | +} | ||
64 | + | ||
65 | bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
66 | MMUAccessType access_type, int mmu_idx, | ||
67 | bool probe, uintptr_t retaddr) | ||
68 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
69 | } | ||
70 | } | ||
71 | } else { | ||
72 | + pmu_tlb_fill_incr_ctr(cpu, access_type); | ||
73 | /* Single stage lookup */ | ||
74 | ret = get_physical_address(env, &pa, &prot, address, NULL, | ||
75 | access_type, mmu_idx, true, false, false); | ||
76 | -- | ||
77 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | Qemu virt machine can support few cache events and cycle/instret counters. | ||
4 | It also supports counter overflow for these events. | ||
5 | |||
6 | Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine | ||
7 | capabilities. There are some dummy nodes added for testing as well. | ||
8 | |||
9 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Signed-off-by: Atish Patra <atish.patra@wdc.com> | ||
11 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
12 | Message-Id: <20220824221701.41932-5-atishp@rivosinc.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/pmu.h | 1 + | ||
16 | hw/riscv/virt.c | 16 +++++++++++++ | ||
17 | target/riscv/pmu.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
18 | 3 files changed, 74 insertions(+) | ||
19 | |||
20 | diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/target/riscv/pmu.h | ||
23 | +++ b/target/riscv/pmu.h | ||
24 | @@ -XXX,XX +XXX,XX @@ int riscv_pmu_init(RISCVCPU *cpu, int num_counters); | ||
25 | int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value, | ||
26 | uint32_t ctr_idx); | ||
27 | int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx); | ||
28 | +void riscv_pmu_generate_fdt_node(void *fdt, int num_counters, char *pmu_name); | ||
29 | int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value, | ||
30 | uint32_t ctr_idx); | ||
31 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/hw/riscv/virt.c | ||
34 | +++ b/hw/riscv/virt.c | ||
35 | @@ -XXX,XX +XXX,XX @@ | ||
36 | #include "hw/char/serial.h" | ||
37 | #include "target/riscv/cpu.h" | ||
38 | #include "hw/core/sysbus-fdt.h" | ||
39 | +#include "target/riscv/pmu.h" | ||
40 | #include "hw/riscv/riscv_hart.h" | ||
41 | #include "hw/riscv/virt.h" | ||
42 | #include "hw/riscv/boot.h" | ||
43 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s, | ||
44 | aplic_phandles[socket] = aplic_s_phandle; | ||
45 | } | ||
46 | |||
47 | +static void create_fdt_pmu(RISCVVirtState *s) | ||
48 | +{ | ||
49 | + char *pmu_name; | ||
50 | + MachineState *mc = MACHINE(s); | ||
51 | + RISCVCPU hart = s->soc[0].harts[0]; | ||
52 | + | ||
53 | + pmu_name = g_strdup_printf("/soc/pmu"); | ||
54 | + qemu_fdt_add_subnode(mc->fdt, pmu_name); | ||
55 | + qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu"); | ||
56 | + riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name); | ||
57 | + | ||
58 | + g_free(pmu_name); | ||
59 | +} | ||
60 | + | ||
61 | static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, | ||
62 | bool is_32_bit, uint32_t *phandle, | ||
63 | uint32_t *irq_mmio_phandle, | ||
64 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, | ||
65 | |||
66 | create_fdt_flash(s, memmap); | ||
67 | create_fdt_fw_cfg(s, memmap); | ||
68 | + create_fdt_pmu(s); | ||
69 | |||
70 | update_bootargs: | ||
71 | if (cmdline && *cmdline) { | ||
72 | diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c | ||
73 | index XXXXXXX..XXXXXXX 100644 | ||
74 | --- a/target/riscv/pmu.c | ||
75 | +++ b/target/riscv/pmu.c | ||
76 | @@ -XXX,XX +XXX,XX @@ | ||
77 | #include "cpu.h" | ||
78 | #include "pmu.h" | ||
79 | #include "sysemu/cpu-timers.h" | ||
80 | +#include "sysemu/device_tree.h" | ||
81 | |||
82 | #define RISCV_TIMEBASE_FREQ 1000000000 /* 1Ghz */ | ||
83 | #define MAKE_32BIT_MASK(shift, length) \ | ||
84 | (((uint32_t)(~0UL) >> (32 - (length))) << (shift)) | ||
85 | |||
86 | +/* | ||
87 | + * To keep it simple, any event can be mapped to any programmable counters in | ||
88 | + * QEMU. The generic cycle & instruction count events can also be monitored | ||
89 | + * using programmable counters. In that case, mcycle & minstret must continue | ||
90 | + * to provide the correct value as well. Heterogeneous PMU per hart is not | ||
91 | + * supported yet. Thus, number of counters are same across all harts. | ||
92 | + */ | ||
93 | +void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name) | ||
94 | +{ | ||
95 | + uint32_t fdt_event_ctr_map[20] = {}; | ||
96 | + uint32_t cmask; | ||
97 | + | ||
98 | + /* All the programmable counters can map to any event */ | ||
99 | + cmask = MAKE_32BIT_MASK(3, num_ctrs); | ||
100 | + | ||
101 | + /* | ||
102 | + * The event encoding is specified in the SBI specification | ||
103 | + * Event idx is a 20bits wide number encoded as follows: | ||
104 | + * event_idx[19:16] = type | ||
105 | + * event_idx[15:0] = code | ||
106 | + * The code field in cache events are encoded as follows: | ||
107 | + * event_idx.code[15:3] = cache_id | ||
108 | + * event_idx.code[2:1] = op_id | ||
109 | + * event_idx.code[0:0] = result_id | ||
110 | + */ | ||
111 | + | ||
112 | + /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */ | ||
113 | + fdt_event_ctr_map[0] = cpu_to_be32(0x00000001); | ||
114 | + fdt_event_ctr_map[1] = cpu_to_be32(0x00000001); | ||
115 | + fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0); | ||
116 | + | ||
117 | + /* SBI_PMU_HW_INSTRUCTIONS: 0x02 : type(0x00) */ | ||
118 | + fdt_event_ctr_map[3] = cpu_to_be32(0x00000002); | ||
119 | + fdt_event_ctr_map[4] = cpu_to_be32(0x00000002); | ||
120 | + fdt_event_ctr_map[5] = cpu_to_be32(cmask | 1 << 2); | ||
121 | + | ||
122 | + /* SBI_PMU_HW_CACHE_DTLB : 0x03 READ : 0x00 MISS : 0x00 type(0x01) */ | ||
123 | + fdt_event_ctr_map[6] = cpu_to_be32(0x00010019); | ||
124 | + fdt_event_ctr_map[7] = cpu_to_be32(0x00010019); | ||
125 | + fdt_event_ctr_map[8] = cpu_to_be32(cmask); | ||
126 | + | ||
127 | + /* SBI_PMU_HW_CACHE_DTLB : 0x03 WRITE : 0x01 MISS : 0x00 type(0x01) */ | ||
128 | + fdt_event_ctr_map[9] = cpu_to_be32(0x0001001B); | ||
129 | + fdt_event_ctr_map[10] = cpu_to_be32(0x0001001B); | ||
130 | + fdt_event_ctr_map[11] = cpu_to_be32(cmask); | ||
131 | + | ||
132 | + /* SBI_PMU_HW_CACHE_ITLB : 0x04 READ : 0x00 MISS : 0x00 type(0x01) */ | ||
133 | + fdt_event_ctr_map[12] = cpu_to_be32(0x00010021); | ||
134 | + fdt_event_ctr_map[13] = cpu_to_be32(0x00010021); | ||
135 | + fdt_event_ctr_map[14] = cpu_to_be32(cmask); | ||
136 | + | ||
137 | + /* This a OpenSBI specific DT property documented in OpenSBI docs */ | ||
138 | + qemu_fdt_setprop(fdt, pmu_name, "riscv,event-to-mhpmcounters", | ||
139 | + fdt_event_ctr_map, sizeof(fdt_event_ctr_map)); | ||
140 | +} | ||
141 | + | ||
142 | static bool riscv_pmu_counter_valid(RISCVCPU *cpu, uint32_t ctr_idx) | ||
143 | { | ||
144 | if (ctr_idx < 3 || ctr_idx >= RV_MAX_MHPMCOUNTERS || | ||
145 | -- | ||
146 | 2.37.2 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | The sscofpmf extension was ratified as a part of priv spec v1.12. | ||
4 | Mark the csr_ops accordingly. | ||
5 | |||
6 | Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
9 | Message-Id: <20220824221701.41932-6-atishp@rivosinc.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/csr.c | 90 ++++++++++++++++++++++++++++++---------------- | ||
13 | 1 file changed, 60 insertions(+), 30 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/csr.c | ||
18 | +++ b/target/riscv/csr.c | ||
19 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
20 | write_mhpmevent }, | ||
21 | |||
22 | [CSR_MHPMEVENT3H] = { "mhpmevent3h", sscofpmf, read_mhpmeventh, | ||
23 | - write_mhpmeventh }, | ||
24 | + write_mhpmeventh, | ||
25 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
26 | [CSR_MHPMEVENT4H] = { "mhpmevent4h", sscofpmf, read_mhpmeventh, | ||
27 | - write_mhpmeventh }, | ||
28 | + write_mhpmeventh, | ||
29 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
30 | [CSR_MHPMEVENT5H] = { "mhpmevent5h", sscofpmf, read_mhpmeventh, | ||
31 | - write_mhpmeventh }, | ||
32 | + write_mhpmeventh, | ||
33 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
34 | [CSR_MHPMEVENT6H] = { "mhpmevent6h", sscofpmf, read_mhpmeventh, | ||
35 | - write_mhpmeventh }, | ||
36 | + write_mhpmeventh, | ||
37 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
38 | [CSR_MHPMEVENT7H] = { "mhpmevent7h", sscofpmf, read_mhpmeventh, | ||
39 | - write_mhpmeventh }, | ||
40 | + write_mhpmeventh, | ||
41 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
42 | [CSR_MHPMEVENT8H] = { "mhpmevent8h", sscofpmf, read_mhpmeventh, | ||
43 | - write_mhpmeventh }, | ||
44 | + write_mhpmeventh, | ||
45 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
46 | [CSR_MHPMEVENT9H] = { "mhpmevent9h", sscofpmf, read_mhpmeventh, | ||
47 | - write_mhpmeventh }, | ||
48 | + write_mhpmeventh, | ||
49 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
50 | [CSR_MHPMEVENT10H] = { "mhpmevent10h", sscofpmf, read_mhpmeventh, | ||
51 | - write_mhpmeventh }, | ||
52 | + write_mhpmeventh, | ||
53 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
54 | [CSR_MHPMEVENT11H] = { "mhpmevent11h", sscofpmf, read_mhpmeventh, | ||
55 | - write_mhpmeventh }, | ||
56 | + write_mhpmeventh, | ||
57 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
58 | [CSR_MHPMEVENT12H] = { "mhpmevent12h", sscofpmf, read_mhpmeventh, | ||
59 | - write_mhpmeventh }, | ||
60 | + write_mhpmeventh, | ||
61 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
62 | [CSR_MHPMEVENT13H] = { "mhpmevent13h", sscofpmf, read_mhpmeventh, | ||
63 | - write_mhpmeventh }, | ||
64 | + write_mhpmeventh, | ||
65 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
66 | [CSR_MHPMEVENT14H] = { "mhpmevent14h", sscofpmf, read_mhpmeventh, | ||
67 | - write_mhpmeventh }, | ||
68 | + write_mhpmeventh, | ||
69 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
70 | [CSR_MHPMEVENT15H] = { "mhpmevent15h", sscofpmf, read_mhpmeventh, | ||
71 | - write_mhpmeventh }, | ||
72 | + write_mhpmeventh, | ||
73 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
74 | [CSR_MHPMEVENT16H] = { "mhpmevent16h", sscofpmf, read_mhpmeventh, | ||
75 | - write_mhpmeventh }, | ||
76 | + write_mhpmeventh, | ||
77 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
78 | [CSR_MHPMEVENT17H] = { "mhpmevent17h", sscofpmf, read_mhpmeventh, | ||
79 | - write_mhpmeventh }, | ||
80 | + write_mhpmeventh, | ||
81 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
82 | [CSR_MHPMEVENT18H] = { "mhpmevent18h", sscofpmf, read_mhpmeventh, | ||
83 | - write_mhpmeventh }, | ||
84 | + write_mhpmeventh, | ||
85 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
86 | [CSR_MHPMEVENT19H] = { "mhpmevent19h", sscofpmf, read_mhpmeventh, | ||
87 | - write_mhpmeventh }, | ||
88 | + write_mhpmeventh, | ||
89 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
90 | [CSR_MHPMEVENT20H] = { "mhpmevent20h", sscofpmf, read_mhpmeventh, | ||
91 | - write_mhpmeventh }, | ||
92 | + write_mhpmeventh, | ||
93 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
94 | [CSR_MHPMEVENT21H] = { "mhpmevent21h", sscofpmf, read_mhpmeventh, | ||
95 | - write_mhpmeventh }, | ||
96 | + write_mhpmeventh, | ||
97 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
98 | [CSR_MHPMEVENT22H] = { "mhpmevent22h", sscofpmf, read_mhpmeventh, | ||
99 | - write_mhpmeventh }, | ||
100 | + write_mhpmeventh, | ||
101 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
102 | [CSR_MHPMEVENT23H] = { "mhpmevent23h", sscofpmf, read_mhpmeventh, | ||
103 | - write_mhpmeventh }, | ||
104 | + write_mhpmeventh, | ||
105 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
106 | [CSR_MHPMEVENT24H] = { "mhpmevent24h", sscofpmf, read_mhpmeventh, | ||
107 | - write_mhpmeventh }, | ||
108 | + write_mhpmeventh, | ||
109 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
110 | [CSR_MHPMEVENT25H] = { "mhpmevent25h", sscofpmf, read_mhpmeventh, | ||
111 | - write_mhpmeventh }, | ||
112 | + write_mhpmeventh, | ||
113 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
114 | [CSR_MHPMEVENT26H] = { "mhpmevent26h", sscofpmf, read_mhpmeventh, | ||
115 | - write_mhpmeventh }, | ||
116 | + write_mhpmeventh, | ||
117 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
118 | [CSR_MHPMEVENT27H] = { "mhpmevent27h", sscofpmf, read_mhpmeventh, | ||
119 | - write_mhpmeventh }, | ||
120 | + write_mhpmeventh, | ||
121 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
122 | [CSR_MHPMEVENT28H] = { "mhpmevent28h", sscofpmf, read_mhpmeventh, | ||
123 | - write_mhpmeventh }, | ||
124 | + write_mhpmeventh, | ||
125 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
126 | [CSR_MHPMEVENT29H] = { "mhpmevent29h", sscofpmf, read_mhpmeventh, | ||
127 | - write_mhpmeventh }, | ||
128 | + write_mhpmeventh, | ||
129 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
130 | [CSR_MHPMEVENT30H] = { "mhpmevent30h", sscofpmf, read_mhpmeventh, | ||
131 | - write_mhpmeventh }, | ||
132 | + write_mhpmeventh, | ||
133 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
134 | [CSR_MHPMEVENT31H] = { "mhpmevent31h", sscofpmf, read_mhpmeventh, | ||
135 | - write_mhpmeventh }, | ||
136 | + write_mhpmeventh, | ||
137 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
138 | |||
139 | [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh }, | ||
140 | [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh }, | ||
141 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
142 | write_mhpmcounterh }, | ||
143 | [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh, | ||
144 | write_mhpmcounterh }, | ||
145 | - [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf }, | ||
146 | + [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf, | ||
147 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
148 | |||
149 | #endif /* !CONFIG_USER_ONLY */ | ||
150 | }; | ||
151 | -- | ||
152 | 2.37.2 | diff view generated by jsdifflib |